home *** CD-ROM | disk | FTP | other *** search
- // Copyright (C) 1996, 1997 Meta Four Software. All rights reserved.
- //
- // See the comments in "kbound.h" for details on how to use this code.
- //
- //! rev="$Id: kbound.cpp,v 1.2 1997/05/27 00:06:43 jcw Rel $"
-
- #include "kbound.h"
-
- /////////////////////////////////////////////////////////////////////////////
-
- // the default encoder does nothing
-
- static void NullEncoder(bool encode_, int block_, char* ptr_, int len_)
- {
- }
-
- void (*c4_BoundStorage::_Encoder)(bool,int,char*,int) = NullEncoder;
-
- /////////////////////////////////////////////////////////////////////////////
-
- #define FLAG_BYTES 2 /* Number of bytes used by copy flag. */
- #define FLAG_COMPRESS 0 /* Signals that compression occurred. */
- #define FLAG_COPY 1 /* Signals that a copyover occurred. */
- static void fast_copy(BYTE *p_src,BYTE *p_dst,int len) /* Fast copy routine. */
- {while (len--) *p_dst++=*p_src++;}
-
- void lzrw1_decompress(BYTE *p_src_first,DWORD src_len,
- BYTE *p_dst_first,DWORD *p_dst_len)
- /* Input : Specify input block using p_src_first and src_len. */
- /* Input : Point p_dst_first to the start of the output zone. */
- /* Input : Point p_dst_len to a DWORD to receive the output length. */
- /* Input : Input block and output zone must not overlap. User knows */
- /* Input : upperbound on output block length from earlier compression. */
- /* Input : In any case, maximum expansion possible is eight times. */
- /* Output : Length of output block written to *p_dst_len. */
- /* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
- /* Output : Writes only in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
- {WORD controlbits=0, control;
- BYTE *p_src=p_src_first+FLAG_BYTES, *p_dst=p_dst_first,
- *p_src_post=p_src_first+src_len;
- if (*p_src_first==FLAG_COPY)
- {fast_copy(p_src_first+FLAG_BYTES,p_dst_first,(int)src_len-FLAG_BYTES);
- *p_dst_len=src_len-FLAG_BYTES; return;}
- while (p_src!=p_src_post)
- {if (controlbits==0)
- {control=*p_src++; control|=(*p_src++)<<8; controlbits=16;}
- if (control&1)
- {WORD offset,len; BYTE *p;
- offset=(*p_src&0xF0)<<4; len=1+(*p_src++&0xF);
- offset+=*p_src++&0xFF; p=p_dst-offset;
- while (len--) *p_dst++=*p++;}
- else
- *p_dst++=*p_src++;
- control>>=1; controlbits--;
- }
- *p_dst_len=p_dst-p_dst_first;
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- class c4_BoundReader : public CFile
- {
- BYTE *_begin, *_curr, *_end;
- int _base;
-
- public:
- c4_BoundReader (int base_)
- : _base (base_)
- {
- _begin = _curr = _end = new BYTE [c4_BoundStorage::kBlockSize];
- }
-
- virtual ~c4_BoundReader ()
- {
- delete [] _begin;
- }
-
- virtual UINT Read(void* lpBuf, UINT nCount)
- {
- UINT n = nCount;
-
- while (n > 0)
- {
- if (_curr >= _end && !LoadNextBlock())
- break;
-
- int i = n;
- if (i > _end - _curr)
- i = _end - _curr;
-
- memcpy(lpBuf, _curr, i);
- lpBuf = (BYTE*) lpBuf + i;
-
- _curr += i;
- n -= i;
- }
-
- return nCount - n;
- }
-
- virtual void Write(const void* lpBuf, UINT nCount)
- {
- ASSERT(0);
- }
-
- private:
- bool LoadNextBlock()
- {
- #ifdef _WIN32
- HINSTANCE hInst = 0;
- #else
- HINSTANCE hInst = AfxGetResourceHandle();
- #endif
-
- HRSRC hRes = ::FindResource(hInst, MAKEINTRESOURCE(_base++), RT_RCDATA);
- if (hRes)
- {
- HGLOBAL hData = ::LoadResource(hInst, hRes);
- if (hData)
- {
- const BYTE* p = (const BYTE*) ::LockResource(hData);
- DWORD k = *(const WORD*) p >> 1;
- ASSERT(k <= c4_BoundStorage::kBlockSize + 2);
-
- c4_Bytes temp;
- BYTE* tempBuf = (BYTE*) memcpy(temp.SetBuffer((int) k), p, (WORD)k);
- *(WORD*) tempBuf &= 1; // restore the copy flag
-
- ::UnlockResource(hData);
- ::FreeResource(hData);
-
- ASSERT(c4_BoundStorage::_Encoder);
- c4_BoundStorage::_Encoder(false, _base - 1,
- (char*) tempBuf + 2, (int) k - 2);
-
- lzrw1_decompress(tempBuf, k, _begin, &k);
- ASSERT(k <= c4_BoundStorage::kBlockSize);
-
- _curr = _begin;
- _end = _begin + k;
-
- return true;
- }
- }
-
- return false;
- }
- };
-
- /////////////////////////////////////////////////////////////////////////////
-
- c4_BoundStorage::c4_BoundStorage (int base_)
- {
- c4_BoundReader reader (base_);
- LoadFromStream(&reader);
- }
-
- c4_BoundStorage::~c4_BoundStorage ()
- {
- }
-
- /////////////////////////////////////////////////////////////////////////////
-