📄 giffile.cpp
字号:
static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
0x001F, 0x003F, 0x007F, 0x00FF,
0x01FF, 0x03FF, 0x07FF, 0x0FFF,
0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
void GIFFile::output( code_int code)
{
cur_accum &= masks[ cur_bits ];
if( cur_bits > 0 )
cur_accum |= ((long)code << cur_bits);
else
cur_accum = code;
cur_bits += n_bits;
while( cur_bits >= 8 )
{
char_out( (unsigned int)(cur_accum & 0xff) );
cur_accum >>= 8;
cur_bits -= 8;
}
/*
* If the next entry is going to be too big for the code size,
* then increase it, if possible.
*/
if ( free_ent > maxcode || clear_flg )
{
if( clear_flg ) {
maxcode = MAXCODE (n_bits = g_init_bits);
clear_flg = 0;
}
else
{
++n_bits;
if ( n_bits == maxbits )
maxcode = maxmaxcode;
else
maxcode = MAXCODE(n_bits);
}
}
if( code == EOFCode )
{
/*
* At EOF, write the rest of the buffer.
*/
while( cur_bits > 0 ) {
char_out( (unsigned int)(cur_accum & 0xff) );
cur_accum >>= 8;
cur_bits -= 8;
}
flush_char();
fflush( g_outfile );
if( ferror( g_outfile ) )
{
AfxMessageBox("Write Error in GIF file",MB_OK);
}
}
}
void GIFFile::cl_block()
{
cl_hash((count_int)HSIZE);
free_ent=ClearCode+2;
clear_flg=1;
output((code_int)ClearCode);
}
void GIFFile::cl_hash(register count_int hsize)
{
register count_int *htab_p = htab+hsize;
register long i;
register long m1 = -1L;
i = hsize - 16;
do {
*(htab_p-16)=m1;
*(htab_p-15)=m1;
*(htab_p-14)=m1;
*(htab_p-13)=m1;
*(htab_p-12)=m1;
*(htab_p-11)=m1;
*(htab_p-10)=m1;
*(htab_p-9)=m1;
*(htab_p-8)=m1;
*(htab_p-7)=m1;
*(htab_p-6)=m1;
*(htab_p-5)=m1;
*(htab_p-4)=m1;
*(htab_p-3)=m1;
*(htab_p-2)=m1;
*(htab_p-1)=m1;
htab_p-=16;
} while ((i-=16) >=0);
for (i+=16;i>0;--i)
*--htab_p=m1;
}
/*******************************************************************************
* GIF specific
*******************************************************************************/
static int a_count;
void GIFFile::char_init()
{
a_count=0;
}
static char accum[256];
void GIFFile::char_out(int c)
{
accum[a_count++]=c;
if (a_count >=254)
flush_char();
}
void GIFFile::flush_char()
{
if (a_count > 0)
{
fputc(a_count,g_outfile);
fwrite(accum,1,a_count,g_outfile);
a_count=0;
}
}
BYTE * MakeColormappedGrayscale(BYTE *inBuf,
UINT inWidth,
UINT inHeight,
UINT inWidthBytes,
UINT colors,
RGBQUAD* colormap)
{
////////////////////////////////////////////////////////////////////////
// allocate a buffer to colormap
BYTE *tmp = (BYTE *) new BYTE[inWidth * inHeight];
if (tmp==NULL)
return NULL;
// force our image to use a stupid gray scale
UINT color;
for (color = 0;color < colors; color++) {
colormap[color].rgbRed = color * 256 / colors;
colormap[color].rgbGreen = color * 256 / colors;
colormap[color].rgbBlue = color * 256 / colors;
}
UINT col, row;
for (row =0; row < inHeight; row++) {
for (col=0;col <inWidth; col++) {
BYTE inRed, inBlue, inGreen;
// src pixel
long in_offset = row * inWidthBytes + col * 3;
inRed = *(inBuf + in_offset + 0);
inGreen = *(inBuf + in_offset + 1);
inBlue = *(inBuf + in_offset + 2);
// luminance
int lum = (int)(.299 * (double)(inRed) +
.587 * (double)(inGreen) +
.114 * (double)(inBlue));
// force luminance value into our range of colors
lum = colors * lum / 256;
// dest pixel
long out_offset = row * inWidth + col;
*(tmp+out_offset) = (BYTE)lum;
}
}
return tmp;
}
// 读 PCX 图像的函数实现
BOOL ReadPcxImage(CFile * iFile,BYTE *iTempFile, LPPCXD_VAR lpPCXDVar,long wWidthBytes)
{
BYTE* lpImage;
BYTE* lpTemp;
BYTE* lpImageBgn;
BYTE* lpPlane0;
BYTE* lpPlane1;
BYTE* lpPlane2;
BYTE* lpPlane3;
//DWORD dwDataBgn;
WORD wi;
WORD wj;
BYTE byTemp;
BYTE byPlane0;
BYTE byPlane1;
BYTE byPlane2;
BYTE byPlane3;
BYTE bySysPal16[48] = { 0, 0, 0, 0, 0,128,
0,128, 0, 0,128,128,
128, 0, 0,128, 0,128,
128,128, 0,128,128,128,
192,192,192, 0, 0,255,
0,255, 0, 0,255,255,
255, 0, 0,255, 0,255,
255,255, 0,255,255,255 };
lpPCXDVar->dwDataLen = iFile->GetLength();
lpPCXDVar->dwDataLen -= sizeof(PCXHEADER);
lpPCXDVar->dwDataLen -= ( (lpPCXDVar->wNewBits==8) ? 769 : 0 );
iFile->Seek(sizeof(PCXHEADER),CFile::begin);
lpPCXDVar->wMemLen = lpPCXDVar->dwDataLen;
lpPCXDVar->lpDataBuff = new BYTE[lpPCXDVar->wMemLen];
iFile->ReadHuge(lpPCXDVar->lpDataBuff,lpPCXDVar->wMemLen);
lpPCXDVar->lpBgnBuff = lpPCXDVar->lpDataBuff;
lpPCXDVar->lpEndBuff = lpPCXDVar->lpBgnBuff + lpPCXDVar->wMemLen;
lpTemp = new BYTE[wWidthBytes];
for(wi=0;wi<lpPCXDVar->wDepth;wi++)
{
lpImage = iTempFile + (lpPCXDVar->wDepth -1 -wi) * wWidthBytes;
lpImageBgn = lpImage;
iDecodeLine(lpPCXDVar,lpTemp);
switch(lpPCXDVar->wNewBits)
{
case 1:
case 8:
{
memcpy(lpImage,lpTemp,lpPCXDVar->wLineBytes);
break;
}
case 4:
{
lpImage = lpImageBgn;
lpPlane0 = lpTemp;
lpPlane1 = lpPlane0 + lpPCXDVar->wLineBytes;
lpPlane2 = lpPlane1 + lpPCXDVar->wLineBytes;
lpPlane3 = lpPlane2 + lpPCXDVar->wLineBytes;
for(wj=0;wj<lpPCXDVar->wLineBytes;wj++)
{
byPlane0 = *lpPlane0++;
byPlane1 = *lpPlane1++;
byPlane2 = *lpPlane2++;
byPlane3 = *lpPlane3++;
byTemp = 0x00;
byTemp |= ( (byPlane3 & 0x80) ? 0x80 : byTemp );
byTemp |= ( (byPlane2 & 0x80) ? 0x40 : byTemp );
byTemp |= ( (byPlane1 & 0x80) ? 0x20 : byTemp );
byTemp |= ( (byPlane0 & 0x80) ? 0x10 : byTemp );
byTemp |= ( (byPlane3 & 0x40) ? 0x08 : byTemp );
byTemp |= ( (byPlane2 & 0x40) ? 0x04 : byTemp );
byTemp |= ( (byPlane1 & 0x40) ? 0x02 : byTemp );
byTemp |= ( (byPlane0 & 0x40) ? 0x01 : byTemp );
*lpImage++ = byTemp;
byTemp = 0x00;
byTemp |= ( (byPlane3 & 0x20) ? 0x80 : byTemp );
byTemp |= ( (byPlane2 & 0x20) ? 0x40 : byTemp );
byTemp |= ( (byPlane1 & 0x20) ? 0x20 : byTemp );
byTemp |= ( (byPlane0 & 0x20) ? 0x10 : byTemp );
byTemp |= ( (byPlane3 & 0x10) ? 0x08 : byTemp );
byTemp |= ( (byPlane2 & 0x10) ? 0x04 : byTemp );
byTemp |= ( (byPlane1 & 0x10) ? 0x02 : byTemp );
byTemp |= ( (byPlane0 & 0x10) ? 0x01 : byTemp );
*lpImage++ = byTemp;
byTemp = (BYTE)0x00;
byTemp |= ( (byPlane3 & 0x08) ? 0x80 : byTemp );
byTemp |= ( (byPlane2 & 0x08) ? 0x40 : byTemp );
byTemp |= ( (byPlane1 & 0x08) ? 0x20 : byTemp );
byTemp |= ( (byPlane0 & 0x08) ? 0x10 : byTemp );
byTemp |= ( (byPlane3 & 0x04) ? 0x08 : byTemp );
byTemp |= ( (byPlane2 & 0x04) ? 0x04 : byTemp );
byTemp |= ( (byPlane1 & 0x04) ? 0x02 : byTemp );
byTemp |= ( (byPlane0 & 0x04) ? 0x01 : byTemp );
*lpImage++ = byTemp;
byTemp = 0x00;
byTemp |= ( (byPlane3 & 0x02) ? 0x80 : byTemp );
byTemp |= ( (byPlane2 & 0x02) ? 0x40 : byTemp );
byTemp |= ( (byPlane1 & 0x02) ? 0x20 : byTemp );
byTemp |= ( (byPlane0 & 0x02) ? 0x10 : byTemp );
byTemp |= ( (byPlane3 & 0x01) ? 0x08 : byTemp );
byTemp |= ( (byPlane2 & 0x01) ? 0x04 : byTemp );
byTemp |= ( (byPlane1 & 0x01) ? 0x02 : byTemp );
byTemp |= ( (byPlane0 & 0x01) ? 0x01 : byTemp );
*lpImage++ = byTemp;
}
break;
}
case 24:
{
lpPlane0 = lpTemp;
lpPlane1 = lpPlane0 + lpPCXDVar->wLineBytes;
lpPlane2 = lpPlane1 + lpPCXDVar->wLineBytes;
for(wj=0;wj<lpPCXDVar->wLineBytes;wj++)
{
*lpImage++ = *lpPlane2++;
*lpImage++ = *lpPlane1++;
*lpImage++ = *lpPlane0++;
}
break;
}
}
}
if(lpTemp!=NULL) delete lpTemp;
if(lpPCXDVar->lpDataBuff!=NULL) delete lpPCXDVar->lpDataBuff;
lpPCXDVar->lpDataBuff = lpTemp = NULL;
return 0;
}
void iDecodeLine(LPPCXD_VAR lpPCXDVar,BYTE* lpTemp)
{
BYTE* lpTempEnd;
WORD wi;
BYTE byChar;
int iCount;
//int iReturn;
for(wi=0;wi<lpPCXDVar->wPlanes;wi++)
{
lpTempEnd = lpTemp + lpPCXDVar->wLineBytes;
while( lpTemp<lpTempEnd )
{
byChar = *lpPCXDVar->lpBgnBuff++;
if ( (byChar & 0xC0) == 0xC0 )
{
iCount = (int)(byChar & 0x3F);
byChar = *lpPCXDVar->lpBgnBuff++;
while( iCount-- )
{
*lpTemp++ = byChar;
}
}
else
{
*lpTemp++ = byChar;
}
}
}
}
BOOL WritePcxImage(CFile * OutFile,BYTE *iTempFile,LPPCXC_VAR lpPCXCVar,long wWidthBytes)
{
BYTE* lpImage;
BYTE* lpTemp;
BYTE* lpImageBgn;
BYTE* lpPlane0;
BYTE* lpPlane1;
BYTE* lpPlane2;
BYTE* lpPlane3;
WORD wi;
WORD wj;
BYTE byTemp;
BYTE byPlane0;
BYTE byPlane1;
BYTE byPlane2;
BYTE byPlane3;
lpPCXCVar->lpDataBuff = new BYTE[MAX_BUFF_SIZE];
lpPCXCVar->lpEndBuff = lpPCXCVar->lpDataBuff;
lpPCXCVar->wByteCnt = 0;
lpTemp = new BYTE[wWidthBytes];
for(wi=0;wi<lpPCXCVar->wDepth;wi++)
{
lpImage = iTempFile + (lpPCXCVar->wDepth -1 -wi) * wWidthBytes;
lpImageBgn = lpImage;
switch(lpPCXCVar->wBits)
{
case 1:
case 8:
{
memcpy(lpTemp,lpImage,lpPCXCVar->wLineBytes);
break;
}
case 4:
{
lpPlane0 = lpTemp;
lpPlane1 = lpPlane0 + lpPCXCVar->wLineBytes;
lpPlane2 = lpPlane1 + lpPCXCVar->wLineBytes;
lpPlane3 = lpPlane2 + lpPCXCVar->wLineBytes;
for(wj=0;wj<lpPCXCVar->wLineBytes;wj++)
{
byPlane0 = 0x00;
byPlane1 = 0x00;
byPlane2 = 0x00;
byPlane3 = 0x00;
byTemp = *lpImage++;
byPlane3 |= ( (byTemp & 0x80) ? 0x80 : byPlane3 );
byPlane2 |= ( (byTemp & 0x40) ? 0x80 : byPlane2 );
byPlane1 |= ( (byTemp & 0x20) ? 0x80 : byPlane1 );
byPlane0 |= ( (byTemp & 0x10) ? 0x80 : byPlane0 );
byPlane3 |= ( (byTemp & 0x08) ? 0x40 : byPlane3 );
byPlane2 |= ( (byTemp & 0x04) ? 0x40 : byPlane2 );
byPlane1 |= ( (byTemp & 0x02) ? 0x40 : byPlane1 );
byPlane0 |= ( (byTemp & 0x01) ? 0x40 : byPlane0 );
byTemp = *lpImage++;
byPlane3 |= ( (byTemp & 0x80) ? 0x20 : byPlane3 );
byPlane2 |= ( (byTemp & 0x40) ? 0x20 : byPlane2 );
byPlane1 |= ( (byTemp & 0x20) ? 0x20 : byPlane1 );
byPlane0 |= ( (byTemp & 0x10) ? 0x20 : byPlane0 );
byPlane3 |= ( (byTemp & 0x08) ? 0x10 : byPlane3 );
byPlane2 |= ( (byTemp & 0x04) ? 0x10 : byPlane2 );
byPlane1 |= ( (byTemp & 0x02) ? 0x10 : byPlane1 );
byPlane0 |= ( (byTemp & 0x01) ? 0x10 : byPlane0 );
byTemp = *lpImage++;
byPlane3 |= ( (byTemp & 0x80) ? 0x08 : byPlane3 );
byPlane2 |= ( (byTemp & 0x40) ? 0x08 : byPlane2 );
byPlane1 |= ( (byTemp & 0x20) ? 0x08 : byPlane1 );
byPlane0 |= ( (byTemp & 0x10) ? 0x08 : byPlane0 );
byPlane3 |= ( (byTemp & 0x08) ? 0x04 : byPlane3 );
byPlane2 |= ( (byTemp & 0x04) ? 0x04 : byPlane2 );
byPlane1 |= ( (byTemp & 0x02) ? 0x04 : byPlane1 );
byPlane0 |= ( (byTemp & 0x01) ? 0x04 : byPlane0 );
byTemp = *lpImage++;
byPlane3 |= ( (byTemp & 0x80) ? 0x02 : byPlane3 );
byPlane2 |= ( (byTemp & 0x40) ? 0x02 : byPlane2 );
byPlane1 |= ( (byTemp & 0x20) ? 0x02 : byPlane1 );
byPlane0 |= ( (byTemp & 0x10) ? 0x02 : byPlane0 );
byPlane3 |= ( (byTemp & 0x08) ? 0x01 : byPlane3 );
byPlane2 |= ( (byTemp & 0x04) ? 0x01 : byPlane2 );
byPlane1 |= ( (byTemp & 0x02) ? 0x01 : byPlane1 );
byPlane0 |= ( (byTemp & 0x01) ? 0x01 : byPlane0 );
*lpPlane0++ = byPlane0;
*lpPlane1++ = byPlane1;
*lpPlane2++ = byPlane2;
*lpPlane3++ = byPlane3;
}
break;
}
case 24:
{
lpPlane0 = lpTemp;
lpPlane1 = lpPlane0 + lpPCXCVar->wLineBytes;
lpPlane2 = lpPlane1 + lpPCXCVar->wLineBytes;
for(wj=0;wj<lpPCXCVar->wLineBytes;wj++)
{
*lpPlane2++ = *lpImage++;
*lpPlane1++ = *lpImage++;
*lpPlane0++ = *lpImage++;
}
break;
}
}
iEncodeLine(OutFile,lpPCXCVar,lpTemp);
}
if(lpPCXCVar->wByteCnt )
{
OutFile->Write(lpPCXCVar->lpDataBuff,lpPCXCVar->wByteCnt);
}
if(lpTemp!=NULL) delete lpTemp;
if(lpPCXCVar->lpDataBuff!=NULL) delete lpPCXCVar->lpDataBuff;
lpPCXCVar->lpDataBuff = lpTemp = NULL;
return TRUE;
}
void iEncodeLine(CFile * ExportFile,LPPCXC_VAR lpPCXCVar,BYTE* lpTemp)
{
BYTE* lpTempEnd;
WORD wi;
int iCount;
for(wi=0;wi<lpPCXCVar->wPlanes;wi++)
{
lpTempEnd = lpTemp + lpPCXCVar->wLineBytes;
while( lpTemp<lpTempEnd )
{
iCount = 1;
while( (*lpTemp == *(lpTemp+1)) && (iCount < 63) && ((lpTemp+1)<lpTempEnd) )
{
iCount ++;
lpTemp ++;
}
if ( iCount>1 )
{
*lpPCXCVar->lpEndBuff++ = (BYTE)(iCount | 0xC0);
lpPCXCVar->wByteCnt ++;
if ( lpPCXCVar->wByteCnt==MAX_BUFF_SIZE )
{
ExportFile->Write(lpPCXCVar->lpDataBuff,lpPCXCVar->wByteCnt);
lpPCXCVar->wByteCnt = 0;
lpPCXCVar->lpEndBuff = lpPCXCVar->lpDataBuff;
}
}
else
{
if ( (*lpTemp & 0xC0) == 0xC0 )
{
*lpPCXCVar->lpEndBuff++ = 0xC1;
lpPCXCVar->wByteCnt ++;
if ( lpPCXCVar->wByteCnt==MAX_BUFF_SIZE )
{
ExportFile->Write(lpPCXCVar->lpDataBuff,lpPCXCVar->wByteCnt);
lpPCXCVar->wByteCnt = 0;
lpPCXCVar->lpEndBuff = lpPCXCVar->lpDataBuff;
}
}
}
*lpPCXCVar->lpEndBuff++ = *lpTemp++;
lpPCXCVar->wByteCnt ++;
if ( lpPCXCVar->wByteCnt==MAX_BUFF_SIZE )
{
ExportFile->Write(lpPCXCVar->lpDataBuff,lpPCXCVar->wByteCnt);
lpPCXCVar->wByteCnt = 0;
lpPCXCVar->lpEndBuff = lpPCXCVar->lpDataBuff;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -