📄 blocks.cpp
字号:
{ // Has been included at least once before head.put_bit((included)?1:0); } if (!included) return; // If we get here, the code-block does contribute to the current layer. if (pass_idx == 0) { // First time contribution. Need to get MSB's. for (msbs_wbar=0; msbs_wbar <= msbs_w; ) { // Run tag tree decoder. kd_block *scan, *prev, *next; // Walk up to the root note 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 decoding steps. kdu_byte wbar_min = 0; kdu_byte threshold = msbs_wbar+1; prev = NULL; while (scan != NULL) { if (scan->msbs_wbar < wbar_min) scan->msbs_wbar = wbar_min; while ((scan->msbs_w >= scan->msbs_wbar) && (scan->msbs_wbar < threshold)) { scan->msbs_wbar++; head.put_bit((scan->msbs_w >= scan->msbs_wbar)?0:1); } wbar_min = (scan->msbs_w<scan->msbs_wbar)?scan->msbs_w:scan->msbs_wbar; next=scan->up_down; scan->up_down=prev; prev=scan; scan=next; } } beta = 3; } // Encode number of passes. int val = pending_new_passes - 1; int delta = (val > 1)?1:val; val -= delta; head.put_bit(delta); if (delta) { // new_passes > 1 delta = (val > 1)?1:val; val -= delta; head.put_bit(delta); if (delta) { // new_passes > 2 delta = (val > 3)?3:val; val -= delta; head.put_bits(delta,2); if (delta == 3) { delta = (val > 31)?31:val; val -= delta; head.put_bits(delta,5); if (delta == 31) { delta = (val > 127)?127:val; val -= delta; head.put_bits(delta,7); } } } } assert(val == 0); // Finally, encode the length information. int segment_passes, segment_bytes, total_bytes, length_bits, new_passes, idx; bool bypass_term = ((((int) modes) & Cmodes_BYPASS) != 0); bool all_term = ((((int) modes) & Cmodes_RESTART) != 0); if (all_term) bypass_term = false; // Save buffer status kd_code_buffer *save_current_buf = current_buf; kdu_byte save_buf_pos = buf_pos; // Walk through the coding passes a first time to determine beta. for (total_bytes=0, idx=pass_idx, new_passes=pending_new_passes; new_passes > 0; new_passes-=segment_passes, total_bytes+=segment_bytes, idx+=segment_passes) { if (all_term) segment_passes = 1; else if (bypass_term) { if (idx < 10) segment_passes = 10-idx; else if (((idx-10) % 3) == 0) segment_passes = 2; else segment_passes = 1; if (segment_passes > new_passes) segment_passes = new_passes; } else segment_passes = new_passes; for (length_bits=0; (1<<length_bits) <= segment_passes; length_bits++); length_bits--; length_bits += beta; for (segment_bytes=0, val=segment_passes; val > 0; val--) { get_byte(); get_byte(); delta = get_byte(); delta = (delta<<8) + get_byte(); segment_bytes += delta; } while (segment_bytes >= (1<<length_bits)) { head.put_bit(1); length_bits++; beta++; } } assert(total_bytes == (int) temp_length); head.put_bit(0); // End of the `beta' signalling comma code. // Restore buffer status for second time through current_buf = save_current_buf; buf_pos = save_buf_pos; // Walk through the coding passes a second time to encode the segment lengths for (total_bytes=0, idx=pass_idx, new_passes=pending_new_passes; new_passes > 0; new_passes-=segment_passes, total_bytes+=segment_bytes, idx+=segment_passes) { if (all_term) segment_passes = 1; else if (bypass_term) { if (idx < 10) segment_passes = 10-idx; else if (((idx-10) % 3) == 0) segment_passes = 2; else segment_passes = 1; if (segment_passes > new_passes) segment_passes = new_passes; } else segment_passes = new_passes; for (length_bits=0; (1<<length_bits) <= segment_passes; length_bits++); length_bits--; length_bits += beta; for (segment_bytes=0, val=segment_passes; val > 0; val--) { get_byte(); get_byte(); delta = get_byte(); delta = (delta<<8) + get_byte(); segment_bytes += delta; } assert(segment_bytes < (1<<length_bits)); head.put_bits(segment_bytes,length_bits); } assert(total_bytes == (int) temp_length); if (simulate) { // Restore buffer status so we can try different thresholds for this layer current_buf = save_current_buf; buf_pos = save_buf_pos; } else { // Commit state changes for this layer if (pass_idx == 0) body_bytes_offset = ((kdu_uint16) num_passes) << 2; pass_idx += pending_new_passes; pending_new_passes = 0; }}/*****************************************************************************//* kd_block::write_body_bytes *//*****************************************************************************/void kd_block::write_body_bytes(kdu_output *dest){ if (temp_length == 0) return; int pos = body_bytes_offset; kd_code_buffer *scan = first_buf; while (pos >= KD_CODE_BUFFER_LEN) { pos -= KD_CODE_BUFFER_LEN; scan = scan->next; assert(scan != NULL); } int new_bytes = temp_length; assert((new_bytes+(int) body_bytes_offset) < (2<<16)); body_bytes_offset += temp_length; temp_length = 0; while (new_bytes > 0) { int xfer_bytes = KD_CODE_BUFFER_LEN-pos; assert((xfer_bytes > 0) && (scan != NULL)); if (xfer_bytes > new_bytes) xfer_bytes = new_bytes; new_bytes -= xfer_bytes; dest->write(scan->buf+pos,xfer_bytes); scan = scan->next; pos = 0; } pending_new_passes = 0;}/*****************************************************************************//* STATIC MEMBER kd_block::build_tree *//*****************************************************************************/kd_block * kd_block::build_tree(kdu_coords size, int *return_num_nodes){ int level_nodes, total_nodes, level_idx, num_levels; kdu_coords level_size; total_nodes = level_nodes = size.x*size.y; assert(total_nodes >= 0); level_size = size; num_levels = 1; while (level_nodes > 1) { level_size.x = (level_size.x+1)>>1; level_size.y = (level_size.y+1)>>1; level_nodes = level_size.x*level_size.y; total_nodes += level_nodes; num_levels++; } if (return_num_nodes != NULL) *return_num_nodes = total_nodes; if (total_nodes == 0) return NULL; kd_block *blocks = new kd_block[total_nodes]; memset(blocks,0,(size_t)(sizeof(kd_block)*total_nodes)); kd_block *node, *next; kdu_coords next_size; for (node=blocks, level_size=size, level_idx=0; level_idx < num_levels; level_idx++, level_size=next_size) { next_size.x = (level_size.x+1)>>1; next_size.y = (level_size.y+1)>>1; level_nodes = level_size.x*level_size.y; next = node+level_nodes; for (int y=0; y < level_size.y; y++) for (int x=0; x < level_size.x; x++, node++) { node->up_down = next + (y>>1)*next_size.x + (x>>1); if (level_idx == (num_levels-1)) { assert((x==0) && (y==0)); node->up_down = NULL; } } } assert(node == (blocks+total_nodes)); return blocks;}/*****************************************************************************//* STATIC MEMBER kd_block::reset_output_tree *//*****************************************************************************/void kd_block::reset_output_tree(kd_block *node, kdu_coords size){ bool leaf_node = true; int x, y; if ((size.x == 0) || (size.y == 0)) return; do { if (leaf_node) { x = size.x; y = size.y; node += x*y; } else { for (y=0; y < size.y; y++) for (x=0; x < size.x; x++, node++) { node->msbs_wbar = 0; node->layer_wbar = 0; node->msbs_w = 0xFF; node->layer_w = 0xFFFF; } } size.y = (size.y+1)>>1; size.x = (size.x+1)>>1; leaf_node = false; } while ((x > 1) || (y > 1));}/*****************************************************************************//* STATIC MEMBER kd_block::save_output_tree *//*****************************************************************************/void kd_block::save_output_tree(kd_block *node, kdu_coords size){ bool leaf_node = true; int x, y; if ((size.x == 0) || (size.y == 0)) return; do { for (y=0; y < size.y; y++) for (x=0; x < size.x; x++, node++) { if (leaf_node) { // Commit the pending new coding passes. int buf_pos = node->buf_pos; buf_pos += ((int) node->pending_new_passes)<<2; while (buf_pos > KD_CODE_BUFFER_LEN) { node->current_buf = node->current_buf->next; assert(node->current_buf != NULL); buf_pos -= KD_CODE_BUFFER_LEN; } node->buf_pos = (kdu_byte) buf_pos; node->pass_idx += node->pending_new_passes; node->pending_new_passes = 0; node->save_beta = node->beta; } else { node->save_layer_w = node->layer_w; node->save_layer_wbar = node->layer_wbar; node->save_msbs_wbar = node->msbs_wbar; } } size.y = (size.y+1)>>1; size.x = (size.x+1)>>1; leaf_node = false; } while ((x > 1) || (y > 1));}/*****************************************************************************//* STATIC MEMBER kd_block::restore_output_tree *//*****************************************************************************/void kd_block::restore_output_tree(kd_block *node, kdu_coords size){ bool leaf_node = true; int x, y; if ((size.x == 0) || (size.y == 0)) return; do { if (leaf_node) { for (y=0; y < size.y; y++) for (x=0; x < size.x; x++, node++) node->beta = node->save_beta; } else { // Only restore non-leaf node state. for (y=0; y < size.y; y++) for (x=0; x < size.x; x++, node++) { node->layer_w = node->save_layer_w; node->layer_wbar = node->save_layer_wbar; node->msbs_wbar = node->save_msbs_wbar; } } size.y = (size.y+1)>>1; size.x = (size.x+1)>>1; leaf_node = false; } while ((x > 1) || (y > 1));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -