📄 quantizer.cc
字号:
/*---------------------------------------------------------------------------*/// Baseline Wavelet Transform Coder Construction Kit//// Geoff Davis// gdavis@cs.dartmouth.edu// http://www.cs.dartmouth.edu/~gdavis//// Copyright 1996 Geoff Davis 9/11/96//// Permission is granted to use this software for research purposes as// long as this notice stays attached to this software.///*---------------------------------------------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <math.h>#include <iostream.h>#include <iomanip.h>#include "global.hh"#include "quantizer.hh"/*---------------------------------------------------------------------------*/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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -