⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decode.cpp

📁 基于块方向的图像无损压缩代码
💻 CPP
字号:
#include "stdafx.h"
#include "fp_preprocess.h"
#include "fpdirectionimage.h"

#define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B')

extern BOOL ErrorSet;
 
void Depredictor(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;

	image[starty][startx]=DPCM[0];
	for(i=1;i<width;i++)
		image[0][startx+i]=DPCM[i]+image[0][startx+i-1];
	for(j=1;j<height;j++)
	{
		image[starty+j][0]=DPCM[j*width]+image[starty+j-1][0];
		for(i=1;i<width;i++)
		{
			switch(deta)
			{
				case 0://direction:0
					image[starty+j][startx+i]=DPCM[j*width+i]+image[starty+j][startx+i-1];
					break;
				case 1://direction:22.5
					image[starty+j][startx+i]=DPCM[j*width+i]+(image[starty+j-1][startx+i+2]+image[starty+j-1][startx+i+3])/2;
					break;
				case 2://direction:45
					image[starty+j][startx+i]=DPCM[j*width+i]+image[starty+j-1][startx+i+1];
					break;
				case 3://direction:67.5
					image[starty+j][startx+i]=DPCM[j*width+i]+(image[starty+j-1][startx+i]+image[starty+j-1][startx+i+1])/2;
					break;
				case 4://direction:90
					image[starty+j][startx+i]=DPCM[j*width+i]+image[starty+j-1][startx+i];
					break;
				case 5://direction:112.5
					image[starty+j][startx+i]=DPCM[j*width+i]+(image[starty+j-1][startx+i-1]+image[starty+j-1][startx+i])/2;
					break;
				case 6://direction:135
					image[starty+j][startx+i]=DPCM[j*width+i]+image[starty+j-1][startx+i-1];
					break;
				case 7://direction:157.5
					image[starty+j][startx+i]=DPCM[j*width+i]+(image[starty+j][startx+i-1]+image[starty+j-1][startx+i-1])/2;
					break;
				case 8://direction:nothing
					image[starty+j][startx+i]=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;
			}
		}
	}
}

//according the block direction,decode the image data
void DecodingImage(short int **ImageData,long width,long height,CString InputFileName)
{
	int i,j;
	short int deta;
	short int BlockSize=8;
	long XSize,YSize;
	long StartX,StartY;
	short int *DPCM;
    HANDLE hDirectionBlock[BLOCK_NO*2];          //8*8块方向图
	PBYTE DirectionBlock[BLOCK_NO*2];
	int  AllocSize=BLOCK_NO*2;

	CFile cInFile;

	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 ;  
		}
    }

	DPCM=new short int [BlockSize*BlockSize];	
	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];
			Depredictor(ImageData,DPCM,StartX,StartY,BlockSize,BlockSize,deta);
		}
	}

	delete[] DPCM;

	//free the memory space
	for(i=0;i<BLOCK_NO*2;i++)
	{
		GlobalUnlock(hDirectionBlock[i]);
		GlobalFree(hDirectionBlock[i]);
	}
}

void  CreateBitmapFile(CString FileName,unsigned char *pc,short int wide,short int deep)
{
	CFile cFile;
	BOOL bOpen;
	char msg[60];

	DWORD dw;
	RGBQUAD bmiColors[256];
	BITMAPINFOHEADER bi;
	BITMAPFILEHEADER bf;
	short int  i,NumColors=256;
	BYTE nVal,nInc=0x01;

	//填写信息标题
    bi.biSize               = sizeof(BITMAPINFOHEADER);
    bi.biWidth              = wide;
    bi.biHeight             = deep;
    bi.biPlanes             = 1;
    bi.biBitCount           = 8;
    bi.biCompression        = 0;
    bi.biSizeImage = (DWORD)(bi.biWidth+3)/4*4 * bi.biBitCount* bi.biHeight;
    bi.biXPelsPerMeter      = 0;
    bi.biYPelsPerMeter      = 0;
    bi.biClrUsed            = 0;
    bi.biClrImportant       = 0;

	dw = bi.biSize + 256 * sizeof(RGBQUAD) + bi.biSizeImage;

    //填写文件标题
	bf.bfType=DIB_HEADER_MARKER;  // "BM"
	bf.bfSize=sizeof(BITMAPFILEHEADER)+dw;
    bf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);//sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO);
	bf.bfReserved1 = 0;
	bf.bfReserved2 = 0;

	// Generate RGB combinations to fill the palette entries.彩表在此!!!!! 2000.11.2
	for (i=NumColors-1, nVal=0; i>=0; --i, nVal+=nInc) 
	{
		bmiColors[i].rgbRed   = 255-nVal;
		bmiColors[i].rgbGreen = 255-nVal;
		bmiColors[i].rgbBlue  = 255-nVal;
		bmiColors[i].rgbReserved = (BYTE)0;                     
	}

	bOpen=cFile.Open(FileName,CFile::modeCreate |CFile::modeWrite);
	if(bOpen==0)      
	{
		sprintf(msg,"Can not create file %s!",FileName);
		AfxMessageBox(msg);
		return ;
    }

	cFile.Write(&bf, sizeof(BITMAPFILEHEADER));
    cFile.Write(&bi, sizeof(BITMAPINFOHEADER));
	cFile.Write(&bmiColors, NumColors*sizeof(RGBQUAD));

	if(wide%4==0)
		cFile.WriteHuge(pc,wide*deep);
	else
	{
		long temp=(wide+3)/4*4-wide;
		unsigned char *data;
		data=new unsigned char [temp];
		for(int i=0;i<temp;i++)
			data[i]=0;
		for(i=0;i<deep;i++)
		{
			cFile.WriteHuge(pc,wide);
			cFile.WriteHuge(data,temp);
			pc=pc+wide;
		}
		delete data;
	}
	cFile.Close();
}

void _GA_Decompress(CString InputFileName, CString OutputFileName)
{
	short int wide,height;
	unsigned char *pc;
	short int **ImageData;
	short int i,j;
	
	wide=640;
	height=640;

	pc=new unsigned char [wide*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 [wide])==NULL)
		{
			AfxMessageBox("not enough memory to ImageData");
			return ;
		}
	}

	//according the block direction,decode the image data
	DecodingImage(ImageData,wide,height, InputFileName);

	//substract the mean value
	for(j=0;j<height;j++)
		for(i=0;i<wide;i++)
			pc[j*wide+i]=ImageData[j][i]+128;
	
	//create the bitmap file,and output the stream to the file
	CreateBitmapFile(OutputFileName,pc,wide,height);

	//delete the memory space
	for(j=0;j<height;j++)
		delete[] ImageData[j];
	delete[] ImageData;

	delete[] pc;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -