📄 floatcompressornew.cpp
字号:
/*
===============================================================================
FILE: floatcompressornew.cpp
CONTENTS:
see corresponding header file
PROGRAMMERS:
martin isenburg@cs.unc.edu
COPYRIGHT:
Copyright (C) 2000 Martin Isenburg (isenburg@cs.unc.edu)
This software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
CHANGE HISTORY:
see corresponding header file
===============================================================================
*/
#include "floatcompressornew.h"
#include <stdlib.h>
#define BITS_HIGH 12
FloatCompressorNew::FloatCompressorNew()
{
ae_mantissa_none = (RangeEncoder**)malloc(sizeof(RangeEncoder*)*3);
ae_mantissa_last = (RangeEncoder**)malloc(sizeof(RangeEncoder*)*3);
ae_mantissa_across = (RangeEncoder**)malloc(sizeof(RangeEncoder*)*3);
ad_mantissa_none = (RangeDecoder**)malloc(sizeof(RangeDecoder*)*3);
ad_mantissa_last = (RangeDecoder**)malloc(sizeof(RangeDecoder*)*3);
ad_mantissa_across = (RangeDecoder**)malloc(sizeof(RangeDecoder*)*3);
}
FloatCompressorNew::~FloatCompressorNew()
{
free(ae_mantissa_none);
free(ae_mantissa_last);
free(ae_mantissa_across);
free(ad_mantissa_none);
free(ad_mantissa_last);
free(ad_mantissa_across);
}
void FloatCompressorNew::SetupCompressor(RangeEncoder* re)
{
last_float = 0;
if (re == 0)
{
// none predictions
ae_signexponent_none = new RangeEncoder(0);
ae_mantissa_none[0] = new RangeEncoder(0);
ae_mantissa_none[1] = new RangeEncoder(0);
ae_mantissa_none[2] = new RangeEncoder(0);
// last predictions
ae_signexponent_last = new RangeEncoder(0);
ae_mantissa_last[0] = new RangeEncoder(0);
ae_mantissa_last[1] = new RangeEncoder(0);
ae_mantissa_last[2] = new RangeEncoder(0);
// across predictions
ae_signexponent_across = new RangeEncoder(0);
ae_mantissa_across[0] = new RangeEncoder(0);
ae_mantissa_across[1] = new RangeEncoder(0);
ae_mantissa_across[2] = new RangeEncoder(0);
}
else
{
// none predictions
ae_signexponent_none = re;
ae_mantissa_none[0] = re;
ae_mantissa_none[1] = re;
ae_mantissa_none[2] = re;
// last predictions
ae_signexponent_last = re;
ae_mantissa_last[0] = re;
ae_mantissa_last[1] = re;
ae_mantissa_last[2] = re;
// across predictions
ae_signexponent_across = re;
ae_mantissa_across[0] = re;
ae_mantissa_across[1] = re;
ae_mantissa_across[2] = re;
}
alloc_range_tables();
}
void FloatCompressorNew::SetupDecompressor(RangeDecoder* rd)
{
last_float = 0;
if (rd == 0)
{
// none predictions
ad_signexponent_none = new RangeDecoder(ae_signexponent_none->getChars(), ae_signexponent_none->getNumberChars());
ad_mantissa_none[0] = new RangeDecoder(ae_mantissa_none[0]->getChars(), ae_mantissa_none[0]->getNumberChars());
ad_mantissa_none[1] = new RangeDecoder(ae_mantissa_none[1]->getChars(), ae_mantissa_none[1]->getNumberChars());
ad_mantissa_none[2] = new RangeDecoder(ae_mantissa_none[2]->getChars(), ae_mantissa_none[2]->getNumberChars());
// last predictions
ad_signexponent_last = new RangeDecoder(ae_signexponent_last->getChars(), ae_signexponent_last->getNumberChars());
ad_mantissa_last[0] = new RangeDecoder(ae_mantissa_last[0]->getChars(), ae_mantissa_last[0]->getNumberChars());
ad_mantissa_last[1] = new RangeDecoder(ae_mantissa_last[1]->getChars(), ae_mantissa_last[1]->getNumberChars());
ad_mantissa_last[2] = new RangeDecoder(ae_mantissa_last[2]->getChars(), ae_mantissa_last[2]->getNumberChars());
// across predictions
ad_signexponent_across = new RangeDecoder(ae_signexponent_across->getChars(), ae_signexponent_across->getNumberChars());
ad_mantissa_across[0] = new RangeDecoder(ae_mantissa_across[0]->getChars(), ae_mantissa_across[0]->getNumberChars());
ad_mantissa_across[1] = new RangeDecoder(ae_mantissa_across[1]->getChars(), ae_mantissa_across[1]->getNumberChars());
ad_mantissa_across[2] = new RangeDecoder(ae_mantissa_across[2]->getChars(), ae_mantissa_across[2]->getNumberChars());
}
else
{
// none predictions
ad_signexponent_none = rd;
ad_mantissa_none[0] = rd;
ad_mantissa_none[1] = rd;
ad_mantissa_none[2] = rd;
// last predictions
ad_signexponent_last = rd;
ad_mantissa_last[0] = rd;
ad_mantissa_last[1] = rd;
ad_mantissa_last[2] = rd;
// across predictions
ad_signexponent_across = rd;
ad_mantissa_across[0] = rd;
ad_mantissa_across[1] = rd;
ad_mantissa_across[2] = rd;
}
alloc_range_tables();
}
void FloatCompressorNew::alloc_range_tables()
{
int i;
rmSignExponentNone = (RangeModel**)malloc(sizeof(RangeModel*)*256);
rmMantissaBitsNone = (RangeModel**)malloc(sizeof(RangeModel*)*256);
rmSignExponentLast = (RangeModel**)malloc(sizeof(RangeModel*)*256);
rmMantissaBitsLast = (RangeModel**)malloc(sizeof(RangeModel*)*256);
rmSignExponentAcross = (RangeModel**)malloc(sizeof(RangeModel*)*256);
rmMantissaBitsAcross = (RangeModel**)malloc(sizeof(RangeModel*)*256);
for (i = 0; i < 256; i++)
{
rmSignExponentNone[i] = 0;
rmSignExponentLast[i] = 0;
rmSignExponentAcross[i] = 0;
rmMantissaBitsNone[i] = 0;
rmMantissaBitsLast[i] = 0;
rmMantissaBitsAcross[i] = 0;
}
rmExponentOther = 0;
// entries [0] to [BITS_HIGH-1] are for the lower corrector bits
// while [BITS_HIGH] to [22] are used for corrector's high bits
rmMantissa = (RangeModel**)malloc(sizeof(RangeModel*)*23);
for (i = 0; i < 23; i++)
{
rmMantissa[i] = 0;
}
}
void FloatCompressorNew::dealloc_range_tables()
{
int i;
for (i = 0; i < 256; i++)
{
if (rmSignExponentNone[i]) delete rmSignExponentNone[i];
if (rmSignExponentLast[i]) delete rmSignExponentLast[i];
if (rmSignExponentAcross[i]) delete rmSignExponentAcross[i];
if (rmMantissaBitsNone[i]) delete rmMantissaBitsNone[i];
if (rmMantissaBitsLast[i]) delete rmMantissaBitsLast[i];
if (rmMantissaBitsAcross[i]) delete rmMantissaBitsAcross[i];
}
free(rmSignExponentNone);
free(rmMantissaBitsNone);
free(rmSignExponentLast);
free(rmMantissaBitsLast);
free(rmSignExponentAcross);
free(rmMantissaBitsAcross);
if (rmExponentOther) delete rmExponentOther;
for (i = 0; i < 23; i++)
{
if (rmMantissa[i]) delete rmMantissa[i];
}
free(rmMantissa);
}
void FloatCompressorNew::FinishCompressor()
{
if (ae_signexponent_none != ae_signexponent_last)
{
ae_signexponent_none->done();
ae_signexponent_last->done();
ae_signexponent_across->done();
ae_mantissa_none[0]->done();
ae_mantissa_last[0]->done();
ae_mantissa_across[0]->done();
ae_mantissa_none[1]->done();
ae_mantissa_last[1]->done();
ae_mantissa_across[1]->done();
ae_mantissa_none[2]->done();
ae_mantissa_last[2]->done();
ae_mantissa_across[2]->done();
}
dealloc_range_tables();
}
void FloatCompressorNew::FinishDecompressor()
{
if (ad_signexponent_none != ad_signexponent_last)
{
ad_signexponent_none->done();
ad_signexponent_last->done();
ad_signexponent_across->done();
ad_mantissa_none[0]->done();
ad_mantissa_last[0]->done();
ad_mantissa_across[0]->done();
ad_mantissa_none[1]->done();
ad_mantissa_last[1]->done();
ad_mantissa_across[1]->done();
ad_mantissa_none[2]->done();
ad_mantissa_last[2]->done();
ad_mantissa_across[2]->done();
}
dealloc_range_tables();
}
int FloatCompressorNew::GetTotalBytes()
{
return GetSignExponentBytes()+GetMantissaBytes();
}
int FloatCompressorNew::GetSignExponentBytes()
{
return ae_signexponent_none->getNumberChars()+ae_signexponent_last->getNumberChars()+ae_signexponent_across->getNumberChars();
}
int FloatCompressorNew::GetMantissaBytes()
{
return GetMantissaBytes(0)+GetMantissaBytes(1)+GetMantissaBytes(2);
}
int FloatCompressorNew::GetMantissaBytes(int i)
{
return ae_mantissa_none[i]->getNumberChars()+ae_mantissa_last[i]->getNumberChars()+ae_mantissa_across[i]->getNumberChars();
}
#define DIFFERENT_SIGN 0
#define EXPONENT_MINUS_3 1
#define EXPONENT_MINUS_2 2
#define EXPONENT_MINUS_1 3
#define SAME_EXPONENT 4
#define EXPONENT_PLUS_1 5
#define EXPONENT_PLUS_2 6
#define EXPONENT_PLUS_3 7
#define OTHER_EXPONENT 8
void FloatCompressorNew::compress_signexponent(int signexponentPred, int signexponentReal, RangeEncoder* re_signexponent, RangeModel** rmSignExponent)
{
if (rmSignExponent[signexponentPred&0xFF] == 0)
{
rmSignExponent[signexponentPred&0xFF] = new RangeModel(9, 0, 1, 8192, 16);
}
if (signexponentPred == signexponentReal)
{
re_signexponent->encode(rmSignExponent[signexponentPred&0xFF],SAME_EXPONENT);
}
else
{
if ((signexponentPred & 0x100) == (signexponentReal & 0x100)) // same sign ?
{
int diff = signexponentReal - signexponentPred; // exponent difference
if ((-3 <= diff) && (diff <= 3))
{
re_signexponent->encode(rmSignExponent[signexponentPred&0xFF],SAME_EXPONENT+diff);
}
else
{
re_signexponent->encode(rmSignExponent[signexponentPred&0xFF],OTHER_EXPONENT);
if (rmExponentOther == 0)
{
rmExponentOther = new RangeModel(255, 0, 1, 8192, 16);
}
re_signexponent->encode(rmExponentOther,signexponentReal&0xFF);
}
}
else
{
re_signexponent->encode(rmSignExponent[signexponentPred&0xFF],DIFFERENT_SIGN);
if (rmExponentOther == 0)
{
rmExponentOther = new RangeModel(255, 0, 1, 8192, 16);
}
re_signexponent->encode(rmExponentOther,signexponentReal&0xFF);
}
}
}
int FloatCompressorNew::decompress_signexponent(int signexponentPred, RangeDecoder* rd_signexponent, RangeModel** rmSignExponent)
{
if (rmSignExponent[signexponentPred&0xFF] == 0)
{
rmSignExponent[signexponentPred&0xFF] = new RangeModel(9, 0, 0, 8192, 16);
}
int signexponentReal = rd_signexponent->decode(rmSignExponent[signexponentPred&0xFF]);
if (signexponentReal == SAME_EXPONENT)
{
return signexponentPred;
}
else
{
if ((EXPONENT_MINUS_3 <= signexponentReal) && (signexponentReal <= EXPONENT_PLUS_3))
{
return signexponentPred - (SAME_EXPONENT-signexponentReal);
}
else
{
if (rmExponentOther == 0)
{
rmExponentOther = new RangeModel(255, 0, 0, 8192, 16);
}
if (signexponentReal == OTHER_EXPONENT) // but same sign
{
return (signexponentPred & 0x100) | rd_signexponent->decode(rmExponentOther);
}
else // ... but different sign
{
return ((~signexponentPred) & 0x100) | rd_signexponent->decode(rmExponentOther);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -