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

📄 ebcot_decoder.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 3 页
字号:
      else
        { /* This is a refinement pass for this group of siblings. */
          for (feasible_pos=15, n=0; n < 4; n++, feasible_pos--)
            if (((flags >> feasible_pos) & 1) == 0)
              { /* Otherwise, the node's significance is already known. */
                get_uniform_symbol(state,A,C,word,avail,symbol);
                if (symbol)
                  {
                    flags |= (1<<feasible_pos);
                    *(scan->node_update[n]) |= QUAD_PARENT_SIGNIFICANT;
                  }
              }
        }
      scan->flags = flags;
    }
  state->A=A; state->C=C; state->word=word; state->available_bits=avail;
}

/*****************************************************************************/
/* STATIC                     reset_block_contexts                           */
/*****************************************************************************/

static void
  reset_block_contexts(std_short *ctxt, int rows, int cols, int row_gap)
{
  register int c;
  int outside;

  outside = (4-cols) & 3;
  row_gap -= (cols + outside);
  assert(row_gap > 0);
  for (; rows > 0; rows--, ctxt += row_gap)
    {
      for (c=cols; c > 0; c--)
        *(ctxt++) = 0;
      for (c=outside; c > 0; c--)
        *(ctxt++) = OUT_OF_BOUNDS;
    }
}

/*****************************************************************************/
/* STATIC                         decode_block                               */
/*****************************************************************************/

static void
  decode_block(the_decoder_ref self, ifc_int *sample_buffer,
               band_info_ptr band, 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 = &(self->master);
  code_subblock_ptr sblk;
  int block_rows, block_cols;
  int bitplane_idx, last_bitplane, pass_idx, n;
  int max_significant_bit_idx, significant, msb_first;
  clock_t cpu_time = 0;

  master->bit_idx = IMPLEMENTATION_PRECISION-2;
  max_significant_bit_idx = master->bit_idx - info->insignificant_msbs;
  last_bitplane = master->bit_idx - band->extra_lsbs;
  if (band->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; /* Last allowable pass */
      if (pass_idx < info->num_passes)
        info->num_passes = pass_idx+1;
    }
  if (info->total_bytes == 0)
    {
      memset(sample_buffer,0,sizeof(ifc_int)*master->row_gap*info->rows);
      return;
    }
  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. */
      heap_unit_ptr heap;
      int heap_remnant;
      std_int word, *wp;

      heap = info->first_unit;
      wp = heap->words;
      heap_remnant = 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 = HEAP_WORDS; heap=heap->next; wp=heap->words; }
        }
    }

  /* Start of timed section. */

  if (master->cpu_time >= 0)
    cpu_time = clock();

  /* Get ready for the decoding passes. */

  if (band->band_idx == HL_BAND)
    {
      master->sample_buffer =
        self->sample_buffer_heap_mgr->get_buffer(
                                      self->sample_buffer_heap_mgr);
      block_rows = info->cols;
      block_cols = info->rows;
    }
  else
    {
      master->sample_buffer = sample_buffer;
      block_rows = info->rows;
      block_cols = info->cols;
    }
  memset(master->sample_buffer,0,sizeof(ifc_int)*block_rows*master->row_gap);
  for (sblk=master->first_subblock; sblk <= master->last_subblock; sblk++)
    {
      sblk->significant = 0;
      sblk->rows = block_rows - sblk->top_row;
      sblk->cols = block_cols - sblk->left_col;
      if (sblk->rows > master->max_sub_dim)
        sblk->rows = master->max_sub_dim;
      if (sblk->cols > master->max_sub_dim)
        sblk->cols = master->max_sub_dim;
    }
  master->zc_lut = band->zc_lut;
  initialize_quadtree(master);
  ebcot_arith_coder__initialize(&(master->coder_state),info->first_unit,
                                info->total_bytes);
#ifdef LOG_SYMBOLS
  master->coder_state.symbol_log = start_symbol_log(band,info);
#endif /* LOG_SYMBOLS */
  reset_block_contexts(master->context_buffer,block_rows,block_cols,
                       master->row_gap);

  /* Perform the decoding passes. */

  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) && (master->bit_idx <= max_significant_bit_idx))
        {
          significant = 1;
          master->block_update[0] |= QUAD_PARENT_SIGNIFICANT;
        }
      if (significant)
        decode_quadtree(master);
      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)
            {
              pass_function = band->pass_funcs[n];
              master->context_mask = band->pass_masks[n];
              pass_function(master);
              if (n == 0)
                ebcot_arith_coder__renormalize(&(master->coder_state));
            }
        }
    }
