2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS cabinet manager
4 * FILE: tools/cabman/mszip.cpp
5 * PURPOSE: CAB codec for MSZIP compressed data
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * NOTES: The ZLIB does the real work. Get the full version
8 * from http://www.cdrom.com/pub/infozip/zlib/
10 * CSH 21/03-2001 Created
11 * CSH 15/08-2003 Made it portable
17 /* Memory functions */
19 voidpf MSZipAlloc(voidpf opaque, uInt items, uInt size)
21 DPRINT(DEBUG_MEMORY, ("items = (%d) size = (%d)\n", items, size));
22 return AllocateMemory(items * size);
25 void MSZipFree (voidpf opaque, voidpf address)
27 DPRINT(DEBUG_MEMORY, ("\n"));
34 CMSZipCodec::CMSZipCodec()
36 * FUNCTION: Default constructor
39 ZStream.zalloc = MSZipAlloc;
40 ZStream.zfree = MSZipFree;
41 ZStream.opaque = (voidpf)0;
45 CMSZipCodec::~CMSZipCodec()
47 * FUNCTION: Default destructor
53 unsigned long CMSZipCodec::Compress(void* OutputBuffer,
55 unsigned long InputLength,
56 unsigned long* OutputLength)
58 * FUNCTION: Compresses data in a buffer
60 * OutputBuffer = Pointer to buffer to place compressed data
61 * InputBuffer = Pointer to buffer with data to be compressed
62 * InputLength = Length of input buffer
63 * OutputLength = Address of buffer to place size of compressed data
66 unsigned short* Magic;
68 DPRINT(MAX_TRACE, ("InputLength (%d).\n", InputLength));
70 Magic = (unsigned short*)OutputBuffer;
73 ZStream.next_in = (unsigned char*)InputBuffer;
74 ZStream.avail_in = InputLength;
75 ZStream.next_out = (unsigned char*)((unsigned long)OutputBuffer + 2);
76 ZStream.avail_out = CAB_BLOCKSIZE + 12;
78 /* WindowBits is passed < 0 to tell that there is no zlib header */
79 Status = deflateInit2(&ZStream,
86 DPRINT(MIN_TRACE, ("deflateInit() returned (%d).\n", Status));
90 Status = deflate(&ZStream, Z_FINISH);
91 if ((Status != Z_OK) && (Status != Z_STREAM_END)) {
92 DPRINT(MIN_TRACE, ("deflate() returned (%d) (%s).\n", Status, ZStream.msg));
93 if (Status == Z_MEM_ERROR)
98 *OutputLength = ZStream.total_out + 2;
100 Status = deflateEnd(&ZStream);
101 if (Status != Z_OK) {
102 DPRINT(MIN_TRACE, ("deflateEnd() returned (%d).\n", Status));
110 unsigned long CMSZipCodec::Uncompress(void* OutputBuffer,
112 unsigned long InputLength,
113 unsigned long* OutputLength)
115 * FUNCTION: Uncompresses data in a buffer
117 * OutputBuffer = Pointer to buffer to place uncompressed data
118 * InputBuffer = Pointer to buffer with data to be uncompressed
119 * InputLength = Length of input buffer
120 * OutputLength = Address of buffer to place size of uncompressed data
123 unsigned short Magic;
125 DPRINT(MAX_TRACE, ("InputLength (%d).\n", InputLength));
127 Magic = *((unsigned short*)InputBuffer);
129 if (Magic != MSZIP_MAGIC) {
130 DPRINT(MID_TRACE, ("Bad MSZIP block header magic (0x%X)\n", Magic));
134 ZStream.next_in = (unsigned char*)((unsigned long)InputBuffer + 2);
135 ZStream.avail_in = InputLength - 2;
136 ZStream.next_out = (unsigned char*)OutputBuffer;
137 ZStream.avail_out = CAB_BLOCKSIZE + 12;
139 /* WindowBits is passed < 0 to tell that there is no zlib header.
140 * Note that in this case inflate *requires* an extra "dummy" byte
141 * after the compressed stream in order to complete decompression and
142 * return Z_STREAM_END.
144 Status = inflateInit2(&ZStream, -MAX_WBITS);
145 if (Status != Z_OK) {
146 DPRINT(MIN_TRACE, ("inflateInit2() returned (%d).\n", Status));
150 while ((ZStream.total_out < CAB_BLOCKSIZE + 12) &&
151 (ZStream.total_in < InputLength - 2)) {
152 Status = inflate(&ZStream, Z_NO_FLUSH);
153 if (Status == Z_STREAM_END) break;
154 if (Status != Z_OK) {
155 DPRINT(MIN_TRACE, ("inflate() returned (%d) (%s).\n", Status, ZStream.msg));
156 if (Status == Z_MEM_ERROR)
162 *OutputLength = ZStream.total_out;
164 Status = inflateEnd(&ZStream);
165 if (Status != Z_OK) {
166 DPRINT(MIN_TRACE, ("inflateEnd() returned (%d).\n", Status));