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

📄 hp_dummy_encoder.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))
#define MAX_IFC_MAG ((ifc_int)(~MIN_IFC_INT))

/* ========================================================================= */
/* ------------------------------ 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 unfilled_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;
    heap_unit_ptr store, tail;
    std_int remaining_words;
    std_int word;
    ifc_int extra_bits;
    std_int run;
    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;

/****************************** Encoder 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_encoder_obj {
    encoder_obj base;
    heap_group_ptr heap;
    int num_levels;
    int num_components;
    component_info_ptr components;
    bitstream_sink_ref output;
  } the_encoder_obj, *the_encoder_ref;


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

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

static heap_unit_ptr
  get_heap_unit(the_encoder_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_encoder_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                        output_word                                 */
/*****************************************************************************/

static void
  output_word(the_encoder_ref self, band_info_ptr band)
{
  if (band->remaining_words == 0)
    {
      heap_unit_ptr unit;

      unit = get_heap_unit(self);
      unit->next = NULL;
      if (band->tail == NULL)
        band->store = band->tail = unit;
      else
        band->tail = band->tail->next = unit;
      band->remaining_words = HEAP_WORDS;
    }
  band->tail->words[HEAP_WORDS-band->remaining_words] = band->word;
  band->remaining_words--;
  band->word = 0;
}

/*****************************************************************************/
/* STATIC                        output_byte                                 */
/*****************************************************************************/

static void
  output_byte(the_encoder_ref self, band_info_ptr band, int byte)
{
  band->num_bytes++;
  band->word <<= 8;
  band->word |= (byte & 0x00FF);
  if ((band->num_bytes & 3) == 0)
    output_word(self,band);
}

/*****************************************************************************/
/* 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_encoder interface functions----------- */
/* ========================================================================= */

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

static void
  __initialize(encoder_ref base, int decomposition, int levels, int components,
               int component_rows[], int component_cols[],
               filter_info_ref info, int required_profile,
               int *supported_profile, int dedicated_bytes,
               int max_extra_bytes, bitstream_sink_ref output,
               int argc, char *argv[])
{
  the_encoder_ref self = (the_encoder_ref) base;
  component_info_ptr comp_info;
  level_info_ptr lev;
  int n, b, comp, profile_flags, rows, cols;

  if (decomposition != DECOMPOSITION__MALLAT)
    {
      fprintf(stderr,"This simple example coding engine does not support "
              "anything other\n  than the standard Mallat decomposition!\n");
      exit(-1);
    }
  profile_flags = PROFILE__RESOLUTION_PROGRESSIVE;
  profile_flags |= PROFILE__RESOLUTION_PARSABLE;
  profile_flags |= PROFILE__COMPONENT_PARSABLE;
  if (required_profile & ~profile_flags)
    {
      fprintf(stderr,"This \"dummy\" coder is non-embedded.  It supports "
              "neither\n  random access, nor SNR scalability!\n");
      exit(-1);
    }
  *supported_profile = profile_flags;
  self->num_levels = levels;
  self->num_components = components;
  self->output = output;
  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++)
    {
      rows = component_rows[comp];
      cols = component_cols[comp];
      comp_info = self->components + comp;
      comp_info->num_levels = levels;
      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].rows = lev->bands[b].cols = 0;
              lev->bands[b].num_bytes = 0;
              lev->bands[b].store = NULL;
              lev->bands[b].tail = NULL;
              lev->bands[b].remaining_words = 0;
              lev->bands[b].word = 0;
              lev->bands[b].run = 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;

⌨️ 快捷键说明

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