📄 encode.cpp
字号:
#include "stdafx.h"
#include "fp_preprocess.h"
#include "fpdirectionimage.h"
BOOL ErrorSet ;
short int **TempData;
extern void EncodingImage(short int **ImageData,PBYTE DirectionBlock[BLOCK_NO*2],long width,long height,CString OutputFileName);
/////////////////////////////////////////////////////
///used in coding
FILE *ifp,*ofp;
int **in_buf;
int **out_buf;
struct Image_Coord { int x, y; };
struct Image_Coord pdim, dim, x, a, b, c, d;
int bit_set_mask[] =
{0x00000001,0x00000002,0x00000004,0x00000008,
0x00000010,0x00000020,0x00000040,0x00000080,
0x00000100,0x00000200,0x00000400,0x00000800,
0x00001000,0x00002000,0x00004000,0x00008000,
0x00010000,0x00020000,0x00040000,0x00080000,
0x00100000,0x00200000,0x00400000,0x00800000,
0x01000000,0x02000000,0x04000000,0x08000000,
0x10000000,0x20000000,0x40000000,0x80000000};
int current_write_byte;
int current_read_byte;
int read_position;
int write_position;
int count;
int J[] = {0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,
4,5,5,6,6,7,7,8,9,10,11,12,13,14,15};
int P, T1, T2, T3, MAXVAL;
int Ix, Ra, Rb, Rc, Rd;
int EOLine;
int RANGE;
int A[367], B[365], C[365], N[367], Nn[367];
int RUNindex, RUNval, RUNcnt;
int D[3], Q[3], q;
int SIGN;
int Px, Rx;
int Errval, MErrval, EMErrval;
int k, TEMP;
int RItype, map;
/* updated variables */
int LIMIT, qbpp, bpp;
///////////////////////////////////////////
void predictor(short int **image,short int *DPCM,short int startx,
short int starty, short int width,short int height,short int deta)
{
short int i,j;
DPCM[0]=image[starty][startx];
for(i=1;i<width;i++)
DPCM[i]=image[starty][startx+i]-image[starty][startx+i-1];
for(j=1;j<height;j++)
{
DPCM[j*width]=image[starty+j][startx]-image[starty+j-1][startx];
for(i=1;i<width;i++)
{
switch(deta)
{
case 0://direction:0
DPCM[j*width+i]=image[starty+j][startx+i-1];
break;
case 1://direction:22.5
DPCM[j*width+i]=(image[starty+j-1][startx+i+2]+image[starty+j-1][startx+i+3])/2;
break;
case 2://direction:45
DPCM[j*width+i]=image[starty+j-1][startx+i+1];
break;
case 3://direction:67.5
DPCM[j*width+i]=(image[starty+j-1][startx+i]+image[starty+j-1][startx+i+1])/2;
break;
case 4://direction:90
DPCM[j*width+i]=image[starty+j-1][startx+i];
break;
case 5://direction:112.5
DPCM[j*width+i]=(image[starty+j-1][startx+i-1]+image[starty+j-1][startx+i])/2;
break;
case 6://direction:135
DPCM[j*width+i]=image[starty+j-1][startx+i-1];
break;
case 7://direction:157.5
DPCM[j*width+i]=(image[starty+j][startx+i-1]+image[starty+j-1][startx+i-1])/2;
break;
case 8://direction:nothing
DPCM[j*width+i]=image[starty+j][startx+i-1]+(image[starty+j-1][startx+i]-image[starty+j-1][startx+i-1])/2;
break;
default:
break;
}
DPCM[j*width+i]=image[starty+j][startx+i]-DPCM[j*width+i];
}
}
for(j=0;j<height;j++)
for(i=0;i<width;i++)
TempData[starty+j][startx+i]=DPCM[j*width+i];
}
void SmoothDirection2(PBYTE DirectionBlock[BLOCK_NO*2])
{
HANDLE hBlock;
BYTE *Block;
short x,y;
BYTE i,k;
short n1,n2;
short ax,ay;
BYTE Direction[9];
BYTE FirstDirection,SecondDirection;
hBlock = GlobalAlloc(GHND,BLOCK_NO*BLOCK_NO*4);
if (!hBlock)
{
AfxMessageBox("not enough memory1 in preproc!");
return;
}
Block = (BYTE *)GlobalLock(hBlock);
if (Block==NULL)
{
AfxMessageBox( "not enough memory1 in preproc!");
return;
}
for(x=0;x<BLOCK_NO*2;x++)
for(y=0;y<BLOCK_NO*2;y++)
Block[x*BLOCK_NO*2+y]=DirectionBlock[x][y];
for(x=1;x<BLOCK_NO*2-1;x++)
for(y=1;y<BLOCK_NO*2-1;y++)
{
for(i=0;i<8;i++)
Direction[i]=0;
for(ax=-1;ax<2;ax++)
for(ay=-1;ay<2;ay++)
{
k=Block[(x+ax)*BLOCK_NO*2+y+ay];
Direction[k]++;
}
FirstDirection=0;
SecondDirection=1;
for(i=1;i<8;i++)
if(Direction[i]>Direction[FirstDirection])
{
SecondDirection=FirstDirection;
FirstDirection=i;
}
else
{
if(Direction[i]>Direction[SecondDirection])
SecondDirection=i;
}
k=DirectionBlock[x][y];
if(Direction[FirstDirection]>=7)//5)
DirectionBlock[x][y]=FirstDirection;
else if(Direction[FirstDirection]>=5 &&
Direction[k] < 2 && k != SecondDirection)
DirectionBlock[x][y]=FirstDirection;
else if(Direction[FirstDirection]>=5 &&
abs( (short)FirstDirection-k) != 1 &&
abs( (short)FirstDirection-k) != 7)
DirectionBlock[x][y]=FirstDirection;
else
{
n1=(short)FirstDirection-1;
if(n1==-1)
n1=7;
n2=(short)FirstDirection+1;
if(n2==8)
n2=0;
if( (Direction[FirstDirection]
+Direction[n1] >= 6 &&
DirectionBlock[x][y] != n1) ||
(Direction[FirstDirection]
+Direction[n2] >= 6 &&
DirectionBlock[x][y] != n2) )
DirectionBlock[x][y]=FirstDirection;
}
}
GlobalUnlock(hBlock);
GlobalFree(hBlock);
}
void CalculateBlockDirection(unsigned char *lpSourceImage,PBYTE DirectionBlock[BLOCK_NO*2])
{
HANDLE hImage[DIR_IMAGE_SIZE];
PBYTE lpImage[DIR_IMAGE_SIZE];
HANDLE hWeight[DIR_IMAGE_SIZE];
WEIGHT *lpWeight[DIR_IMAGE_SIZE]; //求方向图的权值
HANDLE hDirectionImage[DIR_IMAGE_SIZE];
PBYTE lpDirectionImage[DIR_IMAGE_SIZE];
int AllocSize;
int i,j;
for(i=0; i<DIR_IMAGE_SIZE; i++)
{
hImage[i] = (HGLOBAL)GlobalAlloc(GHND,DIR_IMAGE_SIZE);
if(!hImage[i])
{
AfxMessageBox("not enough memory in preprocess to hImage!");
return;
}
lpImage[i] = (PBYTE)GlobalLock(hImage[i]);
if(lpImage[i]==NULL)
{
AfxMessageBox("not enough memory to lpImage!");
return ;
}
}
AllocSize=(unsigned long)DIR_IMAGE_SIZE*sizeof(WEIGHT);
for(i=0; i<DIR_IMAGE_SIZE; i++)
{
hWeight[i] = (HGLOBAL)GlobalAlloc(GHND,AllocSize);
if(!hWeight[i])
{
AfxMessageBox("not enough memory1 in preproc!");
return;
}
lpWeight[i] = (WEIGHT *)GlobalLock(hWeight[i]);
if(lpWeight[i] == NULL)
{
AfxMessageBox("not enough memory13!");
return;
}
}
AllocSize=(ULONG)DIR_IMAGE_SIZE*sizeof(BYTE);
for(i=0; i<DIR_IMAGE_SIZE; i++)
{
hDirectionImage[i]=(HGLOBAL)GlobalAlloc(GHND,AllocSize);
if(!hDirectionImage[i])
{
AfxMessageBox("not enough memory1 in preproc!");
return;
}
lpDirectionImage[i] = (BYTE *)GlobalLock(hDirectionImage[i]);
if(lpDirectionImage[i] == NULL)
{
AfxMessageBox("not enough memory14!");
return;
}
}
for(j=0;j<DIR_IMAGE_SIZE;j++)
for(i=0;i<DIR_IMAGE_SIZE;i++)
lpImage[j][i]=lpSourceImage[(j+48)*DIR_IMAGE_SIZE+i+48];
DirectionProcess(lpImage, lpWeight, DirectionBlock,lpDirectionImage);
SmoothDirection2(DirectionBlock);
SmoothDirection2(DirectionBlock);
SmoothDirection2(DirectionBlock); //DirectionBlock中为文线垂直方向
for(i=0;i<DIR_IMAGE_SIZE;i++)
{
GlobalUnlock(hImage[i]);
GlobalFree(hImage[i]);
GlobalUnlock(hWeight[i]);
GlobalFree(hWeight[i]);
GlobalUnlock(hDirectionImage[i]);
GlobalFree(hDirectionImage[i]);
}
}
//read the data from the input file
unsigned char *ReadBMPFile(CString InputFileName,long *wide,long *deep)
{
CFile cFile;
unsigned char *buff;
DWORD dwTime1,dwTime2,count=0;
BOOL bOpen=FALSE;
long i,length;
do
{
bOpen = cFile.Open(InputFileName,CFile::modeRead|CFile::shareExclusive);
dwTime1 = GetTickCount();
do
{
dwTime2 = GetTickCount();
}while ((dwTime2-dwTime1)<300);
count ++;
if (count>=15) break;
}while(bOpen == 0);
if (bOpen==0)
{
ErrorSet = TRUE;
return NULL;
}
BITMAPFILEHEADER bHead;
BITMAPINFOHEADER bi;
//read the header of the BITMAP file
cFile.Read(&bHead,sizeof(BITMAPFILEHEADER));
cFile.Read(&bi,sizeof(BITMAPINFOHEADER));
cFile.Seek(4*256,CFile::current);
*wide=bi.biWidth;
*deep=bi.biHeight;
//allocate the work buffer
length=(*wide)*(*deep);
buff=new unsigned char [length];
if(buff==NULL)
{
AfxMessageBox("not enough memory to pc!");
return NULL;
}
//read the data stream of the file
if((*wide)%4==0)
cFile.ReadHuge(buff,length);
else
{
long temp=(*wide+3)/4*4-(*wide);
long temp1;
temp1=0;
for(i=0;i<*deep;i++)
{
cFile.ReadHuge(buff+temp1,*wide);
cFile.Seek(temp,CFile::current);
temp1+=(*wide);
}
}
cFile.Close();
return buff;
}
//according the block direction,encode the image data
/*void EncodingImage(short int **ImageData,PBYTE DirectionBlock[BLOCK_NO*2],long width,long height,CString OutputFileName)
{
int i,j;
short int deta;
short int BlockSize=8;
long XSize,YSize;
long StartX,StartY;
short int *DPCM;
DPCM=new short int [BlockSize*BlockSize];
if((TempData=new short int *[height])==NULL)
{
AfxMessageBox("not enough memory to TempData");
return ;
}
for(j=0;j<height;j++)
{
if((TempData[j]=new short int [width])==NULL)
{
AfxMessageBox("not enough memory to TempData");
return ;
}
}
XSize=width/BlockSize;
YSize=height/BlockSize;
for(j=0;j<YSize;j++)
{
StartY=j*BlockSize;
for(i=0;i<XSize;i++)
{
StartX=i*BlockSize;
if(j<8 || j>YSize-8) deta=8;
else if(i<8 || i>XSize-8) deta=8;
else deta=DirectionBlock[j-8][i-8];
predictor(ImageData,DPCM,StartX,StartY,BlockSize,BlockSize,deta);
}
}
delete[] DPCM;
CFile cTempFile;
BOOL bOpen;
bOpen=cTempFile.Open("temp.dat",CFile::modeCreate |CFile::modeWrite);
if(bOpen==0)
{
AfxMessageBox("Can not create file temp.dat!");
return ;
}
for(j=0;j<height;j++)
{
cTempFile.Write(TempData[j],width*sizeof(short int));
}
cTempFile.Close();
//delete the memory space
for(j=0;j<height;j++)
delete[] TempData[j];
delete[] TempData;
}
*/
//encoding the image file
void _GA_Compress(CString InputFileName,CString OutputFileName)
{
HANDLE hDirectionBlock[BLOCK_NO*2]; //8*8块方向图
PBYTE DirectionBlock[BLOCK_NO*2];
int i,j;
int AllocSize=BLOCK_NO*2;
long width,height;
unsigned char *pc;
short int **ImageData;
for(i=0; i<BLOCK_NO*2; i++)
{
hDirectionBlock[i] = (HGLOBAL)GlobalAlloc(GHND,AllocSize);
if(!hDirectionBlock[i])
{
AfxMessageBox("not enough memory in preprocess to hDirectionBlock!");
return;
}
DirectionBlock[i] = (PBYTE)GlobalLock(hDirectionBlock[i]);
if(DirectionBlock[i]==NULL)
{
AfxMessageBox("not enough memory to DirectionBlock!");
return ;
}
}
pc=ReadBMPFile(InputFileName,&width,&height);
if((ImageData=new short int *[height])==NULL)
{
AfxMessageBox("not enough memory to ImageData");
return ;
}
for(j=0;j<height;j++)
{
if((ImageData[j]=new short int [width])==NULL)
{
AfxMessageBox("not enough memory to ImageData");
return ;
}
}
//give the value of pc to lpSourceImage
for(j=0;j<height;j++)
for(i=0;i<width;i++)
ImageData[j][i]=pc[j*width+i];//-128;
/*
CFile cTempFile;
BOOL bOpen;
bOpen=cTempFile.Open("temp.pgm",CFile::modeCreate |CFile::modeWrite);
if(bOpen==0)
{
AfxMessageBox("Can not create file temp.dat!");
return ;
}
cTempFile.WriteHuge(pc,width*height);
cTempFile.Close();
*/
//calculate the block direction(0-7)
CalculateBlockDirection(pc,DirectionBlock);
delete[] pc;
//according the block direction,encode the image data
EncodingImage(ImageData,DirectionBlock,width,height,OutputFileName);
//delete the memory space
for(j=0;j<height;j++)
delete[] ImageData[j];
delete[] ImageData;
//free the memory space
for(i=0;i<BLOCK_NO*2;i++)
{
GlobalUnlock(hDirectionBlock[i]);
GlobalFree(hDirectionBlock[i]);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -