RNCDecompressor.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. /* Copyright (C) Teemu Suutari */
  2. #include <algorithm>
  3. #include "RNCDecompressor.hpp"
  4. #include "HuffmanDecoder.hpp"
  5. #include "InputStream.hpp"
  6. #include "OutputStream.hpp"
  7. #include "common/CRC16.hpp"
  8. #include "common/OverflowCheck.hpp"
  9. #include "common/Common.hpp"
  10. // This allows decompression of pc compressed files from unonfficial (and unpatched) compressor
  11. // PC games do not need chunk count, and are happy to read these files.
  12. // Official tools put it and amiga decompressors require it
  13. #define ALLOW_MISSING_CHUNKS 1
  14. namespace ancient::internal
  15. {
  16. bool RNCDecompressor::detectHeader(uint32_t hdr) noexcept
  17. {
  18. return hdr==FourCC("RNC\001") || hdr==FourCC("RNC\002");
  19. }
  20. std::shared_ptr<Decompressor> RNCDecompressor::create(const Buffer &packedData,bool exactSizeKnown,bool verify)
  21. {
  22. return std::make_shared<RNCDecompressor>(packedData,verify);
  23. }
  24. RNCDecompressor::RNCDecompressor(const Buffer &packedData,bool verify) :
  25. _packedData(packedData)
  26. {
  27. uint32_t hdr=packedData.readBE32(0);
  28. _rawSize=packedData.readBE32(4);
  29. _packedSize=packedData.readBE32(8);
  30. if (!_rawSize || !_packedSize ||
  31. _rawSize>getMaxRawSize() || _packedSize>getMaxPackedSize()) throw InvalidFormatError();
  32. bool verified=false;
  33. if (hdr==FourCC("RNC\001"))
  34. {
  35. // now detect between old and new version
  36. // since the old and the new version share the same id, there is no foolproof way
  37. // to tell them apart. It is easier to prove that it is not something by finding
  38. // specific invalid bitstream content.
  39. // well, this is silly though but lets assume someone has made old format RNC1 with total size less than 19
  40. if (packedData.size()<19)
  41. {
  42. _ver=Version::RNC1Old;
  43. } else {
  44. uint8_t newStreamStart=packedData.read8(18);
  45. uint8_t oldStreamStart=packedData.read8(_packedSize+11);
  46. // Check that stream starts with a literal(s)
  47. if (!(oldStreamStart&0x80))
  48. _ver=Version::RNC1New;
  49. // New stream have two bits in start as a filler on new stream. Those are always 0
  50. // (although this is not strictly mandated)
  51. // +
  52. // Even though it is possible to make new RNC1 stream which starts with zero literal table size,
  53. // it is extremely unlikely
  54. else if ((newStreamStart&3) || !(newStreamStart&0x7c))
  55. _ver=Version::RNC1Old;
  56. // now the last resort: check CRC.
  57. else if (_packedData.size()>=_packedSize+18 && CRC16(_packedData,18,_packedSize,0)==packedData.readBE16(14))
  58. {
  59. _ver=Version::RNC1New;
  60. verified=true;
  61. } else _ver=Version::RNC1Old;
  62. }
  63. } else if (hdr==FourCC("RNC\002")) {
  64. _ver=Version::RNC2;
  65. } else throw InvalidFormatError();
  66. uint32_t hdrSize=(_ver==Version::RNC1Old)?12:18;
  67. if (OverflowCheck::sum(_packedSize,hdrSize)>packedData.size()) throw InvalidFormatError();
  68. if (_ver!=Version::RNC1Old)
  69. {
  70. _rawCRC=packedData.readBE16(12);
  71. _chunks=packedData.read8(17);
  72. if (verify && !verified)
  73. {
  74. if (CRC16(_packedData,18,_packedSize,0)!=packedData.readBE16(14))
  75. throw VerificationError();
  76. }
  77. }
  78. }
  79. RNCDecompressor::~RNCDecompressor()
  80. {
  81. // nothing needed
  82. }
  83. const std::string &RNCDecompressor::getName() const noexcept
  84. {
  85. static std::string names[3]={
  86. "RNC1: Rob Northen RNC1 Compressor (old)",
  87. "RNC1: Rob Northen RNC1 Compressor ",
  88. "RNC2: Rob Northen RNC2 Compressor"};
  89. return names[static_cast<uint32_t>(_ver)];
  90. }
  91. size_t RNCDecompressor::getPackedSize() const noexcept
  92. {
  93. if (_ver==Version::RNC1Old) return _packedSize+12;
  94. else return _packedSize+18;
  95. }
  96. size_t RNCDecompressor::getRawSize() const noexcept
  97. {
  98. return _rawSize;
  99. }
  100. void RNCDecompressor::decompressImpl(Buffer &rawData,bool verify)
  101. {
  102. if (rawData.size()<_rawSize) throw DecompressionError();
  103. switch (_ver)
  104. {
  105. case Version::RNC1Old:
  106. return RNC1DecompressOld(rawData,verify);
  107. case Version::RNC1New:
  108. return RNC1DecompressNew(rawData,verify);
  109. case Version::RNC2:
  110. return RNC2Decompress(rawData,verify);
  111. default:
  112. throw DecompressionError();
  113. }
  114. }
  115. void RNCDecompressor::RNC1DecompressOld(Buffer &rawData,bool verify)
  116. {
  117. BackwardInputStream inputStream(_packedData,12,_packedSize+12);
  118. MSBBitReader<BackwardInputStream> bitReader(inputStream);
  119. auto readBits=[&](uint32_t count)->uint32_t
  120. {
  121. return bitReader.readBits8(count);
  122. };
  123. auto readBit=[&]()->uint32_t
  124. {
  125. return bitReader.readBits8(1);
  126. };
  127. auto readByte=[&]()->uint8_t
  128. {
  129. return inputStream.readByte();
  130. };
  131. // the anchor-bit does not seem always to be at the correct place
  132. {
  133. uint8_t halfByte=readByte();
  134. for (uint32_t i=0;i<7;i++)
  135. if (halfByte&(1<<i))
  136. {
  137. bitReader.reset(halfByte>>(i+1),7-i);
  138. break;
  139. }
  140. }
  141. BackwardOutputStream outputStream(rawData,0,_rawSize);
  142. HuffmanDecoder<uint8_t> litDecoder
  143. {
  144. HuffmanCode<uint8_t>{1,0b00,0},
  145. HuffmanCode<uint8_t>{2,0b10,1},
  146. HuffmanCode<uint8_t>{2,0b11,2}
  147. };
  148. HuffmanDecoder<uint8_t> lengthDecoder
  149. {
  150. HuffmanCode<uint8_t>{1,0b0000,0},
  151. HuffmanCode<uint8_t>{2,0b0010,1},
  152. HuffmanCode<uint8_t>{3,0b0110,2},
  153. HuffmanCode<uint8_t>{4,0b1110,3},
  154. HuffmanCode<uint8_t>{4,0b1111,4}
  155. };
  156. HuffmanDecoder<uint8_t> distanceDecoder
  157. {
  158. HuffmanCode<uint8_t>{1,0b00,0},
  159. HuffmanCode<uint8_t>{2,0b10,1},
  160. HuffmanCode<uint8_t>{2,0b11,2}
  161. };
  162. for (;;)
  163. {
  164. uint32_t litLength=litDecoder.decode(readBit);
  165. if (litLength==2)
  166. {
  167. static const uint32_t litBitLengths[4]={2,2,3,10};
  168. static const uint32_t litAdditions[4]={2,5,8,15};
  169. for (uint32_t i=0;i<4;i++)
  170. {
  171. litLength=readBits(litBitLengths[i]);
  172. if (litLength!=(1U<<litBitLengths[i])-1U || i==3)
  173. {
  174. litLength+=litAdditions[i];
  175. break;
  176. }
  177. }
  178. }
  179. for (uint32_t i=0;i<litLength;i++) outputStream.writeByte(readByte());
  180. // the only way to successfully end the loop!
  181. if (outputStream.eof()) break;
  182. uint32_t count;
  183. {
  184. uint32_t lengthIndex=lengthDecoder.decode(readBit);
  185. static const uint32_t lengthBitLengths[5]={0,0,1,2,10};
  186. static const uint32_t lengthAdditions[5]={2,3,4,6,10};
  187. count=readBits(lengthBitLengths[lengthIndex])+lengthAdditions[lengthIndex];
  188. }
  189. uint32_t distance;
  190. if (count!=2)
  191. {
  192. uint32_t distanceIndex=distanceDecoder.decode(readBit);
  193. static const uint32_t distanceBitLengths[3]={8,5,12};
  194. static const uint32_t distanceAdditions[3]={32,0,288};
  195. distance=readBits(distanceBitLengths[distanceIndex])+distanceAdditions[distanceIndex];
  196. } else {
  197. if (!readBit())
  198. {
  199. distance=readBits(6);
  200. } else {
  201. distance=readBits(9)+64;
  202. }
  203. }
  204. outputStream.copy((distance)?distance+count-1:1,count);
  205. }
  206. }
  207. void RNCDecompressor::RNC1DecompressNew(Buffer &rawData,bool verify)
  208. {
  209. ForwardInputStream inputStream(_packedData,18,_packedSize+18);
  210. LSBBitReader<ForwardInputStream> bitReader(inputStream);
  211. auto readBits=[&](uint32_t count)->uint32_t
  212. {
  213. return bitReader.readBits16Limit(count);
  214. };
  215. auto readByte=[&]()->uint8_t
  216. {
  217. return inputStream.readByte();
  218. };
  219. ForwardOutputStream outputStream(rawData,0,_rawSize);
  220. typedef HuffmanDecoder<uint32_t> RNC1HuffmanDecoder;
  221. // helpers
  222. auto readHuffmanTable=[&](RNC1HuffmanDecoder &dec)
  223. {
  224. uint32_t length=readBits(5);
  225. if (!length) return;
  226. uint32_t maxDepth=0;
  227. uint8_t lengthTable[31];
  228. for (uint32_t i=0;i<length;i++)
  229. {
  230. lengthTable[i]=readBits(4);
  231. if (lengthTable[i]>maxDepth) maxDepth=lengthTable[i];
  232. }
  233. dec.createOrderlyHuffmanTable(lengthTable,length);
  234. };
  235. auto huffmanDecode=[&](const RNC1HuffmanDecoder &dec)->int32_t
  236. {
  237. // this is kind of non-specced
  238. uint32_t ret=dec.decode([&]()->uint32_t{return readBits(1);});
  239. if (ret>=2)
  240. ret=(1<<(ret-1))|readBits(ret-1);
  241. return ret;
  242. };
  243. auto processLiterals=[&](const RNC1HuffmanDecoder &dec)
  244. {
  245. uint32_t litLength=huffmanDecode(dec);
  246. for (uint32_t i=0;i<litLength;i++) outputStream.writeByte(readByte());
  247. };
  248. readBits(2);
  249. #ifdef ALLOW_MISSING_CHUNKS
  250. while (!outputStream.eof())
  251. #else
  252. for (uint8_t chunks=0;chunks<_chunks;chunks++)
  253. #endif
  254. {
  255. RNC1HuffmanDecoder litDecoder,distanceDecoder,lengthDecoder;
  256. readHuffmanTable(litDecoder);
  257. readHuffmanTable(distanceDecoder);
  258. readHuffmanTable(lengthDecoder);
  259. uint32_t count=readBits(16);
  260. for (uint32_t sub=1;sub<count;sub++)
  261. {
  262. processLiterals(litDecoder);
  263. uint32_t distance=huffmanDecode(distanceDecoder);
  264. uint32_t count=huffmanDecode(lengthDecoder);
  265. distance++;
  266. count+=2;
  267. outputStream.copy(distance,count);
  268. }
  269. processLiterals(litDecoder);
  270. }
  271. if (!outputStream.eof()) throw DecompressionError();
  272. if (verify && CRC16(rawData,0,_rawSize,0)!=_rawCRC) throw VerificationError();
  273. }
  274. void RNCDecompressor::RNC2Decompress(Buffer &rawData,bool verify)
  275. {
  276. ForwardInputStream inputStream(_packedData,18,_packedSize+18);
  277. MSBBitReader<ForwardInputStream> bitReader(inputStream);
  278. auto readBit=[&]()->uint32_t
  279. {
  280. return bitReader.readBits8(1);
  281. };
  282. auto readByte=[&]()->uint8_t
  283. {
  284. return inputStream.readByte();
  285. };
  286. ForwardOutputStream outputStream(rawData,0,_rawSize);
  287. // Huffman decoding
  288. enum class Cmd
  289. {
  290. LIT=0, // 0, Literal
  291. MOV, // 10, Move bytes + length + distance, Get bytes if length=9 + 4bits
  292. MV2, // 110, Move 2 bytes
  293. MV3, // 1110, Move 3 bytes
  294. CND // 1111, Conditional copy, or EOF
  295. };
  296. HuffmanDecoder<Cmd> cmdDecoder
  297. {
  298. HuffmanCode<Cmd>{1,0b0000,Cmd::LIT},
  299. HuffmanCode<Cmd>{2,0b0010,Cmd::MOV},
  300. HuffmanCode<Cmd>{3,0b0110,Cmd::MV2},
  301. HuffmanCode<Cmd>{4,0b1110,Cmd::MV3},
  302. HuffmanCode<Cmd>{4,0b1111,Cmd::CND}
  303. };
  304. /* length of 9 is a marker for literals */
  305. HuffmanDecoder<uint8_t> lengthDecoder
  306. {
  307. HuffmanCode<uint8_t>{2,0b000,4},
  308. HuffmanCode<uint8_t>{2,0b010,5},
  309. HuffmanCode<uint8_t>{3,0b010,6},
  310. HuffmanCode<uint8_t>{3,0b011,7},
  311. HuffmanCode<uint8_t>{3,0b110,8},
  312. HuffmanCode<uint8_t>{3,0b111,9}
  313. };
  314. HuffmanDecoder<int8_t> distanceDecoder
  315. {
  316. HuffmanCode<int8_t>{1,0b000000,0},
  317. HuffmanCode<int8_t>{3,0b000110,1},
  318. HuffmanCode<int8_t>{4,0b001000,2},
  319. HuffmanCode<int8_t>{4,0b001001,3},
  320. HuffmanCode<int8_t>{5,0b010101,4},
  321. HuffmanCode<int8_t>{5,0b010111,5},
  322. HuffmanCode<int8_t>{5,0b011101,6},
  323. HuffmanCode<int8_t>{5,0b011111,7},
  324. HuffmanCode<int8_t>{6,0b101000,8},
  325. HuffmanCode<int8_t>{6,0b101001,9},
  326. HuffmanCode<int8_t>{6,0b101100,10},
  327. HuffmanCode<int8_t>{6,0b101101,11},
  328. HuffmanCode<int8_t>{6,0b111000,12},
  329. HuffmanCode<int8_t>{6,0b111001,13},
  330. HuffmanCode<int8_t>{6,0b111100,14},
  331. HuffmanCode<int8_t>{6,0b111101,15}
  332. };
  333. // helpers
  334. auto readDistance=[&]()->uint32_t
  335. {
  336. int8_t distMult=distanceDecoder.decode(readBit);
  337. if (distMult<0) throw DecompressionError();
  338. uint8_t distByte=readByte();
  339. return (uint32_t(distByte)|(uint32_t(distMult)<<8))+1;
  340. };
  341. auto moveBytes=[&](uint32_t distance,uint32_t count)->void
  342. {
  343. if (!count) throw DecompressionError();
  344. outputStream.copy(distance,count);
  345. };
  346. readBit();
  347. readBit();
  348. uint8_t foundChunks=0;
  349. bool done=false;
  350. while (!done && foundChunks<_chunks)
  351. {
  352. Cmd cmd=cmdDecoder.decode(readBit);
  353. switch (cmd) {
  354. case Cmd::LIT:
  355. outputStream.writeByte(readByte());
  356. break;
  357. case Cmd::MOV:
  358. {
  359. uint8_t count=lengthDecoder.decode(readBit);
  360. if (count!=9)
  361. moveBytes(readDistance(),count);
  362. else {
  363. uint32_t rep=0;
  364. for (uint32_t i=0;i<4;i++)
  365. rep=(rep<<1)|readBit();
  366. rep=(rep+3)*4;
  367. for (uint32_t i=0;i<rep;i++)
  368. outputStream.writeByte(readByte());
  369. }
  370. }
  371. break;
  372. case Cmd::MV2:
  373. moveBytes(uint32_t(readByte())+1,2);
  374. break;
  375. case Cmd::MV3:
  376. moveBytes(readDistance(),3);
  377. break;
  378. case Cmd::CND:
  379. {
  380. uint8_t count=readByte();
  381. if (count)
  382. moveBytes(readDistance(),uint32_t(count+8));
  383. else {
  384. foundChunks++;
  385. done=!readBit();
  386. }
  387. }
  388. break;
  389. }
  390. }
  391. if (!outputStream.eof() || _chunks!=foundChunks) throw DecompressionError();
  392. if (verify && CRC16(rawData,0,_rawSize,0)!=_rawCRC) throw VerificationError();
  393. }
  394. }