Compression.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: Compression.cpp /////////////////////////////////////////////////////
  24. // Author: Matthew D. Campbell
  25. //////////////////////////////////////////////////////////////////////////////
  26. #include "PreRTS.h"
  27. #include "Compression.h"
  28. #ifdef _INTERNAL
  29. // for occasional debugging...
  30. //#pragma optimize("", off)
  31. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  32. #endif
  33. ///////////////////////////////////////////////////////////////////////////////////////////
  34. ///////////////////////////////////////////////////////////////////////////////////////////
  35. ///// Performance Testing ///////////////////////////////////////////////////////////////
  36. ///////////////////////////////////////////////////////////////////////////////////////////
  37. ///////////////////////////////////////////////////////////////////////////////////////////
  38. //#define TEST_COMPRESSION
  39. #ifdef TEST_COMPRESSION
  40. #include "GameClient/MapUtil.h"
  41. #include "Common/FileSystem.h"
  42. #include "Common/File.h"
  43. #include "Common/PerfTimer.h"
  44. enum { NUM_TIMES = 1 };
  45. struct CompData
  46. {
  47. public:
  48. Int origSize;
  49. Int compressedSize[COMPRESSION_MAX+1];
  50. };
  51. #define TEST_COMPRESSION_MIN COMPRESSION_BTREE
  52. #define TEST_COMPRESSION_MAX COMPRESSION_MAX
  53. void DoCompressTest( void )
  54. {
  55. Int i;
  56. /*
  57. PerfGather *s_compressGathers[TEST_COMPRESSION_MAX+1];
  58. PerfGather *s_decompressGathers[TEST_COMPRESSION_MAX+1];
  59. for (i = TEST_COMPRESSION_MIN; i < TEST_COMPRESSION_MAX+1; ++i)
  60. {
  61. s_compressGathers[i] = new PerfGather(CompressionManager::getCompressionNameByType((CompressionType)i));
  62. s_decompressGathers[i] = new PerfGather(CompressionManager::getDecompressionNameByType((CompressionType)i));
  63. }
  64. */
  65. std::map<AsciiString, CompData> s_sizes;
  66. std::map<AsciiString, MapMetaData>::const_iterator it = TheMapCache->find("userdata\\maps\\_usa01\\_usa01.map");
  67. if (it != TheMapCache->end())
  68. {
  69. //if (it->second.m_isOfficial)
  70. //{
  71. //++it;
  72. //continue;
  73. //}
  74. //static Int count = 0;
  75. //if (count++ > 2)
  76. //break;
  77. File *f = TheFileSystem->openFile(it->first.str());
  78. if (f)
  79. {
  80. DEBUG_LOG(("***************************\nTesting '%s'\n\n", it->first.str()));
  81. Int origSize = f->size();
  82. UnsignedByte *buf = (UnsignedByte *)f->readEntireAndClose();
  83. UnsignedByte *uncompressedBuf = NEW UnsignedByte[origSize];
  84. CompData d = s_sizes[it->first];
  85. d.origSize = origSize;
  86. d.compressedSize[COMPRESSION_NONE] = origSize;
  87. for (i=TEST_COMPRESSION_MIN; i<=TEST_COMPRESSION_MAX; ++i)
  88. {
  89. DEBUG_LOG(("=================================================\n"));
  90. DEBUG_LOG(("Compression Test %d\n", i));
  91. Int maxCompressedSize = CompressionManager::getMaxCompressedSize( origSize, (CompressionType)i );
  92. DEBUG_LOG(("Orig size is %d, max compressed size is %d bytes\n", origSize, maxCompressedSize));
  93. UnsignedByte *compressedBuf = NEW UnsignedByte[maxCompressedSize];
  94. memset(compressedBuf, 0, maxCompressedSize);
  95. memset(uncompressedBuf, 0, origSize);
  96. Int compressedLen, decompressedLen;
  97. for (Int j=0; j < NUM_TIMES; ++j)
  98. {
  99. //s_compressGathers[i]->startTimer();
  100. compressedLen = CompressionManager::compressData((CompressionType)i, buf, origSize, compressedBuf, maxCompressedSize);
  101. //s_compressGathers[i]->stopTimer();
  102. //s_decompressGathers[i]->startTimer();
  103. decompressedLen = CompressionManager::decompressData(compressedBuf, compressedLen, uncompressedBuf, origSize);
  104. //s_decompressGathers[i]->stopTimer();
  105. }
  106. d.compressedSize[i] = compressedLen;
  107. DEBUG_LOG(("Compressed len is %d (%g%% of original size)\n", compressedLen, (double)compressedLen/(double)origSize*100.0));
  108. DEBUG_ASSERTCRASH(compressedLen, ("Failed to compress\n"));
  109. DEBUG_LOG(("Decompressed len is %d (%g%% of original size)\n", decompressedLen, (double)decompressedLen/(double)origSize*100.0));
  110. DEBUG_ASSERTCRASH(decompressedLen == origSize, ("orig size does not match compressed+uncompressed output\n"));
  111. if (decompressedLen == origSize)
  112. {
  113. Int ret = memcmp(buf, uncompressedBuf, origSize);
  114. if (ret != 0)
  115. {
  116. DEBUG_CRASH(("orig buffer does not match compressed+uncompressed output - ret was %d\n", ret));
  117. }
  118. }
  119. delete compressedBuf;
  120. compressedBuf = NULL;
  121. }
  122. DEBUG_LOG(("d = %d -> %d\n", d.origSize, d.compressedSize[i]));
  123. s_sizes[it->first] = d;
  124. DEBUG_LOG(("s_sizes[%s] = %d -> %d\n", it->first.str(), s_sizes[it->first].origSize, s_sizes[it->first].compressedSize[i]));
  125. delete[] buf;
  126. buf = NULL;
  127. delete[] uncompressedBuf;
  128. uncompressedBuf = NULL;
  129. }
  130. ++it;
  131. }
  132. for (i=TEST_COMPRESSION_MIN; i<=TEST_COMPRESSION_MAX; ++i)
  133. {
  134. Real maxCompression = 1000.0f;
  135. Real minCompression = 0.0f;
  136. Int totalUncompressedBytes = 0;
  137. Int totalCompressedBytes = 0;
  138. for (std::map<AsciiString, CompData>::iterator cd = s_sizes.begin(); cd != s_sizes.end(); ++cd)
  139. {
  140. CompData d = cd->second;
  141. Real ratio = d.compressedSize[i]/(Real)d.origSize;
  142. maxCompression = min(maxCompression, ratio);
  143. minCompression = max(minCompression, ratio);
  144. totalUncompressedBytes += d.origSize;
  145. totalCompressedBytes += d.compressedSize[i];
  146. }
  147. DEBUG_LOG(("***************************************************\n"));
  148. DEBUG_LOG(("Compression method %s:\n", CompressionManager::getCompressionNameByType((CompressionType)i)));
  149. DEBUG_LOG(("%d bytes compressed to %d (%g%%)\n", totalUncompressedBytes, totalCompressedBytes,
  150. totalCompressedBytes/(Real)totalUncompressedBytes*100.0f));
  151. DEBUG_LOG(("Min ratio: %g%%, Max ratio: %g%%\n",
  152. minCompression*100.0f, maxCompression*100.0f));
  153. DEBUG_LOG(("\n"));
  154. }
  155. /*
  156. PerfGather::dumpAll(10000);
  157. PerfGather::resetAll();
  158. CopyFile( "AAAPerfStats.csv", "AAACompressPerfStats.csv", FALSE );
  159. for (i = TEST_COMPRESSION_MIN; i < TEST_COMPRESSION_MAX+1; ++i)
  160. {
  161. delete s_compressGathers[i];
  162. s_compressGathers[i] = NULL;
  163. delete s_decompressGathers[i];
  164. s_decompressGathers[i] = NULL;
  165. }
  166. */
  167. }
  168. #endif // TEST_COMPRESSION