📄 ebcot_decoder.c
字号:
*(sup++) = 0x0000FF00;}/*****************************************************************************//* STATIC consume_segment_marker *//*****************************************************************************/static int consume_segment_marker(block_master_ptr master) /* Original function by Sarnoff, modified by David Taubman. Returns the number of verified bits (i.e. 4) if successful, 0 if error resilient decoding has not been requested, and a large negative number if an error is detected. */{ dst_arith_state_ptr state; std_int areg, code, symbol, n; unsigned long creg; int ct; dst_context_state_ptr csp; state = &(master->coder_state); assert(state->mqd.active); areg = state->mqd.areg; creg = state->mqd.creg; ct = state->mqd.ct; csp = state->contexts + UNI_OFFSET; for (code=0, n=3; n >= 0; n--) { dst_get_symbol(areg,creg,ct,state,symbol,csp); code |= (symbol << n); } state->mqd.areg = areg; state->mqd.creg = creg; state->mqd.ct = ct; if (master->min_erkeep_bits > 0) { if (code != 0x000A) return(-1000); return(4); } return(0);}/*****************************************************************************//* STATIC convert_special_lengths *//*****************************************************************************/static void convert_special_lengths(ebcot_block_info_ptr block) /* This function processes the `ebcot_pass_info' array of the supplied code-block to convert the `special_length' field's interpretation as described in "ebcot_decoder.h" under the definition of `ebcot_pass_info'. Only at this point will the member code-blocks be ready for decoding by the `decode_block' function. The function must be called before the block is actually decoded, but not before the relevant packet has been recovered from the code-stream and reduced in length as required to satisfy any simulated parsing constraint. */{ int layer_bytes, last_layer_bytes, layer_idx; int idx, scn, have_length, length; ebcot_pass_info_ptr passes; assert(!block->special_lengths_converted); /* First convert the `special_length' fields associated with terminated passes to refer to the length of the entire code-stream, rather than the length relative to the last layer boundary. */ passes = block->passes; last_layer_bytes = 0; layer_idx = passes[0].layer_idx; layer_bytes = passes[0].layer_bytes; for (idx=0; idx < block->num_passes; idx++) { if (layer_idx < (int) passes[idx].layer_idx) { last_layer_bytes = layer_bytes; layer_idx = passes[idx].layer_idx; layer_bytes += passes[idx].layer_bytes; } assert(layer_idx == (int) passes[idx].layer_idx); if (passes[idx].terminated) passes[idx].special_length += last_layer_bytes; } /* Now fill in the `special_length' fields of all entries in the `ebcot_pass_info' array to identify the total number of bytes from the start of the code-stream to the end of the next termination point. */ length = have_length = 0; for (idx=0; idx < block->num_passes; idx++) { if (!have_length) { /* Compute length of current segment. */ length = block->total_bytes; for (scn=idx; scn < block->num_passes; scn++) if (passes[scn].terminated) { length = passes[scn].special_length; break; } have_length = 1; } block->passes[idx].special_length = (std_ushort) length; if (block->passes[idx].terminated) have_length = 0; } block->special_lengths_converted = 1;}/*****************************************************************************//* STATIC decode_block_once *//*****************************************************************************/static int decode_block_once(block_master_ptr master, ebcot_band_info_ptr band, ebcot_block_info_ptr info, int extra_lsbs) /* This function performs most of the work of the block decoding process, with the exception of preparatory phases for ROI decoding and bit-stream byte-order reversal and with the exception of the final writing of the decoded output buffer to the storage swath used to serve calls to the `__pull_line' interface function. The reason for isolating the actual decoding code in a separate function from these pre- and post-processing stages is three-fold: 1) it should make the implementation more readable; 2) it eases the construction of accurate timing loops which measure the time taken to decode the same information multiple times to decrease measurement jitter; and 3) it simplifies the implementation of error resilient decoding. The function returns 1 if successful and 0 if an error was detected during decoding. In the latter event the function will be called a second time to decode everything up until the last coding pass which is considered reliable. */{ int bitplane_idx, last_bitplane, pass_idx, n; int max_significant_bit_idx, significant; master->bit_idx = IMPLEMENTATION_PRECISION-2; max_significant_bit_idx = master->bit_idx - info->insignificant_msbs; last_bitplane = master->bit_idx - extra_lsbs; if (extra_lsbs < 1) { /* Cannot decode all bit-planes with current implementation precision. Adjust `last_bitplane' and `info->num_passes'. */ last_bitplane = master->bit_idx-1; pass_idx = last_bitplane * PASSES_PER_BITPLANE; if (pass_idx < info->num_passes) info->num_passes = pass_idx+1; } master->height = info->rows; master->width = info->cols; master->stripes = (master->height+3)>>2; memset(master->interleaved_sample_buffer,0,sizeof(ifc_int) * (size_t)(master->stripes*master->interleaved_row_gap)); /* Get ready for the decoding passes. */ dst_arith_coder__initialize(&(master->coder_state),EBCOT_TOTAL_CONTEXTS, master->contexts,info->first_unit, info->total_bytes, master->error_resilient_termination && (master->min_erkeep_bits > 0)); dst_arith_coder__model_init(&(master->coder_state),initial_mq_contexts); dst_arith_coder__set_segment_size(&(master->coder_state), info->passes[0].special_length);#ifdef DST_LOG_SYMBOLS master->coder_state.symbol_log = start_symbol_log(band,info);#endif /* DST_LOG_SYMBOLS */ reset_block_contexts(master); if (master->speed_up_buffer != NULL) prepare_speedup_buffer(master); if (master->min_erkeep_bits > 0) memset(master->incremental_er_bits,0, sizeof(int)*(size_t) info->num_passes); master->zc_lut = band->zc_lut; /* Perform the decoding passes. */ master->first_bit_idx = -1; for (significant=0, bitplane_idx=0, pass_idx=0; bitplane_idx <= last_bitplane; bitplane_idx++, master->bit_idx--) { if (pass_idx == info->num_passes) break; assert(master->bit_idx > 0); if (!significant) { if (master->bit_idx <= max_significant_bit_idx) { significant = 1; master->first_bit_idx = master->bit_idx; } } for (n=0; n < PASSES_PER_BITPLANE; n++, pass_idx++) { block_coding_pass_func pass_function; if (pass_idx == info->num_passes) break; if (significant) { int verified_bits; pass_function = band->pass_funcs[n]; if (master->reset) dst_arith_coder__model_init(&(master->coder_state), initial_mq_contexts); pass_function(master); verified_bits = 0; if (master->segmark && (n==0)) verified_bits = consume_segment_marker(master); if (info->passes[pass_idx].terminated) { verified_bits += dst_arith_coder__deactivate(&(master->coder_state)); if (pass_idx < (info->num_passes-1)) dst_arith_coder__set_segment_size(&(master->coder_state), info->passes[pass_idx+1].special_length); } if (verified_bits < 0) { assert(master->min_erkeep_bits > 0); info->num_passes = pass_idx; return(0); /* Error detected. */ } master->incremental_er_bits[pass_idx] = verified_bits; } } } dst_arith_coder__terminate(&(master->coder_state));#ifdef DST_LOG_SYMBOLS fclose(master->coder_state.symbol_log); master->coder_state.symbol_log = NULL;#endif /* DST_LOG_SYMBOLS */ return(1);}/*****************************************************************************//* STATIC decode_block *//*****************************************************************************/static void decode_block(ebcot_decoder_ref self, ebcot_tile_ptr tile, ebcot_component_info_ptr comp_info, ifc_int *sample_buffer, ebcot_band_info_ptr band, ebcot_block_info_ptr info) /* Decodes a single block of sample values. The actual dimensions of the block may be found in the `info' structure. The `sample_buffer' array receives the samples organized in lexicographical fashion, with consecutive rows of block samples separated by `self->master.row_gap' samples, which is always larger than the block width. */{ block_master_ptr master = &(comp_info->master); int extra_lsbs, roi_boost_delta, msb_first, n, success, cpu_iterations; dst_heap_unit_ptr heap; clock_t cpu_time = 0; if (info->last_packet_sequence_idx >= tile->available_packets) { retrieve_packet(self,tile,info->last_packet_sequence_idx); assert(info->last_packet_sequence_idx < tile->available_packets); } if (!info->special_lengths_converted) convert_special_lengths(info); /* Check ROI information and determine the actual number of extra LSB's. */ extra_lsbs = band->extra_lsbs; roi_boost_delta = 0; if (band->roi != NULL) { int min_boost; if (master->roi_mask == NULL) master->roi_mask = (std_byte **) local_malloc(EBCOT_MEM_KEY,sizeof(std_byte *)*master->max_height); roi_boost_delta = band->roi->check_roi(band->roi,band->component_idx,band->level_idx, band->band_idx,info->rows,info->cols, info->top_row,info->left_col, &min_boost,master->roi_mask); /* We can completely ignore `min_boost', since this was taken care of implicitly at the encoder by adjusting distortion estimates. */ assert((roi_boost_delta >= 0) && (roi_boost_delta <= band->max_roi_boost)); extra_lsbs -= roi_boost_delta; } /* SAIC TCQ begin mods */ /* Force signalling for inverse TCQ when all indices get decoded to zero. See the note under decoder__pull_line__func in ifc.h for details */ if (info->total_bytes == 0) { if (info->insignificant_msbs == 0) { int ii; for (ii=0; ii< master->sample_row_gap*info->rows; ii++) { sample_buffer[ii] = 1 << (band->extra_lsbs - 1); /* Do not use variable extra_lsbs in above line since that variable is modified during ROI processing */ } } else { memset(sample_buffer,0, sizeof(ifc_int)*(size_t)(master->sample_row_gap*info->rows)); } return; } /* SAIC TCQ end mods */ assert(info->num_passes > 0); /* See if code word byte order needs to be reversed. */ msb_first = 1; *((std_byte *)(&msb_first)) = 0; if (!msb_first) { /* Least significant byte appears first in each code word. Need to reverse this to account for the fact that word buffers were read from the bit-stream as byte buffers. */ int heap_remnant; std_int word, *wp; heap = info->first_unit; wp = heap->words; heap_remnant = DST_HEAP_WORDS; for (n=(info->total_bytes+3)>>2; n > 0; n--) { word = *wp; word = ((word >> 24) & 0x000000FF) | ((word >> 8) & 0x0000FF00) | ((word << 8) & 0x00FF0000) | ((word << 24) & 0xFF000000); *(wp++) = word; if ((--heap_remnant) == 0) { heap_remnant = DST_HEAP_WORDS; heap=heap->next; wp=heap->words; } } } /* Start of timed section. */ if (self->cpu_time >= 0) { cpu_time = clock(); cpu_iterations = EBCOT_CPU_ITERATIONS; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -