wavemain.cpp
来自「this is source code for image compressio」· C++ 代码 · 共 802 行 · 第 1/2 页
CPP
802 行
image.LoadRawFile(fname,512,512);
// transform.
Wavelet *cw = &wAntonini;
cw->Transform(image,NSTEPS);
//printf("Number of zeros = %d\n",image.SetZeroBelow(2.0));
// init some subband data & alloc memory for data in each subband
struct stBlock *subband = new struct stBlock[NBANDS];
AllocSubBands(image, subband, NSTEPS);
// separate subband data & find max & min values in each subband.
InitSubBands(image, subband);
// Find the bitallocation for the bands
int *BitAllocation = new int[NBANDS];
double TargetRate = 0.32; // BitsPerPixel for the target image.
CalcBitAllocation(subband, BitAllocation, NBANDS, 12, TargetRate);
//int BitAllocation[] = {7,7,6,7,6,5,5,5,4,4,4,4,3,2,0,0};
// quantize all the coeffs into the 'symbols' array.
for(i=0; i<=NBANDS-1; i++)
{
int nLevels = (1<<BitAllocation[i]);
UniformQuant *uq = new UniformQuant(subband[i].maxcoeff, subband[i].mincoeff, nLevels);
subband[i].uq = uq;
double *coeffs = subband[i].coeffs;
unsigned int *symbols = subband[i].symbols;
for(int j=subband[i].ncoeffs; j>0; j--)
*symbols++ = uq->Symbol(*coeffs++);
}
// open the output file.
FILE *fp = fopen("wletn.cmp","wb");
BitStream bs(fp);
// write the file header.
bs.WriteBits(image.width, 16);
bs.WriteBits(image.height, 16);
bs.WriteBits(NSTEPS, 16);
// write each band of data.
for(i=0; i<NBANDS; i++)
{
unsigned int nlevels = (1<<BitAllocation[i]);
UniformQuant *uq = subband[i].uq;
// write quantizer header.
uq->WriteHeader(bs);
// write the symbols.
if (nlevels>1) // if nlevels==1, then all symbols are the same
{ // hence no need to write them to the file.
ArithEncoder aec(&bs);
aec.SetNumSyms(nlevels);
aec.InitEncode();
unsigned int *symbols = subband[i].symbols;
for(j = subband[i].ncoeffs; j>0; j--)
{
aec.Encode(*symbols++);
}
aec.Flush();
}
}
bs.Flush();
fclose(fp);
delete[] BitAllocation;
FreeSubbands(subband, NBANDS);
for(i=0; i<NBANDS; i++)
delete subband[i].uq;
delete[] subband;
}
//------------------------------------------------------------//
//------------------------------------------------------------//
void zerotree_decode(char *fname)
{
FILE *fp = fopen(fname,"rb");
BitStream bs(fp);
int i;
//read in the file header.
int imwidth = bs.ReadBits(16);
int imheight = bs.ReadBits(16);
int nsteps = bs.ReadBits(16);
int nbands = nsteps*3+1;
// create an empty image.
Image image;
image.InitEmptyImage(imwidth, imheight);
// allocate memory for each subband.
struct stBlock *subband = new struct stBlock[nbands];
AllocSubBands(image, subband, nsteps);
// alloc mem for the sigmap.
unsigned char *SigMap = new unsigned char[imwidth * imheight];
for(i=0; i<imwidth*imheight; i++)
SigMap[i]=-1;
// read the sigmap.
ArithDecoder SigmapAdc(&bs);
SigmapAdc.SetNumSyms(3);
SigmapAdc.InitDecode();
for(i=0; i<nbands; i++)
{
// parent subband index.
int pband = ((i-3)>0)?i-3:0;
for(int y=0; y<subband[i].height; y++)
{
for(int x=0; x<subband[i].width; x++)
{
if (i==0) // no zerotrees for root subband.
{
SigMap[(subband[i].y+y)*imwidth+(subband[i].x+x)]=SigmapAdc.Decode();
}
else
{
// is the parent symbol not a zerotree root?
if (SigMap[(subband[pband].y+(y/2))*imwidth+(subband[pband].x+(x/2))] != 2)
{
SigMap[(subband[i].y+y)*imwidth+(subband[i].x+x)]=SigmapAdc.Decode();
}
else // mark this also as a zerotree root (for its children)
SigMap[(subband[i].y+y)*imwidth+(subband[i].x+x)]=2;
}
}
}
}
// readin the symbols.
for(i=0; i<nbands; i++)
{
// read in the quantizer header.
UniformQuant *uq = new UniformQuant();
uq->ReadHeader(bs);
subband[i].uq = uq;
int nlevels = uq->nLevels/2;
unsigned int *symbols = subband[i].symbols;
unsigned int zeroSymbol = uq->Symbol(0.0);
if (nlevels <=1)
{
for(int y=0; y<subband[i].height; y++)
for(int x=0; x<subband[i].width; x++)
*symbols++ = zeroSymbol;
}
else
{
ArithDecoder adc(&bs);
adc.SetNumSyms(nlevels);
adc.InitDecode();
for(int y=0; y<subband[i].height; y++)
{
for(int x=0; x<subband[i].width; x++)
{
unsigned int symbol;
// insignificant symbol?
if (i!=0 && SigMap[(subband[i].y+y)*imwidth+(subband[i].x+x)]==2)
symbol = zeroSymbol;
else
symbol = adc.Decode();
*symbols++ = symbol;
}
}
}
// dequantize
double *coeffs = subband[i].coeffs;
symbols = subband[i].symbols;
int xx=0;
for(int y=0; y<subband[i].height; y++)
{
for(int x=0; x<subband[i].width; x++)
{
// reconstruct the MSB
if (SigMap[(subband[i].y+y)*imwidth+(subband[i].x+x)]==1)
{
*symbols = *symbols | nlevels;
}
*coeffs = uq->Value(*symbols++);
coeffs++;
}
}
image.SetData(subband[i].x, subband[i].y, subband[i].width, subband[i].height, subband[i].coeffs);
}
fclose(fp);
// take inverse transform.
Wavelet *cw = &wAntonini;
cw->Inverse(image, nsteps);
image.SaveRawFile("wletz.raw");
delete[] SigMap;
FreeSubbands(subband, nbands);
for(i=0; i<nbands; i++)
delete subband[i].uq;
delete[] subband;
}
//------------------------------------------------------------//
//------------------------------------------------------------//
void zerotree_encode(char *fname)
{
int i;
Image image;
image.LoadRawFile(fname,512,512);
// transform.
Wavelet *cw = &wAntonini;
cw->Transform(image,NSTEPS);
//printf("Number of zeros = %d\n",image.SetZeroBelow(5.0));
// init some subband data & alloc memory for data in each subband
struct stBlock *subband = new struct stBlock[NBANDS];
AllocSubBands(image, subband, NSTEPS);
// separate subband data & find max & min values in each subband.
InitSubBands(image, subband);
// Find the bitallocation for the bands
int *BitAllocation = new int[NBANDS];
double TargetRate = 0.32; // BitsperPixel for the target image.
CalcBitAllocation(subband, BitAllocation, NBANDS, 12, TargetRate);
// alloc mem for the significance map.
unsigned char *SigMap = new unsigned char[image.width*image.height];
for(i=0; i<image.width*image.height; i++)
SigMap[i] = -1;
// quantize all the coeffs into the 'symbols' array.
// also, find if there are any zerotrees, and mark them.
for(i=NBANDS-1; i>=0; i--)
{
int nLevels = (1<<BitAllocation[i]);
UniformQuant *uq = new UniformQuant(subband[i].maxcoeff, subband[i].mincoeff, nLevels);
subband[i].uq = uq;
double *coeffs = subband[i].coeffs;
unsigned int *symbols = subband[i].symbols;
// if this is the last subband in the pyramid, child=this itself.
int childSubband = ((i+3)>=NBANDS)?i:i+3;
unsigned int zeroSymbol = uq->Symbol(0.0);
unsigned int zeroTreeSymbol = nLevels;
unsigned int meanSymbol = uq->Symbol(subband[i].meancoeff);
unsigned int *childSymbols = subband[childSubband].symbols;
int childx=subband[childSubband].x;
int childy=subband[childSubband].y;
for(int y=0; y<subband[i].height; y++)
{
for(int x=0; x<subband[i].width; x++)
{
unsigned int symbol = uq->Symbol((*coeffs));
// store the MSB in the SigMap.
if (symbol > meanSymbol)
SigMap[(subband[i].y+y)*image.width+(subband[i].x+x)] = 1;
else
SigMap[(subband[i].y+y)*image.width+(subband[i].x+x)] = 0;
// not the root band?
if (i!=0)
{
// a zero? then we can look for zerotrees.
if (symbol == zeroSymbol)
{
// is this the last subband in the pyramid? then mark as zerotree.
if (childSubband == i)
{
symbol = zeroTreeSymbol;
// Set SigMap[...] = 2, indicating that this is a zerotree.
SigMap[(subband[i].y+y)*image.width+(subband[i].x+x)] = 2;
}
// are ALL the children also zerotrees?
else if (SigMap[(childy+y*2 )*image.width+(childx+x*2 )] == 2 &&
SigMap[(childy+y*2 )*image.width+(childx+x*2+1)] == 2 &&
SigMap[(childy+y*2+1)*image.width+(childx+x*2 )] == 2 &&
SigMap[(childy+y*2+1)*image.width+(childx+x*2+1)] == 2)
{
symbol = zeroTreeSymbol;
SigMap[(subband[i].y+y)*image.width+(subband[i].x+x)] = 2;
// Set SigMap[...] = 3 for children, indicating to ignore them.
SigMap[(childy+y*2 )*image.width+(childx+x*2 )] = 3;
SigMap[(childy+y*2 )*image.width+(childx+x*2+1)] = 3;
SigMap[(childy+y*2+1)*image.width+(childx+x*2 )] = 3;
SigMap[(childy+y*2+1)*image.width+(childx+x*2+1)] = 3;
}
}
}
// remove the MSB (which is now encoded in the SigMap)
symbol = (symbol & ((uq->nLevels-1)>>1));
*symbols++ = symbol;
// removing the MSB means removing the sign of the actual coefficient.
*coeffs = fabs(*coeffs);
coeffs++;
}
}
}
// open the output file.
FILE *fp = fopen("wletz.cmp","wb");
BitStream bs(fp);
// write the file header.
bs.WriteBits(image.width, 16);
bs.WriteBits(image.height, 16);
bs.WriteBits(NSTEPS, 16);
// write the sigmap.
ArithEncoder SigmapAec(&bs);
SigmapAec.SetNumSyms(3);
SigmapAec.InitEncode();
for(i=0; i<NBANDS; i++)
{
for(int y=0; y<subband[i].height; y++)
{
for(int x=0; x<subband[i].width; x++)
{
// write the symbol only if it is not marked as ignorable.
if (SigMap[(subband[i].y+y)*image.width+(subband[i].x+x)] < 3)
{
SigmapAec.Encode(SigMap[(subband[i].y+y)*image.width+(subband[i].x+x)]);
}
}
}
}
SigmapAec.Flush();
printf("Number of bits to code the zerotree = %d\n",bs.numBitsWritten);
// write the symbols into the file.
for(i=0; i<NBANDS; i++)
{
UniformQuant *uq = subband[i].uq;
unsigned int nLevels = uq->nLevels/2;
// write band specific data.
uq->WriteHeader(bs);
if (nLevels>1)
{
ArithEncoder aec(&bs);
aec.SetNumSyms(nLevels);
aec.InitEncode();
unsigned int *symbols = subband[i].symbols;
for(int y=0; y<subband[i].height; y++)
{
for(int x=0; x<subband[i].width; x++)
{
// write the symbol only if it is not a zerotree root or child.
if (SigMap[(subband[i].y+y)*image.width+(subband[i].x+x)] < 2)
aec.Encode(*symbols);
symbols++;
}
}
aec.Flush();
}
}
bs.Flush();
printf("Total number of bits to code image = %d\n",bs.numBitsWritten);
fclose(fp);
delete[] BitAllocation;
delete[] SigMap;
FreeSubbands(subband, NBANDS);
for(i=0; i<NBANDS; i++)
delete subband[i].uq;
delete[] subband;
}
//------------------------------------------------------------//
//------------------------------------------------------------//
int main()
{
normal_encode("lena.raw"); // writes o/p to file wletn.cmp
normal_decode("wletn.cmp"); // writes o/p to file wletn.raw
zerotree_encode("lena.raw"); // writes o/p to file wletz.cmp
zerotree_decode("wletz.cmp"); // writes o/p to file wletz.raw
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?