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

📄 hpdz_dequant.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 <math.h>
#include <assert.h>
#include <line_block_ifc.h>

static ifc_int low_seven_3_8_lut[128];
static ifc_int high_seven_3_8_lut[128];
#if (IMPLEMENTATION_PRECISION == 32)
  static ifc_int very_high_seven_3_8_lut[256];
  static ifc_int ultra_high_seven_3_8_lut[256];
#endif /* IMPLEMENTATION_PRECISION */

/* ========================================================================= */
/* ---------------- Implementation of deadzone dequantizer ----------------- */
/* ========================================================================= */

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

typedef
  struct quant_info {
    float scale; /* Scaling factor for floating point data. */
    ifc_int left_shift; /* Left shift for fixed-point data.  May be -ve. */
  } quant_info, *quant_info_ptr;

typedef
  struct component_info {
    int num_levels;
    int num_bands; /* Number of bands per resolution level, per component. */
    quant_info_ptr info;
    float **tree_scales;
    ifc_int **tree_shifts;
  } component_info, *component_info_ptr;

typedef
  struct dz_dequantizer_obj {
    dequantizer_obj base;
    int num_components;
    int num_levels;
    int num_bands; /* Number of bands per resolution level, per component. */
    component_info_ptr components;
    int three_eighths; /* true if using 3/8 rule for representation levels. */
    decoder_ref decoder;
  } dz_dequantizer_obj, *dz_dequantizer_ref;


/* ========================================================================= */
/* --------------------------- Functional Macros --------------------------- */
/* ========================================================================= */

#if (IMPLEMENTATION_PRECISION == 16)
#  define three_eighths_convert(_val) \
    { \
      if (_val) \
        { \
          if (_val & 0x007F) \
            _val += low_seven_3_8_lut[_val & 0x007F]; \
          else \
            _val += high_seven_3_8_lut[(_val>>7) & 0x007F]; \
        } \
    }
#else
#  define three_eighths_convert(_val) \
    { \
      if (_val) \
        { \
          if (_val & 0x0000007F) \
            _val += low_seven_3_8_lut[_val & 0x0000007F]; \
          else if ((_val>>7) & 0x0000007F) \
            _val += high_seven_3_8_lut[(_val>>7) & 0x0000007F]; \
          else if ((_val>>14) & 0x000000FF) \
            _val += very_high_seven_3_8_lut[(_val>>14) & 0x000000FF]; \
          else \
            _val += ultra_high_seven_3_8_lut[(_val>>22) & 0x000000FF]; \
        } \
    }
#endif /* IMPLEMENTATION_PRECISION */

/*****************************************************************************/
/* STATIC                      initialize_3_8_luts                           */
/*****************************************************************************/

static void
  initialize_3_8_luts(void)
{
  ifc_int lsb, c, *lut, offset;

  lut = low_seven_3_8_lut;
  for (lut[0]=0, c=1; c < 128; c++)
    lut[c] = 1; /* Until we set real values. */
  for (lsb=0; lsb < 7; lsb++)
    {
      offset = -(1<<lsb); /* Offset to remove the signalling bit (1/2). */
      if (lsb < 2)
        offset += 1<<lsb; /* Add 1/2. */
      else
        offset += 3<<(lsb-2); /* Add 3/8. */
      for (c=0; c < (1<<(6-lsb)); c++)
        lut[(c+c+1)<<lsb] = offset;
    }
  for (c=0; c < 128; c++)
    assert(lut[c] <= 0);

  lut = high_seven_3_8_lut;
  for (lut[0]=0, c=1; c < 128; c++)
    lut[c] = 1; /* Until we set real values. */
  for (lsb=0; lsb < 7; lsb++)
    {
      offset = -(1<<(lsb+7)); /* Offset to remove the signalling bit (1/2). */
      offset += 3<<(lsb+7-2); /* Add 3/8. */
      for (c=0; c < (1<<(6-lsb)); c++)
        lut[(c+c+1)<<lsb] = offset;
    }
  for (c=0; c < 128; c++)
    assert(lut[c] <= 0);

#if (IMPLEMENTATION_PRECISION == 32)
  lut = very_high_seven_3_8_lut;
  for (lut[0]=0, c=1; c < 256; c++)
    lut[c] = 1; /* Until we set real values. */
  for (lsb=0; lsb < 8; lsb++)
    {
      offset = -(1<<(lsb+14)); /* Offset to remove the signalling bit (1/2). */
      offset += 3<<(lsb+14-2); /* Add 3/8. */
      for (c=0; c < (1<<(7-lsb)); c++)
        lut[(c+c+1)<<lsb] = offset;
    }
  for (c=0; c < 256; c++)
    assert(lut[c] <= 0);

  lut = ultra_high_seven_3_8_lut;
  for (lut[0]=0, c=1; c < 256; c++)
    lut[c] = 1; /* Until we set real values. */
  for (lsb=0; lsb < 8; lsb++)
    {
      offset = -(1<<(lsb+22)); /* Offset to remove the signalling bit (1/2). */
      offset += 3<<(lsb+22-2); /* Add 3/8. */
      for (c=0; c < (1<<(7-lsb)); c++)
        lut[(c+c+1)<<lsb] = offset;
    }
  for (c=0; c < 256; c++)
    assert(lut[c] <= 0);
#endif /* IMPLEMENTATION_PRECISION == 32 */
}

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

static void
  __initialize(dequantizer_ref base, int decomposition, int levels,
               int components, int component_rows[], int component_cols[],
               filter_info_ref info, decoder_ref decoder,
               int argc, char *argv[])
{
  dz_dequantizer_ref self = (dz_dequantizer_ref) base;
  component_info_ptr comp_info;
  quant_info_ptr qi;
  int comp, n, b, b1, b2;
  float step_size;
  int exponent, extra_lsbs;

  self->three_eighths = 0;
  for (n=0; n < argc; n++)
    if (strcmp(argv[n],"-Q3_8") == 0)
      {
        argv[n] = "";
        self->three_eighths = 1;
      }
  self->num_components = components;
  self->num_levels = levels;
  if (decomposition == DECOMPOSITION__MALLAT)
    self->num_bands = 4;
  else
    {
      assert(decomposition == DECOMPOSITION__SPACL);
      self->num_bands = 16;
    }
  self->decoder = decoder;
  if (self->three_eighths)
    initialize_3_8_luts();
  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 = self->num_levels;
      comp_info->num_bands = self->num_bands;
      comp_info->info = qi = (quant_info_ptr)
        local_malloc(sizeof(quant_info)*(size_t)(self->num_bands*levels+1));
      for (n=0; n <= levels; n++)
        for (b=0; b < comp_info->num_bands; b++)
          {
            b1 = (b&3);
            b2 = (b>>2);
            if (((n > 0) && (n < levels) && (b1==0)) ||
                ((n == levels) && (b > 0)))
              continue;
            info->get_quant_info(info,comp,n,b,&step_size,&exponent,
                                 NULL,&extra_lsbs);
            if (extra_lsbs > 0)
              step_size = step_size / ((float)(1<<extra_lsbs));
            else if (extra_lsbs < 0)
              step_size = step_size * ((float)(1<<-extra_lsbs));
            qi[self->num_bands*n+b].scale = step_size;
            qi[self->num_bands*n+b].left_shift =
              (ifc_int)(exponent - extra_lsbs);
          }
    }
}

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

static void
  __print_usage(dequantizer_ref base, FILE *dest)
{
  fprintf(dest,">> HP Deadzone Dequantizer arguments:\n"
          "   -Q3_8 -- forces representation levels to 3/8 of a\n"
          "            step above the threshold, rather than midway\n"
          "            between one threshold and the next.\n");
}

/*****************************************************************************/
/* STATIC                      __pull_line_float                             */
/*****************************************************************************/

