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

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

/* ========================================================================= */
/* ----------------- Implementation of deadzone quantizer ------------------ */
/* ========================================================================= */

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

typedef
  struct quant_info {
    float scale; /* Scaling factor for floating point data. */
    ifc_int right_shift; /* Right 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_quantizer_obj {
    quantizer_obj base;
    int num_components;
    int num_levels;
    int num_bands; /* Number of bands per resolution level, per component. */
    component_info_ptr components;
    encoder_ref encoder;
  } dz_quantizer_obj, *dz_quantizer_ref;


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

static void
  __initialize(quantizer_ref base, int decomposition, int levels,
               int components, int component_rows[], int component_cols[],
               filter_info_ref info, encoder_ref encoder,
               int argc, char *argv[])
{
  dz_quantizer_ref self = (dz_quantizer_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->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->encoder = encoder;
  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);
            qi[self->num_bands*n+b].scale =
              ((float)(1<<extra_lsbs)) / step_size;
            qi[self->num_bands*n+b].right_shift =
              (ifc_int)(exponent - extra_lsbs);
          }
    }
}

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

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

/*****************************************************************************/
/* STATIC                      __push_line_float                             */
/*****************************************************************************/

static void
  __push_line_float(quantizer_ref base, float *line_buf,
                    int component_idx, int level_idx, int band_idx, int width)
{
  dz_quantizer_ref self = (dz_quantizer_ref) base;
  component_info_ptr comp_info;
  float scale, *sp;
  ifc_int *cast_buf, *dp, 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;
  for (sp=line_buf, dp=cast_buf, i=width; i > 0; i--, sp++, dp++)
    {
      val = (ifc_int)(*sp * scale);
      val = (val<0)?(MIN_IFC_INT-val):val; /* Convert to sign-mag. */
      *dp = val;
    }
  self->encoder->push_line(self->encoder,cast_buf,
                           component_idx,level_idx,band_idx,width);  
}

/*****************************************************************************/
/* STATIC                      __push_line_fixed                             */
/*****************************************************************************/

static void
  __push_line_fixed(quantizer_ref base, ifc_int *line_buf,
                    int component_idx, int level_idx, int band_idx, int width)
{
  dz_quantizer_ref self = (dz_quantizer_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].right_shift;
  if (shift == 0)
    for (sp=line_buf, i=width; i > 0; i--, sp++)
      { /* It can be shown that the `shift'=0 case occurs almost always. */
        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 = MIN_IFC_INT + ((-val) >> 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 = MIN_IFC_INT + ((-val) << shift);
        else
          val <<= shift;
        *sp = val;
      }
  self->encoder->push_line(self->encoder,line_buf,
                           component_idx,level_idx,band_idx,width);
}

/*****************************************************************************/
/* STATIC                     __push_block_float                             */
/*****************************************************************************/

static void
  __push_block_float(quantizer_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)
{
  dz_quantizer_ref self = (dz_quantizer_ref) base;
  component_info_ptr comp_info;
  float scale, *sp, **spp;
  ifc_int **cast_buf, *dp, **dpp, val;
  int i, j;

  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 **) block_buf;
  for (spp=block_buf, dpp=cast_buf, j=block_rows; j > 0; j--, spp++, dpp++)
    for (sp=*spp, dp=*dpp, i=block_cols; i > 0; i--, sp++, dp++)
      {
        val = (ifc_int)(*sp * scale);
        val = (val<0)?(MIN_IFC_INT-val):val;
        *dp = val;
      }
  self->encoder->push_block(self->encoder,cast_buf,component_idx,level_idx,
                            band_idx,block_rows,block_cols,top_row,left_col);
}

/*****************************************************************************/
/* STATIC                     __push_block_fixed                             */
/*****************************************************************************/

static void
  __push_block_fixed(quantizer_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)
{
  dz_quantizer_ref self = (dz_quantizer_ref) base;
  component_info_ptr comp_info;
  ifc_int *sp, **spp, shift, val;
  int i, j;

  comp_info = self->components + component_idx;
  assert((component_idx < self->num_components) &&

⌨️ 快捷键说明

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