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

📄 hp_dummy_decoder.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company                                   */
/* All rights reserved                                                       */
/* Author: David Taubman                                                     */
/* Version: V2.0                                                             */
/* Last Revised: 9/22/98                                                     */
/*****************************************************************************/
#include <local_heap.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <line_block_ifc.h>

#define MIN_IFC_INT (((ifc_int) 1)<<(IMPLEMENTATION_PRECISION-1))

/* ========================================================================= */
/* ------------------------------ Definitions ------------------------------ */
/* ========================================================================= */

/******************************** Basic Types ********************************/

#if (INT_MAX == 2147483647)
  typedef int std_int;
#elif (LONG_MAX == 2147483647)
  typedef long int std_int
#else
#error "Platform does not support 32-bit integers"
#endif

typedef short int std_short;

typedef unsigned char std_byte;


/******************************* Heap Manager ********************************/

#define HEAP_WORDS 64
#define HEAP_BYTES (HEAP_WORDS*4)
#define HEAP_GROUP_UNITS 64

typedef
  struct heap_unit {
    std_int words[HEAP_WORDS];
    struct heap_unit *next;
    struct heap_group *group;
    int in_use;
  } heap_unit, *heap_unit_ptr;
  /* This structure is used to manage the dynamic memory consumption
     associated with compressed bit-streams.  Heap units are managed
     within larger `heap_group' structures to minimize the impact of
     dynamic memory allocation on implementation efficiency.  The
     `group' field points to the group to which the heap unit belongs,
     while the `in_use' flag indicates whether or not the heap unit
     is currently being used to hold compressed bit-stream information. */

typedef
  struct heap_group {
    heap_unit units[HEAP_GROUP_UNITS];
    int free_units;
    struct heap_group *next;
  } heap_group, *heap_group_ptr;
  /* This structure is used to allocate and manage multiple heap units
     at once for improved efficiency.  All heap units managed by the
     encoder/decoder are chained via their `next' fields. */

/***************************** Block Buffering *******************************/

typedef
  struct row_of_blocks {
    int first_row;
    int unfetched_blocks;
    ifc_int **rows;
    struct row_of_blocks *next;
  } row_of_blocks, *row_of_blocks_ptr;

typedef
  struct block_buffering {
    int block_rows, block_cols;
    int blocks_per_row;
    row_of_blocks_ptr head, tail;
  } block_buffering, *block_buffering_ptr;

/**************************** Subband Structure ******************************/

typedef
  struct band_info {
    int rows, cols;
    int num_bytes;
    int consumed_bytes;
    heap_unit_ptr store, tail;
    std_int consumed_words;
    std_int word;
    ifc_int extra_bits;
    std_int run;
    int lines_decoded;
    block_buffering blocks;
  } band_info, *band_info_ptr;

typedef
  struct level_info {
    int min_band;
    int max_band;
    band_info bands[4];
  } level_info, *level_info_ptr;

/****************************** Decoder Object *******************************/

typedef
  struct component_info {
    int num_levels;
    level_info_ptr levels;
    ifc_int **tree_to_block_map;
  } component_info, *component_info_ptr;

typedef
  struct the_decoder_obj {
    decoder_obj base;
    heap_group_ptr heap;
    int num_levels;
    int num_components;
    component_info_ptr components;
    int actual_bytes;
  } the_decoder_obj, *the_decoder_ref;


/* ========================================================================= */
/* ------------------ Internal non-interface functions --------------------- */
/* ========================================================================= */


/*****************************************************************************/
/* STATIC                       get_heap_unit                                */
/*****************************************************************************/

static heap_unit_ptr
  get_heap_unit(the_decoder_ref self)
 /* Utility function providing efficient management of storage for
    holding one or more dynamically growing bitstreams. */
{
  heap_group_ptr scan;
  heap_unit_ptr unit;
  int i;

  for (scan=self->heap; scan != NULL; scan=scan->next)
    if (scan->free_units)
      break;
  if (scan == NULL)
    {
      scan = (heap_group_ptr)
        local_malloc(sizeof(heap_group));
      scan->next = self->heap;
      self->heap = scan;
      scan->free_units = HEAP_GROUP_UNITS;
      for (unit=scan->units, i=HEAP_GROUP_UNITS; i > 0; i--, unit++)
        {
          unit->next = NULL;
          unit->in_use = 0;
          unit->group = scan;
        }
    }
  for (unit=scan->units, i=HEAP_GROUP_UNITS; i > 0; i--, unit++)
    if (!unit->in_use)
      break;
  assert(i > 0);
  scan->free_units--;
  unit->in_use = 1;
  unit->next = NULL;
  return(unit);
}

/*****************************************************************************/
/* STATIC                     return_heap_unit                               */
/*****************************************************************************/

static void
  return_heap_unit(the_decoder_ref self, heap_unit_ptr unit)
 /* Utility function; returns bitstream storage allocated
    by `get_heap_unit'. */
{
  heap_group_ptr group;

  group = unit->group;
  assert(unit->in_use && (group->free_units < HEAP_GROUP_UNITS));
  group->free_units++;
  unit->in_use = 0;
}

/*****************************************************************************/
/* STATIC                         input_word                                 */
/*****************************************************************************/

static void
  input_word(the_decoder_ref self, band_info_ptr band)
{
  assert(band->consumed_bytes < band->num_bytes);
  band->word = band->store->words[band->consumed_words];
  band->consumed_words++;
  if (band->consumed_words == HEAP_WORDS)
    {
      heap_unit_ptr tmp;

      tmp = band->store;
      band->store = tmp->next;
      return_heap_unit(self,tmp);
      band->consumed_words = 0;
    }
}

/*****************************************************************************/
/* STATIC                         input_byte                                 */
/*****************************************************************************/

static int
  input_byte(the_decoder_ref self, band_info_ptr band)
{
  int result;

  if ((band->consumed_bytes & 3) == 0)
    input_word(self,band);
  result = (band->word >> 24) & 0x00FF;
  band->word <<= 8;
  band->consumed_bytes++;
  return(result);
}

/*****************************************************************************/
/* STATIC                       reverse_words                                */
/*****************************************************************************/

static void
  reverse_words(std_int *words, int num_words)
 /* Reverses the byte order in each of the `num_words' entries of the `words'
    array. */
{
  std_int val;

  for (; num_words > 0; num_words--, words++)
    {
      val = *words;
      val = ((val >> 24) & 0x000000FF)
          | ((val >> 8)  & 0x0000FF00)
          | ((val << 8)  & 0x00FF0000)
          | ((val << 24) & 0xFF000000);
      *words = val;
    }
}

/*****************************************************************************/
/* STATIC                    destroy_block_buffering                         */
/*****************************************************************************/

static void
  destroy_block_buffering(block_buffering_ptr blocks)
{
  row_of_blocks_ptr bp;
  int r;

  while ((bp=blocks->head) != NULL)
    {
      blocks->head = bp;
      for (r=0; r < blocks->block_rows; r++)
        local_free(bp->rows[r]);
      local_free(bp->rows);
      local_free(bp);
    }
}


/* ========================================================================= */
/* ---------- Implementation of dummy_decoder interface functions----------- */
/* ========================================================================= */

/*****************************************************************************/
/* 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_info;
  int comp, n, b, actual_bytes, rows, cols;
  level_info_ptr lev;
  band_info_ptr band;
  int right_endian; /* True if the MSB appears first in each word. */

  if (decomposition != DECOMPOSITION__MALLAT)
    {
      fprintf(stderr,"This simple example decoding engine does not support "
              "anything other\n  than the standard Mallat decomposition!\n");
      exit(-1);
    }
  assert(profile == (PROFILE__RESOLUTION_PARSABLE |
                     PROFILE__RESOLUTION_PROGRESSIVE |
                     PROFILE__COMPONENT_PARSABLE));
    /* The bit-stream produced by this coder has only one order, which is
       resolution progressive. */

  self->num_levels = levels;
  self->num_components = components;
  self->components = (component_info_ptr)
    local_malloc(sizeof(component_info)*(size_t) components);
  memset(self->components,0,sizeof(component_info)*(size_t) components);
  for (comp=0; comp < components; comp++)
    {
      comp_info = self->components + comp;
      comp_info->num_levels = levels;
      rows = component_rows[comp];
      cols = component_cols[comp];
      comp_info->levels = lev = (level_info_ptr)
        local_malloc(sizeof(level_info)*(size_t)(levels+1));
      for (n=0; n <= levels; n++, lev++)
        {
          for (b=0; b < 4; b++)
            {
              lev->bands[b].num_bytes = 0;
              lev->bands[b].consumed_bytes = 0;
              lev->bands[b].store = NULL;
              lev->bands[b].tail = NULL;
              lev->bands[b].consumed_words = 0;
              lev->bands[b].word = 0;
              lev->bands[b].run = 0;
              lev->bands[b].lines_decoded = 0;
              lev->bands[b].blocks.head = lev->bands[b].blocks.tail = NULL;
            }
          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;
            }
          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;
        }
    }

  /* Now we read in the bit-stream. */

  right_endian = 1;
  *((std_byte *)(&right_endian)) = 0;
  actual_bytes = 0;
  for (n=0; n < levels; n++)
    {
      for (comp=0; comp < components; comp++)
        {
          int discard;

          discard = 0;
          if ((n >= max_levels) || (comp >= max_components) ||
              (actual_bytes >= max_extra_bytes))
            discard = 1;

⌨️ 快捷键说明

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