#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(const char *pathFileName) : IStream(pathFileName), 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) { 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; 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; } LZWDecompression::~LZWDecompression() { if(!mIsConstructed)return; cleanup(); } void LZWDecompression::unpackData(USHORT imageWide,USHORT imageDeep,USHORT isInterlaced,USHORT bitsPerPixel) { USHORT clearCode; USHORT pixelSize; USHORT endOfInput; CHAR firstCode; 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); } if(mhGlobalctLast) { ::GlobalUnlock(mhGlobalctLast); ::GlobalFree(mhGlobalctLast); } if(mhGlobalctLink) { ::GlobalUnlock(mhGlobalctLink); ::GlobalFree(mhGlobalctLink); } if(mhGlobalOutRow) { ::GlobalUnlock(mhGlobalOutRow); ::GlobalFree(mhGlobalOutRow); } if(mhGlobalStack) { ::GlobalUnlock(mhGlobalStack); ::GlobalFree(mhGlobalStack); } } // VIRTUALS void LZWDecompression::showHandler(UCHAR FAR */*lpOutRow*/,USHORT /*yLocation*/) { } void LZWDecompression::errorHandler(CHAR */*errorMessage*/) { }