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

📄 ebcot_decoder.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
  std_short *cp;
  std_int *dcp, *dcpp, dbl_out_of_bounds;

  rows = master->height;
  cols = master->width;
  dcpp = (std_int *)(master->interleaved_context_buffer);
  assert((master->interleaved_row_gap & 3) == 0);
  d_gap = master->interleaved_row_gap >> 1;
  dbl_out_of_bounds = (1<<OUT_OF_BOUNDS_POS);
  dbl_out_of_bounds <<= 16;
  dbl_out_of_bounds |= (1<<OUT_OF_BOUNDS_POS);
  for (; rows > 0; rows -= 4, dcpp+=d_gap)
    {
      for (dcp=dcpp, c=cols; c > 0; c--)
        { *(dcp++) = 0; *(dcp++) = 0; }
      for (c=8; c > 0; c--)
        { *(dcp++) = dbl_out_of_bounds; *(dcp++) = dbl_out_of_bounds; }
    }
  if (rows < 0)
    { /* One or more rows in the final stripe is out of bounds. */
      dcpp -= d_gap;
      for (; rows < 0; rows++)
        {
          cp = ((std_short *) dcpp) + (4+rows);
          for (c=cols; c > 0; c--, cp+=4)
            *cp = OUT_OF_BOUNDS;
        }
    }
}

/*****************************************************************************/
/* STATIC                    prepare_speedup_buffer                          */
/*****************************************************************************/

static void
  prepare_speedup_buffer(block_master_ptr master)
{
  int whole_stripes, partial_stripe, r, gap;
  int internal_words, extra_words, c;
  std_int *sup, *supp, boundary_word;

  whole_stripes = master->stripes;
  partial_stripe = 0;
  if (master->height & 3)
    { whole_stripes--; partial_stripe = 1; }
  internal_words = master->width >> 3;
  c = master->width - (internal_words<<3);
  boundary_word = ((-1)<<(c+9)) & 0x0000FF00;
  extra_words = 2; /* Beyond the boundary word. */
  gap = master->speed_up_row_gap;
  if ((internal_words+extra_words+1) > gap)
    extra_words--;
  assert((internal_words+extra_words+1) <= gap);
  for (supp=master->speed_up_buffer, r=whole_stripes; r > 0; r--, supp+=gap)
    {
      for (sup=supp, c=internal_words; c > 0; c--)
        *(sup++) = 0;
      *(sup++) = boundary_word;
      for (c=extra_words; c > 0; c--)
        *(sup++) = 0x0000FF00;
    }
  if (partial_stripe)
    for (sup=supp, c=internal_words+extra_words+1; c > 0; 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. */

{
  ebcot_precinct_info_ptr precinct;
  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;

/* Begin DST POC mod */
  precinct = info->precinct;
  while (precinct->recovered_layers < precinct->max_recoverable_layers)
    retrieve_next_packet(self);
/* End DST POC mod */
  if (!info->special_lengths_converted)
    convert_special_lengths(info);

  /* Check ROI information and determine the actual number of extra LSB's. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -