www.pudn.com > 医学图像处理示例源代码.rar > GifFile.cpp
//////////////////////////////////////////////////////////// // GIFFile - A C++ class to allow reading and writing of GIF Images // // It is based on code from Programming for Graphics Files // by John Levine // // This is free to use and modify provided proper credit is given // // This reads GIF 87a and 89a. // // See GIFFile.h for example // //////////////////////////////////////////////////////////// #include "stdafx.h" #include#include #include #include #include #include #include "GifFile.h" #ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #endif #define new DEBUG_NEW struct { unsigned int Width; unsigned int Height; unsigned char ColorMap[3][MAXCOLORMAPSIZE]; unsigned int BitPixel; unsigned int ColorResolution; unsigned int BackGround; unsigned int AspectRatio; } GifScreen; struct { int transparent; int delayTime; int inputFlag; int disposal; } Gif89={-1,-1,-1,0}; GIFFile::GIFFile() { m_GIFErrorText="No Error"; // yet } GIFFile::~GIFFile() { // nothing } //****************************************************************************** // // char * GIFFile::GIFReadInputFile(CString path, // UINT *width, // UINT *height) // // Give a path. // It will read the .GIF at that path, allocate a buffer and give you // an RGB buffer back. width and height are modified to reflect the image dim's. // // m_GIFErrorText is modifed to reflect error status // //****************************************************************************** BYTE * GIFFile::GIFReadFileToRGB(CString path, UINT *width, UINT *height) { UCHAR buf[16]; UCHAR c; UCHAR localColorMap[3][MAXCOLORMAPSIZE]; int useGlobalColormap; int bitPixel; int imageCount =0; char version[4]; FILE *fd; int w=0; int h=0; if (path=="") { m_GIFErrorText="No Name Given"; return NULL; } BYTE *bigBuf; fd = fopen(path,"rb"); if( fd == NULL ) { m_GIFErrorText = "Cant open GIF :\n" + path; return NULL; } // read GIF file header if( !ReadOK(fd, buf, 6) ) { m_GIFErrorText =" Error reading GIF Magic #\n"+path; fclose(fd); return NULL; } // need the string "GIF" in the header if( strncmp((char *)buf, "GIF", 3) != 0) { m_GIFErrorText = "Error, "+ path+ " is not a valid .GIF file"; fclose(fd); return NULL; } strncpy(version, (char *)(buf+3),3 ); version[3] = '\0'; // only handle v 87a and 89a if ((strcmp(version, "87a")!=0)&&(strcmp(version,"89a")!=0)) { m_GIFErrorText = "Error, Bad GIF Version number"; fclose(fd); return NULL; } // screen description if (!ReadOK(fd,buf,7)) { m_GIFErrorText="Error, failed to GIF read screen descriptor.\nGiving up"; fclose(fd); return NULL; } GifScreen.Width = LM_to_uint((UCHAR)buf[0],(UCHAR)buf[1]); GifScreen.Height = LM_to_uint((UCHAR)buf[2],(UCHAR)buf[3]); GifScreen.BitPixel = 2 << ((UCHAR)buf[4] & 0x07); GifScreen.ColorResolution = ((((UCHAR)buf[4] & 0x70) >> 3) + 1); GifScreen.BackGround = (UCHAR)buf[5]; // background color... GifScreen.AspectRatio = (UCHAR)buf[6]; // read colormaps if( BitSet((UCHAR)buf[4], LOCALCOLORMAP) ) { if( !ReadColorMap(fd, GifScreen.BitPixel, GifScreen.ColorMap) ) { m_GIFErrorText = "Error reading GIF colormap"; fclose(fd); return NULL; } } // non-square pixels, so what? if( (GifScreen.AspectRatio!=0 ) && (GifScreen.AspectRatio!=49) ) { m_GIFErrorText = "Non-square pixels in GIF image.\nIgnoring that fact..."; } // there can be multiple images in a GIF file... uh? // what the hell do we do with multiple images? // so, we'll be interested in just the first image, cause we're lazy for(;;) { // read a byte; if (!ReadOK(fd,&c,1)) { m_GIFErrorText="Unexpected EOF in GIF.\nGiving up"; fclose(fd); return NULL; } // image terminator if (c==';') { } if (c=='!') { if (!ReadOK(fd,&c,1)) { m_GIFErrorText="Error on extension read.\nGiving up"; fclose(fd); return NULL; } DoExtension(fd,c); continue; } if (c!=',') { // Ignoring c continue; } // read image header if (!ReadOK(fd,buf,9)) { m_GIFErrorText="Error on dimension read\nGiving up"; fclose(fd); return NULL; } useGlobalColormap=!BitSet((UCHAR)buf[8],LOCALCOLORMAP); bitPixel=1<<(((UCHAR)buf[8]&0x07)+1); // let's see if we have enough mem to continue? long bufsize; if ((int)buf[5]>4) { //AfxMessageBox("This GIF file claims to be > 2000 bytes wide!",MB_OK | MB_ICONINFORMATION); } if ((int)buf[7]>4) { //AfxMessageBox("This GIF file claims to be > 2000 bytes high!",MB_OK | MB_ICONINFORMATION); } w=LM_to_uint((UCHAR)buf[4],(UCHAR)buf[5]); h=LM_to_uint((UCHAR)buf[6],(UCHAR)buf[7]); if ((w<0) || (h<0)) { m_GIFErrorText="Negative image dimensions!\nGiving up"; fclose(fd); return NULL; } bufsize=(long)w*(long)h; bufsize*=3; bigBuf= (BYTE *) new char [bufsize]; if (bigBuf==NULL) { m_GIFErrorText="Out of Memory in GIFRead"; fclose(fd); return NULL; } if (!useGlobalColormap) { if (!ReadColorMap(fd,bitPixel,localColorMap)) { m_GIFErrorText="Error reading GIF colormap\nGiving up"; delete [] bigBuf; fclose(fd); return NULL; } //read image if (!ReadImage(fd, bigBuf, w, h, localColorMap, BitSet((UCHAR)buf[8],INTERLACE))) { m_GIFErrorText="Error reading GIF file\nLocalColorMap\nGiving up"; delete [] bigBuf; fclose(fd); return NULL; } } else { if (!ReadImage(fd, bigBuf, w, h, GifScreen.ColorMap, BitSet((UCHAR)buf[8],INTERLACE))) { m_GIFErrorText="Error reading GIF file\nGIFScreen Colormap\nGiving up"; delete [] bigBuf; fclose(fd); return NULL; } } break; } *width = w; *height = h; fclose(fd); return bigBuf; } static int ReadColorMap(FILE *fd, int number, UCHAR buffer[3][MAXCOLORMAPSIZE]) { int i; UCHAR rgb[3]; for (i=0;i < number; ++i) { if (!ReadOK(fd,rgb,sizeof(rgb))) { return FALSE; } buffer[CM_RED][i]=rgb[0]; buffer[CM_GREEN][i]=rgb[1]; buffer[CM_BLUE][i]=rgb[2]; } return TRUE; } static int DoExtension(FILE *fd, int label) { static char buf[256]; char *str; switch(label) { case 0x01 : str="Plain Text Ext"; break; case 0xff : str= "Appl ext"; break; case 0xfe : str="Comment Ext"; while (GetDataBlock(fd,(UCHAR *)buf)!=0) { //AfxMessageBox(buf, MB_OK | MB_ICONINFORMATION); } return FALSE; break; case 0XF9 : str="Graphic Ctrl Ext"; (void)GetDataBlock(fd,(UCHAR *)buf); Gif89.disposal =(buf[0]>>2) &0x7; Gif89.inputFlag =(buf[0]>>1) &0x1; Gif89.delayTime =LM_to_uint(buf[1],buf[2]); if ((buf[0]&0x1)!=0) Gif89.transparent=buf[3]; while (GetDataBlock(fd,(UCHAR *)buf)!=0); return FALSE; break; default : str=buf; sprintf(buf,"UNKNOWN (0x%02x)",label); break; } while (GetDataBlock(fd,(UCHAR *)buf)!=0); return FALSE; } int ZeroDataBlock=FALSE; static int GetDataBlock(FILE *fd, UCHAR *buf) { UCHAR count; if (!ReadOK(fd,&count,1)) { //m_GIFErrorText="Error in GIF DataBlock Size"; return -1; } ZeroDataBlock=count==0; if ((count!=0) && (!ReadOK(fd,buf,count))) { //m_GIFErrorText="Error reading GIF datablock"; return -1; } return count; } static int GetCode(FILE *fd, int code_size, int flag) { static UCHAR buf[280]; static int curbit, lastbit, done, last_byte; int i,j,ret; UCHAR count; if (flag) { curbit=0; lastbit=0; done=FALSE; return 0; } if ((curbit+code_size) >=lastbit) { if (done) { if (curbit >=lastbit) { //m_GIFErrorText="Ran off the end of my bits"; return 0; } return -1; } buf[0]=buf[last_byte-2]; buf[1]=buf[last_byte-1]; if ((count=GetDataBlock(fd,&buf[2]))==0) done=TRUE; last_byte=2+count; curbit=(curbit - lastbit) + 16; lastbit = (2+count)*8; } ret=0; for (i=curbit,j=0; j stack) return *--sp; while ((code= GetCode(fd,code_size,FALSE)) >=0) { if (code==clear_code) { for (i=0;i 0); if (count!=0) //AfxMessageBox("Missing EOD in GIF data stream (common occurrence)",MB_OK); return -2; } incode = code; if (code >= max_code) { *sp++=firstcode; code=oldcode; } while (code >=clear_code) { *sp++=vals[code]; if (code==(int)next[code]) { //m_GIFErrorText="Circular table entry, big GIF Error!"; return -1; } code=next[code]; } *sp++ = firstcode=vals[code]; if ((code=max_code) <(1< =max_code_size) && (max_code_size < (1< stack) return *--sp; } return code; } static BOOL ReadImage( FILE *fd, BYTE * bigMemBuf, int width, int height, UCHAR cmap[3][MAXCOLORMAPSIZE], int interlace) { UCHAR c; int color; int xpos=0, ypos=0, pass=0; long curidx; if (!ReadOK(fd,& c,1)) { return FALSE; } if (LZWReadByte(fd,TRUE,c)<0) { return FALSE; } while ((color = LZWReadByte(fd, FALSE, c)) >= 0 ) { curidx=(long)xpos + (long)ypos * (long)width; curidx*=3; *(bigMemBuf+curidx) = cmap[0][color]; *(bigMemBuf+curidx+1) = cmap[1][color]; *(bigMemBuf+curidx+2) = cmap[2][color]; ++xpos; if (xpos==width) { xpos=0; if (interlace) { switch (pass) { case 0: case 1: ypos += 8; break; case 2: ypos += 4; break; case 3: ypos += 2; break; } if (ypos>=height) { ++pass; switch (pass) { case 1: ypos = 4; break; case 2: ypos = 2; break; case 3: ypos = 1; break; default : goto fini; } } } else { ++ypos; } } if (ypos >=height) break; } fini : if (LZWReadByte(fd,FALSE,c)>=0) { } return TRUE; } // gets image dimensions // returns -1,-1 on bad read void GIFFile::GIFGetDimensions(CString path, UINT *width, UINT *height) { UCHAR buf[16]; UCHAR c; char version[4]; FILE *fd; int w=0; int h=0; if (_access(path,0)!=0) { *width=(UINT)-1;*height=(UINT)-1; return; } fd=fopen(path,"rb"); if (fd==NULL) { *width=(UINT)-1;*height=(UINT)-1; return; } // read GIF file header if (!ReadOK(fd,buf,6)) goto bail; // need the string "GIF" in the header if (strncmp((char *)buf,"GIF",3)!=0) goto bail; strncpy(version,(char *)(buf+3),3); version[3]='\0'; // only handle v 87a and 89a if ((strcmp(version,"87a")!=0)&&(strcmp(version,"89a")!=0)) goto bail; // screen description if (!ReadOK(fd,buf,7)) goto bail; GifScreen.Width = LM_to_uint((UCHAR)buf[0],(UCHAR)buf[1]); GifScreen.Height = LM_to_uint((UCHAR)buf[2],(UCHAR)buf[3]); GifScreen.BitPixel = 2<<((UCHAR)buf[4]&0x07); GifScreen.ColorResolution=((((UCHAR)buf[4]&0x70)>>3)+1); GifScreen.BackGround= (UCHAR)buf[5]; // background color... GifScreen.AspectRatio= (UCHAR)buf[6]; *width = GifScreen.Width; *height = GifScreen.Height; // read colormaps if (BitSet((UCHAR)buf[4],LOCALCOLORMAP)) if (!ReadColorMap(fd,GifScreen.BitPixel,GifScreen.ColorMap)) goto bail; if (!ReadOK(fd,&c,1)) goto bail; if (c!=',') goto bail; // read image header if (!ReadOK(fd,buf,9)) goto bail; //*width=LM_to_uint((UCHAR)buf[4],(UCHAR)buf[5]); //*height=LM_to_uint((UCHAR)buf[6],(UCHAR)buf[7]); if ((*width<0) || (*height<0)) goto bail; // good fclose(fd); return; bail: // bad fclose(fd); //*width=(UINT)-1;*height=(UINT)-1; return; } //////////////////////////////////////////////////////////////////////// // // This is the writing portion of the GIFFile class. // It is based on code from Programming for Graphics Files by John Levine // // This is free to use and modify provided proper credit is given // // This writes 256 color GIFs version GIF87a. // // see GIFFile.h for example //////////////////////////////////////////////////////////////////////// //////////// // // GIF writing section // //////////// // a code_int must be able to hold 2**BITS values of type int, and also -1 static int Width, Height; static int curx, cury; static long CountDown; static unsigned long cur_accum = 0; static int cur_bits = 0; static unsigned char *buffer; /* * Bump the 'curx' and 'cury' to point to the next pixel */ void GIFFile::BumpPixel() { /* * Bump the current X position */ ++curx; if( curx == Width ) { curx = 0; ++cury; } } /******************************************************************************* * Return the next pixel from the image *******************************************************************************/ int GIFFile::GIFNextPixel( ) { unsigned long index; int r; if( CountDown == 0 ) return EOF; --CountDown; index= (unsigned long)curx + (unsigned long)cury * (unsigned long)Width; r = *(buffer+index); BumpPixel(); return r; } /******************************************************************************* * here's the entry point. * file ptr, screen width, height, background color, bits per pixel and * arrays of color values (0-255) *******************************************************************************/ BOOL GIFFile::GIFWriteFileFrom256Color(unsigned char * buf, CString name, int GWidth, int GHeight, int BackGround, int Red[], int Green[], int Blue[]) { FILE *fp; int B; int RWidth, RHeight; int LeftOfs, TopOfs; int Resolution; int ColorMapSize; int InitCodeSize; int i; int BitsPerPixel = 8; fp=fopen(name,"wb"); if (fp==NULL) { m_GIFErrorText="Can't open GIF for writing"; return FALSE; } ColorMapSize = 1 << BitsPerPixel; buffer=buf; RWidth = Width = GWidth; RHeight = Height = GHeight; LeftOfs = TopOfs = 0; cur_accum = 0; cur_bits = 0; Resolution = BitsPerPixel; CountDown = (long)Width * (long) Height; if (BitsPerPixel <=1) InitCodeSize=2; else InitCodeSize = BitsPerPixel; curx = cury =0; fwrite("GIF87a",1,6,fp); Putword(RWidth,fp); Putword(RHeight,fp); B=0x80; B |=(Resolution -1) << 5; B |=(BitsPerPixel - 1); fputc(B,fp); fputc(BackGround,fp); fputc(0,fp); for(i=0; i 0 ) goto probe; nomatch: output ( (code_int) ent ); ent = c; if ( free_ent < maxmaxcode ) { /* } */ CodeTabOf (i) = free_ent++; /* code -> hashtable */ HashTabOf (i) = fcode; } else cl_block(); } /* * Put out the final code. */ output( (code_int)ent ); output( (code_int) EOFCode ); } /***************************************************************** * TAG( output ) * * Output the given code. * Inputs: * code: A n_bits-bit integer. If == -1, then EOF. This assumes * that n_bits =< (long)wordsize - 1. * Outputs: * Outputs code to the file. * Assumptions: * Chars are 8 bits long. * Algorithm: * Maintain a BITS character long buffer (so that 8 codes will * fit in it exactly). Use the VAX insv instruction to insert each * code in turn. When the buffer fills up empty it and start over. */ 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 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 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 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 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 wPlanes;wi++) { lpTempEnd = lpTemp + lpPCXDVar->wLineBytes; while( lpTemp 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 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 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 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 wPlanes;wi++) { lpTempEnd = lpTemp + lpPCXCVar->wLineBytes; while( lpTemp 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; } } } }