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

📄 ebcot_decoder.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
  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
    cpu_iterations = 1;
  do {
    success = decode_block_once(master,band,info,extra_lsbs);
    if (!success)
      { /* The `info->num_passes' value should now identify the number of
           passes decoded up to but not including the point at which the
           error occurred.  Further adjust the value of `info->num_passes'
           according to our error tolerance and decode again. */
        int verified_bits;

        assert(master->min_erkeep_bits > 0);
        verified_bits = 0;
        for (n=info->num_passes-1; n >= 0; n--)
          {
            verified_bits += master->incremental_er_bits[n];
            if (verified_bits >= master->min_erkeep_bits)
              break;
          }
        info->num_passes = n+1;
        success = decode_block_once(master,band,info,extra_lsbs);
        assert(success);
      }
    cpu_iterations--;
  } while (cpu_iterations > 0);
  if (self->cpu_time >= 0)
    self->cpu_time += (std_int)(clock()-cpu_time);
  /* End of timed section. */

  /* Copy the interleaved sample buffer into the non-interleaved
     `sample_buffer' array. */

  deinterleave_sample_buffer(master,sample_buffer);

  /* Make any necessary adjustments to compensate for ROI activities at
     the encoder. */

  if (roi_boost_delta)
    {
      if (band->roi_implicit)
        {
          assert(master->roi_mask[0] == NULL);
          undo_roi_boost_using_implicit_mask(sample_buffer,info->rows,
                                             info->cols,
                                             master->sample_row_gap,
                                             roi_boost_delta);
        }
      else
        {
          assert(master->roi_mask[0] != NULL);
          undo_roi_boost_using_mask(sample_buffer,info->rows,info->cols,
                                    master->sample_row_gap,roi_boost_delta,
                                    master->roi_mask);
        }
    }

  /* SAIC TCQ begin */  /* Force signalling for non-fully-decoded
                           inverse TCQ See the note under
                           decoder__pull_line__func in ifc.h for details. */
  if ((info->num_passes == info->max_passes) ||
       ((info->passes[info->max_passes-1].layer_bytes == 0) &&
        (info->num_passes == (info->max_passes - 1)))) {

    int ii;

    for (ii=0; ii<master->sample_row_gap*info->rows; ii++) {
      sample_buffer[ii] |= 1 << (band->extra_lsbs - 1);
    }
  }
  /* SAIC TCQ end */

  /* Release storage used for block code-stream. */

  while ((heap = info->first_unit) != NULL)
    {
      info->first_unit = heap->next;
      self->code_heap_mgr->return_unit(self->code_heap_mgr,heap);
    }
}


/* ========================================================================= */
/* -------------------- Configuration Management Functions ----------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                      set_code_block_dims                           */
/*****************************************************************************/

static void
  set_code_block_dims(stream_in_ref stream, ebcot_component_info_ptr comp_info)
{
  int tnum = comp_info->tnum;
  int instance = comp_info->component_idx;
  int xcb, ycb;

  xcb = 2 + (int)
    stream->get_marker_val(stream,tnum,MARKER_COC_XCB,instance,0);
  ycb = 2 + (int)
    stream->get_marker_val(stream,tnum,MARKER_COC_YCB,instance,0);
  comp_info->master.max_height = (1<<ycb);
  comp_info->master.max_width = (1<<xcb);
}

/*****************************************************************************/
/* STATIC                   set_precinct_partition_dims                      */
/*****************************************************************************/

static void
  set_precinct_partition_dims(stream_in_ref stream,
                              ebcot_component_info_ptr comp_info)
{
  int tnum = comp_info->tnum;
  int instance = comp_info->component_idx;
  ebcot_level_info_ptr lev;
  int x_specs, y_specs, n;

  x_specs = stream->size_marker_elt(stream,tnum,MARKER_COC_PPX,instance);
  y_specs = stream->size_marker_elt(stream,tnum,MARKER_COC_PPY,instance);
  assert(x_specs == y_specs);
  if (x_specs == 0)
    { /* Partition dimensions default to 2^15. */
      for (n=0; n <= comp_info->num_levels; n++)
        {
          lev = comp_info->levels + n;
          lev->ppx = lev->ppy = 15;
        }
    }
  else
    {
      assert(x_specs == (comp_info->num_levels+1));
      for (n=0; n <= comp_info->num_levels; n++)
        {
          lev = comp_info->levels + n;
          lev->ppx = (int)
            stream->get_marker_val(stream,tnum,MARKER_COC_PPX,instance,n);
          lev->ppy = (int)
            stream->get_marker_val(stream,tnum,MARKER_COC_PPY,instance,n);
        }
    }
}

