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

📄 hp_dummy_decoder.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 2 页
字号:
          comp_info = self->components + comp;
          lev = comp_info->levels + n;
          for (b=lev->min_band; b <= lev->max_band; b++)
            { /* Read in the bit-stream for this subband. */
              int pull_bytes;
              std_int word;

              band = lev->bands + b;
              word = 0x7FFFFFFF;
              if (input->pull_bytes(input,(std_byte *)(&word),4) < 4)
                { word = 0; discard = 1; }
              else
                {
                  if (!right_endian)
                    reverse_words(&word,1);
                  if (!discard)
                    actual_bytes += 4;
                }
              if (discard)
                band->num_bytes = 0;
              else
                {
                  band->num_bytes = word;
                  actual_bytes += band->num_bytes;
                }
              while ((pull_bytes = word) > 0)
                {
                  heap_unit_ptr unit;

                  if (pull_bytes > HEAP_BYTES)
                    pull_bytes = HEAP_BYTES;
                  unit = get_heap_unit(self);
                  unit->next = NULL;
                  if (band->tail == NULL)
                    band->store = band->tail = unit;
                  else
                    band->tail = band->tail->next = unit;
                  if (input->pull_bytes(input,(std_byte *)(unit->words),
                                        pull_bytes) != pull_bytes)
                    break; /* Bit-stream terminated early. */
                  if (!right_endian)
                    reverse_words(unit->words,(pull_bytes+3)>>2);
                  word -= pull_bytes;
                }
              if ((word != 0) || (actual_bytes > max_extra_bytes))
                discard = 1;
              if (discard)
                { /* Bit-stream terminated early or subband should be
                     parsed out */
                  actual_bytes -= band->num_bytes; /* Could be parsed out. */
                  band->num_bytes = 0;
                  while ((band->tail = band->store) != NULL)
                    {
                      band->store = band->tail->next;
                      return_heap_unit(self,band->tail);
                    }
                }
              else
                band->run = input_byte(self,band);
            }
        }
    }
  self->actual_bytes = actual_bytes;
}

/*****************************************************************************/
/* STATIC                         __print_usage                              */
/*****************************************************************************/

static void
  __print_usage(decoder_ref base, FILE *dest)
{
  return; /* No special command-line options for this object. */
}

/*****************************************************************************/
/* STATIC                        __pull_line                                 */
/*****************************************************************************/

static void
  __pull_line(decoder_ref base, ifc_int *line_buf, int component_idx,
              int level_idx, int band_idx, int width)
{
  the_decoder_ref self = (the_decoder_ref) base;
  component_info_ptr comp_info;
  ifc_int extra_bits, val, half_bit;
  std_int big_val, num_bytes, n, down_shift, up_shift;
  band_info_ptr band;

  comp_info = self->components + component_idx;
  assert((component_idx < self->num_components) &&
         (level_idx < comp_info->num_levels));
  band = comp_info->levels[level_idx].bands + band_idx;
  assert(width == band->cols);
  extra_bits = band->extra_bits;
  if (band->consumed_bytes >= band->num_bytes)
    {
      for (; width > 0; width--)
        *(line_buf++) = 0;
      return;
    }

  /* Perform simple run-length decoding. */

  num_bytes = (IMPLEMENTATION_PRECISION - extra_bits + 7) >> 3;
  down_shift = (4-num_bytes)<<3;
  up_shift = 0;
  if (extra_bits < 1)
    {
      down_shift += -extra_bits;
      half_bit = 1;
    }
  else
    {
      up_shift = extra_bits;
      half_bit = (ifc_int)(1<<(extra_bits-1));
    }
  
  for (; width > 0; width--, line_buf++)
    {
      if (band->run)
        {
          *line_buf = 0;
          band->run--;
        }
      else
        {
          big_val=0;
          for (n=num_bytes; n > 0; n--)
            {
              big_val = (big_val >> 8) & 0x00FFFFFF;
              big_val |= input_byte(self,band) << 24;
            }
          if (big_val < 0)
            {
              big_val &= 0x7FFFFFFF;
              big_val >>= down_shift;
              big_val <<= up_shift;
              val = MIN_IFC_INT | ((ifc_int) big_val);
            }
          else
            {
              big_val >>= down_shift;
              big_val <<= up_shift;
              val = (ifc_int) big_val;
            }
          val &= (ifc_int)(~1);
          val |= half_bit;
          *line_buf = val;
          band->run = input_byte(self,band);
        }
    }
  band->lines_decoded++;
}

