template GIFDecoder::GIFDecoder(const char *pathFileName) : LZWDecompression(pathFileName), mhGlobalPalette(0), mlpPaletteData(0), mColors(0), mIsInterlaced(0), mBufferCount(0), mPaletteObject(0), mBackgroundObject(0), mImageObject(0), mShowObject(0), mErrorObject(0), mPaletteMethod(0), mBackgroundMethod(0), mImageMethod(0), mShowMethod(0), mErrorMethod(0) { } template GIFDecoder::~GIFDecoder() { if(mhGlobalPalette) { ::GlobalUnlock(mhGlobalPalette); ::GlobalFree(mhGlobalPalette); } } template WORD GIFDecoder::unpackImage(void) { Index i; int hasProcessed; hasProcessed=FALSE; 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; if(mPaletteObject && mPaletteMethod) (mPaletteObject->*mPaletteMethod)(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; } template 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; if(mPaletteObject && mPaletteMethod) (mPaletteObject->*mPaletteMethod)(mlpPaletteData,mColors); } if(mBackgroundObject && mBackgroundMethod) (mBackgroundObject->*mBackgroundMethod)(mBackgroundColor); mBufferCount=0; if(!getChar())return FALSE; unpackData(mImageWide,mImageDeep,mIsInterlaced,mPixelSize); if(mImageObject && mImageMethod) (mImageObject->*mImageMethod)(); return TRUE; } template 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(Index i=0;i void GIFDecoder::showHandler(UCHAR FAR *lpOutRow,USHORT yLocation) { if(mShowObject && mShowMethod) (mShowObject->*mShowMethod)(mImageWide,mImageDeep,lpOutRow,yLocation); } template void GIFDecoder::setPaletteHandler(T *object,void (T::*method)(const UCHAR FAR *lpPaletteData,USHORT numColors)) { mPaletteObject=object; mPaletteMethod=method; } template void GIFDecoder::setBackgroundHandler(T *object,void (T::*method)(USHORT backgroundColor)) { mBackgroundObject=object; mBackgroundMethod=method; } template void GIFDecoder::setImageHandler(T *object,void (T::*method)(void)) { mImageObject=object; mImageMethod=method; } template void GIFDecoder::setShowHandler(T *object,void (T::*method)(USHORT imageWide,USHORT imageDeep,const UCHAR FAR *lpRowData,USHORT yLocation)) { mShowObject=object; mShowMethod=method; } template void GIFDecoder::setErrorHandler(T *object,void (T::*method)(const char FAR *message)) { mErrorObject=object; mErrorMethod=method; }