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

📄 tcq_dequant.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/
/* Copyright 1999 Science Applications International Corporation (SAIC).     */
/* Copyright 1995 University of Arizona, Arizona Board of Regents.           */
/* All rights reserved                                                       */
/* File: "tcq_dequant.c"                                                     */
/* Description: Trellis coded dequantization                                 */
/* Author: Joe Triscari/Tom Flohr                                            */
/* Affiliation: SAIC                                                         */
/* Version: VM9.0                                                            */
/* Last Revised: 20 April, 2001                                              */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by David Taubman to support arbitrary reference points for the   */
/* transform and the various regular partitions, so as to facilitate         */
/* cropping and geometric transformations in the compressed domain and to    */
/* enable full support for CRF's single-sample overlap Wavelet transform,    */
/* as originally documented in Seoul.  Changes are too numerous to flag      */
/* individually within the code.  Changes copyrighted by HP with all rights  */
/* reserved for the modified parts.                                          */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by David Taubman to support interface modifications, arbitrary   */
/* changes in coding parameters from component to component and from tile    */
/* to tile, to support the full generality of PART-1 of the JPEG2000         */
/* standard, and to support most anticipated generality of PART-2.  Changes  */
/* are too numerous to flag individually within the code, which in some      */
/* places has been completely rewritten.  All changes copyrighted by HP with */
/* all rights reserved for the modified parts.                               */
/*****************************************************************************/

/*****************************************************************************/
/* Modified for general wavelet decompositions.                              */
/* Copyright 2000 Science Applications International Corporation (SAIC).     */
/* Copyright 1995 University of Arizona, Arizona Board of Regents.           */
/* All Rights Reserved for modified parts.                                   */
/*****************************************************************************/

/*****************************************************************************/
/* Modified for general offset and scalar quantization.                      */
/* Copyright 2000 The MITRE Corporation.                                     */
/* All Rights Reserved for modified parts.                                   */
/*****************************************************************************/

#include <local_services.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <ifc.h>
#include "tcq_dequant_local.h"

#ifndef MIN
#define MIN(A,B) ((A)<(B)?(A):(B))
#endif

/* SAIC General Decomp. Begin */
#ifndef MAX
#define MAX(A,B) ((A)>(B)?(A):(B))
#endif
/* SAIC General Decomp. End */


extern void fitcq (float *class_coef, std_int *quant_code_words,
		   std_int num_codewords, float step,
		   int fully_decoded, int *scan_order);

/* ========================================================================= */
/* ---------------------------- Internal Functions ------------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                          is_power_of_2                             */
/*****************************************************************************/

static int
  is_power_of_2(int val)
{
  if (val == 0)
    return(0);
  while (!(val & 1))
    val>>=1;
  return(val == 1);
}

/*****************************************************************************/
/* STATIC                       AllocateBlockBuffer                          */
/*****************************************************************************/

static float **
  AllocateBlockBuffer(int width, int height)
{
  float **retval;
  int i;
  retval = (float **)local_malloc(TCQ_MEM_KEY,
				    sizeof(float*)*height);
  retval[0] = (float *) local_malloc(TCQ_MEM_KEY,
                                        sizeof(float)*width*height);
  for (i = 1; i < height; i++)
    retval[i] = retval[i-1] + width;
  return (retval);
}

/*****************************************************************************/
/* STATIC                        DeleteBlockBuffer                           */
/*****************************************************************************/

static void
  DeleteBlockBuffer(float **buffer)
{
  if (buffer == NULL) return;
  local_free(buffer[0]);
  local_free(buffer);
}

/*****************************************************************************/
/* STATIC                        ConvertDeTCQStates                          */
/*****************************************************************************/

static void
  ConvertDeTCQStates(std_int *cast_buf, int width, int extra_lsbs,
                     int use_inverse_TCQ)
{
  int i, sign_bit, sign_mask, isneg;
  int extra_lsbs_neg = 0;
  std_int tmp_buf;

  if (extra_lsbs < 0) {
    extra_lsbs_neg = 1;
    extra_lsbs *= -1;
  }
  sign_bit = 1<<(31);
  sign_mask = (1<<(31-extra_lsbs)) - 1;
  if (extra_lsbs_neg == 0) {
    for (i = 0; i < width; i++) {
      isneg = (cast_buf[i] & sign_bit);
      tmp_buf = cast_buf[i] >> extra_lsbs;
      cast_buf[i] = tmp_buf & sign_mask;
      if (!use_inverse_TCQ) { 
        /* Better for progressively decoding if odd indices are converted to even indices */
        if (cast_buf[i] % 2) cast_buf[i] -= 1;
      }
      if (isneg) cast_buf[i] = -cast_buf[i];
    }
  }
  else {
    for (i = 0; i < width; i++) {
      isneg = (cast_buf[i] & sign_bit);
      tmp_buf = cast_buf[i] << extra_lsbs;
      cast_buf[i] = tmp_buf & sign_mask;
      if (!use_inverse_TCQ) { 
        /* Better for progressively decoding if odd indices are converted to even indices */
        if (cast_buf[i] % 2) cast_buf[i] -= 1;
      }
      if (isneg) cast_buf[i] = -cast_buf[i];
    }
  }
}

