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

📄 hp_dummy_encoder.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 2 页
字号:
              if (levels > 0)
                lev->max_band = -1;
            }
          for (b=lev->min_band; b <= lev->max_band; b++)
            {
              int extra_bits;

              info->get_quant_info(info,comp,n,b,NULL,NULL,NULL,&extra_bits);
              lev->bands[b].extra_bits = (ifc_int) extra_bits;
            }
        }
      n--; lev--;
      lev->bands[0].rows = rows; lev->bands[0].cols = cols;
      for (n--, lev--; n >= 0; n--, lev--)
        {
          lev->bands[HL_BAND].cols = lev->bands[HH_BAND].cols = cols >> 1;
          lev->bands[LL_BAND].cols = lev->bands[LH_BAND].cols = (cols+1)>>1;
          lev->bands[LH_BAND].rows = lev->bands[HH_BAND].rows = rows >> 1;
          lev->bands[LL_BAND].rows = lev->bands[HL_BAND].rows = (rows+1)>>1;
          rows = lev->bands[LL_BAND].rows;
          cols = lev->bands[LL_BAND].cols;
        }
    }
}

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

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

/*****************************************************************************/
/* STATIC                        __push_line                                 */
/*****************************************************************************/

static void
  __push_line(encoder_ref base, ifc_int *line_buf, int component_idx,
              int level_idx, int band_idx, int width)
{
  the_encoder_ref self = (the_encoder_ref) base;
  component_info_ptr comp_info;
  ifc_int extra_bits, val, mag, num_bytes, sign, n;
  band_info_ptr band;

  assert(component_idx < self->num_components);
  comp_info = self->components + component_idx;
  band = comp_info->levels[level_idx].bands + band_idx;
  extra_bits = band->extra_bits;

  /* Perform simple run-length coding and push bytes out to bit-stream. */

  assert(width == band->cols);
  num_bytes = (IMPLEMENTATION_PRECISION - extra_bits + 7) >> 3;
  sign = (ifc_int)(1<<((num_bytes<<3)-1));
  for (; width > 0; width--, line_buf++)
    {
      val = *line_buf;
      mag = val & MAX_IFC_MAG;
      mag >>= extra_bits;
      if (mag || (band->run == 255))
        {
          output_byte(self,band,band->run);
          val = (val<0)?(mag|sign):mag;
          for (n=num_bytes; n > 0; n--, val >>= 8)
            output_byte(self,band,(val & 0x00FF));
          band->run = 0;
        }
      else
        band->run++;
    }
}

/*****************************************************************************/
/* STATIC                        __push_block                                */
/*****************************************************************************/

static void
  __push_block(encoder_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 blocks up into lines and ultimately calls the
    `__push_line' function.  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 arrival pattern for the subband data. */

{
  the_encoder_ref self = (the_encoder_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;

  assert(component_idx < self->num_components);
  comp_info = self->components + component_idx;
  band = comp_info->levels[level_idx].bands + band_idx;
  next_row = 0;
  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->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->unfilled_blocks = band->blocks.blocks_per_row;
          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;
        }
      else
        bp = bp->next;
    }
  assert((bp->first_row == top_row) && (bp->unfilled_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 (sp=block_buf[r], dp=bp->rows[r]+left_col, c=block_cols; c > 0; c--)
      *(dp++) = *(sp++);

  /* Check for completed rows of blocks. */

  bp->unfilled_blocks--;
  while ((bp->unfilled_blocks == 0) && (bp == band->blocks.head))
    { /* Push all block rows and then shuffle the record to the tail. */
      for (r=0; r < block_rows; r++)
        __push_line(base,bp->rows[r],
                    component_idx,level_idx,band_idx,band->cols);
      bp->first_row = band->blocks.tail->first_row + band->blocks.block_rows;
      bp->unfilled_blocks = band->blocks.blocks_per_row;
      band->blocks.tail->next = bp;
      band->blocks.tail = bp;
      band->blocks.head = bp->next;
      bp->next = NULL;
      bp = band->blocks.head;
    }
}

/*****************************************************************************/
/* STATIC                        __push_tree                                 */
/*****************************************************************************/

static void
  __push_tree(encoder_ref base, ifc_int **tree_buf, int levels,
              int component_idx, int root_row, int root_col)
{
  the_encoder_ref self = (the_encoder_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;

  assert(component_idx < self->num_components);
  comp_info = self->components + component_idx;
  assert(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<<comp_info->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;
          __push_block(base,row_ptrs,component_idx,lev,b,
                       rows,cols,top_row,left_col);
        }
    }
}

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

static void
  __terminate(encoder_ref base)
{
  the_encoder_ref self = (the_encoder_ref) base;
  heap_group_ptr group;
  int right_endian; /* True if the MSB appears first in each word. */

  right_endian = 1;
  *((std_byte *)(&right_endian)) = 0;

  if (self->components)
    {
      component_info_ptr comp_info;
      level_info_ptr lev;
      int comp, n, max_n, b;
      
      max_n = self->num_levels - 1;
      if (max_n < 0)
        max_n = 0;
      for (n=0; n <= max_n; n++)
        {
          for (comp=0; comp < self->num_components; comp++)
            {
              comp_info = self->components + comp;
              lev = comp_info->levels + n;
              for (b=lev->min_band; b <= lev->max_band; b++)
                { /* Push out the code words for this band. */
                  heap_unit_ptr up;
                  band_info_ptr band;
                  int push_bytes;
                  std_int word;

                  band = lev->bands + b;
                  destroy_block_buffering(&(band->blocks));

                  /* Push out last run. */
                  
                  output_byte(self,band,band->run);
                  band->run = 0;

                  if (band->num_bytes & 3)
                    { /* Flush partial word. */
                      band->word <<= 8*(4 - (band->num_bytes & 3));
                      output_word(self,band);
                    }
            
                  word = band->num_bytes;
                  if (!right_endian)
                    reverse_words(&word,1);
                  self->output->push_bytes(self->output,(std_byte *)(&word),4);

                  while ((push_bytes = band->num_bytes) > 0)
                    {
                      if (push_bytes > HEAP_BYTES)
                        push_bytes = HEAP_BYTES;
                      up = band->store;
                      if (!right_endian)
                        reverse_words(up->words,(push_bytes+3)>>2);
                      self->output->push_bytes(self->output,
                                               (std_byte *)(up->words),
                                               push_bytes);
                      band->store = up->next;
                      return_heap_unit(self,up);
                      band->num_bytes -= push_bytes;
                    }
                }
            }
        }

      for (comp=0; comp < self->num_components; comp++)
        {
          comp_info = self->components + comp;
          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);
    }
  local_free(self);
}

/*****************************************************************************/
/* EXTERN                     create_dummy_encoder                           */
/*****************************************************************************/

encoder_ref
  create_dummy_encoder(void)
{
  the_encoder_ref result;

  result = (the_encoder_ref)
    local_malloc(sizeof(the_encoder_obj));
  memset(result,0,sizeof(the_encoder_obj));
  result->base.initialize = __initialize;
  result->base.print_usage = __print_usage;
  result->base.push_line = __push_line;
  result->base.push_block = __push_block;
  result->base.push_tree = __push_tree;
  result->base.terminate = __terminate;
  return((encoder_ref) result);
}

⌨️ 快捷键说明

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