#include USHORT LZWDecompression::mStartTable[LZWDecompression::STARTTABLESIZE]= {0x00,0x04,0x02,0x01,0x00}; USHORT LZWDecompression::mIncTable[LZWDecompression::INCTABLESIZE]= {0x08,0x08,0x04,0x02,0x00}; USHORT LZWDecompression::mcMask[LZWDecompression::CMASKSIZE]= {0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF}; CHAR LZWDecompression::errorMessage[]="Error reading data."; LZWDecompression::LZWDecompression(void) : mhGlobalctFirst(0), mhGlobalctLast(0), mhGlobalctLink(0), mhGlobalOutRow(0), mhGlobalStack(0), mlpctFirst(0), mlpctLast(0), mlpctLink(0), mlpOutRow(0), mlpStack(0), mNextCode(0), mNextLimit(0), mBufferCount(0), mRemct(0), mRem(0), mPass(0), mxLocation(0), myLocation(0), mRowCount(0), mIsConstructed(FALSE), mReqct(0), mCode(0) { initialize(); } LZWDecompression::~LZWDecompression() { if(!mIsConstructed)return; cleanup(); } BOOL LZWDecompression::initialize(void) { cleanup(); mhGlobalctFirst=::GlobalAlloc(GMEM_FIXED,CTSIZE); mhGlobalctLast=::GlobalAlloc(GMEM_FIXED,CTSIZE); mhGlobalctLink=::GlobalAlloc(GMEM_FIXED,CTSIZE*sizeof(USHORT)); mhGlobalOutRow=::GlobalAlloc(GMEM_FIXED,OUTROWSIZE); mhGlobalStack=::GlobalAlloc(GMEM_FIXED,STACKSIZE); if(!mhGlobalctFirst||!mhGlobalctLast||!mhGlobalctLink||!mhGlobalOutRow||!mhGlobalStack)return FALSE; mlpctFirst=(CHAR FAR *)::GlobalLock(mhGlobalctFirst); mlpctLast=(CHAR FAR *)::GlobalLock(mhGlobalctLast); mlpctLink=(SHORT FAR *)::GlobalLock(mhGlobalctLink); mlpOutRow=(UCHAR FAR *)::GlobalLock(mhGlobalOutRow); mlpStack=(UCHAR FAR *)::GlobalLock(mhGlobalStack); ::memset(mlpctFirst,0,CTSIZE); ::memset(mlpctLast,0,CTSIZE); ::memset(mlpctLink,0,CTSIZE*sizeof(USHORT)); ::memset(mlpOutRow,0,OUTROWSIZE); ::memset(mlpStack,0,STACKSIZE); mIsConstructed=TRUE; return TRUE; } BOOL LZWDecompression::unpackData(USHORT imageWide,USHORT imageDeep,USHORT isInterlaced,USHORT bitsPerPixel) { USHORT clearCode; USHORT pixelSize; USHORT endOfInput; CHAR firstCode; initialize(); firstCode=currentChar(); mImageWide=imageWide; mImageDeep=imageDeep; mIsInterlaced=isInterlaced; pixelSize=bitsPerPixel; clearCode=(1<=code)break; } if(1==pixelSize) { while(i>0) { lpStack--; tempCode=(*lpStack)&0x0001; doPixel(tempCode); tempCode=(*lpStack)&0x00FF; tempCode>>=1; doPixel(tempCode); i--; } } else { while(i>0) { lpStack--; tempCode=(*lpStack)&0x00FF; doPixel(tempCode); i--; } } } void LZWDecompression::doPixel(CHAR tempCode) { *(mlpOutRow+mxLocation)=tempCode; mxLocation++; mRowCount--; if(0!=mRowCount)return; showHandler(mlpOutRow,myLocation); mxLocation=0; mRowCount=mImageWide; if(!mIsInterlaced) { myLocation++; if(myLocation>=mImageDeep)myLocation=0; } else { myLocation+=mIncTable[mPass]; if(myLocation>=(code&0x00FF); return tempCode; } USHORT LZWDecompression::getCode(USHORT reqct) { USHORT tempCode1; USHORT tempCode2; if(reqct<=8)return getBCode(reqct); tempCode1=getBCode(8); tempCode2=getBCode(reqct-8); tempCode2<<=8; tempCode2|=tempCode1; return tempCode2; } WORD LZWDecompression::insertCode(SHORT code) { if(mNextCode>=CTSIZE)return FALSE; *(mlpctLink+mNextCode)=mOldCode; *(mlpctLast+mNextCode)=*(mlpctFirst+code); *(mlpctFirst+mNextCode)=*(mlpctFirst+mOldCode); mNextCode++; if(mNextCode!=mNextLimit)return TRUE; if(mReqct>=12)return TRUE; mReqct++; mNextLimit<<=1; return TRUE; } void LZWDecompression::flush(void) { while(TRUE) { if(0==mBufferCount) { if(!getChar())return; mBufferCount=currentChar(); if(0==mBufferCount)return; } else { if(!getChar())return; mBufferCount--; } } } void LZWDecompression::cleanup(void) { if(mhGlobalctFirst) { ::GlobalUnlock(mhGlobalctFirst); ::GlobalFree(mhGlobalctFirst); mhGlobalctFirst=0; } if(mhGlobalctLast) { ::GlobalUnlock(mhGlobalctLast); ::GlobalFree(mhGlobalctLast); mhGlobalctLast=0; } if(mhGlobalctLink) { ::GlobalUnlock(mhGlobalctLink); ::GlobalFree(mhGlobalctLink); mhGlobalctLink=0; } if(mhGlobalOutRow) { ::GlobalUnlock(mhGlobalOutRow); ::GlobalFree(mhGlobalOutRow); mhGlobalOutRow=0; } if(mhGlobalStack) { ::GlobalUnlock(mhGlobalStack); ::GlobalFree(mhGlobalStack); mhGlobalStack=0; } mIsConstructed=FALSE; mlpctFirst=0; mlpctLast=0; mlpctLink=0; mlpOutRow=0; mlpStack=0; mNextCode=0; mNextLimit=0; mBufferCount=0; mRemct=0; mRem=0; mPass=0; mxLocation=0; myLocation=0; mRowCount=0; mReqct=0; mCode=0; } // VIRTUALS void LZWDecompression::showHandler(UCHAR FAR * /*lpOutRow*/,USHORT /*yLocation*/) { } void LZWDecompression::errorHandler(CHAR * /*errorMessage*/) { }