/*****************************************************************************/
/* STATIC                        __pull_block                                */
/*****************************************************************************/

static void
  __pull_block(decoder_ref base, ifc_int **block_buf, int component_idx,
               int level_idx, int band_idx, int block_rows, int block_cols,
               int top_row, int left_col)

 /* This function buffers up lines retrieved from `__pull_line' in order
    to satisfy block requests.   Any line-based coder would probably
    duplicate this implementation.  Block-based coders may choose to
    implement the function more efficiently in order to optimally
    utilize the block-oriented consumption pattern for the subband data. */

{
  the_decoder_ref self = (the_decoder_ref) base;
  component_info_ptr comp_info;
  band_info_ptr band;
  row_of_blocks_ptr bp;
  ifc_int *sp, *dp;
  int next_row, r, c;

  comp_info = self->components + component_idx;
  assert((component_idx < self->num_components) &&
         (level_idx < comp_info->num_levels));
  band = comp_info->levels[level_idx].bands + band_idx;
  bp = band->blocks.tail;
  if (bp == NULL)
    { /* First call. */
      band->blocks.block_rows = block_rows;
      band->blocks.block_cols = block_cols;
      band->blocks.blocks_per_row = 1 + (band->cols-1)/block_cols;
      next_row = 0;
    }
  else
    next_row = bp->first_row + band->blocks.block_rows;
  bp = band->blocks.head;
  while ((bp == NULL) || (bp->unfetched_blocks < 0) ||
         (bp->first_row < top_row))
    {
      if (bp == NULL)
        {
          bp = (row_of_blocks_ptr) local_malloc(sizeof(row_of_blocks));
          bp->first_row = next_row;
          next_row += band->blocks.block_rows;
          bp->unfetched_blocks = -1; /* Indicates undecoded. */
          bp->rows = (ifc_int **)
            local_malloc(sizeof(ifc_int *) *
                         (size_t)(band->blocks.block_rows));
          for (r=0; r < band->blocks.block_rows; r++)
            bp->rows[r] = (ifc_int *)
              local_malloc(sizeof(ifc_int)*(size_t)(band->cols));
          bp->next = NULL;
          if (band->blocks.tail == NULL)
            band->blocks.head = band->blocks.tail = bp;
          else
            band->blocks.tail = band->blocks.tail->next = bp;
        }
      if (bp->unfetched_blocks < 0)
        { /* Decode all rows in the row of blocks. */
          int current_rows;

          bp->unfetched_blocks = band->blocks.blocks_per_row;
          current_rows = band->rows - bp->first_row;
          if (current_rows > band->blocks.block_rows)
            current_rows = band->blocks.block_rows;
          for (r=0; r < current_rows; r++)
            __pull_line(base,bp->rows[r],component_idx,
                        level_idx,band_idx,band->cols);
        }
      else
        bp = bp->next;
    }
  assert((bp->first_row == top_row) && (bp->unfetched_blocks > 0) &&
         (block_rows <= band->blocks.block_rows) &&
         (block_cols <= band->blocks.block_cols) &&
         ((block_rows+top_row) <= band->rows) &&
         ((block_cols+left_col) <= band->cols));

  /* Copy block contents. */

  for (r=0; r < block_rows; r++)
    for (dp=block_buf[r], sp=bp->rows[r]+left_col, c=block_cols; c > 0; c--)
      *(dp++) = *(sp++);

  /* Check for completed rows of blocks. */

  bp->unfetched_blocks--;
  while ((bp->unfetched_blocks == 0) && (bp == band->blocks.head))
    { /* Shuffle the record to the tail. */
      bp->first_row = band->blocks.tail->first_row + band->blocks.block_rows;
      bp->unfetched_blocks = -1; /* Rows have yet to be pulled out. */
      band->blocks.tail->next = bp;
      band->blocks.tail = bp;
      band->blocks.head = bp->next;
      bp->next = NULL;
      bp = band->blocks.head;
    }
}

/*****************************************************************************/
/* STATIC                        __pull_tree                                 */
/*****************************************************************************/

static void
  __pull_tree(decoder_ref base, ifc_int **tree_buf, int levels,
              int component_idx, int root_row, int root_col)
{
  the_decoder_ref self = (the_decoder_ref) base;
  component_info_ptr comp_info;
  int lev, b, top_row, left_col, rows, cols, max_dim, r, r_off, c_off;
  level_info_ptr li;
  band_info_ptr band;
  ifc_int **row_ptrs;

  comp_info = self->components + component_idx;
  assert((component_idx < self->num_components) &&
         (levels <= comp_info->num_levels));
  if (comp_info->tree_to_block_map == NULL)
    comp_info->tree_to_block_map = (ifc_int **)
      local_malloc(sizeof(ifc_int *)*(size_t)(1<<self->num_levels));
  row_ptrs = comp_info->tree_to_block_map;
  for (lev=0; lev < levels; lev++)
    {
      li = comp_info->levels + lev;
      top_row = root_row << lev;
      left_col = root_col << lev;
      max_dim = 1<<lev;
      for (b=li->min_band; b <= li->max_band; b++)
        {
          band = li->bands + b;
          rows = band->rows - top_row;
          cols = band->cols - left_col;
          if (rows > max_dim)
            rows = max_dim;
          if (cols > max_dim)
            cols = max_dim;
          switch (b) {
            case LL_BAND: r_off = c_off = 0; break;
            case HL_BAND: r_off = 0; c_off = 1<<lev; break;
            case LH_BAND: r_off = 1<<lev; c_off = 0; break;
            case HH_BAND: r_off = 1<<lev; c_off = 1<<lev; break;
            default: assert(0);
          }
          for (r=0; r < rows; r++)
            row_ptrs[r] = tree_buf[r+r_off] + c_off;
          __pull_block(base,row_ptrs,component_idx,lev,b,
                       rows,cols,top_row,left_col);
        }
    }
}

/*****************************************************************************/
/* STATIC                        __terminate                                 */
/*****************************************************************************/

static int
  __terminate(decoder_ref base)
{
  the_decoder_ref self = (the_decoder_ref) base;
  component_info_ptr comp_info;
  heap_group_ptr group;
  int result, comp;

  if (self->components != NULL)
    {
      for (comp=0; comp < self->num_components; comp++)
        {
          int b, n;
          band_info_ptr band;

          comp_info = self->components + comp;
          for (n=0; n <= comp_info->num_levels; n++)
            for (b=0; b < 4; b++)
              {
                band = comp_info->levels[n].bands + b;
                destroy_block_buffering(&(band->blocks));
              }
            local_free(comp_info->levels);
            if (comp_info->tree_to_block_map != NULL)
              local_free(comp_info->tree_to_block_map);
        }
      local_free(self->components);
    }

  /* Free the entire bitstream heap. */

  while ((group=self->heap) != NULL)
    {
      self->heap = group->next;
      local_free(group);
    }
  result = self->actual_bytes;
  local_free(self);
  return(result);
}

/*****************************************************************************/
/* EXTERN                     create_dummy_decoder                           */
/*****************************************************************************/

decoder_ref
  create_dummy_decoder(void)
{
  the_decoder_ref result;

  result = (the_decoder_ref)
    local_malloc(sizeof(the_decoder_obj));
  memset(result,0,sizeof(the_decoder_obj));
  result->base.initialize = __initialize;
  result->base.print_usage = __print_usage;
  result->base.pull_line = __pull_line;
  result->base.pull_block = __pull_block;
  result->base.pull_tree =__pull_tree;
  result->base.terminate = __terminate;
  return((decoder_ref) result);
}

⌨️ 快捷键说明

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