📄 quanti.cpp
字号:
for (int i = 0; i < nData; i++)
initialDist += (*err)(residual[i]);
entropy->reset ();
}
/*---------------------------------------------------------------------------*/
void LayerQuant::setDataDecode (Real *newData, int newNData, int imax,
int imin, int imean)
{
data = newData;
nData = newNData;
if (imin < imax) {
qmax = intToReal (imin, paramPrecision);
qmean = intToReal (imean, paramPrecision);
if (signedSym) {
qmin = -qmax;
threshold = qmax/2.0;
} else {
qmin = intToReal (imin, paramPrecision);
threshold = (qmax - qmin)/2.0;
}
}
currentLayer = -1;
if (context != NULL)
delete [] context;
context = new int [nData];
if (signedSym) {
for (int i = 0; i < nData; i++) {
data[i] = 0;
context[i] = 0;
}
} else {
for (int i = 0; i < nData; i++) {
data[i] = qmean;
context[i] = 0;
}
}
resetLayer ();
entropy->reset ();
}
/*---------------------------------------------------------------------------*/
void LayerQuant::getRateDist (int precision, Real minStepSize,
Real &rate, Real &dist)
{
assert (precision <= nLayers);
Real currentRate = 0;
Real currentDist = initialDist;
for (int i = 0; i < precision; i++) {
// rates & distortions have been computed for layers up to currentLayer
if (i <= currentLayer) {
currentRate += layerRate[i];
currentDist += layerDist[i];
} else {
if (threshold > minStepSize) {
quantizeLayer (NULL);
currentRate += layerRate[i];
currentDist += layerDist[i];
} else {
layerRate[i] = MaxReal;
layerDist[i] = -MaxReal;
currentRate = MaxReal;
currentDist = MaxReal;
}
}
}
rate = currentRate;
dist = currentDist;
}
/*---------------------------------------------------------------------------*/
void LayerQuant::quantize (Encoder *encoder, int precision)
{
resetLayer ();
entropy->reset ();
for (int i = 0; i < precision; i++) {
quantizeLayer (encoder);
}
}
/*---------------------------------------------------------------------------*/
void LayerQuant::resetLayer ()
{
if (residual != NULL) {
if (signedSym) {
for (int i = 0 ;i < nData; i++) {
residual[i] = data[i];
context[i] = 0;
}
} else {
// on the first layer we remove the mean
for (int i = 0 ;i < nData; i++) {
residual[i] = data[i] - 0.5*(qmax+qmin);
context[i] = 0;
}
}
} else {
if (signedSym) {
for (int i = 0 ;i < nData; i++) {
context[i] = 0;
}
} else {
// on the first layer we remove the mean
for (int i = 0 ;i < nData; i++) {
context[i] = 0;
}
}
}
currentLayer = -1;
if (signedSym)
threshold = qmax/2.0;
else
threshold = (qmax - qmin)/2.0;
}
/*---------------------------------------------------------------------------*/
// deltaRate = bits required to code current layer
// deltaDist = reduction in distortion from current layer
void LayerQuant::quantizeLayer (Encoder *encoder)
{
const Real halfThreshold = 0.5 * threshold;
const Real threeHalvesThreshold = 1.5 * threshold;
Real deltaRate = 0, deltaDist = 0;
int symbol;
currentLayer++;
// printf ("current layer = %d, threshold = %g\n", currentLayer, threshold);
if (signedSym) {
for (int i = 0; i < nData; i++) {
deltaDist -= (*err)(residual[i]); // subtract off old error
// Real oldResid = residual[i];
if (context[i] == 0) {
if (residual[i] > threshold) {
symbol = 1;
residual[i] -= threeHalvesThreshold;
} else if (residual[i] < -threshold) {
symbol = -1;
residual[i] += threeHalvesThreshold;
} else {
symbol = 0;
}
} else {
if (residual[i] > 0) {
symbol = 1;
residual[i] -= halfThreshold;
} else {
symbol = 0;
residual[i] += halfThreshold;
}
}
// printf ("%d (%d): %g -> %g\n", symbol, context[i], oldResid,
// residual[i]);
deltaDist += (*err)(residual[i]); // add in new error
deltaRate += entropy->write (encoder, symbol, TRUE, currentLayer,
context[i]);
context[i] = 2*context[i] + symbol;
}
} else {
for (int i = 0; i < nData; i++) {
deltaDist -= (*err)(residual[i]); // subtract off old error
if (residual[i] > 0) {
symbol = 1;
residual[i] -= halfThreshold;
} else {
symbol = 0;
residual[i] += halfThreshold;
}
deltaDist += (*err)(residual[i]); // add in new error
deltaRate += entropy->write (encoder, symbol, TRUE, currentLayer,
context[i]);
context[i] = 2*context[i] + symbol;
}
}
// printf ("layer= %d cost = %g\n", currentLayer, deltaRate);
threshold *= 0.5;
layerRate[currentLayer] = deltaRate;
layerDist[currentLayer] = deltaDist;
}
/*---------------------------------------------------------------------------*/
void LayerQuant::dequantize (Decoder *decoder, int precision)
{
resetLayer ();
for (int i = 0; i < precision; i++) {
dequantizeLayer (decoder);
}
}
/*---------------------------------------------------------------------------*/
void LayerQuant::dequantizeLayer (Decoder *decoder)
{
int symbol;
currentLayer++;
// printf ("current layer = %d, threshold = %g\n", currentLayer, threshold);
if (signedSym) {
for (int i = 0; i < nData; i++) {
symbol = entropy->read (decoder, TRUE, currentLayer,
context[i]);
// int oldData = data[i];
if (context[i] == 0)
data[i] += 1.5*threshold * symbol;
else
data[i] += (symbol - 0.5) * threshold;
// printf ("%d (%d): %g -> %g (%g)\n", symbol, context[i],
// oldData, data[i], threshold);
context[i] = 2*context[i] + symbol;
}
} else {
for (int i = 0; i < nData; i++) {
symbol = entropy->read (decoder, TRUE, currentLayer, context[i]);
data[i] += (symbol - 0.5) * threshold;
context[i] = 2*context[i] + symbol;
}
}
threshold *= 0.5;
}
/*---------------------------------------------------------------------------*/
void LayerQuant::writeHeader (Encoder *encoder, int precision)
{
encoder->writeNonneg (precision);
if (precision > 0) {
encoder->writeInt (imax);
if (!signedSym)
encoder->writeInt (imin);
} else {
if (!signedSym)
encoder->writeInt (imean);
}
// printf ("precision = %d\n", precision);
// printf ("qmax = %g qmin = %g qmean = %g\n", qmax, qmin, qmean);
}
/*---------------------------------------------------------------------------*/
void LayerQuant::readHeader (Decoder *decoder, int &precision)
{
precision = decoder->readNonneg ();
// printf ("precision = %d\n", precision);
if (precision > 0) {
imax = decoder->readInt ();
qmax = intToReal (imax, paramPrecision);
if (signedSym) {
qmin = -qmax;
qmean = 0;
} else {
imin = decoder->readInt ();
qmin = intToReal (imin, paramPrecision);
qmean = 0.5 * (qmax + qmin);
}
} else {
if (!signedSym) {
imean = decoder->readInt ();
qmean = intToReal (imean, paramPrecision);
} else {
qmean = 0;
imean = realToInt (qmean, paramPrecision);
}
qmax = qmin = qmean;
}
// printf ("qmax = %g qmin = %g qmean = %g\n", qmax, qmin, qmean);
}
/*---------------------------------------------------------------------------*/
void LayerQuant::setParams (int newParamPrecision, Real newMax,
Real newMin, Real newMean)
{
paramPrecision = newParamPrecision;
qmax = newMax;
qmin = newMin;
qmean = newMean;
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -