Current News Archived News Search News Discussion Forum Old Forum Install Programs More Downloads... Troubleshooting Source Code Format Specs. Misc. Information Non-SF Stuff Links Small banner for links to this site: |
9a930ad241f35cfcbd80f9fbee65ac7bc4759330
1 // SComp.cpp - Main compression/decompression and wrapper routines
2 //
3 // Requires Zlib for Warcraft III files (not included).
4 // Get it at http://www.gzip.org/zlib/
5 //
6 // Converted from assembly to C++ by ShadowFlare.
7 // E-mail : blakflare@hotmail.com
8 // Webpage : http://sfsrealm.hopto.org/
9 // License information for this code is in license.txt
12 // Define NO_WINDOWS_H globally if compiling for
13 // Windows to disable calling Windows functions.
15 // Comment this out to disable Zlib compression support.
16 #define USE_ZLIB
18 // Comment this out to disable bzip 2 compression support.
19 #define USE_BZIP2
21 #include "SComp.h"
22 #include "SErr.h"
23 #include "SMem.h"
24 #include "wave.h"
25 #include "huffman.h"
27 #ifdef USE_ZLIB
28 #ifndef __SYS_ZLIB
29 #define ZLIB_INTERNAL
30 #include "zlib/zlib.h"
31 #else
32 #include <zlib.h>
33 #endif
34 #endif
36 #include "pklib.h"
38 #ifdef USE_BZIP2
39 #ifndef __SYS_BZLIB
40 #include "bzip2/bzlib.h"
41 #else
42 #include <bzlib.h>
43 #endif
44 #endif
46 typedef void (__fastcall *FCOMPRESS)(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
47 typedef void (__fastcall *FDECOMPRESS)(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
49 struct CompressFunc {
50 DWORD dwFlag;
51 FCOMPRESS fnCompress;
52 };
54 struct DecompressFunc {
55 DWORD dwFlag;
56 FDECOMPRESS fnDecompress;
57 };
59 void __fastcall CompressWaveMono(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
60 void __fastcall CompressWaveStereo(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
61 void __fastcall HuffmanCompress(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
62 #ifdef USE_ZLIB
63 void __fastcall Deflate(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
64 #endif
65 void __fastcall Implode(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
66 #ifdef USE_BZIP2
67 void __fastcall CompressBZ2(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
68 #endif
70 void __fastcall DecompressWaveMono(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
71 void __fastcall DecompressWaveStereo(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
72 void __fastcall HuffmanDecompress(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
73 #ifdef USE_ZLIB
74 void __fastcall Inflate(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
75 #endif
76 void __fastcall Explode(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
77 #ifdef USE_BZIP2
78 void __fastcall DecompressBZ2(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
79 #endif
81 void __fastcall InitWaveCompress(DWORD dwCompressLevel, LPDWORD *lplpdwCompressionSubType, LPDWORD lpdwCompressionSubType);
83 typedef struct {
84 LPVOID lpvDestinationMem;
85 DWORD dwDestStart;
86 DWORD dwDestLen;
87 LPVOID lpvSourceMem;
88 DWORD dwSrcStart;
89 DWORD dwSrcLen;
90 } BUFFERINFO;
92 unsigned int FillInput(char *lpvBuffer, unsigned int *lpdwSize, void *param);
93 void FillOutput(char *lpvBuffer, unsigned int *lpdwSize, void *param);
95 const unsigned int UNSUPPORTED_COMPRESSION = (0xFF ^ (0x40 | 0x80 | 0x01
96 #ifdef USE_ZLIB
97 | 0x02
98 #endif
99 | 0x08
100 #ifdef USE_BZIP2
101 | 0x10
102 #endif
103 ));
104 const unsigned int UNSUPPORTED_DECOMPRESSION = (0xFF ^ (0x40 | 0x80 | 0x01
105 #ifdef USE_ZLIB
106 | 0x02
107 #endif
108 | 0x08
109 #ifdef USE_BZIP2
110 | 0x10
111 #endif
112 ));
114 CompressFunc CompressionFunctions[] =
115 {
116 {0x40, CompressWaveMono},
117 {0x80, CompressWaveStereo},
118 {0x01, HuffmanCompress},
119 #ifdef USE_ZLIB
120 {0x02, Deflate},
121 #endif
122 {0x08, Implode},
123 #ifdef USE_BZIP2
124 {0x10, CompressBZ2},
125 #endif
126 };
128 DecompressFunc DecompressionFunctions[] =
129 {
130 {0x40, DecompressWaveMono},
131 {0x80, DecompressWaveStereo},
132 {0x01, HuffmanDecompress},
133 #ifdef USE_ZLIB
134 {0x02, Inflate},
135 #endif
136 {0x08, Explode},
137 #ifdef USE_BZIP2
138 {0x10, DecompressBZ2},
139 #endif
140 };
142 const DWORD nCompFunctions = sizeof(CompressionFunctions) / sizeof(CompressionFunctions[0]);
143 const DWORD nDecompFunctions = sizeof(DecompressionFunctions) / sizeof(DecompressionFunctions[0]);
145 CompressFunc *lpLastCompressMethod = &CompressionFunctions[nCompFunctions-1];
146 DecompressFunc *lpLastDecompressMethod = &DecompressionFunctions[nDecompFunctions-1];
148 BOOL WINAPI SCompCompress(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, DWORD dwCompressionType, DWORD dwCompressionSubType, DWORD dwCompressLevel)
149 {
150 DWORD dwCompressCount,dwCurFlag,dwTempFlags,dwInSize,dwOutSize;
151 LPVOID lpvInBuffer,lpvOutBuffer,lpvWorkBuffer,lpvAllocBuffer;
152 CompressFunc *lpCFuncTable;
154 if (!lpdwCompressedSize) {
155 SErrSetLastError(ERROR_INVALID_PARAMETER);
156 return FALSE;
157 }
158 if (*lpdwCompressedSize < dwDecompressedSize || !lpvDestinationMem || !lpvSourceMem) {
159 SErrSetLastError(ERROR_INVALID_PARAMETER);
160 return FALSE;
161 }
163 dwCompressCount = 0;
164 dwTempFlags = dwCompressionType;
165 lpCFuncTable = CompressionFunctions;
167 do {
168 dwCurFlag = lpCFuncTable->dwFlag;
170 if (dwCompressionType & dwCurFlag) {
171 dwCompressCount++;
172 }
174 lpCFuncTable++;
175 dwTempFlags &= ~dwCurFlag;
176 } while (lpCFuncTable <= lpLastCompressMethod);
178 if (dwTempFlags) {
179 return FALSE;
180 }
182 dwInSize = dwDecompressedSize;
183 lpvAllocBuffer = 0;
185 if (dwCompressCount >= 2
186 || !((LPBYTE)lpvDestinationMem+dwInSize <= (LPBYTE)lpvSourceMem
187 || (LPBYTE)lpvSourceMem+dwInSize <= (LPBYTE)lpvDestinationMem
188 || !dwCompressCount))
189 {
190 lpvWorkBuffer = SMemAlloc(dwInSize);
192 if (!lpvWorkBuffer) {
193 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
194 return FALSE;
195 }
197 lpvAllocBuffer = lpvWorkBuffer;
198 }
200 lpvInBuffer = lpvSourceMem;
201 lpCFuncTable = CompressionFunctions;
203 do {
204 dwTempFlags = dwCompressionType;
205 dwCurFlag = lpCFuncTable->dwFlag;
207 if (dwTempFlags & dwCurFlag) {
208 dwCompressCount--;
210 if (dwCompressCount & 1) {
211 lpvOutBuffer = lpvWorkBuffer;
212 }
213 else {
214 lpvOutBuffer = (LPVOID)((LPBYTE)lpvDestinationMem+1);
215 }
217 if ((LPBYTE)lpvOutBuffer+dwInSize > (LPBYTE)lpvInBuffer
218 && (LPBYTE)lpvInBuffer+dwInSize > (LPBYTE)lpvOutBuffer)
219 {
220 if ((LPBYTE)lpvOutBuffer+dwInSize > (LPBYTE)lpvWorkBuffer
221 && (LPBYTE)lpvWorkBuffer+dwInSize > (LPBYTE)lpvOutBuffer)
222 {
223 lpvWorkBuffer = lpvDestinationMem;
224 lpvOutBuffer = (LPVOID)((LPBYTE)lpvWorkBuffer+1);
225 }
226 else {
227 lpvOutBuffer = lpvWorkBuffer;
228 }
229 }
231 dwDecompressedSize = dwInSize-1;
232 lpCFuncTable->fnCompress(lpvOutBuffer,&dwDecompressedSize,lpvInBuffer,dwInSize,&dwCompressionSubType,dwCompressLevel);
233 dwOutSize = dwDecompressedSize+1;
235 if (dwOutSize < dwInSize) {
236 lpvInBuffer = lpvOutBuffer;
237 dwInSize = dwDecompressedSize;
238 }
239 else {
240 dwCurFlag = lpCFuncTable->dwFlag;
241 dwCompressionType = dwCompressionType & (~dwCurFlag);
242 }
244 lpvWorkBuffer = lpvAllocBuffer;
245 }
247 lpCFuncTable++;
248 } while (lpCFuncTable <= lpLastCompressMethod);
250 lpvOutBuffer = lpvDestinationMem;
252 if (lpvInBuffer != lpvOutBuffer) {
253 if ((LPBYTE)lpvInBuffer == (LPBYTE)lpvOutBuffer+1) {
254 *(LPBYTE)lpvOutBuffer = (BYTE)dwCompressionType;
255 dwInSize++;
256 }
257 else {
258 if (dwCompressionType) {
259 SMemCopy((LPBYTE)lpvOutBuffer+1,lpvInBuffer,dwInSize);
260 dwInSize++;
261 *(LPBYTE)lpvOutBuffer = (BYTE)dwCompressionType;
262 }
263 else {
264 SMemCopy(lpvOutBuffer,lpvInBuffer,dwInSize);
265 }
267 lpvWorkBuffer = lpvAllocBuffer;
268 }
269 }
271 *lpdwCompressedSize = dwInSize;
273 if (lpvWorkBuffer) {
274 SMemFree(lpvWorkBuffer);
275 }
277 return TRUE;
278 }
280 BOOL WINAPI SCompDecompress(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
281 {
282 DWORD dwDecompressedSize, dwOutSize, dwCompressTypes, dwCurFlag, dwTempFlags,dwCompressCount;
283 LPVOID lpvInBuffer,lpvOutBuffer,lpvWorkBuffer,lpvTempBuffer;
284 DecompressFunc *lpCFuncTable;
286 if (!lpdwDecompressedSize) {
287 SErrSetLastError(ERROR_INVALID_PARAMETER);
288 return FALSE;
289 }
291 dwDecompressedSize = *lpdwDecompressedSize;
293 if (dwDecompressedSize < dwCompressedSize || !lpvDestinationMem || !lpvSourceMem || dwCompressedSize < 1) {
294 SErrSetLastError(ERROR_INVALID_PARAMETER);
295 return FALSE;
296 }
298 if (dwCompressedSize == dwDecompressedSize) {
299 if (lpvDestinationMem == lpvSourceMem)
300 return TRUE;
302 SMemCopy(lpvDestinationMem,lpvSourceMem,dwCompressedSize);
303 return TRUE;
304 }
306 dwCompressCount = 0;
307 dwCompressTypes = *(LPBYTE)lpvSourceMem;
308 lpvInBuffer = (LPVOID)((LPBYTE)lpvSourceMem+1);
309 dwCompressedSize--;
310 dwTempFlags = dwCompressTypes;
311 lpCFuncTable = lpLastDecompressMethod;
313 do {
314 dwCurFlag = lpCFuncTable->dwFlag;
316 if (dwCompressTypes & dwCurFlag) {
317 dwCompressCount++;
318 }
320 dwTempFlags &= ~dwCurFlag;
321 lpCFuncTable--;;
322 } while (lpCFuncTable >= DecompressionFunctions);
324 if (dwTempFlags) {
325 return FALSE;
326 }
328 lpvWorkBuffer = 0;
330 if (dwCompressCount >= 2
331 || !((LPBYTE)lpvDestinationMem+dwCompressedSize <= (LPBYTE)lpvInBuffer
332 || (LPBYTE)lpvInBuffer+dwCompressedSize <= (LPBYTE)lpvDestinationMem
333 || !dwCompressCount))
334 {
335 lpvWorkBuffer = SMemAlloc(dwDecompressedSize);
337 if (!lpvWorkBuffer) {
338 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
339 return FALSE;
340 }
341 }
343 lpCFuncTable = lpLastDecompressMethod;
345 do {
346 if (dwCompressTypes & lpCFuncTable->dwFlag) {
347 lpvOutBuffer = lpvWorkBuffer;
348 dwCompressCount--;
350 if (!(dwCompressCount & 1)) {
351 lpvOutBuffer = lpvDestinationMem;
352 }
354 if ((LPBYTE)lpvOutBuffer+dwCompressedSize > (LPBYTE)lpvInBuffer
355 && (LPBYTE)lpvInBuffer+dwCompressedSize > (LPBYTE)lpvOutBuffer)
356 {
357 if ((LPBYTE)lpvOutBuffer+dwCompressedSize <= (LPBYTE)lpvWorkBuffer) {
358 lpvOutBuffer = lpvWorkBuffer;
359 }
360 else {
361 lpvTempBuffer = lpvOutBuffer;
362 lpvOutBuffer = lpvDestinationMem;
364 if ((LPBYTE)lpvWorkBuffer+dwCompressedSize <= (LPBYTE)lpvTempBuffer)
365 lpvOutBuffer = lpvWorkBuffer;
366 }
367 }
369 dwOutSize = dwDecompressedSize;
370 lpCFuncTable->fnDecompress(lpvOutBuffer,&dwOutSize,lpvInBuffer,dwCompressedSize);
371 dwCompressedSize = dwOutSize;
372 lpvInBuffer = lpvOutBuffer;
373 }
375 lpCFuncTable--;
376 } while (lpCFuncTable >= DecompressionFunctions);
378 if (lpvInBuffer != lpvDestinationMem) {
379 SMemCopy(lpvDestinationMem,lpvInBuffer,dwCompressedSize);
380 }
382 *lpdwDecompressedSize = dwCompressedSize;
384 if (lpvWorkBuffer) {
385 SMemFree(lpvWorkBuffer);
386 }
388 return TRUE;
389 }
391 void __fastcall InitWaveCompress(DWORD dwCompressLevel, LPDWORD *lplpdwCompressionSubType, LPDWORD lpdwCompressionSubType)
392 {
393 if (dwCompressLevel) {
394 if (dwCompressLevel <= 2) {
395 *(LPBYTE)lplpdwCompressionSubType = 4;
396 *lpdwCompressionSubType = 6;
397 return;
398 }
399 else if (dwCompressLevel == 3) {
400 *(LPBYTE)lplpdwCompressionSubType = 6;
401 *lpdwCompressionSubType = 8;
402 return;
403 }
404 }
406 *(LPBYTE)lplpdwCompressionSubType = 5;
407 *lpdwCompressionSubType = 7;
408 }
410 void __fastcall CompressWaveMono(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
411 {
412 InitWaveCompress(dwCompressLevel,&lpdwCompressionSubType,lpdwCompressionSubType);
413 *lpdwCompressedSize = CompressWave((LPBYTE)lpvDestinationMem,*lpdwCompressedSize,(short *)lpvSourceMem,dwDecompressedSize,1,(unsigned int)lpdwCompressionSubType & 0xFF);
414 }
416 void __fastcall CompressWaveStereo(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
417 {
418 InitWaveCompress(dwCompressLevel,&lpdwCompressionSubType,lpdwCompressionSubType);
419 *lpdwCompressedSize = CompressWave((LPBYTE)lpvDestinationMem,*lpdwCompressedSize,(short *)lpvSourceMem,dwDecompressedSize,2,(unsigned int)lpdwCompressionSubType & 0xFF);
420 }
422 void __fastcall HuffmanCompress(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
423 {
424 THuffmannTree *ht; // Huffmann tree for compression
425 TOutputStream os; // Output stream
426 THTreeItem * pItem;
427 int nCount;
429 ht = (THuffmannTree *)SMemAlloc(sizeof(THuffmannTree));
431 if (!ht) {
432 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
433 return;
434 }
436 // Initialize output stream
437 os.pbOutBuffer = (unsigned char *)lpvDestinationMem;
438 os.dwOutSize = *lpdwCompressedSize;
439 os.pbOutPos = (unsigned char *)lpvDestinationMem;
440 os.dwBitBuff = 0;
441 os.nBits = 0;
443 // Clear links for all the items in the tree
444 for(pItem = ht->items0008, nCount = 0x203; nCount != 0; nCount--, pItem++)
445 pItem->ClearItemLinks();
447 ht->pItem3054 = NULL;
448 ht->pItem3054 = PTR_PTR(&ht->pItem3054);
449 ht->pItem3058 = PTR_NOT(&ht->pItem3054);
451 ht->pItem305C = NULL;
452 ht->pFirst = PTR_PTR(&ht->pFirst);
453 ht->pLast = PTR_NOT(&ht->pFirst);
455 ht->offs0004 = 1;
456 ht->nItems = 0;
458 *lpdwCompressedSize = ht->DoCompression(&os, (unsigned char *)lpvSourceMem, dwDecompressedSize, *lpdwCompressionSubType);
459 /*
460 // The following code is not necessary to run, because it has no
461 // effect on the output data. It only clears the huffmann tree, but when
462 // the tree is on the stack, who cares ?
463 while(PTR_INT(ht.pLast) > 0)
464 {
465 pItem = ht.pItem305C->Call1501DB70(ht.pLast);
466 pItem->RemoveItem();
467 }
469 for(pItem = ht.pFirst; PTR_INT(ht.pItem3058) > 0; pItem = ht.pItem3058)
470 pItem->RemoveItem();
471 PTR_PTR(&ht.pItem3054)->RemoveItem();
473 for(pItem = ht.items0008 + 0x203, nCount = 0x203; nCount != 0; nCount--)
474 {
475 pItem--;
476 pItem->RemoveItem();
477 pItem->RemoveItem();
478 }
479 */
480 }
482 #ifdef USE_ZLIB
484 void __fastcall Deflate(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
485 {
486 if (*lpdwCompressionSubType == 0) {
487 switch (dwCompressLevel) {
488 case 1:
489 dwCompressLevel = Z_BEST_COMPRESSION;
490 break;
491 case 2:
492 dwCompressLevel = Z_BEST_SPEED;
493 break;
494 default:
495 dwCompressLevel = (DWORD)Z_DEFAULT_COMPRESSION;
496 }
497 }
499 compress2((LPBYTE)lpvDestinationMem,(unsigned long *)lpdwCompressedSize,(LPBYTE)lpvSourceMem,dwDecompressedSize,dwCompressLevel);
500 *lpdwCompressionSubType = 0;
501 }
503 #endif
505 void __fastcall Implode(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
506 {
507 BUFFERINFO BufferInfo;
508 unsigned int dwCompType, dwDictSize;
509 LPVOID lpvWorkBuffer;
511 lpvWorkBuffer = SMemAlloc(CMP_BUFFER_SIZE);
513 if (!lpvWorkBuffer) {
514 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
515 return;
516 }
518 BufferInfo.lpvSourceMem = lpvSourceMem;
519 BufferInfo.dwSrcStart = 0;
520 BufferInfo.dwSrcLen = dwDecompressedSize;
521 BufferInfo.lpvDestinationMem = lpvDestinationMem;
522 BufferInfo.dwDestStart = 0;
523 BufferInfo.dwDestLen = *lpdwCompressedSize;
525 dwCompType = (*lpdwCompressionSubType==2)?CMP_ASCII:CMP_BINARY;
527 if (dwDecompressedSize >= 0xC00) {
528 dwDictSize = 0x1000;
529 }
530 else if (dwDecompressedSize < 0x600) {
531 dwDictSize = 0x400;
532 }
533 else {
534 dwDictSize = 0x800;
535 }
537 implode(FillInput,FillOutput,(char *)lpvWorkBuffer,&BufferInfo,&dwCompType,&dwDictSize);
538 *lpdwCompressedSize = BufferInfo.dwDestStart;
539 *lpdwCompressionSubType = 0;
541 SMemFree(lpvWorkBuffer);
542 }
544 #ifdef USE_BZIP2
546 void __fastcall CompressBZ2(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
547 {
548 int nBlockSize;
550 nBlockSize = 9;
551 if (lpdwCompressionSubType)
552 if (*lpdwCompressionSubType >= 1 && *lpdwCompressionSubType <= 9)
553 nBlockSize = *lpdwCompressionSubType;
555 BZ2_bzBuffToBuffCompress((char *)lpvDestinationMem, (unsigned int *)lpdwCompressedSize, (char *)lpvSourceMem, (unsigned int)dwDecompressedSize, nBlockSize, 0, 0);
556 *lpdwCompressionSubType = 0;
557 }
559 #endif
561 void __fastcall DecompressWaveMono(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
562 {
563 *lpdwDecompressedSize = DecompressWave((LPBYTE)lpvDestinationMem,*lpdwDecompressedSize,(LPBYTE)lpvSourceMem,dwCompressedSize,1);
564 }
566 void __fastcall DecompressWaveStereo(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
567 {
568 *lpdwDecompressedSize = DecompressWave((LPBYTE)lpvDestinationMem,*lpdwDecompressedSize,(LPBYTE)lpvSourceMem,dwCompressedSize,2);
569 }
571 void __fastcall HuffmanDecompress(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
572 {
573 THuffmannTree *ht;
574 TInputStream is;
575 THTreeItem * pItem;
576 unsigned int nCount;
578 ht = (THuffmannTree *)SMemAlloc(sizeof(THuffmannTree));
580 if (!ht) {
581 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
582 return;
583 }
585 // Initialize input stream
586 is.pbInBuffer = (unsigned char *)lpvSourceMem;
587 is.dwBitBuff = *(unsigned long *)lpvSourceMem;
588 is.pbInBuffer += sizeof(unsigned long);
589 is.nBits = 32;
591 // Initialize the Huffman tree
592 for(pItem = ht->items0008, nCount = 0x203; nCount != 0; pItem++, nCount--)
593 pItem->ClearItemLinks();
595 ht->pItem3050 = NULL;
596 ht->pItem3054 = PTR_PTR(&ht->pItem3054);
597 ht->pItem3058 = PTR_NOT(ht->pItem3054);
599 ht->pItem305C = NULL;
600 ht->pFirst = PTR_PTR(&ht->pFirst);
601 ht->pLast = PTR_NOT(ht->pFirst);
603 ht->offs0004 = 1;
604 ht->nItems = 0;
606 // Clear all TQDecompress items
607 for(nCount = 0; nCount < sizeof(ht->qd3474) / sizeof(TQDecompress); nCount++)
608 ht->qd3474[nCount].offs00 = 0;
610 *lpdwDecompressedSize = ht->DoDecompression((unsigned char *)lpvDestinationMem, *lpdwDecompressedSize, &is);
611 /*
612 // The following code is not necessary to run, because it has no
613 // effect on the output data. It only clears the huffmann tree, but when
614 // the tree is on the stack, who cares ?
615 while(PTR_INT(ht.pLast) > 0)
616 {
617 pItem = ht.pItem305C->Call1501DB70(ht.pLast);
618 pItem->RemoveItem();
619 }
621 for(pItem = ht.pFirst; PTR_INT(ht.pItem3058) > 0; pItem = ht.pItem3058)
622 pItem->RemoveItem();
623 PTR_PTR(&ht.pItem3054)->RemoveItem();
625 for(pItem = ht.items0008 + 0x203, nCount = 0x203; nCount != 0; nCount--)
626 {
627 pItem--;
628 pItem->RemoveItem();
629 pItem->RemoveItem();
630 }
631 */
633 SMemFree(ht);
634 }
636 #ifdef USE_ZLIB
638 void __fastcall Inflate(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
639 {
640 uncompress((LPBYTE)lpvDestinationMem,(unsigned long *)lpdwDecompressedSize,(LPBYTE)lpvSourceMem,dwCompressedSize);
641 }
643 #endif
645 void __fastcall Explode(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
646 {
647 BUFFERINFO BufferInfo;
648 LPVOID lpvWorkBuffer;
650 lpvWorkBuffer = SMemAlloc(EXP_BUFFER_SIZE);
652 if (!lpvWorkBuffer) {
653 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
654 return;
655 }
657 BufferInfo.lpvSourceMem = lpvSourceMem;
658 BufferInfo.dwSrcStart = 0;
659 BufferInfo.dwSrcLen = dwCompressedSize;
660 BufferInfo.lpvDestinationMem = lpvDestinationMem;
661 BufferInfo.dwDestStart = 0;
662 BufferInfo.dwDestLen = *lpdwDecompressedSize;
664 explode(FillInput,FillOutput,(char *)lpvWorkBuffer,&BufferInfo);
665 *lpdwDecompressedSize = BufferInfo.dwDestStart;
667 SMemFree(lpvWorkBuffer);
668 }
670 #ifdef USE_BZIP2
672 void __fastcall DecompressBZ2(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
673 {
674 BZ2_bzBuffToBuffDecompress((char *)lpvDestinationMem, (unsigned int *)lpdwDecompressedSize, (char *)lpvSourceMem, (unsigned int)dwCompressedSize, 0, 0);
675 }
677 #endif
679 unsigned int FillInput(char *lpvBuffer, unsigned int *lpdwSize, void *param)
680 {
681 DWORD dwBufferSize;
682 BUFFERINFO *lpBufferInfo = (BUFFERINFO *)param;
684 dwBufferSize = *lpdwSize;
686 if (dwBufferSize >= lpBufferInfo->dwSrcLen - lpBufferInfo->dwSrcStart) {
687 dwBufferSize = lpBufferInfo->dwSrcLen - lpBufferInfo->dwSrcStart;
688 }
690 SMemCopy(lpvBuffer,(LPBYTE)lpBufferInfo->lpvSourceMem+lpBufferInfo->dwSrcStart,dwBufferSize);
691 lpBufferInfo->dwSrcStart += dwBufferSize;
692 return dwBufferSize;
693 }
695 void FillOutput(char *lpvBuffer, unsigned int *lpdwSize, void *param)
696 {
697 DWORD dwBufferSize;
698 BUFFERINFO *lpBufferInfo = (BUFFERINFO *)param;
700 dwBufferSize = *lpdwSize;
702 if (dwBufferSize >= lpBufferInfo->dwDestLen - lpBufferInfo->dwDestStart) {
703 dwBufferSize = lpBufferInfo->dwDestLen - lpBufferInfo->dwDestStart;
704 }
706 SMemCopy((LPBYTE)lpBufferInfo->lpvDestinationMem+lpBufferInfo->dwDestStart,lpvBuffer,dwBufferSize);
707 lpBufferInfo->dwDestStart += dwBufferSize;
708 }
710 #ifdef __cplusplus
711 extern "C" {
712 #endif
714 #ifdef USE_BZIP2
716 void bz_internal_error ( int errcode )
717 {
718 }
720 #endif
722 #ifdef __cplusplus
723 }; // extern "C"
724 #endif
|