#ifdef SYMBOL_LOG
  fclose(master->coder_state.symbol_log);
  master->coder_state.symbol_log = NULL;
#endif /* SYMBOL_LOG */

  if (master->sample_buffer != sample_buffer)
    {
      transpose_sample_buffer(master->sample_buffer,sample_buffer,
                              block_rows,block_cols,master->row_gap);
      self->sample_buffer_heap_mgr->return_buffer(self->sample_buffer_heap_mgr,
                                                  master->sample_buffer);
    }

  /* End of timed section. */

  if (master->cpu_time >= 0)
    master->cpu_time += (long int)(clock()-cpu_time);
}


/* ========================================================================= */
/* ------------------------- Interface Implementation ---------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                        __initialize                                */
/*****************************************************************************/

static void
  __initialize(decoder_ref base, int decomposition, int levels,
               int components, int component_rows[], int component_cols[],
               filter_info_ref info, int profile, int dedicated_bytes,
               int max_extra_bytes, int max_levels, int max_components,
               bitstream_source_ref input, int argc, char *argv[])
{
  the_decoder_ref self = (the_decoder_ref) base;
  component_info_ptr comp;
  level_info_ptr lev;
  code_subblock_ptr subblock;
  int block_dim, block_width, block_height, subblock_dim;
  int num_subs, subs_total, context_size;
  int rows, cols;
  int comp_idx, n, b, r, c, top_row, left_col;

  if (decomposition != DECOMPOSITION__MALLAT)
    {
      fprintf(stderr,"The current implementation of the EBCOT decoder "
              "object\n  does not support anything other than Mallat-style "
              "decompositions!\n");
      exit(-1);
    }

  self->extra_header_bytes = 0;
  self->input = input;
  self->profile = profile;
  get_block_dimensions(self);
  get_layer_info(self);
  self->max_bytes = max_extra_bytes - self->extra_header_bytes;
  block_dim = self->master.max_dim;
  subblock_dim = self->master.max_sub_dim;
  block_width = block_dim;
  block_height = self->max_block_height;
  assert(block_height <= block_dim);
  self->num_levels = levels;
  self->max_levels = max_levels;
  self->num_components = components;
  self->max_components = max_components;
  assert((max_levels <= levels) && (max_components <= components));

  self->components = (component_info_ptr)
    local_malloc(sizeof(component_info)*(size_t) components);
  for (comp_idx=0; comp_idx < components; comp_idx++)
    {
      comp = self->components + comp_idx;
      rows = component_rows[comp_idx];
      cols = component_cols[comp_idx];
      comp->levels = (level_info_ptr)
        local_malloc(sizeof(level_info)*(size_t)(levels+1));
      memset(comp->levels,0,sizeof(level_info)*(size_t)(levels+1));
      for (lev=comp->levels, n=0; n <= levels; n++, lev++)
        {
          lev->component_idx = comp_idx;
          lev->level_idx = n;
          lev->min_band = (n==0)?0:1;
          lev->max_band = 3;
          if (n == levels)
            { /* Special level for whole image to cover degenerate case of a
                 zero level transform. */
              lev->min_band = lev->max_band = 0;
              if (levels > 0)
                lev->max_band = -1;
            }
          lev->layer_tag_bytes = (std_short *)
            local_malloc(sizeof(std_short)*(size_t)(self->bitstream_layers));
          memset(lev->layer_tag_bytes,0,
                 sizeof(std_short)*(size_t)(self->bitstream_layers));
        }
      n = levels; lev = comp->levels + n;
      lev->bands[0].band_rows = rows; lev->bands[0].band_cols = cols;
      while (n > 0)
        {
          n--; lev--;
          lev->bands[HL_BAND].band_cols =
            lev->bands[HH_BAND].band_cols = cols >> 1;
          lev->bands[LL_BAND].band_cols =
            lev->bands[LH_BAND].band_cols = (cols+1)>>1;
          lev->bands[LH_BAND].band_rows =
            lev->bands[HH_BAND].band_rows = rows >> 1;
          lev->bands[LL_BAND].band_rows =
            lev->bands[HL_BAND].band_rows = (rows+1)>>1;
          rows = lev->bands[LL_BAND].band_rows;
          cols = lev->bands[LL_BAND].band_cols;
        }
      for (n=0, lev=comp->levels; n <= levels; n++, lev++)
        for (b=lev->min_band; b <= lev->max_band; b++)
          { /* Complete band initialization. */
            band_info_ptr band = lev->bands + b;
            block_info_ptr block;
            pass_info_ptr passes;
            float step_wmse;
            int extra_lsbs, total_blocks, max_passes;
        
            band->component_idx = comp_idx;
            band->level_idx = n;
            band->band_idx = b;
            info->get_quant_info(info,comp_idx,n,b,
                                 NULL,NULL,&step_wmse,&extra_lsbs);
            max_passes =
              (IMPLEMENTATION_PRECISION-2-extra_lsbs)*PASSES_PER_BITPLANE + 1;
            band->blocks_high = 1 + ((band->band_rows-1) / block_height);
            band->blocks_wide = 1 + ((band->band_cols-1) / block_width);
            band->band_blocks = total_blocks =
              band->blocks_high*band->blocks_wide;
            band->blocks = block = (block_info_ptr)
              local_malloc(sizeof(block_info)*(size_t) total_blocks);
            memset(block,0,sizeof(block_info)*(size_t) total_blocks);
            passes = (pass_info_ptr)
              local_malloc(sizeof(pass_info)*
                           (size_t)(total_blocks*max_passes));
            memset(passes,0,
                   sizeof(pass_info)*(size_t)(total_blocks*max_passes));
            for (top_row=0, r=0; r < band->blocks_high;
                 r++, top_row+=block_height)
              for (left_col=0, c=0; c < band->blocks_wide;
                   c++, left_col+=block_width, block++, passes+=max_passes)
                { /* Complete block initialization. */
                  block->top_row = top_row;
                  block->left_col = left_col;
                  block->rows = band->band_rows - top_row;
                  if (block->rows > block_height)
                    block->rows = block_height;
                  block->cols = band->band_cols - left_col;
                  if (block->cols > block_width)
                    block->cols = block_width;
                  block->passes = passes;
                  block->max_passes = max_passes;
                }
            if (b == HH_BAND)
              band->zc_lut = ebcot_diag_zc_lut;
            else
              band->zc_lut = ebcot_main_zc_lut;
            ebcot_set_pass_funcs_and_masks(band,b);
            band->step_wmse = step_wmse;
            band->extra_lsbs = extra_lsbs;
            band->lines.num_lines = 0;
            band->lines.info = NULL;
            band->lines.buffers = NULL;
          }
    }
  num_subs = 1 + ((block_dim-1) / subblock_dim);
  subs_total = num_subs * num_subs;
  self->master.row_gap = block_dim + 2;
  self->master.first_subblock = subblock = (code_subblock_ptr)
    local_malloc(sizeof(code_subblock)*(size_t) subs_total);
  self->master.last_subblock = subblock + subs_total - 1;
  create_quadtree(num_subs,num_subs,subblock,
                  &(self->master.first_quad),&(self->master.last_quad));
  self->master.block_update = (std_short *) self->master.first_quad;
  if (self->master.block_update == NULL)
    {
      assert(num_subs == 1);
      self->master.block_update = (std_short *) subblock;
    }
  memset(subblock,0,sizeof(code_subblock)*(size_t) subs_total);
  for (top_row=0, r=0; r < num_subs; r++, top_row+=subblock_dim)
    for (left_col=0, c=0; c < num_subs;
         c++, left_col+=subblock_dim, subblock++)
      {
        subblock->top_row = top_row;
        subblock->left_col = left_col;
        subblock->offset = top_row*self->master.row_gap + left_col;
      }
  context_size = self->master.row_gap * (block_dim+2) + 2;
  self->master.context_buffer = (std_short *)
    local_malloc(sizeof(std_short)*(size_t) context_size);
  self->master.context_buffer += self->master.row_gap + 2;
  self->master.coder_state.contexts = self->master.contexts;
  self->master.cpu_time = -1;
  for (r=0; r < argc; r++)
    if (strcmp(argv[r],"-Ccpu") == 0)
      {
        argv[r] = "";
        self->master.cpu_time = 0;

⌨️ 快捷键说明

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