Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PKWARE Data Compression Library format source code

868 views
Skip to first unread message

D. Kane

unread,
Oct 7, 2001, 10:36:37 PM10/7/01
to
This is in response to the post by Ben Rudiak-Gould describing the
format for PKWARE DCL--great information, thanks. In return I'm
posting a copy of my source code (C++) for decompression. I didn't
implement the prefix-coded literals, but the rest ought to function.

-DK

--------------------------------------------------------------------------
tcDecoder.h
tcBitstream.h
decompress.h
tcDecoder.cpp
tcBitstream.cpp
decompress.cpp

/*****************************************************************************/
// tcDecoder.h
// Douglas Kane 5 OCT 2001
// fost...@yahoo.com
// This file is released to the public domain without restriction. I'd
// appreciate credit if this sees any use. Please post or e-mail me
code
// updates for any improvements that are made by others.
//
// tcDecoder header -- tcDecoder implements PKWARE Data Compression
Library
// decompression as released by Ben Rudiak-Gould (jc...@hotmail.com) on
the
// comp.compression newsgroup.
/*****************************************************************************/
#ifndef _TCDECODER_H_
#define _TCDECODER_H_

#include "tcBitstream.h"

#define MAX_DICTIONARY_SIZE 4096

typedef enum _tokentype {
LITERAL,
LENGTH_OFFSET,
END_OF_STREAM,
ERROR
} teTokenType;

typedef struct _token {
teTokenType meType;
unsigned char mnLiteral;
unsigned int mnLength;
unsigned int mnOffset;
} tsToken;

class tcDecoder {
public:
tcDecoder();
tcDecoder(tcBitstream *apBitstream);
~tcDecoder();

void Decode(char *apBuffer, unsigned int *apSize, unsigned int
anBufferSize);

private:
tcBitstream *mpBitstream;
unsigned char mnSizeByte; // second header byte

// sliding dictionary is implemented as a circular buffer within a
// statically allocated buffer of MAX_DICTIONARY_SIZE
unsigned int mnDictionarySize; // determined from second header
byte
unsigned int mnCurrentPos; // current position in dictionary
unsigned char maDictionary[MAX_DICTIONARY_SIZE];
void GetNextToken(tsToken *apToken);
int CalcOffset(unsigned char anHighByte, unsigned int
anLowOrderBits);
int DecodeCopyLength(void);
int DecodeCopyOffset(unsigned int anLowOrderBits);
};
#endif
/*****************************************************************************/
// tcBitstream.h
// Douglas Kane 5 OCT 2001
// fost...@yahoo.com
// This file is released to the public domain without restriction. I'd
// appreciate credit if this sees any use. Please post or e-mail me
code
// updates for any improvements that are made by others.
//
// tcBitstream header
/*****************************************************************************/
#ifndef _TCBITSTREAM_H_
#define _TCBITSTREAM_H_

#include <stdio.h>

class tcBitstream {
public:
tcBitstream();
tcBitstream(FILE *apFile);
~tcBitstream();
int Get(unsigned int anCount);

private:
FILE *mpFile;
unsigned char mnByte;
unsigned char mnBytePos;
};

unsigned int BitReverse(unsigned int anData, unsigned int anCount);

#endif
/*****************************************************************************/
// decompress.h
// Douglas Kane 5 OCT 2001
// fost...@yahoo.com
// This file is released to the public domain without restriction. I'd
// appreciate credit if this sees any use. Please post or e-mail me
code
// updates for any improvements that are made by others.
//
// Decompress header -- test code to try decompression on a file
/*****************************************************************************/
#ifndef _DECOMPRESS_H_
#define _DECOMPRESS_H_

void Decompress(char *azInFile, char *azOutFile);

#endif
/*****************************************************************************/
// tcDecoder.cpp
// Douglas Kane 5 OCT 2001
// fost...@yahoo.com
// This file is released to the public domain without restriction. I'd
// appreciate credit if this sees any use. Please post or e-mail me
code
// updates for any improvements that are made by others.
//
// tcDecoder class code -- tcDecoder implements PKWARE Data
Compression Library
// decompression as released by Ben Rudiak-Gould (jc...@hotmail.com) on
// comp.compression newsgroup. Prefix-coded literals aren't
implemented. I
// have not tested this with large files. There may be problems with
the circ
// dictionary implementation.
/*****************************************************************************/

#include "tcDecoder.h"
#include <stdlib.h>

