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: |
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 #include "SComp.h"
19 #include "SErr.h"
20 #include "SMem.h"
21 #include "wave.h"
22 #include "huffman.h"
23 #ifdef USE_ZLIB
24 #ifndef __SYS_ZLIB
25 #include "zlib.h"
26 #else
27 #include <zlib.h>
28 #endif
29 #endif
30 #include "pklib.h"
32 typedef void (__fastcall *FCOMPRESS)(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
33 typedef void (__fastcall *FDECOMPRESS)(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
35 struct CompressFunc {
36 DWORD dwFlag;
37 FCOMPRESS fnCompress;
38 };
40 struct DecompressFunc {
41 DWORD dwFlag;
42 FDECOMPRESS fnDecompress;
43 };
45 void __fastcall CompressWaveMono(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
46 void __fastcall CompressWaveStereo(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
47 void __fastcall HuffmanCompress(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
48 #ifdef USE_ZLIB
49 void __fastcall Deflate(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
50 #endif
51 void __fastcall Implode(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel);
53 void __fastcall DecompressWaveMono(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
54 void __fastcall DecompressWaveStereo(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
55 void __fastcall HuffmanDecompress(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
56 #ifdef USE_ZLIB
57 void __fastcall Inflate(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
58 #endif
59 void __fastcall Explode(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize);
61 void __fastcall InitWaveCompress(DWORD dwCompressLevel, LPDWORD *lplpdwCompressionSubType, LPDWORD lpdwCompressionSubType);
63 typedef struct {
64 LPVOID lpvDestinationMem;
65 DWORD dwDestStart;
66 DWORD dwDestLen;
67 LPVOID lpvSourceMem;
68 DWORD dwSrcStart;
69 DWORD dwSrcLen;
70 } BUFFERINFO;
72 unsigned int FillInput(char *lpvBuffer, unsigned int *lpdwSize, void *param);
73 void FillOutput(char *lpvBuffer, unsigned int *lpdwSize, void *param);
75 CompressFunc CompressionFunctions[] =
76 {
77 {0x40, CompressWaveMono},
78 {0x80, CompressWaveStereo},
79 {0x01, HuffmanCompress},
80 #ifdef USE_ZLIB
81 {0x02, Deflate},
82 #endif
83 {0x08, Implode}
84 };
86 DecompressFunc DecompressionFunctions[] =
87 {
88 {0x40, DecompressWaveMono},
89 {0x80, DecompressWaveStereo},
90 {0x01, HuffmanDecompress},
91 #ifdef USE_ZLIB
92 {0x02, Inflate},
93 #endif
94 {0x08, Explode}
95 };
97 const DWORD nCompFunctions = sizeof(CompressionFunctions) / sizeof(CompressionFunctions[0]);
98 const DWORD nDecompFunctions = sizeof(DecompressionFunctions) / sizeof(DecompressionFunctions[0]);
100 CompressFunc *lpLastCompressMethod = &CompressionFunctions[nCompFunctions-1];
101 DecompressFunc *lpLastDecompressMethod = &DecompressionFunctions[nDecompFunctions-1];
103 BOOL WINAPI SCompCompress(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, DWORD dwCompressionType, DWORD dwCompressionSubType, DWORD dwCompressLevel)
104 {
105 DWORD dwCompressCount,dwCurFlag,dwTempFlags,dwInSize,dwOutSize;
106 LPVOID lpvInBuffer,lpvOutBuffer,lpvWorkBuffer,lpvAllocBuffer;
107 CompressFunc *lpCFuncTable;
109 if (!lpdwCompressedSize) {
110 SErrSetLastError(ERROR_INVALID_PARAMETER);
111 return FALSE;
112 }
113 if (*lpdwCompressedSize < dwDecompressedSize || !lpvDestinationMem || !lpvSourceMem) {
114 SErrSetLastError(ERROR_INVALID_PARAMETER);
115 return FALSE;
116 }
118 dwCompressCount = 0;
119 dwTempFlags = dwCompressionType;
120 lpCFuncTable = CompressionFunctions;
122 do {
123 dwCurFlag = lpCFuncTable->dwFlag;
125 if (dwCompressionType & dwCurFlag) {
126 dwCompressCount++;
127 }
129 lpCFuncTable++;
130 dwTempFlags &= ~dwCurFlag;
131 } while (lpCFuncTable <= lpLastCompressMethod);
133 if (dwTempFlags) {
134 return FALSE;
135 }
137 dwInSize = dwDecompressedSize;
138 lpvAllocBuffer = 0;
140 if (dwCompressCount >= 2
141 || !((LPBYTE)lpvDestinationMem+dwInSize <= (LPBYTE)lpvSourceMem
142 || (LPBYTE)lpvSourceMem+dwInSize <= (LPBYTE)lpvDestinationMem
143 || !dwCompressCount))
144 {
145 lpvWorkBuffer = SMemAlloc(dwInSize);
147 if (!lpvWorkBuffer) {
148 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
149 return FALSE;
150 }
152 lpvAllocBuffer = lpvWorkBuffer;
153 }
155 lpvInBuffer = lpvSourceMem;
156 lpCFuncTable = CompressionFunctions;
158 do {
159 dwTempFlags = dwCompressionType;
160 dwCurFlag = lpCFuncTable->dwFlag;
162 if (dwTempFlags & dwCurFlag) {
163 dwCompressCount--;
165 if (dwCompressCount & 1) {
166 lpvOutBuffer = lpvWorkBuffer;
167 }
168 else {
169 lpvOutBuffer = (LPVOID)((LPBYTE)lpvDestinationMem+1);
170 }
172 if ((LPBYTE)lpvOutBuffer+dwInSize > (LPBYTE)lpvInBuffer
173 && (LPBYTE)lpvInBuffer+dwInSize > (LPBYTE)lpvOutBuffer)
174 {
175 if ((LPBYTE)lpvOutBuffer+dwInSize > (LPBYTE)lpvWorkBuffer
176 && (LPBYTE)lpvWorkBuffer+dwInSize > (LPBYTE)lpvOutBuffer)
177 {
178 lpvWorkBuffer = lpvDestinationMem;
179 lpvOutBuffer = (LPVOID)((LPBYTE)lpvWorkBuffer+1);
180 }
181 else {
182 lpvOutBuffer = lpvWorkBuffer;
183 }
184 }
186 dwDecompressedSize = dwInSize-1;
187 lpCFuncTable->fnCompress(lpvOutBuffer,&dwDecompressedSize,lpvInBuffer,dwInSize,&dwCompressionSubType,dwCompressLevel);
188 dwOutSize = dwDecompressedSize+1;
190 if (dwOutSize < dwInSize) {
191 lpvInBuffer = lpvOutBuffer;
192 dwInSize = dwDecompressedSize;
193 }
194 else {
195 dwCurFlag = lpCFuncTable->dwFlag;
196 dwCompressionType = dwCompressionType & (~dwCurFlag);
197 }
199 lpvWorkBuffer = lpvAllocBuffer;
200 }
202 lpCFuncTable++;
203 } while (lpCFuncTable <= lpLastCompressMethod);
205 lpvOutBuffer = lpvDestinationMem;
207 if (lpvInBuffer != lpvOutBuffer) {
208 if ((LPBYTE)lpvInBuffer == (LPBYTE)lpvOutBuffer+1) {
209 *(LPBYTE)lpvOutBuffer = (BYTE)dwCompressionType;
210 dwInSize++;
211 }
212 else {
213 if (dwCompressionType) {
214 SMemCopy((LPBYTE)lpvOutBuffer+1,lpvInBuffer,dwInSize);
215 dwInSize++;
216 *(LPBYTE)lpvOutBuffer = (BYTE)dwCompressionType;
217 }
218 else {
219 SMemCopy(lpvOutBuffer,lpvInBuffer,dwInSize);
220 }
222 lpvWorkBuffer = lpvAllocBuffer;
223 }
224 }
226 *lpdwCompressedSize = dwInSize;
228 if (lpvWorkBuffer) {
229 SMemFree(lpvWorkBuffer);
230 }
232 return TRUE;
233 }
235 BOOL WINAPI SCompDecompress(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
236 {
237 DWORD dwDecompressedSize, dwOutSize, dwCompressTypes, dwCurFlag, dwTempFlags,dwCompressCount;
238 LPVOID lpvInBuffer,lpvOutBuffer,lpvWorkBuffer,lpvTempBuffer;
239 DecompressFunc *lpCFuncTable;
241 if (!lpdwDecompressedSize) {
242 SErrSetLastError(ERROR_INVALID_PARAMETER);
243 return FALSE;
244 }
246 dwDecompressedSize = *lpdwDecompressedSize;
248 if (dwDecompressedSize < dwCompressedSize || !lpvDestinationMem || !lpvSourceMem || dwCompressedSize < 1) {
249 SErrSetLastError(ERROR_INVALID_PARAMETER);
250 return FALSE;
251 }
253 if (dwCompressedSize == dwDecompressedSize) {
254 if (lpvDestinationMem == lpvSourceMem)
255 return TRUE;
257 SMemCopy(lpvDestinationMem,lpvSourceMem,dwCompressedSize);
258 return TRUE;
259 }
261 dwCompressCount = 0;
262 dwCompressTypes = *(LPBYTE)lpvSourceMem;
263 lpvInBuffer = (LPVOID)((LPBYTE)lpvSourceMem+1);
264 dwCompressedSize--;
265 dwTempFlags = dwCompressTypes;
266 lpCFuncTable = lpLastDecompressMethod;
268 do {
269 dwCurFlag = lpCFuncTable->dwFlag;
271 if (dwCompressTypes & dwCurFlag) {
272 dwCompressCount++;
273 }
275 dwTempFlags &= ~dwCurFlag;
276 lpCFuncTable--;;
277 } while (lpCFuncTable >= DecompressionFunctions);
279 if (dwTempFlags) {
280 return FALSE;
281 }
283 lpvWorkBuffer = 0;
285 if (dwCompressCount >= 2
286 || !((LPBYTE)lpvDestinationMem+dwCompressedSize <= (LPBYTE)lpvInBuffer
287 || (LPBYTE)lpvInBuffer+dwCompressedSize <= (LPBYTE)lpvDestinationMem
288 || !dwCompressCount))
289 {
290 lpvWorkBuffer = SMemAlloc(dwDecompressedSize);
292 if (!lpvWorkBuffer) {
293 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
294 return FALSE;
295 }
296 }
298 lpCFuncTable = lpLastDecompressMethod;
300 do {
301 if (dwCompressTypes & lpCFuncTable->dwFlag) {
302 lpvOutBuffer = lpvWorkBuffer;
303 dwCompressCount--;
305 if (!(dwCompressCount & 1)) {
306 lpvOutBuffer = lpvDestinationMem;
307 }
309 if ((LPBYTE)lpvOutBuffer+dwCompressedSize > (LPBYTE)lpvInBuffer
310 && (LPBYTE)lpvInBuffer+dwCompressedSize > (LPBYTE)lpvOutBuffer)
311 {
312 if ((LPBYTE)lpvOutBuffer+dwCompressedSize <= (LPBYTE)lpvWorkBuffer) {
313 lpvOutBuffer = lpvWorkBuffer;
314 }
315 else {
316 lpvTempBuffer = lpvOutBuffer;
317 lpvOutBuffer = lpvDestinationMem;
319 if ((LPBYTE)lpvWorkBuffer+dwCompressedSize <= (LPBYTE)lpvTempBuffer)
320 lpvOutBuffer = lpvWorkBuffer;
321 }
322 }
324 dwOutSize = dwDecompressedSize;
325 lpCFuncTable->fnDecompress(lpvOutBuffer,&dwOutSize,lpvInBuffer,dwCompressedSize);
326 dwCompressedSize = dwOutSize;
327 lpvInBuffer = lpvOutBuffer;
328 }
330 lpCFuncTable--;
331 } while (lpCFuncTable >= DecompressionFunctions);
333 if (lpvInBuffer != lpvDestinationMem) {
334 SMemCopy(lpvDestinationMem,lpvInBuffer,dwCompressedSize);
335 }
337 *lpdwDecompressedSize = dwCompressedSize;
339 if (lpvWorkBuffer) {
340 SMemFree(lpvWorkBuffer);
341 }
343 return TRUE;
344 }
346 void __fastcall InitWaveCompress(DWORD dwCompressLevel, LPDWORD *lplpdwCompressionSubType, LPDWORD lpdwCompressionSubType)
347 {
348 if (dwCompressLevel) {
349 if (dwCompressLevel <= 2) {
350 *(LPBYTE)lplpdwCompressionSubType = 4;
351 *lpdwCompressionSubType = 6;
352 return;
353 }
354 else if (dwCompressLevel == 3) {
355 *(LPBYTE)lplpdwCompressionSubType = 6;
356 *lpdwCompressionSubType = 8;
357 return;
358 }
359 }
361 *(LPBYTE)lplpdwCompressionSubType = 5;
362 *lpdwCompressionSubType = 7;
363 }
365 void __fastcall CompressWaveMono(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
366 {
367 InitWaveCompress(dwCompressLevel,&lpdwCompressionSubType,lpdwCompressionSubType);
368 *lpdwCompressedSize = CompressWave((LPBYTE)lpvDestinationMem,*lpdwCompressedSize,(short *)lpvSourceMem,dwDecompressedSize,1,(unsigned int)lpdwCompressionSubType & 0xFF);
369 }
371 void __fastcall CompressWaveStereo(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
372 {
373 InitWaveCompress(dwCompressLevel,&lpdwCompressionSubType,lpdwCompressionSubType);
374 *lpdwCompressedSize = CompressWave((LPBYTE)lpvDestinationMem,*lpdwCompressedSize,(short *)lpvSourceMem,dwDecompressedSize,2,(unsigned int)lpdwCompressionSubType & 0xFF);
375 }
377 void __fastcall HuffmanCompress(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
378 {
379 THuffmannTree *ht; // Huffmann tree for compression
380 TOutputStream os; // Output stream
381 THTreeItem * pItem;
382 int nCount;
384 ht = (THuffmannTree *)SMemAlloc(sizeof(THuffmannTree));
386 if (!ht) {
387 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
388 return;
389 }
391 // Initialize output stream
392 os.pbOutBuffer = (unsigned char *)lpvDestinationMem;
393 os.dwOutSize = *lpdwCompressedSize;
394 os.pbOutPos = (unsigned char *)lpvDestinationMem;
395 os.dwBitBuff = 0;
396 os.nBits = 0;
398 // Clear links for all the items in the tree
399 for(pItem = ht->items0008, nCount = 0x203; nCount != 0; nCount--, pItem++)
400 pItem->ClearItemLinks();
402 ht->pItem3054 = NULL;
403 ht->pItem3054 = PTR_PTR(&ht->pItem3054);
404 ht->pItem3058 = PTR_NOT(&ht->pItem3054);
406 ht->pItem305C = NULL;
407 ht->pFirst = PTR_PTR(&ht->pFirst);
408 ht->pLast = PTR_NOT(&ht->pFirst);
410 ht->offs0004 = 1;
411 ht->nItems = 0;
413 *lpdwCompressedSize = ht->DoCompression(&os, (unsigned char *)lpvSourceMem, dwDecompressedSize, *lpdwCompressionSubType);
414 /*
415 // The following code is not necessary to run, because it has no
416 // effect on the output data. It only clears the huffmann tree, but when
417 // the tree is on the stack, who cares ?
418 while(PTR_INT(ht.pLast) > 0)
419 {
420 pItem = ht.pItem305C->Call1501DB70(ht.pLast);
421 pItem->RemoveItem();
422 }
424 for(pItem = ht.pFirst; PTR_INT(ht.pItem3058) > 0; pItem = ht.pItem3058)
425 pItem->RemoveItem();
426 PTR_PTR(&ht.pItem3054)->RemoveItem();
428 for(pItem = ht.items0008 + 0x203, nCount = 0x203; nCount != 0; nCount--)
429 {
430 pItem--;
431 pItem->RemoveItem();
432 pItem->RemoveItem();
433 }
434 */
435 }
437 #ifdef USE_ZLIB
439 void __fastcall Deflate(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
440 {
441 if (*lpdwCompressionSubType == 0) {
442 switch (dwCompressLevel) {
443 case 1:
444 dwCompressLevel = Z_BEST_COMPRESSION;
445 break;
446 case 2:
447 dwCompressLevel = Z_BEST_SPEED;
448 break;
449 default:
450 dwCompressLevel = (DWORD)Z_DEFAULT_COMPRESSION;
451 }
452 }
454 compress2((LPBYTE)lpvDestinationMem,lpdwCompressedSize,(LPBYTE)lpvSourceMem,dwDecompressedSize,dwCompressLevel);
455 *lpdwCompressionSubType = 0;
456 }
458 #endif
460 void __fastcall Implode(LPVOID lpvDestinationMem, LPDWORD lpdwCompressedSize, LPVOID lpvSourceMem, DWORD dwDecompressedSize, LPDWORD lpdwCompressionSubType, DWORD dwCompressLevel)
461 {
462 BUFFERINFO BufferInfo;
463 unsigned int dwCompType, dwDictSize;
464 LPVOID lpvWorkBuffer;
466 lpvWorkBuffer = SMemAlloc(CMP_BUFFER_SIZE);
468 if (!lpvWorkBuffer) {
469 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
470 return;
471 }
473 BufferInfo.lpvSourceMem = lpvSourceMem;
474 BufferInfo.dwSrcStart = 0;
475 BufferInfo.dwSrcLen = dwDecompressedSize;
476 BufferInfo.lpvDestinationMem = lpvDestinationMem;
477 BufferInfo.dwDestStart = 0;
478 BufferInfo.dwDestLen = *lpdwCompressedSize;
480 dwCompType = (*lpdwCompressionSubType==2)?CMP_ASCII:CMP_BINARY;
482 if (dwDecompressedSize >= 0xC00) {
483 dwDictSize = 0x1000;
484 }
485 else if (dwDecompressedSize < 0x600) {
486 dwDictSize = 0x400;
487 }
488 else {
489 dwDictSize = 0x800;
490 }
492 implode(FillInput,FillOutput,(char *)lpvWorkBuffer,&BufferInfo,&dwCompType,&dwDictSize);
493 *lpdwCompressedSize = BufferInfo.dwDestStart;
494 *lpdwCompressionSubType = 0;
496 SMemFree(lpvWorkBuffer);
497 }
499 void __fastcall DecompressWaveMono(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
500 {
501 *lpdwDecompressedSize = DecompressWave((LPBYTE)lpvDestinationMem,*lpdwDecompressedSize,(LPBYTE)lpvSourceMem,dwCompressedSize,1);
502 }
504 void __fastcall DecompressWaveStereo(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
505 {
506 *lpdwDecompressedSize = DecompressWave((LPBYTE)lpvDestinationMem,*lpdwDecompressedSize,(LPBYTE)lpvSourceMem,dwCompressedSize,2);
507 }
509 void __fastcall HuffmanDecompress(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
510 {
511 THuffmannTree *ht;
512 TInputStream is;
513 THTreeItem * pItem;
514 unsigned int nCount;
516 ht = (THuffmannTree *)SMemAlloc(sizeof(THuffmannTree));
518 if (!ht) {
519 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
520 return;
521 }
523 // Initialize input stream
524 is.pbInBuffer = (unsigned char *)lpvSourceMem;
525 is.dwBitBuff = *(unsigned long *)lpvSourceMem;
526 is.pbInBuffer += sizeof(unsigned long);
527 is.nBits = 32;
529 // Initialize the Huffman tree
530 for(pItem = ht->items0008, nCount = 0x203; nCount != 0; pItem++, nCount--)
531 pItem->ClearItemLinks();
533 ht->pItem3050 = NULL;
534 ht->pItem3054 = PTR_PTR(&ht->pItem3054);
535 ht->pItem3058 = PTR_NOT(ht->pItem3054);
537 ht->pItem305C = NULL;
538 ht->pFirst = PTR_PTR(&ht->pFirst);
539 ht->pLast = PTR_NOT(ht->pFirst);
541 ht->offs0004 = 1;
542 ht->nItems = 0;
544 // Clear all TQDecompress items
545 for(nCount = 0; nCount < sizeof(ht->qd3474) / sizeof(TQDecompress); nCount++)
546 ht->qd3474[nCount].offs00 = 0;
548 *lpdwDecompressedSize = ht->DoDecompression((unsigned char *)lpvDestinationMem, *lpdwDecompressedSize, &is);
549 /*
550 // The following code is not necessary to run, because it has no
551 // effect on the output data. It only clears the huffmann tree, but when
552 // the tree is on the stack, who cares ?
553 while(PTR_INT(ht.pLast) > 0)
554 {
555 pItem = ht.pItem305C->Call1501DB70(ht.pLast);
556 pItem->RemoveItem();
557 }
559 for(pItem = ht.pFirst; PTR_INT(ht.pItem3058) > 0; pItem = ht.pItem3058)
560 pItem->RemoveItem();
561 PTR_PTR(&ht.pItem3054)->RemoveItem();
563 for(pItem = ht.items0008 + 0x203, nCount = 0x203; nCount != 0; nCount--)
564 {
565 pItem--;
566 pItem->RemoveItem();
567 pItem->RemoveItem();
568 }
569 */
571 SMemFree(ht);
572 }
574 #ifdef USE_ZLIB
576 void __fastcall Inflate(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
577 {
578 uncompress((LPBYTE)lpvDestinationMem,lpdwDecompressedSize,(LPBYTE)lpvSourceMem,dwCompressedSize);
579 }
581 #endif
583 void __fastcall Explode(LPVOID lpvDestinationMem, LPDWORD lpdwDecompressedSize, LPVOID lpvSourceMem, DWORD dwCompressedSize)
584 {
585 BUFFERINFO BufferInfo;
586 LPVOID lpvWorkBuffer;
588 lpvWorkBuffer = SMemAlloc(EXP_BUFFER_SIZE);
590 if (!lpvWorkBuffer) {
591 SErrSetLastError(ERROR_NOT_ENOUGH_MEMORY);
592 return;
593 }
595 BufferInfo.lpvSourceMem = lpvSourceMem;
596 BufferInfo.dwSrcStart = 0;
597 BufferInfo.dwSrcLen = dwCompressedSize;
598 BufferInfo.lpvDestinationMem = lpvDestinationMem;
599 BufferInfo.dwDestStart = 0;
600 BufferInfo.dwDestLen = *lpdwDecompressedSize;
602 explode(FillInput,FillOutput,(char *)lpvWorkBuffer,&BufferInfo);
603 *lpdwDecompressedSize = BufferInfo.dwDestStart;
605 SMemFree(lpvWorkBuffer);
606 }
608 unsigned int FillInput(char *lpvBuffer, unsigned int *lpdwSize, void *param)
609 {
610 DWORD dwBufferSize;
611 BUFFERINFO *lpBufferInfo = (BUFFERINFO *)param;
613 dwBufferSize = *lpdwSize;
615 if (dwBufferSize >= lpBufferInfo->dwSrcLen - lpBufferInfo->dwSrcStart) {
616 dwBufferSize = lpBufferInfo->dwSrcLen - lpBufferInfo->dwSrcStart;
617 }
619 SMemCopy(lpvBuffer,(LPBYTE)lpBufferInfo->lpvSourceMem+lpBufferInfo->dwSrcStart,dwBufferSize);
620 lpBufferInfo->dwSrcStart += dwBufferSize;
621 return dwBufferSize;
622 }
624 void FillOutput(char *lpvBuffer, unsigned int *lpdwSize, void *param)
625 {
626 DWORD dwBufferSize;
627 BUFFERINFO *lpBufferInfo = (BUFFERINFO *)param;
629 dwBufferSize = *lpdwSize;
631 if (dwBufferSize >= lpBufferInfo->dwDestLen - lpBufferInfo->dwDestStart) {
632 dwBufferSize = lpBufferInfo->dwDestLen - lpBufferInfo->dwDestStart;
633 }
635 SMemCopy((LPBYTE)lpBufferInfo->lpvDestinationMem+lpBufferInfo->dwDestStart,lpvBuffer,dwBufferSize);
636 lpBufferInfo->dwDestStart += dwBufferSize;
637 }
|