⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ebcot_decoder.c

📁 关于视频压缩的jpeg2000压缩算法,C编写
💻 C
📖 第 1 页 / 共 5 页
字号:
      *(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 + -