152 lines
3.3 KiB
C++
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)
|
|
{
|
|
}
|