/* * Help Access Library * A Library to access the contents of Windows Help files. * * Copyright (C) 1995-2000 Bernd Herd, http://www.herdsoft.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* TLZCOMPR.C ------------------------------------------ * @doc * @module LZCOMPR.C | * Code to decompress the LZ77-Compressed memory blocks. * * Help Access Library Project. * *-----------------------------------------------------*/ #include #include #include #include #include #include "hlpacces.h" #include "top.h" /************************************************* Returns a 1 if the bit is set, else 0 returned **************************************************/ short static LzBitSet(BYTE BitMap, short Bit) { if (BitMap & (1< 0; counter++) { /* It's a code, so decode it and copy the data */ if (LzBitSet(BitMap, counter)) { Length = ((Set[Index+1] & 0xF0) >> 4) + 3; Distance = (256 * (Set[Index+1] & 0x0F)) + Set[Index] + 1; NumToRead -= 2; CodePtr = CurrPos - Distance; /* Copy data from 'window' */ while (Length) { *CurrPos++ = *CodePtr++; OutBytes++; Length--; } Index += 2; } /* if */ else { *CurrPos++ = Set[Index++]; NumToRead --; OutBytes++; } } /* for */ } /* while */ return OutBytes; } #endif /************************************************* Decompresses the data using Microsoft's LZ77 derivative. **************************************************/ UINT iLZDecompress(HIFSFILE hSourceFile, UINT CompSize, LPSTR Buffer) { DWORD InBytes = 0; /* How many bytes read in */ DWORD OutBytes = 0; /* How many bytes written out */ BYTE BitMap, Set[16]; /* Bitmap and bytes associated with it */ int NumToRead; /* Number of bytes to read for next group */ UINT counter, Index; /* Going through next 8-16 codes or chars */ DWORD Length, Distance; /* Code length and distance back in 'window' */ LPBYTE CurrPos; /* Where we are at any given moment */ LPBYTE CodePtr; /* Poshorter to back-up in LZ77 'window' */ LPBYTE object, srcptr; if (NULL ==(object=Hlpmalloc(CompSize+200)) || CompSize!=IFSReadFile(hSourceFile, object, CompSize)) return 0; srcptr=object; CurrPos = Buffer; /* Go through until we're done */ while (InBytes < CompSize) { /* Get BitMap and data following it */ BitMap = *srcptr++; InBytes++; NumToRead = BytesToRead(BitMap); /* If we're trying to read more than we've got left, only read what we have left. */ NumToRead = (int) ((CompSize - InBytes) < NumToRead ? CompSize-InBytes : NumToRead); memcpy(&Set, srcptr, NumToRead); srcptr+=NumToRead; InBytes += NumToRead; /* Go through and decode data */ for (counter = 0, Index = 0; NumToRead > 0; counter++) { /* It's a code, so decode it and copy the data */ if (LzBitSet(BitMap, counter)) { Length = ((Set[Index+1] & 0xF0) >> 4) + 3; Distance = (256 * (Set[Index+1] & 0x0F)) + Set[Index] + 1; NumToRead -= 2; CodePtr = CurrPos - Distance; /* Copy data from 'window' */ while (Length) { *CurrPos++ = *CodePtr++; OutBytes++; Length--; } Index += 2; } /* if */ else { *CurrPos++ = Set[Index++]; NumToRead --; OutBytes++; } } /* for */ } /* while */ Hlpfree(object); return OutBytes; }