/*****************************************************************************/
/* STATIC                       set_respect_frames                           */
/*****************************************************************************/

static void
  set_respect_frames(stream_in_ref stream, ebcot_component_info_ptr comp_info)
{
  int tnum = comp_info->tnum;
  int instance = comp_info->component_idx;

  if (stream->size_marker_elt(stream,tnum,MARKER_COC_CCB,instance))
    comp_info->respect_frames = (int)
      stream->get_marker_val(stream,tnum,MARKER_COC_CCB,instance,0);
}

/*****************************************************************************/
/* STATIC                        set_mode_flags                              */
/*****************************************************************************/

static void
  set_mode_flags(stream_in_ref stream, ebcot_component_info_ptr comp_info)
{
  int tnum = comp_info->tnum;
  int instance = comp_info->component_idx;
  std_byte mode_byte;

  mode_byte = (std_byte)
    stream->get_marker_val(stream,tnum,MARKER_COC_MOD,instance,0);
  comp_info->master.causal =
    (mode_byte & MODE_FLAG_CAUSAL)?1:0;
  comp_info->master.reset =
    (mode_byte & MODE_FLAG_RESET)?1:0;
  comp_info->master.terminate_each_pass =
    (mode_byte & MODE_FLAG_TERMINATE)?1:0;
  comp_info->master.lazy =
    (mode_byte & MODE_FLAG_LAZY)?1:0;
  comp_info->master.error_resilient_termination =
    (mode_byte & MODE_FLAG_ERTERM)?1:0;
  comp_info->master.segmark =
    (mode_byte & MODE_FLAG_SEGMARK)?1:0;
}

/*****************************************************************************/
/* STATIC                         set_num_layers                             */
/*****************************************************************************/

static void
  set_num_layers(stream_in_ref stream, ebcot_tile_ptr tile)
{
  int tnum = tile->tnum;

  tile->num_layers = (int)
    stream->get_marker_val(stream,tnum,MARKER_COD_LAYERS,0,0);
  assert(tile->num_layers > 0);
}


/* ========================================================================= */
/* ---------------------- Structure Management Functions ------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                  construct_layer_progression                       */
/*****************************************************************************/

static int
  construct_layer_progression(ebcot_tile_ptr tile,
                              ebcot_sequence_ptr seq,
                              int min_level, int min_component,
                              int max_layers, int max_levels,
                              int max_components)
{
  ebcot_component_info_ptr comp_info;
  ebcot_level_info_ptr lev;
  ebcot_precinct_info_ptr precinct;
  int new_packets;
  int layer, n, c, p;

  new_packets = 0;
  for (layer=0; layer < max_layers; layer++)
    for (n=min_level; n < max_levels; n++)
      for (c=min_component; c < max_components; c++)
        {
          comp_info = tile->components + c;
          if (n > comp_info->num_levels)
            continue;
          lev = comp_info->levels + n;
          for (p=0; p < lev->total_precincts; p++)
            {
              precinct = lev->precincts + p;
              if (precinct->sequenced_layers > layer)
                continue;
              assert(precinct->sequenced_layers == layer);
              precinct->sequenced_layers++;
              seq->layer_idx = layer;
              seq->precinct = precinct;
              new_packets++;
              seq++;
            }
        }
  return(new_packets);
}

/*****************************************************************************/
/* STATIC             construct_resolution_layer_progression                 */
/*****************************************************************************/

static int
  construct_resolution_layer_progression(ebcot_tile_ptr tile,
                                         ebcot_sequence_ptr seq,
                                         int min_level, int min_component,
                                         int max_layers, int max_levels,
                                         int max_components)
{
  ebcot_component_info_ptr comp_info;
  ebcot_level_info_ptr lev;
  ebcot_precinct_info_ptr precinct;
  int new_packets;
  int layer, n, c, p;

⌨️ 快捷键说明

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