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

📄 quanti.cpp

📁 wavelet codec there are 34 files with code about the wavelet theory
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream.h>
#include <iomanip.h>
#include "global.h"
#include "quanti.h"
/*---------------------------------------------------------------------------*/
Quantizer::Quantizer (ErrorMetric *err) : err (err)
{
  data = NULL;
  nData = 0;
  max = min = sum = sumSq = mean = var = 0;
  initialDist = 0;
}

/*---------------------------------------------------------------------------*/
void Quantizer::getStats ()
{
  max = -MaxReal;
  min = MaxReal;
  sum = sumSq = 0;

  for (int i = 0; i < nData; i++) {
    if (data[i] < min)
      min = data[i];
    if (data[i] > max)
      max = data[i];
    sum += data[i];
    sumSq += square(data[i]);
  }
  mean = sum / (Real)nData;
  var = sumSq / (Real)nData - square (mean);
}

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
UniformQuant::UniformQuant (MonoLayerCoder *entropy, int paramPrecision,
			    int zeroCenter, ErrorMetric *err) : 
  Quantizer (err), entropy (entropy), paramPrecision (paramPrecision), 
  zeroCenter (zeroCenter)
{
}

/*---------------------------------------------------------------------------*/
void UniformQuant::setDataEncode (Real *newData, int newNData)
{
  data = newData;
  nData = newNData;

  getStats ();
  
  if (zeroCenter) {
    max = fabs(max) > fabs(min) ? fabs(max) : fabs(min);
    min = -max;
  }
  imax = realToInt (max, paramPrecision);
  qmax = intToReal (imax, paramPrecision);
  // Make sure qmax >= max and -qmax <= min
  while (qmax < max)
    qmax = intToReal (++imax, paramPrecision);
  
  if (zeroCenter) {
    imin = -imax;
    qmin = -qmax;
  } else {
    imin = realToInt (min, paramPrecision);
    qmin = intToReal (imin, paramPrecision);
    // Make sure qmin <= min
    while (qmin > min)
      qmin = intToReal (--imin, paramPrecision);
  }

  imean = realToInt (mean, paramPrecision);
  qmean = intToReal (imean, paramPrecision);

  initialDist = 0;
  if (zeroCenter)
    for (int i = 0; i < nData; i++)
      initialDist += (*err)(data[i]);
  else
    for (int i = 0; i < nData; i++)
      initialDist += (*err)(data[i] - qmean);
}

/*---------------------------------------------------------------------------*/
void UniformQuant::setDataDecode (Real *newData, int newNData, 
				  int imax, int imin, int imean)
{
  data = newData;
  nData = newNData;

  if (imin < imax) {
    qmax = intToReal (imin, paramPrecision);
    
    if (zeroCenter) {
      qmin = -qmax;
    } else {
      qmin = intToReal (imin, paramPrecision);
    }
    qmean = intToReal (imean, paramPrecision);
  }
}

/*---------------------------------------------------------------------------*/
void UniformQuant::getRateDist (int precision, Real minStepSize, 
				Real &rate, Real &dist) 
{
  if (precision > 0) {
    const int  nSteps = (1<<precision)-1;
    const Real stepSize = (qmax-qmin)/(Real)nSteps;
    const Real recipStepSize = 1.0/stepSize;
    
    if (stepSize < minStepSize) {
      rate = MaxReal;
      dist = MaxReal;
      return;
  }
    
    entropy->setNSym (nSteps);
    rate = dist = 0;
    
    for (int i = 0; i < nData; i++) {
      int symbol = (int)((data[i]-qmin)*recipStepSize);
      assert (symbol < nSteps && symbol >= 0);
      rate += entropy->cost (symbol, TRUE);
      Real reconstruct = qmin + ((Real)symbol + 0.5) * stepSize;
      dist += (*err) (data[i]-reconstruct);
    }
  } else {
    rate = dist = 0;
    if (zeroCenter) {
      for (int i = 0; i < nData; i++) {
	dist += (*err) (data[i]);
      }
    } else {
      for (int i = 0; i < nData; i++) {
	dist += (*err) (data[i] - qmean);
      }
    }
  }
}

/*---------------------------------------------------------------------------*/
void UniformQuant::quantize (Encoder *encoder, int precision)
{
  if (precision > 0) {
    const int  nSteps = (1<<precision)-1;
    const Real stepSize = (qmax-qmin)/(Real)nSteps;
    const Real recipStepSize = 1.0/stepSize;
    
    entropy->setNSym (nSteps);
    
    for (int i = 0; i < nData; i++) {
      int symbol = (int)((data[i]-qmin)*recipStepSize);
      assert (symbol < nSteps && symbol >= 0);
      entropy->write (encoder, symbol, TRUE);
    }
  }
}

/*---------------------------------------------------------------------------*/
void UniformQuant::dequantize (Decoder *decoder, int precision)
{
  if (precision > 0) {
    const int  nSteps = (1<<precision)-1;
    const Real stepSize = (qmax-qmin)/(Real)nSteps;
    int symbol;
    
    entropy->setNSym (nSteps);
    
    for (int i = 0; i < nData; i++) {
      symbol = entropy->read (decoder, TRUE);
      assert (symbol < nSteps && symbol >= 0);
      data[i] = qmin + ((Real)symbol + 0.5) * stepSize;
    }
  } else {
    for (int i = 0; i < nData; i++) {
      data[i] = qmean;
    }
  }
}

/*---------------------------------------------------------------------------*/
void UniformQuant::writeHeader (Encoder *encoder, int precision)
{
  encoder->writeNonneg (precision);

  if (precision > 0) {
    encoder->writeInt (imax);
    if (!zeroCenter)
      encoder->writeInt (imin);
  } else {
    if (!zeroCenter)
      encoder->writeInt (imean);
  }
}

/*---------------------------------------------------------------------------*/
void UniformQuant::readHeader  (Decoder *decoder, int &precision)
{
  precision = decoder->readNonneg ();

  if (precision > 0) {
    imax = decoder->readInt ();
    qmax = intToReal (imax, paramPrecision);
    
    if (zeroCenter) {
      qmin = -qmax;
    } else {
      imin = decoder->readInt ();
      qmin = intToReal (imin, paramPrecision);
    }
    qmean = 0;
  } else {
    if (!zeroCenter) {
      imean = decoder->readInt ();
      qmean = intToReal (imean, paramPrecision);
    } else {
      qmean = 0;
      imean = realToInt (qmean, paramPrecision);
    }
    qmax = qmin = qmean;
  }
}

/*---------------------------------------------------------------------------*/
void UniformQuant::setParams (int newParamPrecision, Real newMax, 
			      Real newMin, Real newMean)
{
  paramPrecision = newParamPrecision;
  qmax = newMax;
  qmin = newMin;
  qmean = newMean;
}

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
LayerQuant::LayerQuant  (MultiLayerCoder *entropy, int paramPrecision,
			 int signedSym, int nLayers, ErrorMetric *err) :
  Quantizer (err), entropy (entropy), paramPrecision (paramPrecision), 
  signedSym (signedSym), nLayers (nLayers)
{
  currentLayer = -1;
  layerRate = new Real [nLayers];
  layerDist = new Real [nLayers];
  context = NULL;
  residual = NULL;
}

/*---------------------------------------------------------------------------*/
LayerQuant::~LayerQuant ()
{
  delete [] layerRate;
  delete [] layerDist;
  if (context != NULL)
    delete [] context;
  if (residual != NULL)
    delete [] residual;
}

/*---------------------------------------------------------------------------*/
void LayerQuant::setDataEncode  (Real *newData, int newNData)
{
  data = newData;
  nData = newNData;

  getStats ();
  
  if (signedSym) {
    max = fabs(max) > fabs(min) ? fabs(max) : fabs(min);
    min = -max;
  }
  imax = realToInt (max, paramPrecision);
  qmax = intToReal (imax, paramPrecision);
  // Make sure qmax >= max and -qmax <= min
  while (qmax < max)
    qmax = intToReal (++imax, paramPrecision);
  
  if (signedSym) {
    imin = -imax;
    qmin = -qmax;
  } else {
    imin = realToInt (min, paramPrecision);
    qmin = intToReal (imin, paramPrecision);
    // Make sure qmin <= min
    while (qmin > min)
      qmin = intToReal (--imin, paramPrecision);
  }
  if (signedSym)
    threshold = qmax/2.0;
  else
    threshold = (qmax - qmin)/2.0;
  
  currentLayer = -1;
  if (context != NULL)
    delete [] context;
  if (residual != NULL)
    delete [] residual;
  context = new int [nData];
  residual = new Real [nData];

  resetLayer ();

  initialDist = 0;

⌨️ 快捷键说明

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