📄 blocks.cpp
字号:
/*****************************************************************************//* kd_block::read_body_bytes *//*****************************************************************************/void kd_block::read_body_bytes(kd_input *source, kd_buf_server *buf_server){ int body_bytes = this->temp_length; this->temp_length = 0; int xfer_bytes; if (body_bytes == 0) return; if (num_passes == 255) { // Read and discard the code-bytes. assert(first_buf == NULL); kd_code_buffer *tmp_buf = buf_server->get(); while ((body_bytes > 0) && !source->failed()) { xfer_bytes = KD_CODE_BUFFER_LEN; xfer_bytes = (body_bytes < xfer_bytes)?body_bytes:xfer_bytes; source->read(tmp_buf->buf,xfer_bytes); body_bytes -= xfer_bytes; } buf_server->release(tmp_buf); return; } while (body_bytes > 0) { xfer_bytes = KD_CODE_BUFFER_LEN - buf_pos; if (xfer_bytes == 0) { current_buf = current_buf->next = buf_server->get(); buf_pos = 0; xfer_bytes = KD_CODE_BUFFER_LEN; } xfer_bytes = (body_bytes < xfer_bytes)?body_bytes:xfer_bytes; xfer_bytes = source->read(current_buf->buf+buf_pos,xfer_bytes); if (xfer_bytes == 0) break; body_bytes -= xfer_bytes; buf_pos += xfer_bytes; this->num_bytes += xfer_bytes; }}/*****************************************************************************//* kd_block::retrieve_data *//*****************************************************************************/void kd_block::retrieve_data(kdu_block *block, int max_layers){ assert(num_passes < 255); // 255 has the special meaning: "discard block" block->num_passes = 0; // We will increment this as we read them in. block->missing_msbs = msbs_w; if (beta == 0) return; if ((num_bytes+2) > block->max_bytes) block->set_max_bytes(((int) num_bytes)+4096,false); // A generous allocation if (num_passes > block->max_passes) block->set_max_passes(((int) num_passes)+32,false); // A generous allocation int remaining_bytes = num_bytes; kdu_byte *bp = block->byte_buffer; current_buf = first_buf; buf_pos = 0; for (pass_idx=0; pass_idx < num_passes; ) { // Get the layer index for the next contribution. int layer_idx = get_byte(); layer_idx = (layer_idx<<8) + get_byte(); if (layer_idx >= max_layers) break; int new_passes, new_bytes; kdu_byte idx = pass_idx; bool more_headers=true; assert(block->num_passes == (int) pass_idx); while (more_headers) { new_bytes = get_byte(); new_bytes = (new_bytes << 8) + get_byte(); new_passes = get_byte(); more_headers = false; if (new_bytes & (1<<15)) { more_headers = true; new_bytes &= ~(1<<15); } for (; new_passes > 0; new_passes--, new_bytes=0, idx++) { block->pass_lengths[idx] = new_bytes; block->pass_slopes[idx] = 0; } assert(idx <= num_passes); } assert(idx > 0); block->pass_slopes[idx-1] = ((1<<16)-1) - layer_idx; for (; pass_idx < idx; pass_idx++) { new_bytes = block->pass_lengths[pass_idx]; if (new_bytes > remaining_bytes) return; block->num_passes = pass_idx+1; remaining_bytes -= new_bytes; while (new_bytes > 0) { int xfer_bytes = KD_CODE_BUFFER_LEN - buf_pos; if (xfer_bytes == 0) { current_buf = current_buf->next; buf_pos = 0; assert(current_buf != NULL); xfer_bytes = KD_CODE_BUFFER_LEN; } xfer_bytes = (xfer_bytes < new_bytes)?xfer_bytes:new_bytes; new_bytes -= xfer_bytes; while (xfer_bytes--) *(bp++) = current_buf->buf[buf_pos++]; } } }}/*****************************************************************************//* kd_block::store_data *//*****************************************************************************/void kd_block::store_data(kdu_block *block, kd_buf_server *buf_server){ assert(block->modes == (int) modes); assert(block->missing_msbs < 255); assert(block->num_passes <= 255); assert(first_buf == NULL); // Now copy the coding pass summary information. int n, val, total_bytes; msbs_w = (kdu_byte) block->missing_msbs; start_buffering(buf_server); num_passes = (kdu_byte) block->num_passes; total_bytes = 0; for (n=0; n < block->num_passes; n++) { val = block->pass_slopes[n]; assert(val >= 0); put_byte((kdu_byte)(val>>8),buf_server); put_byte((kdu_byte) val,buf_server); val = block->pass_lengths[n]; assert((val >= 0) && (val < (1<<16))); total_bytes += val; put_byte((kdu_byte)(val>>8),buf_server); put_byte((kdu_byte) val,buf_server); } assert(total_bytes <= block->max_bytes); // Finally, copy the code-bytes. kdu_byte *bp = block->byte_buffer; while (total_bytes > 0) { int xfer_bytes = KD_CODE_BUFFER_LEN - buf_pos; if (xfer_bytes == 0) { current_buf = current_buf->next = buf_server->get(); buf_pos = 0; xfer_bytes = KD_CODE_BUFFER_LEN; } xfer_bytes = (xfer_bytes < total_bytes)?xfer_bytes:total_bytes; total_bytes -= xfer_bytes; while (xfer_bytes--) current_buf->buf[buf_pos++] = *(bp++); } current_buf = first_buf; buf_pos = 0;}/*****************************************************************************//* kd_block::trim_data *//*****************************************************************************/bool kd_block::trim_data(kdu_uint16 slope_threshold, kd_buf_server *buf_server){ if (num_passes == 0) return false; // Find the number of passes we can keep. int n; int potential_body_bytes = 0; int max_body_bytes = 0; int max_passes = 0; kd_code_buffer *save_current_buf = current_buf; kdu_byte save_buf_pos = buf_pos; current_buf = first_buf; buf_pos = 0; for (n=0; n < num_passes; n++) { kdu_uint16 slope = get_byte(); slope = (slope<<8) + get_byte(); if ((slope != 0) && (slope <= slope_threshold)) break; // Need to discard this one. kdu_uint16 length = get_byte(); length = (length<<8) + get_byte(); potential_body_bytes += length; if (slope != 0) { max_body_bytes = potential_body_bytes; max_passes = n+1; } } // Restore the counters. current_buf = save_current_buf; buf_pos = save_buf_pos; // Now go back through the data setting additional pass slopes to 0. /* Notice that we do not change `num_passes' for that would prevent us from later locating the body bytes. */ if (n == num_passes) return false; kd_code_buffer *buf_ptr = first_buf; int pos = max_passes << 2; while (pos > KD_CODE_BUFFER_LEN) { buf_ptr = buf_ptr->next; pos -= KD_CODE_BUFFER_LEN; } n = (num_passes-max_passes)<<2; // Number of bytes to set to 0 while (n--) { if (pos == KD_CODE_BUFFER_LEN) { buf_ptr = buf_ptr->next; pos = 0; } buf_ptr->buf[pos++] = 0; } // Now remove the unwanted body bytes. buf_ptr = first_buf; pos = (num_passes<<2) + max_body_bytes; while (pos > KD_CODE_BUFFER_LEN) { buf_ptr = buf_ptr->next; pos -= KD_CODE_BUFFER_LEN; } kd_code_buffer *tmp; while ((tmp=buf_ptr->next) != NULL) { buf_ptr->next = tmp->next; buf_server->release(tmp); } return true;}/*****************************************************************************//* kd_block::start_packet *//*****************************************************************************/int kd_block::start_packet(int layer_idx, kdu_uint16 slope_threshold){ if (layer_idx == 0) { pass_idx = 0; current_buf = first_buf; buf_pos = 0; layer_w = 0xFFFF; if (num_passes == 0) msbs_w = 0xFF; /* We will never include this block. Make sure its `msbs_w' value does not damage the efficiency with with the neighbouring blocks are represented. */ // Reflect `msbs_w' value into higher nodes in the tag tree. for (kd_block *scan=this->up_down; scan != NULL; scan=scan->up_down) if (scan->msbs_w > msbs_w) scan->msbs_w = msbs_w; else break; // No point in going further up the tree. } // Find number of new passes. pending_new_passes = 0; temp_length = 0; if (pass_idx == num_passes) { layer_w = 0xFFFF; // `save_beta' may have been reset by `save_output_tree return 0; } kd_code_buffer *save_current_buf = current_buf; kdu_byte save_buf_pos = buf_pos; int test_length = 0; int test_passes = 0; for (int n=(num_passes-pass_idx); n > 0; n--) { kdu_uint16 slope = get_byte(); slope = (slope<<8) + get_byte(); if ((slope != 0) && (slope <= slope_threshold)) break; kdu_uint16 length = get_byte(); length = (length<<8) + get_byte(); test_passes++; test_length += length; if (slope != 0) { pending_new_passes = test_passes; assert(test_length < (1<<16)); temp_length = (kdu_uint16) test_length; } } current_buf = save_current_buf; buf_pos = save_buf_pos; // See if we need to update tag tree nodes. if (pass_idx == 0) { if (pending_new_passes) { layer_w = (kdu_uint16) layer_idx; for (kd_block *scan=up_down; scan != NULL; scan=scan->up_down) if (scan->layer_w > layer_w) scan->layer_w = layer_w; else break; // No point in going further up the tree. } else layer_w = 0xFFFF; } return temp_length;}/*****************************************************************************//* kd_block::write_packet_header *//*****************************************************************************/void kd_block::write_packet_header(kd_header_out &head, int layer_idx, bool simulate){ // Process inclusion information first bool included = (pending_new_passes > 0); if (pass_idx == 0) { // First time inclusion. assert((included && (layer_w < 0xFFFF)) || ((!included) && (layer_w == 0xFFFF))); kdu_byte save_new_passes=pending_new_passes; // Shares layer_wbar storage layer_wbar = (kdu_uint16) layer_idx; kd_block *scan, *prev, *next; // Walk up to the root node in the tree. scan=this; prev=NULL; while ((next=scan->up_down) != NULL) { scan->up_down=prev; prev=scan; scan=next; } scan->up_down = prev; // Walk back down the tree, performing the encoding steps. kdu_uint16 wbar_min = 0; kdu_uint16 threshold = layer_wbar+1; prev = NULL; while (scan != NULL) { if (scan->layer_wbar < wbar_min) scan->layer_wbar = wbar_min; while ((scan->layer_w >= scan->layer_wbar) && (scan->layer_wbar < threshold)) { scan->layer_wbar++; head.put_bit((scan->layer_w >= scan->layer_wbar)?0:1); } wbar_min = (scan->layer_w<scan->layer_wbar)?scan->layer_w:scan->layer_wbar; next=scan->up_down; scan->up_down=prev; prev=scan; scan=next; } pending_new_passes = save_new_passes; // Finished using layer_wbar now } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -