📄 spiht.cpp
字号:
}
else if ((x%2 == 0)&&(y%2 != 0))
{
min_x = x;
max_x = min_x + 2;
min_y = y - 1;
max_y = min_y + 2;
subband0 = 2;
}
else
{
min_x = x -1;
max_x = min_x + 2;
min_y = y -1;
max_y = min_y + 2;
subband0 = 3;
}
}
else
{
if (band%3 == 1)
{
min_x = (x-subbandxsize[band]) << 1;
max_x = min_x + 2;
min_y = y << 1;
max_y = min_y + 2;
}
else if (band%3 == 2)
{
min_x = x << 1;
max_x = min_x + 2;
min_y = (y-subbandysize[band]) <<1;
max_y = min_y + 2;
}
else
{
min_x = (x-subbandxsize[band]) << 1;
max_x = min_x + 2;
min_y = (y-subbandysize[band]) << 1;
max_y = min_y + 2;
}
subband0 = 3;
}
min_x <<= 1;
max_x <<= 1;
min_y <<= 1;
max_y <<= 1;
return(!ZeroTree(m,threshold,band+subband0,min_x,max_x,min_y,max_y));
}
if(stop==1)
return 1;
else
return 0;
}
void CSPIHT::SortingPass1(CMatrix2D<ElementType> *m, int threshold)
{
int temp, s, i, j;
int band;
int maxy,maxx;
char found;
CLinkList::ListType d, d1;
if(stop==1)
return;
pNewlyAppended = LSP->end;
/* Deal with elements in the LIP */
LIP->Reset();
while(LIP->current!=NULL)
{
d = LIP->GetCurrentElement(&found);
if(found==0)
{
cout << "Warning: Can't retrieve current list element..\n";
return;
}
temp = m->m[d.y][d.x];
if(abs(temp)<threshold)
{
PutBit(0);
if(stop==1)
return;
LIP->current = LIP->current->next;
}
else
{
PutBit(1);
if(temp>0)
PutBit(1);
else
PutBit(0);
if(stop==1)
return;
LIP->RemoveCurrentElement();
LSP->Append(d);
}
}
LIP->Reset();
/* Deal with elements in the LIS */
LIS->Reset();
while(LIS->current!=NULL)
{
d = LIS->GetCurrentElement(&found);
if(found==0)
{
cout<<"Warning: Can't retrieve current list element.\n";
return;
}
band=FindSubband(d.x,d.y);
s = TestSubset(m,d.x,d.y,threshold,d.type,band);
if(d.type==TYPE_A)
{
PutBit((char)s);
if(stop==1)
return;
if(s==1)
{
if(band!=0)
{
if (band%3 == 1)
{
maxx = (d.x-subbandxsize[band]) << 1;
maxy = d.y << 1;
}
else if (band%3 == 2)
{
maxx=d.x << 1;
maxy=(d.y-subbandysize[band]) << 1;
}
else
{
maxx=(d.x-subbandxsize[band]) << 1;
maxy=(d.y-subbandysize[band]) << 1;
}
for(j = maxy; j < maxy+2; j++)
{
for(i = maxx; i < maxx+2; i++)
{
if(band%3 == 1)
{
d1.x = subbandxsize[band+3]+i;
d1.y = j;
temp = m->m[d1.y][d1.x];
}
else if(band%3 == 2)
{
d1.x = i;
d1.y = subbandysize[band+3]+j;
temp = m->m[d1.y][d1.x];
}
else
{
d1.x = subbandxsize[band+3]+i;
d1.y = subbandysize[band+3]+j;
temp = m->m[d1.y][d1.x];
}
if(abs(temp)>=threshold)
{
PutBit(1);
if(stop==1)
return;
LSP->Append(d1);
if(temp>0)
PutBit(1);
else
PutBit(0);
if(stop==1)
return;
}
else
{
PutBit(0);
if(stop==1)
return;
LIP->Append(d1);
}
}
}
}
else
{
if((d.x%2 != 0)&&(d.y%2 == 0))
{
maxx = d.x -1;
maxy = d.y;
for(j = maxy; j < maxy + 2; j++)
{
for(i = maxx; i < maxx + 2; i++)
{
d1.x = subbandxsize[0]+i;
d1.y = j;
temp = m->m[d1.y][d1.x];
if(abs(temp)>=threshold)
{
PutBit(1);
if(stop==1)
return;
LSP->Append(d1);
if(temp>0)
PutBit(1);
else
PutBit(0);
if(stop==1)
return;
}
else
{
PutBit(0);
if(stop==1)
return;
LIP->Append(d1);
}
}
}
}
if((d.x%2 == 0)&&(d.y%2 != 0))
{
maxx = d.x;
maxy = d.y -1;
for(j = maxy; j < maxy + 2; j++)
{
for(i = maxx; i < maxx + 2; i++)
{
d1.x = i;
d1.y = subbandysize[0]+j;
temp = m->m[d1.y][d1.x];
if(abs(temp)>=threshold)
{
PutBit(1);
if(stop==1)
return;
LSP->Append(d1);
if(temp>0)
PutBit(1);
else
PutBit(0);
if(stop==1)
return;
}
else
{
PutBit(0);
if(stop==1)
return;
LIP->Append(d1);
}
}
}
}
if((d.x%2 != 0)&&(d.y%2 != 0))
{
maxx = d.x - 1;
maxy = d.y - 1;
for(j = maxy; j < maxy + 2; j++)
{
for(i = maxx; i < maxx + 2; i++)
{
d1.x = subbandxsize[0]+i;
d1.y = subbandysize[0]+j;
temp = m->m[d1.y][d1.x];
if(abs(temp)>=threshold)
{
PutBit(1);
if(stop==1)
return;
LSP->Append(d1);
if(temp>0)
PutBit(1);
else
PutBit(0);
if(stop==1)
return;
}
else
{
PutBit(0);
if(stop==1)
return;
LIP->Append(d1);
}
}
}
}
}
//如果(d.y,d.x)有孙子节点
if(band < subbands - 6)
{
d1 = d;
d1.type = TYPE_B;
LIS->Append(d1);
}
LIS->RemoveCurrentElement();
}
else
LIS->current = LIS->current->next;
}
//Type B
else
{
PutBit((char)s);
if(stop==1)
return;
if(s==1)
{
if(band != 0)
{
if (band%3 == 1)
{
maxx = (d.x-subbandxsize[band]) << 1;
maxy = d.y << 1;
}
else if (band%3 == 2)
{
maxx = d.x << 1;
maxy = (d.y-subbandysize[band]) << 1;
}
else
{
maxx = (d.x-subbandxsize[band]) << 1;
maxy = (d.y-subbandysize[band]) << 1;
}
for(j = maxy; j < maxy+2; j++)
{
for(i = maxx; i < maxx+2; i++)
{
if(band%3 == 1)
{
d1.x = subbandxsize[band+3]+i;
d1.y = j;
}
else if(band%3 == 2)
{
d1.x = i;
d1.y = subbandysize[band+3]+j;
}
else
{
d1.x = subbandxsize[band+3]+i;
d1.y = subbandysize[band+3]+j;
}
d1.type = TYPE_A;
LIS->Append(d1);
}
}
LIS->RemoveCurrentElement();
}
else
{
if((d.x%2 != 0)&&(d.y%2 == 0))
{
maxx = d.x -1;
maxy = d.y;
for(j = maxy; j < maxy + 2; j++)
{
for(i = maxx; i < maxx + 2; i++)
{
d1.x = subbandxsize[0]+i;
d1.y = j;
d1.type = TYPE_A;
LIS->Append(d1);
}
}
}
if((d.x%2 == 0)&&(d.y%2 != 0))
{
maxx = d.x;
maxy = d.y -1;
for(j = maxy; j < maxy + 2; j++)
{
for(i = maxx; i < maxx + 2; i++)
{
d1.x = i;
d1.y = subbandysize[0]+j;
d1.type = TYPE_A;
LIS->Append(d1);
}
}
}
if((d.x%2 != 0)&&(d.y%2 != 0))
{
maxx = d.x - 1;
maxy = d.y - 1;
for(j = maxy; j < maxy + 2; j++)
{
for(i = maxx; i < maxx + 2; i++)
{
d1.x = subbandxsize[0]+i;
d1.y = subbandysize[0]+j;
d1.type = TYPE_A;
LIS->Append(d1);
}
}
}
LIS->RemoveCurrentElement();
}
}
else
LIS->current = LIS->current->next;
}
}
LIS->Reset();
}
void CSPIHT::RefinementPass1(CMatrix2D<ElementType> *m, int threshold)
{
CLinkList::ListElement *p;
int temp;
if(pNewlyAppended==NULL)
return;
p = LSP->head;
while(p!=pNewlyAppended->next)
{
temp = threshold & abs(m->m[p->data.y][p->data.x]);
if(temp==0)
PutBit(0);
else
PutBit(1);
if(stop==1)
return;
p = p->next;
}
}
void CSPIHT::Encode(ElementType *example)
{
int threshold, pass_count;
/*
* Build work matrix.
*/
header.height = nYDim;
header.width = nXDim;
header.BitRate = BitRate;
header.level = level;
header.selection = selection;
subbands = 3*level+1;
/*扩展后的图像大小*/
pXDim = nXDim;/*注意赋初值*/
pYDim = nYDim;
if ((nXDim>>level)<<level != nXDim)
{
pXDim = ((nXDim>>level)<<level) + (1<<level);
}
if((nYDim>>level)<<level != nYDim)
{
pYDim = ((nYDim>>level)<<level) + (1<<level);
}
SetSubbandSize(pXDim,pYDim);
M = new CMatrix2D<ElementType>;
M->Create(pYDim,pXDim);
if (M==NULL)
{
cout << "Warning: Failed to create matrix!\n";
return;
}
/*如果图像需要扩展,采用均值法填充像素*/
M->LoadData(example,nYDim,nXDim,pYDim,pXDim);
/*
* Prepare output file.
*/
int nInit = (int)(floor(log10(M->MaxMagnitude())/log10(2)));
header.threshold = 1 << nInit;
threshold = header.threshold;
CompressedFileInfo.header = header;
/*保持原图像的编码bit数,即:与扩展后的图像大小无关*/
CompressedFileInfo.lCounts = int(ceil(BitRate*nXDim*nYDim/8.0));
CompressedFileInfo.pFirstByte = new unsigned char[CompressedFileInfo.lCounts+1];
pByte = CompressedFileInfo.pFirstByte;
outputbyte = 0;
mask = 0x80;
pass_count = 0;
stop = 0;
zeroes = 0;
ones = 0;
/*
* Do the SPIHT coding.
*/
Initialization();
while(threshold!=0)
{
pass_count++;
SortingPass1(M,threshold);
RefinementPass1(M,threshold);
threshold >>= 1;
if(stop==1)
break;
}
DumpBuffer();
DestroySubsize();
if(cAction ==TO_DISK)
{
SPIHTFile=fopen(strFileNameOut,"wb");
assert(SPIHTFile);
pByte = CompressedFileInfo.pFirstByte;
fwrite(&CompressedFileInfo,1,sizeof(CompressedFileInfo),SPIHTFile);
fwrite(pByte,1,CompressedFileInfo.lCounts,SPIHTFile);
fclose(SPIHTFile);
}
M->Destroy();
LIP->Destroy();
LIS->Destroy();
LSP->Destroy();
}
void CSPIHT::Decode()
{
int threshold, pass_count;
/*
* Read the file header.
*/
if(cAction == FROM_DISK){
SPIHTFile = fopen(strFileNameIn,"rb");
assert(SPIHTFile);
fread(&CompressedFileInfo,sizeof(CSPIHTFileInfo),1,SPIHTFile);
header = CompressedFileInfo.header;
SetLevel(header.level);
SetBitRate(header.BitRate);
SetImageSize(header.width,header.height);
CompressedFileInfo.pFirstByte = new unsigned char[CompressedFileInfo.lCounts];
fread(CompressedFileInfo.pFirstByte,1,CompressedFileInfo.lCounts,SPIHTFile);
}
else{
SetLevel(level);
SetBitRate(BitRate);
SetImageSize(nXDim,nYDim);
}
pByte = CompressedFileInfo.pFirstByte;
selection = CompressedFileInfo.header.selection;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -