Files
Work/gif/GIF.CPP
2024-08-07 09:16:27 -04:00

152 lines
3.3 KiB
C++

#include <gif/gif.hpp>
GIFDecoder::GIFDecoder(void)
: mhGlobalPalette(0), mlpPaletteData(0), mColors(0), mIsInterlaced(0), mBufferCount(0)
{
}
GIFDecoder::~GIFDecoder()
{
if(mhGlobalPalette)
{
::GlobalUnlock(mhGlobalPalette);
::GlobalFree(mhGlobalPalette);
}
}
WORD GIFDecoder::unpackImage(const char *pathFileName)
{
int i;
int hasProcessed;
hasProcessed=FALSE;
open(pathFileName);
if(!isOpen())return FALSE;
if(!getChar())return FALSE;
if('G'!=currentChar())return FALSE;
for(i=0;i<5;i++)if(!getChar())return FALSE;
if(!getWord())return FALSE;
mScreenWidth=currentWord();
if(!getWord())return FALSE;
mScreenHeight=currentWord();
if(!getChar())return FALSE;
mGlobalFlagByte=currentChar();
mColors=1<<((mGlobalFlagByte&0x07)+1);
if(!getChar())return FALSE;
mBackgroundColor=currentChar();
if(!getChar())return FALSE;
// if(currentChar())return FALSE;
if(mGlobalFlagByte&0x80)
{
if(!readPaletteData())return FALSE;
paletteHandler(mlpPaletteData,mColors);
}
while(TRUE)
{
if(!getChar())break;
switch(currentChar())
{
case '!' : // extension folows
while(getChar() && currentChar()!=',');
if(currentChar()!=',')break;
case ',' : // image follows
if(hasProcessed)break;
hasProcessed=TRUE;
if(!processImage())return FALSE;
break;
case ';' : // file is completely processed
continue;
default :
return FALSE;
}
}
closeFile();
return TRUE;
}
WORD GIFDecoder::processImage(void)
{
UCHAR localFlagByte;
if(!getWord())return FALSE;
mImageStartLeft=currentWord();
if(!getWord())return FALSE;
mImageStartTop=currentWord();
if(!getWord())return FALSE;
mImageWide=currentWord();
if(!getWord())return FALSE;
mImageDeep=currentWord();
if(!getChar())return FALSE;
localFlagByte=currentChar();
mIsInterlaced=localFlagByte&0x40;
mPixelSize=(mGlobalFlagByte&0x07)+1;
if(localFlagByte&0x80)
{
mPixelSize=(localFlagByte&0x07)+1;
mColors=1<<((localFlagByte&0x07)+1);
if(!readPaletteData())return FALSE;
paletteHandler(mlpPaletteData,mColors);
}
attributeHandler(mImageWide,mImageDeep,mPixelSize);
backgroundHandler(mBackgroundColor);
mBufferCount=0;
if(!getChar())return FALSE;
unpackData(mImageWide,mImageDeep,mIsInterlaced,mPixelSize);
imageHandler();
return TRUE;
}
WORD GIFDecoder::readPaletteData(void)
{
if(mhGlobalPalette)
{
::GlobalUnlock(mhGlobalPalette);
::GlobalFree(mhGlobalPalette);
}
mhGlobalPalette=::GlobalAlloc(GMEM_FIXED,mColors*3);
if(!mhGlobalPalette)return FALSE;
mlpPaletteData=(UCHAR FAR *)::GlobalLock(mhGlobalPalette);
for(int i=0;i<mColors*3;i+=3)
{
if(!getChar())return FALSE;
*(mlpPaletteData+i)=currentChar();
if(!getChar())return FALSE;
*(mlpPaletteData+i+1)=currentChar();
if(!getChar())return FALSE;
*(mlpPaletteData+i+2)=currentChar();
}
return TRUE;
}
void GIFDecoder::showHandler(UCHAR FAR *lpOutRow,USHORT yLocation)
{
showHandler(mImageWide,mImageDeep,lpOutRow,yLocation);
}
// virtuals
void GIFDecoder::paletteHandler(const UCHAR FAR *lpPaletteData,USHORT numColors)
{
}
void GIFDecoder::attributeHandler(USHORT imageWide,USHORT imageDeep,USHORT pixelSize)
{
}
void GIFDecoder::backgroundHandler(USHORT backgroundColor)
{
}
void GIFDecoder::imageHandler(void)
{
}
void GIFDecoder::showHandler(USHORT imageWide,USHORT imageDeep,const UCHAR FAR *lpRowData,USHORT yLocation)
{
}
void GIFDecoder::errorHandler(const char FAR *message)
{
}