NoxCompress.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. // compress.c
  19. // Compress interface for packets and files
  20. // Author: Jeff Brown, January 1999
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include "Lib/basetype.h"
  24. #include "Noxcompress.h"
  25. #include "CompLibHeader/lzhl.h"
  26. #ifdef _INTERNAL
  27. // for occasional debugging...
  28. //#pragma optimize("", off)
  29. //#pragma message("************************************** WARNING, optimization disabled for debugging purposes")
  30. #endif
  31. #define BLOCKSIZE 500000
  32. #define NoxRead fread
  33. #define DbgMalloc malloc
  34. #define DbgFree free
  35. #define DEBUG_LOG(x) {}
  36. Bool DecompressFile (char *infile, char *outfile)
  37. {
  38. UnsignedInt rawSize = 0, compressedSize = 0;
  39. FILE *inFilePtr = NULL;
  40. FILE *outFilePtr= NULL;
  41. char *inBlock = NULL;
  42. char *outBlock = NULL;
  43. LZHL_DHANDLE decompress;
  44. Int ok = 0;
  45. UnsignedInt srcSz, dstSz;
  46. // Parameter checking
  47. if (( infile == NULL ) || ( outfile == NULL ))
  48. return FALSE;
  49. inFilePtr = fopen( infile, "rb" );
  50. if ( inFilePtr )
  51. {
  52. // Allocate the appropriate amount of memory
  53. // Get compressed size of file.
  54. fseek( inFilePtr, 0, SEEK_END );
  55. compressedSize = ftell( inFilePtr );
  56. fseek( inFilePtr, 0, SEEK_SET );
  57. compressedSize -= sizeof(UnsignedInt);
  58. // Get uncompressed size. Don't worry about endian,
  59. // this is always INTEL baby!
  60. NoxRead(&rawSize, 1, sizeof(UnsignedInt), inFilePtr);
  61. // This is ick, but allocate a BIIIIG chunk o' memory x 2
  62. inBlock = (char *) DbgMalloc( compressedSize );
  63. outBlock= (char *) DbgMalloc( rawSize );
  64. if (( inBlock == NULL ) || ( outBlock == NULL ))
  65. return FALSE;
  66. // Read in a big chunk o file
  67. NoxRead(inBlock, 1, compressedSize, inFilePtr);
  68. fclose(inFilePtr);
  69. // Decompress
  70. srcSz = compressedSize;
  71. dstSz = rawSize;
  72. // Just Do it!
  73. decompress = LZHLCreateDecompressor();
  74. for (;;)
  75. {
  76. ok = LZHLDecompress( decompress, outBlock + rawSize - dstSz, &dstSz,
  77. inBlock + compressedSize - srcSz, &srcSz);
  78. if ( !ok )
  79. break;
  80. if (srcSz <= 0)
  81. break;
  82. }
  83. DEBUG_LOG(("Decompressed %s to %s, output size = %d\n", infile, outfile, rawSize));
  84. LZHLDestroyDecompressor(decompress);
  85. outFilePtr = fopen(outfile, "wb");
  86. if (outFilePtr)
  87. {
  88. fwrite (outBlock, rawSize, 1, outFilePtr);
  89. fclose(outFilePtr);
  90. }
  91. else
  92. return FALSE;
  93. // Clean up this mess
  94. DbgFree(inBlock);
  95. DbgFree(outBlock);
  96. return TRUE;
  97. } // End of if fileptr
  98. return FALSE;
  99. }
  100. Bool CompressFile (char *infile, char *outfile)
  101. {
  102. UnsignedInt rawSize = 0;
  103. UnsignedInt compressedSize = 0, compressed = 0, i = 0;
  104. FILE *inFilePtr = NULL;
  105. FILE *outFilePtr= NULL;
  106. char *inBlock = NULL;
  107. char *outBlock = NULL;
  108. LZHL_CHANDLE compressor;
  109. UnsignedInt blocklen;
  110. // Parameter checking
  111. if (( infile == NULL ) || ( outfile == NULL ))
  112. return FALSE;
  113. // Allocate the appropriate amount of memory
  114. inFilePtr = fopen( infile, "rb" );
  115. if ( inFilePtr )
  116. {
  117. // Get size of file.
  118. fseek( inFilePtr, 0, SEEK_END );
  119. rawSize = ftell( inFilePtr );
  120. fseek( inFilePtr, 0, SEEK_SET );
  121. // This is ick, but allocate a BIIIIG chunk o' memory x 2
  122. inBlock = (char *) DbgMalloc(rawSize);
  123. outBlock= (char *) DbgMalloc( LZHLCompressorCalcMaxBuf( rawSize ));
  124. if (( inBlock == NULL ) || ( outBlock == NULL ))
  125. return FALSE;
  126. // Read in a big chunk o file
  127. NoxRead(inBlock, 1, rawSize, inFilePtr);
  128. fclose(inFilePtr);
  129. // Compress
  130. compressor = LZHLCreateCompressor();
  131. for ( i = 0; i < rawSize; i += BLOCKSIZE )
  132. {
  133. blocklen = min((UnsignedInt)BLOCKSIZE, rawSize - i);
  134. compressed = LZHLCompress(compressor, outBlock + compressedSize, inBlock + i, blocklen);
  135. compressedSize += compressed;
  136. }
  137. LZHLDestroyCompressor(compressor);
  138. outFilePtr = fopen(outfile, "wb");
  139. if (outFilePtr)
  140. {
  141. // write out the uncompressed size first.
  142. fwrite(&rawSize, sizeof(UnsignedInt), 1, outFilePtr);
  143. fwrite(outBlock, compressedSize, 1, outFilePtr);
  144. fclose(outFilePtr);
  145. }
  146. else
  147. return FALSE;
  148. // Clean up
  149. DbgFree(inBlock);
  150. DbgFree(outBlock);
  151. return TRUE;
  152. }
  153. return FALSE;
  154. }
  155. Bool CompressPacket (char *inPacket, char *outPacket)
  156. {
  157. // Parameter checking
  158. if (( inPacket == NULL ) || ( outPacket == NULL ))
  159. return FALSE;
  160. return TRUE;
  161. }
  162. Bool DecompressPacket (char *inPacket, char *outPacket)
  163. {
  164. // Parameter checking
  165. if (( inPacket == NULL ) || ( outPacket == NULL ))
  166. return FALSE;
  167. return TRUE;
  168. }
  169. UnsignedInt CalcNewSize (UnsignedInt rawSize)
  170. {
  171. return LZHLCompressorCalcMaxBuf(rawSize);
  172. }
  173. Bool DecompressMemory (void *inBufferVoid, Int inSize, void *outBufferVoid, Int& outSize)
  174. {
  175. UnsignedByte *inBuffer = (UnsignedByte *)inBufferVoid;
  176. UnsignedByte *outBuffer = (UnsignedByte *)outBufferVoid;
  177. UnsignedInt rawSize = 0, compressedSize = 0;
  178. LZHL_DHANDLE decompress;
  179. Int ok = 0;
  180. UnsignedInt srcSz, dstSz;
  181. // Parameter checking
  182. if (( inBuffer == NULL ) || ( outBuffer == NULL ) || ( inSize < 4 ) || ( outSize == 0 ))
  183. return FALSE;
  184. // Get compressed size of file.
  185. compressedSize = inSize;
  186. // Get uncompressed size.
  187. rawSize = outSize;
  188. // Decompress
  189. srcSz = compressedSize;
  190. dstSz = rawSize;
  191. // Just Do it!
  192. decompress = LZHLCreateDecompressor();
  193. for (;;)
  194. {
  195. ok = LZHLDecompress( decompress, outBuffer + rawSize - dstSz, &dstSz,
  196. inBuffer + compressedSize - srcSz, &srcSz);
  197. if ( !ok )
  198. break;
  199. if (srcSz <= 0)
  200. break;
  201. }
  202. LZHLDestroyDecompressor(decompress);
  203. outSize = rawSize;
  204. return TRUE;
  205. }
  206. Bool CompressMemory (void *inBufferVoid, Int inSize, void *outBufferVoid, Int& outSize)
  207. {
  208. UnsignedByte *inBuffer = (UnsignedByte *)inBufferVoid;
  209. UnsignedByte *outBuffer = (UnsignedByte *)outBufferVoid;
  210. UnsignedInt rawSize = 0;
  211. UnsignedInt compressedSize = 0, compressed = 0, i = 0;
  212. LZHL_CHANDLE compressor;
  213. UnsignedInt blocklen;
  214. // Parameter checking
  215. if (( inBuffer == NULL ) || ( outBuffer == NULL ) || ( inSize < 4 ) || ( outSize == 0 ))
  216. return FALSE;
  217. rawSize = inSize;
  218. // Compress
  219. compressor = LZHLCreateCompressor();
  220. for ( i = 0; i < rawSize; i += BLOCKSIZE )
  221. {
  222. blocklen = min((UnsignedInt)BLOCKSIZE, rawSize - i);
  223. compressed = LZHLCompress(compressor, outBuffer + compressedSize, inBuffer + i, blocklen);
  224. compressedSize += compressed;
  225. }
  226. LZHLDestroyCompressor(compressor);
  227. outSize = compressedSize;
  228. return TRUE;
  229. }