2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS cabinet manager
4 * FILE: tools/cabman/mszip.cxx
5 * PURPOSE: CAB codec for MSZIP compressed data
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Colin Finck <mail@colinfinck.de>
8 * NOTES: The ZLIB does the real work. Get the full version
9 * from http://www.cdrom.com/pub/infozip/zlib/
11 * CSH 21/03-2001 Created
12 * CSH 15/08-2003 Made it portable
13 * CF 04/05-2007 Made it compatible with 64-bit operating systems
19 /* Memory functions */
21 voidpf
MSZipAlloc(voidpf opaque
, uInt items
, uInt size
)
23 DPRINT(DEBUG_MEMORY
, ("items = (%d) size = (%d)\n", items
, size
));
24 return AllocateMemory(items
* size
);
27 void MSZipFree (voidpf opaque
, voidpf address
)
29 DPRINT(DEBUG_MEMORY
, ("\n"));
36 CMSZipCodec::CMSZipCodec()
38 * FUNCTION: Default constructor
41 ZStream
.zalloc
= MSZipAlloc
;
42 ZStream
.zfree
= MSZipFree
;
43 ZStream
.opaque
= (voidpf
)0;
47 CMSZipCodec::~CMSZipCodec()
49 * FUNCTION: Default destructor
55 ULONG
CMSZipCodec::Compress(void* OutputBuffer
,
60 * FUNCTION: Compresses data in a buffer
62 * OutputBuffer = Pointer to buffer to place compressed data
63 * InputBuffer = Pointer to buffer with data to be compressed
64 * InputLength = Length of input buffer
65 * OutputLength = Address of buffer to place size of compressed data
70 DPRINT(MAX_TRACE
, ("InputLength (%u).\n", (UINT
)InputLength
));
72 Magic
= (PUSHORT
)OutputBuffer
;
75 ZStream
.next_in
= (unsigned char*)InputBuffer
;
76 ZStream
.avail_in
= InputLength
;
77 ZStream
.next_out
= ((unsigned char *)OutputBuffer
+ 2);
78 ZStream
.avail_out
= CAB_BLOCKSIZE
+ 12;
80 /* WindowBits is passed < 0 to tell that there is no zlib header */
81 Status
= deflateInit2(&ZStream
,
82 Z_DEFAULT_COMPRESSION
,
89 DPRINT(MIN_TRACE
, ("deflateInit() returned (%d).\n", Status
));
93 Status
= deflate(&ZStream
, Z_FINISH
);
94 if ((Status
!= Z_OK
) && (Status
!= Z_STREAM_END
))
96 DPRINT(MIN_TRACE
, ("deflate() returned (%d) (%s).\n", Status
, ZStream
.msg
));
97 if (Status
== Z_MEM_ERROR
)
102 *OutputLength
= ZStream
.total_out
+ 2;
104 Status
= deflateEnd(&ZStream
);
107 DPRINT(MIN_TRACE
, ("deflateEnd() returned (%d).\n", Status
));
115 ULONG
CMSZipCodec::Uncompress(void* OutputBuffer
,
120 * FUNCTION: Uncompresses data in a buffer
122 * OutputBuffer = Pointer to buffer to place uncompressed data
123 * InputBuffer = Pointer to buffer with data to be uncompressed
124 * InputLength = Length of input buffer
125 * OutputLength = Address of buffer to place size of uncompressed data
130 DPRINT(MAX_TRACE
, ("InputLength (%u).\n", (UINT
)InputLength
));
132 Magic
= *((PUSHORT
)InputBuffer
);
134 if (Magic
!= MSZIP_MAGIC
)
136 DPRINT(MID_TRACE
, ("Bad MSZIP block header magic (0x%X)\n", Magic
));
140 ZStream
.next_in
= ((unsigned char*)InputBuffer
+ 2);
141 ZStream
.avail_in
= InputLength
- 2;
142 ZStream
.next_out
= (unsigned char*)OutputBuffer
;
143 ZStream
.avail_out
= CAB_BLOCKSIZE
+ 12;
145 /* WindowBits is passed < 0 to tell that there is no zlib header.
146 * Note that in this case inflate *requires* an extra "dummy" byte
147 * after the compressed stream in order to complete decompression and
148 * return Z_STREAM_END.
150 Status
= inflateInit2(&ZStream
, -MAX_WBITS
);
153 DPRINT(MIN_TRACE
, ("inflateInit2() returned (%d).\n", Status
));
157 while ((ZStream
.total_out
< CAB_BLOCKSIZE
+ 12) &&
158 (ZStream
.total_in
< InputLength
- 2))
160 Status
= inflate(&ZStream
, Z_NO_FLUSH
);
161 if (Status
== Z_STREAM_END
) break;
164 DPRINT(MIN_TRACE
, ("inflate() returned (%d) (%s).\n", Status
, ZStream
.msg
));
165 if (Status
== Z_MEM_ERROR
)
171 *OutputLength
= ZStream
.total_out
;
173 Status
= inflateEnd(&ZStream
);
176 DPRINT(MIN_TRACE
, ("inflateEnd() returned (%d).\n", Status
));