/*****************************************************************************/
/* STATIC                            get_scan_order                          */
/*****************************************************************************/

int *get_scan_order(int block_height, int block_width)

{

  int *scan_order;
  int upper_limit;
  int i, j, k, l = 0;

  scan_order = (int *) local_malloc(TCQ_MEM_KEY, sizeof(int)*block_height*block_width);
  for (i=0; i<block_height; i+=4) {
    upper_limit = MIN(i+4, block_height);
    for (j=0; j<block_width; j++) {
      for (k=i; k<upper_limit; k++) {
        scan_order[l++] = k*block_width + j;
      }
    }
  }

  return(scan_order);

}

/*****************************************************************************/
/* STATIC                            DeTCQBlock                              */
/*****************************************************************************/

static void
  DeTCQBlock(float **block, int block_width, int block_height,
             int block_offset, float scale, int extra_lsbs,
             tcq_dequantizer_ref self)

 /* Dequantize one block of the indicated dimensions from the `block' buffer.
    The first entry in each row of the buffer is found by adding `block_offset'
    to the corresponding entry in the `block' array.  On entry, the relevant
    portion of the `block' buffer should contain 32 bit integers representing
    the quantized sample values recovered from the decoder.  Returns with
    floating point data obtained by dequantizing tehese samples. */
{
  int j, tcq_len;
  static float *data = NULL;
  static std_int *states = NULL;
  static int max_height, max_width;
  int fully_decoded = 1;
  int use_inverse_TCQ = 1;
  int *scan_order;

  if (block == NULL) {
    if (data) local_free(data);
    if (states) local_free(states);
    data = NULL;
    states = NULL;
    return;
  }
  if (data == NULL) {
    data = (float *)local_malloc(TCQ_MEM_KEY,
				 sizeof(float)*block_height*block_width);
    states = (std_int *)local_malloc(TCQ_MEM_KEY,
				  sizeof(std_int)*block_height*block_width);
    max_height = block_height;
    max_width = block_width;
  }
  else if ((block_height*block_width) > (max_height*max_width)) {
    local_free(data);
    local_free(states);
    data = (float *)local_malloc(TCQ_MEM_KEY,
				 sizeof(float)*block_height*block_width);
    states = (std_int *)local_malloc(TCQ_MEM_KEY,
				  sizeof(std_int)*block_height*block_width);
    max_height = block_height;
    max_width = block_width;
  }

  tcq_len = 0;
  for (j=0; j < block_height; j++)
    {
      memcpy(states+tcq_len,block[j]+block_offset,sizeof(float)*block_width);
      tcq_len += block_width;
    }
  fully_decoded = 1;
  for (j=0; j < tcq_len; j++)
    {
      if (!((states[j] >> (extra_lsbs - 1)) & 0x1))
        {
          fully_decoded = 0;
          break;
        }
      if (!fully_decoded)
        break;
    }

  if ((!fully_decoded) || self->use_approximate_itcq)
    use_inverse_TCQ = 0;
  ConvertDeTCQStates(states, tcq_len, extra_lsbs, use_inverse_TCQ);

  scan_order = get_scan_order(block_height, block_width);

  fitcq(data, states, tcq_len, scale, use_inverse_TCQ, scan_order);
  local_free(scan_order);

  tcq_len = 0;
  for (j=0; j < block_height; j++)
    {
      memcpy(block[j]+block_offset,data+tcq_len,sizeof(float)*block_width);
      tcq_len += block_width;
    }
}

/*****************************************************************************/
/* STATIC                 destroy_component_structures                       */
/*****************************************************************************/

static void
  destroy_component_structures(tcq_component_info_ptr comp)
{
  tcq_level_info_ptr lev;
  tcq_band_info_ptr band;
  int n, b;

  /* Bug fix added by TJF */
  if (comp->levels == NULL)

⌨️ 快捷键说明

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