/*----------------------------------------------------------------------------*/
// The default constructor isn't supported.
tcDecoder::tcDecoder() {
}
/*----------------------------------------------------------------------------*/
// Use this constructor.
tcDecoder::tcDecoder(tcBitstream *apBitstream) {
int lnBits;

mpBitstream = apBitstream;

lnBits = mpBitstream->Get(8);
printf("Literal setting: %d\n",lnBits);

if (lnBits == 1) {
printf("Error: Variable-length literals are not supported.\n");
exit(2);
}
else if (lnBits != 0) {
printf("Error: Bad header.\n");
exit(2);
}

lnBits = mpBitstream->Get(8);
mnSizeByte = (unsigned char)lnBits;
switch (lnBits) {
case 4:
mnDictionarySize = 1024;
break;
case 5:
mnDictionarySize = 2048;
break;
case 6:
mnDictionarySize = 4096;
break;
default:
printf("Error: Bad second header byte.\n");
exit(2);
}

mnCurrentPos = 0;
}
/*----------------------------------------------------------------------------*/
tcDecoder::~tcDecoder() {
}
/*----------------------------------------------------------------------------*/
void tcDecoder::Decode(char *apBuffer, unsigned int *apSize, unsigned
int anBufferSize) {
unsigned int lnIndex, lnStartIndex, lnCopyCount;
unsigned int lnNextPos;
tsToken lsToken;

*apSize = 0;
lsToken.meType = LITERAL; // initialize to enter loop properly

while ((lsToken.meType == LITERAL)||(lsToken.meType ==
LENGTH_OFFSET)) {
GetNextToken(&lsToken);
if(lsToken.meType == LITERAL) {
apBuffer[(*apSize)++] = lsToken.mnLiteral;
maDictionary[mnCurrentPos++] = lsToken.mnLiteral;
if (mnCurrentPos == mnDictionarySize) mnCurrentPos = 0;
if (*apSize >= anBufferSize) return;
}
else if (lsToken.meType == LENGTH_OFFSET) {
lnStartIndex = (mnCurrentPos-1-lsToken.mnOffset) %
mnDictionarySize;
lnIndex = lnStartIndex;
lnNextPos = mnCurrentPos;
lnCopyCount = 0;

while(lnCopyCount++ < lsToken.mnLength) {
apBuffer[(*apSize)++] = maDictionary[lnIndex];
maDictionary[lnNextPos++] = maDictionary[lnIndex++];
if (lnIndex == mnCurrentPos) lnIndex = lnStartIndex;
if (lnNextPos == mnDictionarySize) lnNextPos = 0;
if (*apSize >= anBufferSize) return;
}
mnCurrentPos = lnNextPos;
}
else if (lsToken.meType == END_OF_STREAM) {}
else if (lsToken.meType == ERROR) {}
} // while
}
/*----------------------------------------------------------------------------*/
void tcDecoder::GetNextToken(tsToken *apToken) {
int lnBits;
int lnLowOrderBits;

lnBits = mpBitstream->Get(1);
if (lnBits < 0) {
apToken->meType = ERROR;
}
else if (lnBits == 0) {
apToken->meType = LITERAL;
apToken->mnLiteral = mpBitstream->Get(8);
}
else {
apToken->meType = LENGTH_OFFSET;
apToken->mnLength = DecodeCopyLength();
if (apToken->mnLength == 519) apToken->meType = END_OF_STREAM;
else {
lnLowOrderBits = (apToken->mnLength == 2) ? 2 : mnSizeByte;
apToken->mnOffset = DecodeCopyOffset(lnLowOrderBits);
}
}
}
/*----------------------------------------------------------------------------*/
/* DecodeCopyLength() uses the prefix code in this table:
2 101
3 11
4 100
5 011
6 0101
7 0100
8 0011
9 00101
10-11 00100x
12-15 00011xx
16-23 00010xxx
24-39 000011xxxx
40-71 000010xxxxx
72-135 000001xxxxxx
136-263 0000001xxxxxxx
264-518 0000000xxxxxxxx

This version is somewhat prone to error and is slow. LOL, there has
to be an
easier way to do this, e.g. based on a formula for creating the tree.
*/
int tcDecoder::DecodeCopyLength(void) {
int lnBits;

lnBits = mpBitstream->Get(2);

if (lnBits == 0x3) return 3; // 11b -> 3
if (lnBits == 0x1) { // 10b
lnBits = mpBitstream->Get(1);
if (lnBits == 0x1) return 2; // 101b -> 2
else return 4; // 100b -> 4
}
else if (lnBits == 0x2) { // 01b
if (mpBitstream->Get(1)) return 5; // 011b -> 5
else { // 010b
if (mpBitstream->Get(1)) return 6; // 0101b -> 6
else return 7; // 0100b -> 7
}
}
else { // 00b
if (mpBitstream->Get(1)) { // 001b
if (mpBitstream->Get(1)) return 8; // 0011b -> 8
else { // 0010b
if (mpBitstream->Get(1)) return 9; // 00101b -> 9
else return (10 + mpBitstream->Get(1)); // 00100xb ->
10-11
}
}
else { // 000b
if (mpBitstream->Get(1)) { // 0001b
if (mpBitstream->Get(1)) {
return (12 + mpBitstream->Get(2)); // 00011xxb -> 12-15
}
else {
return (16 + mpBitstream->Get(3)); // 00010xxxb ->
16-23
}
}
else { // 0000b
lnBits = mpBitstream->Get(2);
if (lnBits == 0x3)
return (24 + mpBitstream->Get(4)); // 000011xxxxb ->
24-39
else if (lnBits == 0x1)
return (40 + mpBitstream->Get(5)); // 000010xxxxxb ->
40-71
else if (lnBits == 0x2)
return (72 + mpBitstream->Get(6)); // 000001xxxxxxb ->
72-135
else { // 000000b
if (mpBitstream->Get(1))
return (136 + mpBitstream->Get(7)); //
0000001xxxxxxxb -> 136-263
else
return (264 + mpBitstream->Get(8)); //
0000000xxxxxxxxb -> 264-518, 519
} // 000000b
} // 0000b
} // 000b
} // 00b

return -1;
}
/*----------------------------------------------------------------------------*/
/* DecodeCopyOffset(int anLowOrderBits) uses the prefix code in this
table:
00 11 20 0010111
01 1011 21 0010110
02 1010 22 0010101
03 10011 23 0010100
04 10010 24 0010011
05 10001 25 0010010
06 10000 26 0010001
07 011111 27 0010000
08 011110 28 0001111
09 011101 29 0001110
0a 011100 2a 0001101
0b 011011 2b 0001100
0c 011010 2c 0001011
0d 011001 2d 0001010
0e 011000 2e 0001001
0f 010111 2f 0001000
10 010110 30 00001111
11 010101 31 00001110
12 010100 32 00001101
13 010011 33 00001100
14 010010 34 00001011
15 010001 35 00001010
16 0100001 36 00001001
17 0100000 37 00001000
18 0011111 38 00000111
19 0011110 39 00000110
1a 0011101 3a 00000101
1b 0011100 3b 00000100
1c 0011011 3c 00000011
1d 0011010 3d 00000010
1e 0011001 3e 00000001
1f 0011000 3f 00000000

anLowOrderBits should be 4, 5, or 6 based on dictionary length
except if the copy length is 2 when it should be 2.
*/
int tcDecoder::DecodeCopyOffset(unsigned int anLowOrderBits) {
int lnBits;

lnBits = mpBitstream->Get(2);
if (lnBits == 0x3) // 11b
return CalcOffset(0x00, anLowOrderBits); // 11b -> 0x00
else if (lnBits == 0x1) { // 10b
if(mpBitstream->Get(1)==1) { // 101b
if(mpBitstream->Get(1)==1) // 1011b
return CalcOffset(0x01, anLowOrderBits); // 0x01
else // 1010b
return CalcOffset(0x02, anLowOrderBits); // 0x02
}
else { // 100b
lnBits = mpBitstream->Get(2);
return CalcOffset(0x06 - BitReverse(lnBits,2),
anLowOrderBits); // 0x03 - 0x06
}
}
else if (lnBits == 0x2) { // 01b
lnBits = mpBitstream->Get(4);
if (lnBits != 0x0)
return CalcOffset(0x16 - BitReverse(lnBits,4),
anLowOrderBits); // 0x07 - 0x15
else { // 010000b
return CalcOffset(0x17 - mpBitstream->Get(1),
anLowOrderBits); // 0x16 - 0x17
}
}
else { // 00b
if (mpBitstream->Get(1)) // 001b
return CalcOffset(0x27 - BitReverse(mpBitstream->Get(4),4),
anLowOrderBits); // 0x18 - 0x27
else { // 000b
if (mpBitstream->Get(1)) // 0001b
return CalcOffset(0x2F -
BitReverse(mpBitstream->Get(3),3),
anLowOrderBits); // 0x28 - 0x2F
else // 0000b
return CalcOffset(0x3F -
BitReverse(mpBitstream->Get(4),4),
anLowOrderBits); // 0x30 - 0x3F
} // 000b

} // 00b
return -1;
}
/*----------------------------------------------------------------------------*/
// anHighByte is shifted and added to the next anLowOrderBits from the
stream */
int tcDecoder::CalcOffset(unsigned char anHighByte,
unsigned int anLowOrderBits) {
return ((anHighByte << anLowOrderBits) |
mpBitstream->Get(anLowOrderBits));
}