static void
  __pull_line_float(dequantizer_ref base, float *line_buf,
                    int component_idx, int level_idx, int band_idx, int width)
{
  dz_dequantizer_ref self = (dz_dequantizer_ref) base;
  component_info_ptr comp_info;
  float scale, *dp;
  ifc_int *cast_buf, *sp, val;
  int i;

  comp_info = self->components + component_idx;
  assert((component_idx < self->num_components) &&
         (band_idx < comp_info->num_bands));
  scale = comp_info->info[comp_info->num_bands*level_idx+band_idx].scale;
  cast_buf = (ifc_int *) line_buf;
  self->decoder->pull_line(self->decoder,cast_buf,
                           component_idx,level_idx,band_idx,width);  
  if (self->three_eighths)
    for (i=width, dp=line_buf+i-1, sp=cast_buf+i-1; i > 0; i--, sp--, dp--)
      {
        val = *sp;
        three_eighths_convert(val);
        val = (val<0)?(MIN_IFC_INT-val):val; /* Convert to two's-complement. */
        *dp = ((float) val) * scale;
      }
  else
    for (i=width, dp=line_buf+i-1, sp=cast_buf+i-1; i > 0; i--, sp--, dp--)
      {
        val = *sp;
        val = (val<0)?(MIN_IFC_INT-val):val; /* Convert to two's-complement. */
        *dp = ((float) val) * scale;
      }
}

/*****************************************************************************/
/* STATIC                      __pull_line_fixed                             */
/*****************************************************************************/

static void
  __pull_line_fixed(dequantizer_ref base, ifc_int *line_buf,
                    int component_idx, int level_idx, int band_idx, int width)
{
  dz_dequantizer_ref self = (dz_dequantizer_ref) base;
  component_info_ptr comp_info;
  ifc_int *sp, shift, val;
  int i;

  comp_info = self->components + component_idx;
  assert((component_idx < self->num_components) &&
         (band_idx < comp_info->num_bands));
  shift = comp_info->info[comp_info->num_bands*level_idx+band_idx].left_shift;
  self->decoder->pull_line(self->decoder,line_buf,
                           component_idx,level_idx,band_idx,width);
  if (self->three_eighths)
    {
      if (shift == 0)
        for (sp=line_buf, i=width; i > 0; i--, sp++)
          { /* The `shift'=0 case occurs almost always in practice. */
            val = *sp;
            three_eighths_convert(val);
            val = (val<0)?(MIN_IFC_INT-val):val;
            *sp = val;
          }
      else if (shift > 0)
        for (sp=line_buf, i=width; i > 0; i--, sp++)
          {
            val = *sp;
            three_eighths_convert(val);
            if (val < 0)
              val = - ((val & MAX_IFC_MAG) << shift);
            else
              val <<= shift;
            *sp = val;
          }
      else
        for (shift=-shift, sp=line_buf, i=width; i > 0; i--, sp++)
          {
            val = *sp;
            three_eighths_convert(val);
            if (val < 0)
              val = - ((val & MAX_IFC_MAG) >> shift);
            else
              val >>= shift;
            *sp = val;
          }
    }
  else
    {
      if (shift == 0)
        for (sp=line_buf, i=width; i > 0; i--, sp++)
          { /* The `shift'=0 case occurs almost always in practice. */
            val = *sp;
            val = (val<0)?(MIN_IFC_INT-val):val;
            *sp = val;
          }
      else if (shift > 0)
        for (sp=line_buf, i=width; i > 0; i--, sp++)
          {
            val = *sp;
            if (val < 0)
              val = - ((val & MAX_IFC_MAG) << shift);
            else
              val <<= shift;
            *sp = val;
          }
      else
        for (shift=-shift, sp=line_buf, i=width; i > 0; i--, sp++)
          {
            val = *sp;
            if (val < 0)
              val = - ((val & MAX_IFC_MAG) >> shift);
            else
              val >>= shift;
            *sp = val;
          }
    }
}

/*****************************************************************************/
/* STATIC                     __pull_block_float                             */
/*****************************************************************************/

static void
  __pull_block_float(dequantizer_ref base, float **block_buf,
                     int component_idx, int level_idx, int band_idx,
                     int block_rows, int block_cols,
                     int top_row, int left_col)
{

⌨️ 快捷键说明

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