/*****************************************************************************/
// tcBitstream.cpp
// Douglas Kane 5 OCT 2001
// fost...@yahoo.com
// This file is released to the public domain without restriction. I'd
// appreciate credit if this sees any use. Please post or e-mail me
code
// updates for any improvements that are made by others.
//
// tcBitstream class code
/*****************************************************************************/
#include "tcBitstream.h"
#include <stdlib.h>
/******************************************************************************/
tcBitstream::tcBitstream(void) {
mpFile = NULL;
mnByte = 0;
mnBytePos = 0;
}
/******************************************************************************/
// file version of constructor, TODO add other versions
tcBitstream::tcBitstream(FILE *apFile) {
mpFile = apFile;
mnByte = 0;
mnBytePos = 0;
}
/******************************************************************************/
// don't use this constructor
tcBitstream::~tcBitstream() {
}
/******************************************************************************/
// Get returns anCount bits fetched in little endian order.
// anCount must be < 32
// If end-of-stream is encountered, the sign bit is set and partial
data is
// returned in the 31 least sig bits.
// Bits are fetched in little endian order, e.g. data 581C produces
bitstream
// 0001101000111000. Bits start with the least significant bit in the
return
// value, e.g. Get(24) on the above stream returns 0x0C58.
int tcBitstream::Get(unsigned int anCount) {
unsigned char lnMask;
unsigned int lnPos = 0;
unsigned int lnCopyCount;
unsigned int lnLoopCount = 0;
int lnRet = 0;

if (anCount > 31) {
printf("Error: tcBitstream Get() count exceeded 31
bits.\n");exit(2);
}

while (lnLoopCount++ < 10) {
/* if mnBytePos == 0 then load another byte */
if (mnBytePos == 0) {
/* if end-of-stream then set the sign bit */
if(!fread(&mnByte,1,1,mpFile)) {return (0x8000000 | lnRet);}
mnBytePos = 8;
}

/* copy up to min(anCount - lnPos , mnBytePos) from byte to
output */
lnCopyCount = __min(anCount - lnPos, mnBytePos);
lnMask = ~(0xFF << lnCopyCount);
lnRet |= (mnByte & lnMask) << lnPos;
lnPos += lnCopyCount;
mnByte = mnByte >> lnCopyCount;
mnBytePos -= lnCopyCount;
/* if lnPos==anCount then return */
if (lnPos == anCount) {
return lnRet;
}
}

printf("Error: Stuck in bit extraction loop.\n");
exit(2);
}
/*----------------------------------------------------------------------------*/
// BitReverse reverses bits (anCount-1):0 in anData and returns
// bits from 31:anCount in anData are ignored
// e.g. BitReverse(0x111C,4) = 0x0003, BitReverse(0x111C,8) = 0x0038
unsigned int BitReverse(unsigned int anData, unsigned int anCount) {
unsigned int lnRet = 0;
unsigned int i;

for(i=0;i<anCount;i++) {
lnRet = lnRet << 1;
lnRet |= (anData & 0x0001);
anData = anData >> 1;
}
return lnRet;
}
/*****************************************************************************/
// decompress.cpp
// Douglas Kane 5 OCT 2001
// fost...@yahoo.com
// This file is released to the public domain without restriction. I'd
// appreciate credit if this sees any use. Please post or e-mail me
code
// updates for any improvements that are made by others.
//
// Decompress test code
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "decompress.h"
#include "tcBitstream.h"
#include "tcDecoder.h"

// example use of Bitstream and Decoder objects for
// PKWARE Data Compression Library decompression
void Decompress(char *azInFile, char *azOutFile) {
FILE *lpInFile, *lpOutFile;
char laBuffer[10240];
unsigned int lnSize;

/* open files */
lpInFile = fopen(azInFile,"rb");
if(lpInFile==NULL) {return;}

lpOutFile = fopen(azOutFile,"wb");
if(lpOutFile==NULL) {return;}

/* initialize Bitstream and Decoder objects */
tcBitstream lcBitstream(lpInFile);
tcDecoder lcDecoder(&lcBitstream);

/* invoke decode method */
lcDecoder.Decode(laBuffer,&lnSize,10240);

/* save results to file */
fwrite(laBuffer,1,lnSize,lpOutFile);

fcloseall();
}

Andreas Koltes

unread,
Oct 8, 2001, 1:46:59 AM10/8/01
to
There is another reverse engineered version of PKWARE's DCL supporting prefix-coded
literals.
The source code is a little bit cryptic but functional. If you are using the Delphi
interface you have to compile the C source to OMF object files. For example they are
produced by Borland C++.
The sources are provided with the tool MPQVIEW.

------------------------------------------------------------------------------------------

DCLIB.H
TYPES.H
EXPLODE.C
TABLES.C
PKDCLAPI.PAS


/*
** DCLib.h
**
** Reverse engineered version of PKWARE Data Compression Library.
**
** PKWARE Data Compression Library (R)
** Copyright 1989-1996 PKWARE Inc. All Rights Reserved
** Patent No. 5,051,745
** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.
** Version 1.11
**
** Source:
** Diablo v1.04 for MacOS (PowerPC)
** Copyright 1996-1998 Blizzard Entertainment.
**
** Reverse engineering by z80. August 28, 1998.
*/

#include "Types.h"

#define CMP_BUFFER_SIZE 36312L /* Work buffer size for imploding */
#define EXP_BUFFER_SIZE 12596L /* Work buffer size for exploding */
#define CMP_BINARY 0
#define CMP_ASCII 1
#define DICT_SIZE_1 1024
#define DICT_SIZE_2 2048
#define DICT_SIZE_4 4096

#define DCL_NO_ERROR 0L
#define DCL_ERROR_1 1L
#define DCL_ERROR_2 2L
#define DCL_ERROR_3 3L
#define DCL_ERROR_4 4L

typedef UInt16 read_data_proc(UInt8 *buffer, UInt16 size, void *param);
typedef void write_data_proc(UInt8 *buffer, UInt16 size, void *param);

extern const UInt8 dcl_table[];
extern UInt32 implode(read_data_proc read_data, write_data_proc write_data,
UInt8 *work_buff, void *param, UInt16 type, UInt16 size);
extern UInt32 explode(read_data_proc read_data, write_data_proc write_data,
UInt8 *work_buff, void *param);
extern UInt32 crc32(UInt8 *buffer, UInt32 size, UInt32 old_crc);


/*
** Types.h
*/

#define UInt8 unsigned char
#define UInt16 unsigned short
#define SInt16 short
#define UInt32 unsigned long


/*
** explode.c
**
** Reverse engineered version of PKWARE Data Compression Library.
**
** PKWARE Data Compression Library (R)
** Copyright 1989-1996 PKWARE Inc. All Rights Reserved
** Patent No. 5,051,745
** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.
** Version 1.11
**
** Source:
** Diablo v1.04 for MacOS (PowerPC)
** Copyright 1996-1998 Blizzard Entertainment.
**
** Reverse engineering by z80. August 28, 1998.
*/

#include "DCLib.h"

static UInt16 __explode_1(UInt8 *buf);
static UInt16 __explode_2(UInt8 *buf);
static UInt16 __explode_3(UInt8 *buf, UInt16 result);
static UInt16 __explode_4(UInt8 *buf, UInt32 flag);
static void __explode_5(UInt16 count, UInt8 *buf_1, const UInt8 *table, UInt8
*buf_2);
static void __explode_6(UInt8 *buf, const UInt8 *table);
void __explode_7(UInt8 *buf, const UInt8 *table, UInt32 count);

UInt32 explode(read_data_proc read_data, write_data_proc write_data,
UInt8 *work_buff, void *param)
{
UInt32 result;
UInt16 read_result;
const UInt8 *table = dcl_table;

*((UInt32 *) (work_buff + 0x16)) = (UInt32) read_data;
*((UInt32 *) (work_buff + 0x1A)) = (UInt32) write_data;
*((void **) (work_buff + 0x12)) = param;
*((UInt16 *) (work_buff + 0x0E)) = 0x0800;
read_result = read_data(work_buff + 0x2222, 0x0800, param);
if (read_result == DCL_ERROR_4)
{
result = DCL_ERROR_3;
}
else
{
UInt16 flag_0 = *(work_buff + 0x2222),
flag_1 = *(work_buff + 0x2223),
flag_2 = *(work_buff + 0x2224);

*((UInt16 *) (work_buff + 0x02)) = flag_0;
*((UInt16 *) (work_buff + 0x06)) = flag_1;
*((UInt16 *) (work_buff + 0x0A)) = flag_2;
*((UInt16 *) (work_buff + 0x0C)) = 0x00;
*((UInt16 *) (work_buff + 0x0E)) = 0x03;
*((UInt16 *) (work_buff + 0x10)) = read_result;
if ((flag_1 < 0x04) || (flag_1 > 0x06))
{
result = DCL_ERROR_1;
}
else
{
*((UInt16 *) (work_buff + 0x08)) = (UInt16) (0x0000FFFFL >> (0x0010 - flag_1));
if (flag_0 > 0x01)
{
result = DCL_ERROR_2;
}
else
{
if (flag_0)
{
__explode_7(work_buff + 0x2FA2, table + 0x00D0, 0x0100);
__explode_6(work_buff, table + 0x01D0);
}
__explode_7(work_buff + 0x30E2, table + 0x00B0, 0x0010);
__explode_5(0x0010, work_buff + 0x30E2, table + 0x00C0, work_buff + 0x2B22);
__explode_7(work_buff + 0x30F2, table + 0x0080, 0x0010);
__explode_7(work_buff + 0x3102, table + 0x0090, 0x0020);
__explode_7(work_buff + 0x30A2, table, 0x0040);
__explode_5(0x0040, work_buff + 0x30A2, table + 0x0040, work_buff + 0x2A22);
if (__explode_1(work_buff) != 0x0306)
{
result = DCL_NO_ERROR;
}
else
{
result = DCL_ERROR_4;
}
}
}
}
return result;
}

UInt16 __explode_1(UInt8 *buf)
{
UInt32 result, temp;
UInt8 *s, *d;
write_data_proc *write_data;
void *param;

*((UInt16 *) (buf + 0x04)) = 0x1000;
while (result = __explode_2(buf), (UInt16) result < 0x0305)
{
if ((UInt16) result < 0x0100)
{
temp = *((UInt16 *) (buf + 0x04));
*((UInt16 *) (buf + 0x04)) = (UInt16) (temp + 0x01);
*(buf + temp + 0x1E) =(UInt8) result;
}
else
{
result -= 0x00FE;
s = (UInt8 *) __explode_3(buf, (UInt16)result);
if (!s)
{
result = 0x0306;
break;
}
else
{
temp = *((UInt16 *) (buf + 0x04));
d = temp + 0x1E + buf;
*((UInt16 *) (buf + 0x04)) =(UInt16) (temp + result);
s = (UInt8 *)((UInt32)d - (UInt32)s);
do
{
result--;
*(d++) = *(s++);
} while (result);
}
}
if (*((UInt16 *) (buf + 4)) >= 0x2000)
{
result = 0x1000;
write_data = (write_data_proc *) *((UInt32 *) (buf + 0x1A));
param = (void *) *((UInt32 *) (buf + 0x12));
write_data(buf + 0x101E, 0x1000, param);
__explode_7(buf + 0x001E, buf + 0x101E, *((UInt16 *) (buf + 0x04)) - 0x1000);
*((UInt16 *) (buf + 0x04)) -= 0x1000;
}
}
write_data = (write_data_proc *) *((UInt32 *) (buf + 0x1A));
param = (void *) *((UInt32 *) (buf + 0x12));
write_data(buf + 0x101E, (UInt16)(*((UInt16 *) (buf + 0x04)) - 0x1000), param);
return (UInt16) result;
}

UInt16 __explode_2(UInt8 *buf)
{
UInt32 result, flag, flag_1;

if (*((UInt16 *) (buf + 0x0A)) & 0x01)
{
if (__explode_4(buf, 0x01)) return 0x0306;
result = *(buf + ((UInt8) *((UInt16 *) (buf + 0x0A))) + 0x2B22);
if (__explode_4(buf, *(buf + ((UInt16) result) + 0x30E2))) return 0x0306;
flag = *(buf + ((UInt16) result) + 0x30F2);
if (flag)
{
flag_1 = (*((UInt16 *) (buf + 0x0A))) & ((0x01 << flag) - 0x01);
if (__explode_4(buf, flag))
{
if ((((UInt16) result) + ((UInt16) flag_1)) != 0x010E) return 0x0306;
}
result = *((UInt16 *) (buf + (((UInt16) result) << 0x01) + 0x3102)) + flag_1;
}
result += 0x0100;
}
else
{
if (__explode_4(buf, 0x01)) return 0x0306;
if (!*((UInt16 *) (buf + 0x02)))
{
result = (UInt8) *((UInt16 *) (buf + 0x0A));
if (__explode_4(buf, 0x08)) return 0x0306;
}
else
{
flag = *((UInt16 *) (buf + 0x0A));
if ((UInt8) flag)
{
result = *(buf + ((UInt8) flag) + 0x2C22);
if (((UInt16) result) == 0x00FF)
{
if (flag & 0x003F)
{
if (__explode_4(buf, 0x04)) return 0x0306;
result = *(buf + ((UInt8) *((UInt16 *) (buf + 0x0A))) + 0x2D22);
}
else
{
if (__explode_4(buf, 0x06)) return 0x0306;
result = *(buf + ((*((UInt16 *) (buf + 0x0A))) & 0x007F) + 0x2E22);
}
}
}
else
{
if (__explode_4(buf, 0x08)) return 0x0306;
result = *(buf + ((UInt8) *((UInt16 *) (buf + 0x0A))) + 0x2EA2);
}
flag = *(buf + ((UInt16) result) + 0x2FA2);
if (__explode_4(buf, flag)) return 0x0306;
}
}
return (UInt16)result;
}

UInt16 __explode_3(UInt8 *buf, UInt16 flag)
{
UInt32 result, flag_1;

result = *(buf + ((UInt8) *((UInt16 *) (buf + 0x0A))) + 0x2A22);
if (__explode_4(buf, *(buf + ((UInt16) result) + 0x30A2))) return 0x00;
if (((UInt16) flag) == 0x02)
{
result <<= 0x02;
result |= *((UInt16 *) (buf + 0x0A)) & 0x03;
if (__explode_4(buf, 0x02)) return 0x00;
}
else
{
flag_1 = *((UInt16 *) (buf + 0x06));
result <<= flag_1;
result |= *((UInt16 *) (buf + 0x08)) & *((UInt16 *) (buf + 0x0A));
if (__explode_4(buf, flag_1)) return 0x00;
}
return (UInt16) (result + 0x01);
}

UInt16 __explode_4(UInt8 *buf, UInt32 flag)
{
UInt32 result;
UInt16 read_result;
read_data_proc *read_data = (read_data_proc *) *((UInt32 *) (buf + 0x16));
void *param = (void *) *((UInt32 *) (buf + 0x12));

result = *((UInt16 *) (buf + 0x0C));
if ((UInt16) flag <= result)
{
*((UInt16 *) (buf + 0x0A)) >>= flag;
*((UInt16 *) (buf + 0x0C)) -= (UInt16)flag;
result = 0x00;
}
else
{
*((UInt16 *) (buf + 0x0A)) >>= result;
result = *((UInt16 *) (buf + 0x0E));
if (result == *((UInt16 *) (buf + 0x10)))
{
*((UInt16 *) (buf + 0x0E)) = 0x0800;
read_result = read_data(buf + 0x2222, 0x0800, param);
*((UInt16 *) (buf + 0x10)) = read_result;
if (!read_result) return 0x01;
*((UInt16 *) (buf + 0x0E)) = 0x00;
}
result = *((UInt16 *) (buf + 0x0E)) + 0x2222;
*((UInt16 *) (buf + 0x0A)) |= *(buf + result) << 0x08;
*((UInt16 *) (buf + 0x0E)) += 0x01;
*((UInt16 *) (buf + 0x0A)) >>= flag - *((UInt16 *) (buf + 0x0C));
*((UInt16 *) (buf + 0x0C)) = (UInt16)(0x08 - (flag - *((UInt16 *) (buf + 0x0C))));

result = 0x00;
}
return (UInt16) result;
}

void __explode_5(UInt16 count, UInt8 *buf_1, const UInt8 *table, UInt8 *buf_2)
{
SInt16 i = (SInt16)(count - 1);
UInt32 idx_1, idx_2;

for (; i >= 0; i--)
{
idx_1 = *(table + i);
idx_2 = 0x01 << *(buf_1 + i);
for (;;)
{
*(buf_2 + (UInt16) idx_1) = (UInt8) i;
idx_1 += idx_2;
if ((UInt16) idx_1 >= 0x0100) break;
}
}
}

void __explode_6(UInt8 *buf, const UInt8 *table)
{
SInt16 i;
UInt32 idx_1, idx_2;

for (i = 0x00FF; i >= 0; i--)
{
idx_1 = *(buf + i + 0x2FA2);
if (idx_1 <= 0x08 )
{
idx_2 = *((UInt16 *) (table + (i << 0x01)));
idx_1 = 0x01 << idx_1;
do
{
*(buf + idx_2 + 0x2C22) =(UInt8) i;
idx_2 += idx_1;
} while ((UInt16) idx_2 < 0x0100);
}
else
{
idx_2 = *((UInt16 *) (table + (i << 0x01)));
if ((UInt8) idx_2)
{

*(buf + (UInt8) idx_2 + 0x2C22) = 0xFF;
if (*((UInt16 *) (table + (i << 0x01))) & 0x003F)
{
*(buf + i + 0x2FA2) -= 0x04;
idx_1 = 0x01 << *(buf + i + 0x2FA2);
idx_2 = *((UInt16 *) (table + (i << 0x01))) >> 0x04;
do
{
*(buf + idx_2 + 0x2D22) =(UInt8) i;
idx_2 += idx_1;
} while ((UInt16) idx_2 < 0x0100);
}
else
{
*(buf + i + 0x2FA2) -= 0x06;
idx_1 = 0x01 << *(buf + i + 0x2FA2);
idx_2 = *((UInt16 *) (table + (i << 0x01))) >> 0x06;
do
{
*(buf + idx_2 + 0x2E22) = (UInt8)i;
idx_2 += idx_1;
} while ((UInt16) idx_2 < 0x0080);
}
}
else
{
*(buf + i + 0x2FA2) -= 0x08;
idx_1 = 0x01 << *(buf + i + 0x2FA2);
idx_2 = *((UInt16 *) (table + (i << 0x01))) >> 0x08;
do
{
*(buf + idx_2 + 0x2EA2) = (UInt8)i;
idx_2 += idx_1;
} while ((UInt16) idx_2 < 0x0100);
}
}
}
}

void __explode_7(UInt8 *buf, const UInt8 *table, UInt32 count)
{
UInt32 half_count = count >> 0x02;
UInt8 *buf_end;

if (half_count)
{
buf_end = buf + (half_count << 0x02);
do
{
*((UInt32 *) buf) = *((UInt32 *) table);
buf += 4;
table += 4;
} while (buf < buf_end);
}
switch (count - (half_count << 0x02))
{
case 3:
*(buf++) = *(table++);

case 2:
*(buf++) = *(table++);

case 1:
*buf = *table;

default:
break;
}
}


/*
** tables.c
**
** Reverse engineered version of PKWARE Data Compression Library.
**
** PKWARE Data Compression Library (R)
** Copyright 1989-1996 PKWARE Inc. All Rights Reserved
** Patent No. 5,051,745
** PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.
** Version 1.11
**
** Source:
** Diablo v1.04 for MacOS (PowerPC)
** Copyright 1996-1998 Blizzard Entertainment.
**
** Reverse engineering by z80. August 28, 1998.
*/

#include "DCLib.h"

const UInt8 dcl_table[] =
{ 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E,
0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02,
0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04,
0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10,
0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00,
0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00,
0x08, 0x00, 0x0A, 0x00, 0x0E, 0x00, 0x16, 0x00,
0x26, 0x00, 0x46, 0x00, 0x86, 0x00, 0x06, 0x01,
0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05,
0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07,
0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14,
0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00,
0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08,
0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07,
0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08,
0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08,
0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06,
0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07,
0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D,
0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D,
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
0x90, 0x04, 0xE0, 0x0F, 0xE0, 0x07, 0xE0, 0x0B,
0xE0, 0x03, 0xE0, 0x0D, 0xE0, 0x05, 0xE0, 0x09,
0xE0, 0x01, 0xB8, 0x00, 0x62, 0x00, 0xE0, 0x0E,
0xE0, 0x06, 0x22, 0x00, 0xE0, 0x0A, 0xE0, 0x02,
0xE0, 0x0C, 0xE0, 0x04, 0xE0, 0x08, 0xE0, 0x00,
0x60, 0x0F, 0x60, 0x07, 0x60, 0x0B, 0x60, 0x03,
0x60, 0x0D, 0x60, 0x05, 0x40, 0x12, 0x60, 0x09,
0x60, 0x01, 0x60, 0x0E, 0x60, 0x06, 0x60, 0x0A,
0x0F, 0x00, 0x50, 0x02, 0x38, 0x00, 0x60, 0x02,
0x50, 0x00, 0x60, 0x0C, 0x90, 0x03, 0xD8, 0x00,
0x42, 0x00, 0x02, 0x00, 0x58, 0x00, 0xB0, 0x01,
0x7C, 0x00, 0x29, 0x00, 0x3C, 0x00, 0x98, 0x00,
0x5C, 0x00, 0x09, 0x00, 0x1C, 0x00, 0x6C, 0x00,
0x2C, 0x00, 0x4C, 0x00, 0x18, 0x00, 0x0C, 0x00,
0x74, 0x00, 0xE8, 0x00, 0x68, 0x00, 0x60, 0x04,
0x90, 0x00, 0x34, 0x00, 0xB0, 0x00, 0x10, 0x07,
0x60, 0x08, 0x31, 0x00, 0x54, 0x00, 0x11, 0x00,
0x21, 0x00, 0x17, 0x00, 0x14, 0x00, 0xA8, 0x00,
0x28, 0x00, 0x01, 0x00, 0x10, 0x03, 0x30, 0x01,
0x3E, 0x00, 0x64, 0x00, 0x1E, 0x00, 0x2E, 0x00,
0x24, 0x00, 0x10, 0x05, 0x0E, 0x00, 0x36, 0x00,
0x16, 0x00, 0x44, 0x00, 0x30, 0x00, 0xC8, 0x00,
0xD0, 0x01, 0xD0, 0x00, 0x10, 0x01, 0x48, 0x00,
0x10, 0x06, 0x50, 0x01, 0x60, 0x00, 0x88, 0x00,
0xA0, 0x0F, 0x07, 0x00, 0x26, 0x00, 0x06, 0x00,
0x3A, 0x00, 0x1B, 0x00, 0x1A, 0x00, 0x2A, 0x00,
0x0A, 0x00, 0x0B, 0x00, 0x10, 0x02, 0x04, 0x00,
0x13, 0x00, 0x32, 0x00, 0x03, 0x00, 0x1D, 0x00,
0x12, 0x00, 0x90, 0x01, 0x0D, 0x00, 0x15, 0x00,
0x05, 0x00, 0x19, 0x00, 0x08, 0x00, 0x78, 0x00,
0xF0, 0x00, 0x70, 0x00, 0x90, 0x02, 0x10, 0x04,
0x10, 0x00, 0xA0, 0x07, 0xA0, 0x0B, 0xA0, 0x03,
0x40, 0x02, 0x40, 0x1C, 0x40, 0x0C, 0x40, 0x14,
0x40, 0x04, 0x40, 0x18, 0x40, 0x08, 0x40, 0x10,
0x40, 0x00, 0x80, 0x1F, 0x80, 0x0F, 0x80, 0x17,
0x80, 0x07, 0x80, 0x1B, 0x80, 0x0B, 0x80, 0x13,
0x80, 0x03, 0x80, 0x1D, 0x80, 0x0D, 0x80, 0x15,
0x80, 0x05, 0x80, 0x19, 0x80, 0x09, 0x80, 0x11,
0x80, 0x01, 0x80, 0x1E, 0x80, 0x0E, 0x80, 0x16,
0x80, 0x06, 0x80, 0x1A, 0x80, 0x0A, 0x80, 0x12,
0x80, 0x02, 0x80, 0x1C, 0x80, 0x0C, 0x80, 0x14,
0x80, 0x04, 0x80, 0x18, 0x80, 0x08, 0x80, 0x10,
0x80, 0x00, 0x00, 0x1F, 0x00, 0x0F, 0x00, 0x17,
0x00, 0x07, 0x00, 0x1B, 0x00, 0x0B, 0x00, 0x13,
0xA0, 0x0D, 0xA0, 0x05, 0xA0, 0x09, 0xA0, 0x01,
0xA0, 0x0E, 0xA0, 0x06, 0xA0, 0x0A, 0xA0, 0x02,
0xA0, 0x0C, 0xA0, 0x04, 0xA0, 0x08, 0xA0, 0x00,
0x20, 0x0F, 0x20, 0x07, 0x20, 0x0B, 0x20, 0x03,
0x20, 0x0D, 0x20, 0x05, 0x20, 0x09, 0x20, 0x01,
0x20, 0x0E, 0x20, 0x06, 0x20, 0x0A, 0x20, 0x02,
0x20, 0x0C, 0x20, 0x04, 0x20, 0x08, 0x20, 0x00,
0xC0, 0x0F, 0xC0, 0x07, 0xC0, 0x0B, 0xC0, 0x03,
0xC0, 0x0D, 0xC0, 0x05, 0xC0, 0x09, 0xC0, 0x01,
0xC0, 0x0E, 0xC0, 0x06, 0xC0, 0x0A, 0xC0, 0x02,
0xC0, 0x0C, 0xC0, 0x04, 0xC0, 0x08, 0xC0, 0x00,
0x40, 0x0F, 0x40, 0x07, 0x40, 0x0B, 0x40, 0x03,
0x00, 0x03, 0x40, 0x0D, 0x00, 0x1D, 0x00, 0x0D,
0x00, 0x15, 0x40, 0x05, 0x00, 0x05, 0x00, 0x19,
0x00, 0x09, 0x40, 0x09, 0x00, 0x11, 0x00, 0x01,
0x00, 0x1E, 0x00, 0x0E, 0x40, 0x01, 0x00, 0x16,
0x00, 0x06, 0x00, 0x1A, 0x40, 0x0E, 0x40, 0x06,
0x40, 0x0A, 0x00, 0x0A, 0x00, 0x12, 0x00, 0x02,
0x00, 0x1C, 0x00, 0x0C, 0x00, 0x14, 0x00, 0x04,
0x00, 0x18, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00,
0x50, 0x4B, 0x57, 0x41, 0x52, 0x45, 0x20, 0x44,
0x61, 0x74, 0x61, 0x20, 0x43, 0x6F, 0x6D, 0x70,
0x72, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x20,
0x4C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20,
0x66, 0x6F, 0x72, 0x20, 0x57, 0x69, 0x6E, 0x33,
0x32, 0x0D, 0x0A, 0x43, 0x6F, 0x70, 0x79, 0x72,
0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x38,
0x39, 0x2D, 0x31, 0x39, 0x39, 0x35, 0x20, 0x50,
0x4B, 0x57, 0x41, 0x52, 0x45, 0x20, 0x49, 0x6E,
0x63, 0x2E, 0x20, 0x20, 0x41, 0x6C, 0x6C, 0x20,
0x52, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x52,
0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2E,
0x0D, 0x0A, 0x50, 0x61, 0x74, 0x65, 0x6E, 0x74,
0x20, 0x4E, 0x6F, 0x2E, 0x20, 0x35, 0x2C, 0x30,
0x35, 0x31, 0x2C, 0x37, 0x34, 0x35, 0x0D, 0x0A,
0x50, 0x4B, 0x57, 0x41, 0x52, 0x45, 0x20, 0x44,
0x61, 0x74, 0x61, 0x20, 0x43, 0x6F, 0x6D, 0x70,
0x72, 0x65, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x20,
0x4C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20,
0x52, 0x65, 0x67, 0x2E, 0x20, 0x55, 0x2E, 0x53,
0x2E, 0x20, 0x50, 0x61, 0x74, 0x2E, 0x20, 0x61,
0x6E, 0x64, 0x20, 0x54, 0x6D, 0x2E, 0x20, 0x4F,
0x66, 0x66, 0x2E, 0x0D, 0x0A, 0x56, 0x65, 0x72,
0x73, 0x69, 0x6F, 0x6E, 0x20, 0x31, 0x2E, 0x31,
0x31
};


unit PKDCLAPI;

{*****************************************************************
Delphi Interface Unit

Reverse engineered version of PKWARE Data Compression Library.

PKWARE Data Compression Library (R)
Copyright 1989-1996 PKWARE Inc. All Rights Reserved
Patent No. 5,051,745
PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.
Version 1.11

Source:
Diablo v1.04 for MacOS (PowerPC)
Copyright 1996-1998 Blizzard Entertainment.

Reverse engineering by z80. August 28, 1998.

Delphi interface by Andreas Koltes. July 12, 2001.
******************************************************************}

interface

// {$L IMPLODE.OBJ}
{$L EXPLODE.OBJ}
{$L TABLES.OBJ}

const
CMP_BUFFER_SIZE = 36312; // Work buffer size for imploding
EXP_BUFFER_SIZE = 12596; // Work buffer size for exploding

CMP_DICT_SIZE1 = 1024;
CMP_DICT_SIZE2 = 2048;
CMP_DICT_SIZE3 = 4096;

CMP_BINARY = 0;
CMP_ASCII = 1;

CMP_NO_ERROR = 0;
CMP_INVALID_DICTSIZE = 1;
CMP_INVALID_MODE = 2;
CMP_BAD_DATA = 3;
CMP_ABORT = 4;

type
TICallBack = function(var buffer; size: Word; var param): Word; cdecl;
TOCallBack = procedure(var buffer; size: Word; var param); cdecl;
PTICallBack = ^TICallBack;
PTOCallBack = ^TOCallBack;

// function _implode(read_buff: TICallBack; write_buff: TOCallBack;
// var work_buf, param; cmp_type, dsize: Word): Cardinal; cdecl; external;

function _explode(read_buff: TICallBack; write_buff: TOCallBack;
var work_buf, param): Cardinal; cdecl; external;

// function _crc32(var buffer; size, old_crc: Cardinal); cdecl; external;

implementation

end.


0 new messages