PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/video/smk_decoder.cpp

https://github.com/aquadran/residualvm
C++ | 878 lines | 621 code | 168 blank | 89 comment | 120 complexity | 4cb0fdca9c6c816f3334299a978b23da MD5 | raw file
Possible License(s): 0BSD, LGPL-2.1, GPL-2.0
  1. /* ScummVM - Graphic Adventure Engine
  2. *
  3. * ScummVM is the legal property of its developers, whose names
  4. * are too numerous to list here. Please refer to the COPYRIGHT
  5. * file distributed with this source distribution.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. *
  21. */
  22. // Based on http://wiki.multimedia.cx/index.php?title=Smacker
  23. // and the FFmpeg Smacker decoder (libavcodec/smacker.c), revision 16143
  24. // http://git.ffmpeg.org/?p=ffmpeg;a=blob;f=libavcodec/smacker.c;hb=b8437a00a2f14d4a437346455d624241d726128e
  25. #include "video/smk_decoder.h"
  26. #include "common/endian.h"
  27. #include "common/util.h"
  28. #include "common/stream.h"
  29. #include "common/memstream.h"
  30. #include "common/bitstream.h"
  31. #include "common/system.h"
  32. #include "common/textconsole.h"
  33. #include "audio/audiostream.h"
  34. #include "audio/mixer.h"
  35. #include "audio/decoders/raw.h"
  36. namespace Video {
  37. enum SmkBlockTypes {
  38. SMK_BLOCK_MONO = 0,
  39. SMK_BLOCK_FULL = 1,
  40. SMK_BLOCK_SKIP = 2,
  41. SMK_BLOCK_FILL = 3
  42. };
  43. /*
  44. * class SmallHuffmanTree
  45. * A Huffman-tree to hold 8-bit values.
  46. */
  47. class SmallHuffmanTree {
  48. public:
  49. SmallHuffmanTree(Common::BitStream &bs);
  50. uint16 getCode(Common::BitStream &bs);
  51. private:
  52. enum {
  53. SMK_NODE = 0x8000
  54. };
  55. uint16 decodeTree(uint32 prefix, int length);
  56. uint16 _treeSize;
  57. uint16 _tree[511];
  58. uint16 _prefixtree[256];
  59. byte _prefixlength[256];
  60. Common::BitStream &_bs;
  61. };
  62. SmallHuffmanTree::SmallHuffmanTree(Common::BitStream &bs)
  63. : _treeSize(0), _bs(bs) {
  64. uint32 bit = _bs.getBit();
  65. assert(bit);
  66. for (uint16 i = 0; i < 256; ++i)
  67. _prefixtree[i] = _prefixlength[i] = 0;
  68. decodeTree(0, 0);
  69. bit = _bs.getBit();
  70. assert(!bit);
  71. }
  72. uint16 SmallHuffmanTree::decodeTree(uint32 prefix, int length) {
  73. if (!_bs.getBit()) { // Leaf
  74. _tree[_treeSize] = _bs.getBits(8);
  75. if (length <= 8) {
  76. for (int i = 0; i < 256; i += (1 << length)) {
  77. _prefixtree[prefix | i] = _treeSize;
  78. _prefixlength[prefix | i] = length;
  79. }
  80. }
  81. ++_treeSize;
  82. return 1;
  83. }
  84. uint16 t = _treeSize++;
  85. if (length == 8) {
  86. _prefixtree[prefix] = t;
  87. _prefixlength[prefix] = 8;
  88. }
  89. uint16 r1 = decodeTree(prefix, length + 1);
  90. _tree[t] = (SMK_NODE | r1);
  91. uint16 r2 = decodeTree(prefix | (1 << length), length + 1);
  92. return r1+r2+1;
  93. }
  94. uint16 SmallHuffmanTree::getCode(Common::BitStream &bs) {
  95. byte peek = bs.peekBits(MIN<uint32>(bs.size() - bs.pos(), 8));
  96. uint16 *p = &_tree[_prefixtree[peek]];
  97. bs.skip(_prefixlength[peek]);
  98. while (*p & SMK_NODE) {
  99. if (bs.getBit())
  100. p += *p & ~SMK_NODE;
  101. p++;
  102. }
  103. return *p;
  104. }
  105. /*
  106. * class BigHuffmanTree
  107. * A Huffman-tree to hold 16-bit values.
  108. */
  109. class BigHuffmanTree {
  110. public:
  111. BigHuffmanTree(Common::BitStream &bs, int allocSize);
  112. ~BigHuffmanTree();
  113. void reset();
  114. uint32 getCode(Common::BitStream &bs);
  115. private:
  116. enum {
  117. SMK_NODE = 0x80000000
  118. };
  119. uint32 decodeTree(uint32 prefix, int length);
  120. uint32 _treeSize;
  121. uint32 *_tree;
  122. uint32 _last[3];
  123. uint32 _prefixtree[256];
  124. byte _prefixlength[256];
  125. /* Used during construction */
  126. Common::BitStream &_bs;
  127. uint32 _markers[3];
  128. SmallHuffmanTree *_loBytes;
  129. SmallHuffmanTree *_hiBytes;
  130. };
  131. BigHuffmanTree::BigHuffmanTree(Common::BitStream &bs, int allocSize)
  132. : _bs(bs) {
  133. uint32 bit = _bs.getBit();
  134. if (!bit) {
  135. _tree = new uint32[1];
  136. _tree[0] = 0;
  137. _last[0] = _last[1] = _last[2] = 0;
  138. return;
  139. }
  140. for (uint32 i = 0; i < 256; ++i)
  141. _prefixtree[i] = _prefixlength[i] = 0;
  142. _loBytes = new SmallHuffmanTree(_bs);
  143. _hiBytes = new SmallHuffmanTree(_bs);
  144. _markers[0] = _bs.getBits(16);
  145. _markers[1] = _bs.getBits(16);
  146. _markers[2] = _bs.getBits(16);
  147. _last[0] = _last[1] = _last[2] = 0xffffffff;
  148. _treeSize = 0;
  149. _tree = new uint32[allocSize / 4];
  150. decodeTree(0, 0);
  151. bit = _bs.getBit();
  152. assert(!bit);
  153. for (uint32 i = 0; i < 3; ++i) {
  154. if (_last[i] == 0xffffffff) {
  155. _last[i] = _treeSize;
  156. _tree[_treeSize++] = 0;
  157. }
  158. }
  159. delete _loBytes;
  160. delete _hiBytes;
  161. }
  162. BigHuffmanTree::~BigHuffmanTree() {
  163. delete[] _tree;
  164. }
  165. void BigHuffmanTree::reset() {
  166. _tree[_last[0]] = _tree[_last[1]] = _tree[_last[2]] = 0;
  167. }
  168. uint32 BigHuffmanTree::decodeTree(uint32 prefix, int length) {
  169. uint32 bit = _bs.getBit();
  170. if (!bit) { // Leaf
  171. uint32 lo = _loBytes->getCode(_bs);
  172. uint32 hi = _hiBytes->getCode(_bs);
  173. uint32 v = (hi << 8) | lo;
  174. _tree[_treeSize] = v;
  175. if (length <= 8) {
  176. for (int i = 0; i < 256; i += (1 << length)) {
  177. _prefixtree[prefix | i] = _treeSize;
  178. _prefixlength[prefix | i] = length;
  179. }
  180. }
  181. for (int i = 0; i < 3; ++i) {
  182. if (_markers[i] == v) {
  183. _last[i] = _treeSize;
  184. _tree[_treeSize] = 0;
  185. }
  186. }
  187. ++_treeSize;
  188. return 1;
  189. }
  190. uint32 t = _treeSize++;
  191. if (length == 8) {
  192. _prefixtree[prefix] = t;
  193. _prefixlength[prefix] = 8;
  194. }
  195. uint32 r1 = decodeTree(prefix, length + 1);
  196. _tree[t] = SMK_NODE | r1;
  197. uint32 r2 = decodeTree(prefix | (1 << length), length + 1);
  198. return r1+r2+1;
  199. }
  200. uint32 BigHuffmanTree::getCode(Common::BitStream &bs) {
  201. byte peek = bs.peekBits(MIN<uint32>(bs.size() - bs.pos(), 8));
  202. uint32 *p = &_tree[_prefixtree[peek]];
  203. bs.skip(_prefixlength[peek]);
  204. while (*p & SMK_NODE) {
  205. if (bs.getBit())
  206. p += (*p) & ~SMK_NODE;
  207. p++;
  208. }
  209. uint32 v = *p;
  210. if (v != _tree[_last[0]]) {
  211. _tree[_last[2]] = _tree[_last[1]];
  212. _tree[_last[1]] = _tree[_last[0]];
  213. _tree[_last[0]] = v;
  214. }
  215. return v;
  216. }
  217. SmackerDecoder::SmackerDecoder(Audio::Mixer::SoundType soundType) : _soundType(soundType) {
  218. _fileStream = 0;
  219. _firstFrameStart = 0;
  220. _frameTypes = 0;
  221. _frameSizes = 0;
  222. }
  223. SmackerDecoder::~SmackerDecoder() {
  224. close();
  225. }
  226. bool SmackerDecoder::loadStream(Common::SeekableReadStream *stream) {
  227. close();
  228. _fileStream = stream;
  229. // Read in the Smacker header
  230. _header.signature = _fileStream->readUint32BE();
  231. if (_header.signature != MKTAG('S', 'M', 'K', '2') && _header.signature != MKTAG('S', 'M', 'K', '4'))
  232. return false;
  233. uint32 width = _fileStream->readUint32LE();
  234. uint32 height = _fileStream->readUint32LE();
  235. uint32 frameCount = _fileStream->readUint32LE();
  236. int32 frameDelay = _fileStream->readSint32LE();
  237. // frame rate contains 2 digits after the comma, so 1497 is actually 14.97 fps
  238. Common::Rational frameRate;
  239. if (frameDelay > 0)
  240. frameRate = Common::Rational(1000, frameDelay);
  241. else if (frameDelay < 0)
  242. frameRate = Common::Rational(100000, -frameDelay);
  243. else
  244. frameRate = 1000;
  245. // Flags are determined by which bit is set, which can be one of the following:
  246. // 0 - set to 1 if file contains a ring frame.
  247. // 1 - set to 1 if file is Y-interlaced
  248. // 2 - set to 1 if file is Y-doubled
  249. // If bits 1 or 2 are set, the frame should be scaled to twice its height
  250. // before it is displayed.
  251. _header.flags = _fileStream->readUint32LE();
  252. SmackerVideoTrack *videoTrack = createVideoTrack(width, height, frameCount, frameRate, _header.flags, _header.signature);
  253. addTrack(videoTrack);
  254. // TODO: should we do any extra processing for Smacker files with ring frames?
  255. // TODO: should we do any extra processing for Y-doubled videos? Are they the
  256. // same as Y-interlaced videos?
  257. uint32 i;
  258. for (i = 0; i < 7; ++i)
  259. _header.audioSize[i] = _fileStream->readUint32LE();
  260. _header.treesSize = _fileStream->readUint32LE();
  261. _header.mMapSize = _fileStream->readUint32LE();
  262. _header.mClrSize = _fileStream->readUint32LE();
  263. _header.fullSize = _fileStream->readUint32LE();
  264. _header.typeSize = _fileStream->readUint32LE();
  265. for (i = 0; i < 7; ++i) {
  266. // AudioRate - Frequency and format information for each sound track, up to 7 audio tracks.
  267. // The 32 constituent bits have the following meaning:
  268. // * bit 31 - indicates Huffman + DPCM compression
  269. // * bit 30 - indicates that audio data is present for this track
  270. // * bit 29 - 1 = 16-bit audio; 0 = 8-bit audio
  271. // * bit 28 - 1 = stereo audio; 0 = mono audio
  272. // * bit 27 - indicates Bink RDFT compression
  273. // * bit 26 - indicates Bink DCT compression
  274. // * bits 25-24 - unused
  275. // * bits 23-0 - audio sample rate
  276. uint32 audioInfo = _fileStream->readUint32LE();
  277. _header.audioInfo[i].hasAudio = audioInfo & 0x40000000;
  278. _header.audioInfo[i].is16Bits = audioInfo & 0x20000000;
  279. _header.audioInfo[i].isStereo = audioInfo & 0x10000000;
  280. _header.audioInfo[i].sampleRate = audioInfo & 0xFFFFFF;
  281. if (audioInfo & 0x8000000)
  282. _header.audioInfo[i].compression = kCompressionRDFT;
  283. else if (audioInfo & 0x4000000)
  284. _header.audioInfo[i].compression = kCompressionDCT;
  285. else if (audioInfo & 0x80000000)
  286. _header.audioInfo[i].compression = kCompressionDPCM;
  287. else
  288. _header.audioInfo[i].compression = kCompressionNone;
  289. if (_header.audioInfo[i].hasAudio) {
  290. if (_header.audioInfo[i].compression == kCompressionRDFT || _header.audioInfo[i].compression == kCompressionDCT)
  291. warning("Unhandled Smacker v2 audio compression");
  292. addTrack(new SmackerAudioTrack(_header.audioInfo[i], _soundType));
  293. }
  294. }
  295. _header.dummy = _fileStream->readUint32LE();
  296. _frameSizes = new uint32[frameCount];
  297. for (i = 0; i < frameCount; ++i)
  298. _frameSizes[i] = _fileStream->readUint32LE();
  299. _frameTypes = new byte[frameCount];
  300. for (i = 0; i < frameCount; ++i)
  301. _frameTypes[i] = _fileStream->readByte();
  302. byte *huffmanTrees = (byte *) malloc(_header.treesSize);
  303. _fileStream->read(huffmanTrees, _header.treesSize);
  304. Common::BitStream8LSB bs(new Common::MemoryReadStream(huffmanTrees, _header.treesSize, DisposeAfterUse::YES), DisposeAfterUse::YES);
  305. videoTrack->readTrees(bs, _header.mMapSize, _header.mClrSize, _header.fullSize, _header.typeSize);
  306. _firstFrameStart = _fileStream->pos();
  307. return true;
  308. }
  309. void SmackerDecoder::close() {
  310. VideoDecoder::close();
  311. delete _fileStream;
  312. _fileStream = 0;
  313. delete[] _frameTypes;
  314. _frameTypes = 0;
  315. delete[] _frameSizes;
  316. _frameSizes = 0;
  317. }
  318. bool SmackerDecoder::rewind() {
  319. // Call the parent method to rewind the tracks first
  320. if (!VideoDecoder::rewind())
  321. return false;
  322. // And seek back to where the first frame begins
  323. _fileStream->seek(_firstFrameStart);
  324. return true;
  325. }
  326. void SmackerDecoder::readNextPacket() {
  327. SmackerVideoTrack *videoTrack = (SmackerVideoTrack *)getTrack(0);
  328. if (videoTrack->endOfTrack())
  329. return;
  330. videoTrack->increaseCurFrame();
  331. uint i;
  332. uint32 chunkSize = 0;
  333. uint32 dataSizeUnpacked = 0;
  334. uint32 startPos = _fileStream->pos();
  335. // Check if we got a frame with palette data, and
  336. // call back the virtual setPalette function to set
  337. // the current palette
  338. if (_frameTypes[videoTrack->getCurFrame()] & 1)
  339. videoTrack->unpackPalette(_fileStream);
  340. // Load audio tracks
  341. for (i = 0; i < 7; ++i) {
  342. if (!(_frameTypes[videoTrack->getCurFrame()] & (2 << i)))
  343. continue;
  344. chunkSize = _fileStream->readUint32LE();
  345. chunkSize -= 4; // subtract the first 4 bytes (chunk size)
  346. if (_header.audioInfo[i].compression == kCompressionNone) {
  347. dataSizeUnpacked = chunkSize;
  348. } else {
  349. dataSizeUnpacked = _fileStream->readUint32LE();
  350. chunkSize -= 4; // subtract the next 4 bytes (unpacked data size)
  351. }
  352. handleAudioTrack(i, chunkSize, dataSizeUnpacked);
  353. }
  354. uint32 frameSize = _frameSizes[videoTrack->getCurFrame()] & ~3;
  355. // uint32 remainder = _frameSizes[videoTrack->getCurFrame()] & 3;
  356. if (_fileStream->pos() - startPos > frameSize)
  357. error("Smacker actual frame size exceeds recorded frame size");
  358. uint32 frameDataSize = frameSize - (_fileStream->pos() - startPos);
  359. byte *frameData = (byte *)malloc(frameDataSize + 1);
  360. // Padding to keep the BigHuffmanTrees from reading past the data end
  361. frameData[frameDataSize] = 0x00;
  362. _fileStream->read(frameData, frameDataSize);
  363. Common::BitStream8LSB bs(new Common::MemoryReadStream(frameData, frameDataSize + 1, DisposeAfterUse::YES), DisposeAfterUse::YES);
  364. videoTrack->decodeFrame(bs);
  365. _fileStream->seek(startPos + frameSize);
  366. }
  367. void SmackerDecoder::handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize) {
  368. if (chunkSize == 0)
  369. return;
  370. if (_header.audioInfo[track].hasAudio) {
  371. // Get the audio track, which start at offset 1 (first track is video)
  372. SmackerAudioTrack *audioTrack = (SmackerAudioTrack *)getTrack(track + 1);
  373. // If it's track 0, play the audio data
  374. byte *soundBuffer = (byte *)malloc(chunkSize + 1);
  375. // Padding to keep the SmallHuffmanTrees from reading past the data end
  376. soundBuffer[chunkSize] = 0x00;
  377. _fileStream->read(soundBuffer, chunkSize);
  378. if (_header.audioInfo[track].compression == kCompressionRDFT || _header.audioInfo[track].compression == kCompressionDCT) {
  379. // TODO: Compressed audio (Bink RDFT/DCT encoded)
  380. free(soundBuffer);
  381. return;
  382. } else if (_header.audioInfo[track].compression == kCompressionDPCM) {
  383. // Compressed audio (Huffman DPCM encoded)
  384. audioTrack->queueCompressedBuffer(soundBuffer, chunkSize + 1, unpackedSize);
  385. free(soundBuffer);
  386. } else {
  387. // Uncompressed audio (PCM)
  388. audioTrack->queuePCM(soundBuffer, chunkSize);
  389. }
  390. } else {
  391. // Ignore possibly unused data
  392. _fileStream->skip(chunkSize);
  393. }
  394. }
  395. VideoDecoder::AudioTrack *SmackerDecoder::getAudioTrack(int index) {
  396. // Smacker audio track indexes are relative to the first audio track
  397. Track *track = getTrack(index + 1);
  398. if (!track || track->getTrackType() != Track::kTrackTypeAudio)
  399. return 0;
  400. return (AudioTrack *)track;
  401. }
  402. SmackerDecoder::SmackerVideoTrack::SmackerVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 signature) {
  403. _surface = new Graphics::Surface();
  404. _surface->create(width, height * (flags ? 2 : 1), Graphics::PixelFormat::createFormatCLUT8());
  405. _frameCount = frameCount;
  406. _frameRate = frameRate;
  407. _flags = flags;
  408. _signature = signature;
  409. _curFrame = -1;
  410. _dirtyPalette = false;
  411. _MMapTree = _MClrTree = _FullTree = _TypeTree = 0;
  412. memset(_palette, 0, 3 * 256);
  413. }
  414. SmackerDecoder::SmackerVideoTrack::~SmackerVideoTrack() {
  415. _surface->free();
  416. delete _surface;
  417. delete _MMapTree;
  418. delete _MClrTree;
  419. delete _FullTree;
  420. delete _TypeTree;
  421. }
  422. uint16 SmackerDecoder::SmackerVideoTrack::getWidth() const {
  423. return _surface->w;
  424. }
  425. uint16 SmackerDecoder::SmackerVideoTrack::getHeight() const {
  426. return _surface->h;
  427. }
  428. Graphics::PixelFormat SmackerDecoder::SmackerVideoTrack::getPixelFormat() const {
  429. return _surface->format;
  430. }
  431. void SmackerDecoder::SmackerVideoTrack::readTrees(Common::BitStream &bs, uint32 mMapSize, uint32 mClrSize, uint32 fullSize, uint32 typeSize) {
  432. _MMapTree = new BigHuffmanTree(bs, mMapSize);
  433. _MClrTree = new BigHuffmanTree(bs, mClrSize);
  434. _FullTree = new BigHuffmanTree(bs, fullSize);
  435. _TypeTree = new BigHuffmanTree(bs, typeSize);
  436. }
  437. void SmackerDecoder::SmackerVideoTrack::decodeFrame(Common::BitStream &bs) {
  438. _MMapTree->reset();
  439. _MClrTree->reset();
  440. _FullTree->reset();
  441. _TypeTree->reset();
  442. // Height needs to be doubled if we have flags (Y-interlaced or Y-doubled)
  443. uint doubleY = _flags ? 2 : 1;
  444. uint bw = getWidth() / 4;
  445. uint bh = getHeight() / doubleY / 4;
  446. uint stride = getWidth();
  447. uint block = 0, blocks = bw*bh;
  448. byte *out;
  449. uint type, run, j, mode;
  450. uint32 p1, p2, clr, map;
  451. byte hi, lo;
  452. uint i;
  453. while (block < blocks) {
  454. type = _TypeTree->getCode(bs);
  455. run = getBlockRun((type >> 2) & 0x3f);
  456. switch (type & 3) {
  457. case SMK_BLOCK_MONO:
  458. while (run-- && block < blocks) {
  459. clr = _MClrTree->getCode(bs);
  460. map = _MMapTree->getCode(bs);
  461. out = (byte *)_surface->getPixels() + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
  462. hi = clr >> 8;
  463. lo = clr & 0xff;
  464. for (i = 0; i < 4; i++) {
  465. for (j = 0; j < doubleY; j++) {
  466. out[0] = (map & 1) ? hi : lo;
  467. out[1] = (map & 2) ? hi : lo;
  468. out[2] = (map & 4) ? hi : lo;
  469. out[3] = (map & 8) ? hi : lo;
  470. out += stride;
  471. }
  472. map >>= 4;
  473. }
  474. ++block;
  475. }
  476. break;
  477. case SMK_BLOCK_FULL:
  478. // Smacker v2 has one mode, Smacker v4 has three
  479. if (_signature == MKTAG('S','M','K','2')) {
  480. mode = 0;
  481. } else {
  482. // 00 - mode 0
  483. // 10 - mode 1
  484. // 01 - mode 2
  485. mode = 0;
  486. if (bs.getBit()) {
  487. mode = 1;
  488. } else if (bs.getBit()) {
  489. mode = 2;
  490. }
  491. }
  492. while (run-- && block < blocks) {
  493. out = (byte *)_surface->getPixels() + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
  494. switch (mode) {
  495. case 0:
  496. for (i = 0; i < 4; ++i) {
  497. p1 = _FullTree->getCode(bs);
  498. p2 = _FullTree->getCode(bs);
  499. for (j = 0; j < doubleY; ++j) {
  500. out[2] = p1 & 0xff;
  501. out[3] = p1 >> 8;
  502. out[0] = p2 & 0xff;
  503. out[1] = p2 >> 8;
  504. out += stride;
  505. }
  506. }
  507. break;
  508. case 1:
  509. p1 = _FullTree->getCode(bs);
  510. out[0] = out[1] = p1 & 0xFF;
  511. out[2] = out[3] = p1 >> 8;
  512. out += stride;
  513. out[0] = out[1] = p1 & 0xFF;
  514. out[2] = out[3] = p1 >> 8;
  515. out += stride;
  516. p2 = _FullTree->getCode(bs);
  517. out[0] = out[1] = p2 & 0xFF;
  518. out[2] = out[3] = p2 >> 8;
  519. out += stride;
  520. out[0] = out[1] = p2 & 0xFF;
  521. out[2] = out[3] = p2 >> 8;
  522. out += stride;
  523. break;
  524. case 2:
  525. for (i = 0; i < 2; i++) {
  526. // We first get p2 and then p1
  527. // Check ffmpeg thread "[PATCH] Smacker video decoder bug fix"
  528. // http://article.gmane.org/gmane.comp.video.ffmpeg.devel/78768
  529. p2 = _FullTree->getCode(bs);
  530. p1 = _FullTree->getCode(bs);
  531. for (j = 0; j < doubleY; ++j) {
  532. out[0] = p1 & 0xff;
  533. out[1] = p1 >> 8;
  534. out[2] = p2 & 0xff;
  535. out[3] = p2 >> 8;
  536. out += stride;
  537. }
  538. for (j = 0; j < doubleY; ++j) {
  539. out[0] = p1 & 0xff;
  540. out[1] = p1 >> 8;
  541. out[2] = p2 & 0xff;
  542. out[3] = p2 >> 8;
  543. out += stride;
  544. }
  545. }
  546. break;
  547. }
  548. ++block;
  549. }
  550. break;
  551. case SMK_BLOCK_SKIP:
  552. while (run-- && block < blocks)
  553. block++;
  554. break;
  555. case SMK_BLOCK_FILL:
  556. uint32 col;
  557. mode = type >> 8;
  558. while (run-- && block < blocks) {
  559. out = (byte *)_surface->getPixels() + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
  560. col = mode * 0x01010101;
  561. for (i = 0; i < 4 * doubleY; ++i) {
  562. out[0] = out[1] = out[2] = out[3] = col;
  563. out += stride;
  564. }
  565. ++block;
  566. }
  567. break;
  568. }
  569. }
  570. }
  571. void SmackerDecoder::SmackerVideoTrack::unpackPalette(Common::SeekableReadStream *stream) {
  572. uint startPos = stream->pos();
  573. uint32 len = 4 * stream->readByte();
  574. byte *chunk = (byte *)malloc(len);
  575. stream->read(chunk, len);
  576. byte *p = chunk;
  577. byte oldPalette[3 * 256];
  578. memcpy(oldPalette, _palette, 3 * 256);
  579. byte *pal = _palette;
  580. int sz = 0;
  581. byte b0;
  582. while (sz < 256) {
  583. b0 = *p++;
  584. if (b0 & 0x80) { // if top bit is 1 (0x80 = 10000000)
  585. sz += (b0 & 0x7f) + 1; // get lower 7 bits + 1 (0x7f = 01111111)
  586. pal += 3 * ((b0 & 0x7f) + 1);
  587. } else if (b0 & 0x40) { // if top 2 bits are 01 (0x40 = 01000000)
  588. byte c = (b0 & 0x3f) + 1; // get lower 6 bits + 1 (0x3f = 00111111)
  589. uint s = 3 * *p++;
  590. sz += c;
  591. while (c--) {
  592. *pal++ = oldPalette[s + 0];
  593. *pal++ = oldPalette[s + 1];
  594. *pal++ = oldPalette[s + 2];
  595. s += 3;
  596. }
  597. } else { // top 2 bits are 00
  598. sz++;
  599. // get the lower 6 bits for each component (0x3f = 00111111)
  600. byte r = b0 & 0x3f;
  601. byte g = (*p++) & 0x3f;
  602. byte b = (*p++) & 0x3f;
  603. // upscale to full 8-bit color values. The Multimedia Wiki suggests
  604. // a lookup table for this, but this should produce the same result.
  605. *pal++ = (r * 4 + r / 16);
  606. *pal++ = (g * 4 + g / 16);
  607. *pal++ = (b * 4 + b / 16);
  608. }
  609. }
  610. stream->seek(startPos + len);
  611. free(chunk);
  612. _dirtyPalette = true;
  613. }
  614. SmackerDecoder::SmackerAudioTrack::SmackerAudioTrack(const AudioInfo &audioInfo, Audio::Mixer::SoundType soundType) :
  615. _audioInfo(audioInfo), _soundType(soundType) {
  616. _audioStream = Audio::makeQueuingAudioStream(_audioInfo.sampleRate, _audioInfo.isStereo);
  617. }
  618. SmackerDecoder::SmackerAudioTrack::~SmackerAudioTrack() {
  619. delete _audioStream;
  620. }
  621. bool SmackerDecoder::SmackerAudioTrack::rewind() {
  622. delete _audioStream;
  623. _audioStream = Audio::makeQueuingAudioStream(_audioInfo.sampleRate, _audioInfo.isStereo);
  624. return true;
  625. }
  626. Audio::AudioStream *SmackerDecoder::SmackerAudioTrack::getAudioStream() const {
  627. return _audioStream;
  628. }
  629. void SmackerDecoder::SmackerAudioTrack::queueCompressedBuffer(byte *buffer, uint32 bufferSize, uint32 unpackedSize) {
  630. Common::BitStream8LSB audioBS(new Common::MemoryReadStream(buffer, bufferSize), DisposeAfterUse::YES);
  631. bool dataPresent = audioBS.getBit();
  632. if (!dataPresent)
  633. return;
  634. bool isStereo = audioBS.getBit();
  635. assert(isStereo == _audioInfo.isStereo);
  636. bool is16Bits = audioBS.getBit();
  637. assert(is16Bits == _audioInfo.is16Bits);
  638. int numBytes = 1 * (isStereo ? 2 : 1) * (is16Bits ? 2 : 1);
  639. byte *unpackedBuffer = (byte *)malloc(unpackedSize);
  640. byte *curPointer = unpackedBuffer;
  641. uint32 curPos = 0;
  642. SmallHuffmanTree *audioTrees[4];
  643. for (int k = 0; k < numBytes; k++)
  644. audioTrees[k] = new SmallHuffmanTree(audioBS);
  645. // Base values, stored as big endian
  646. int32 bases[2];
  647. if (isStereo) {
  648. if (is16Bits) {
  649. bases[1] = SWAP_BYTES_16(audioBS.getBits(16));
  650. } else {
  651. bases[1] = audioBS.getBits(8);
  652. }
  653. }
  654. if (is16Bits) {
  655. bases[0] = SWAP_BYTES_16(audioBS.getBits(16));
  656. } else {
  657. bases[0] = audioBS.getBits(8);
  658. }
  659. // The bases are the first samples, too
  660. for (int i = 0; i < (isStereo ? 2 : 1); i++, curPointer += (is16Bits ? 2 : 1), curPos += (is16Bits ? 2 : 1)) {
  661. if (is16Bits)
  662. WRITE_BE_UINT16(curPointer, bases[i]);
  663. else
  664. *curPointer = (bases[i] & 0xFF) ^ 0x80;
  665. }
  666. // Next follow the deltas, which are added to the corresponding base values and
  667. // are stored as little endian
  668. // We store the unpacked bytes in big endian format
  669. while (curPos < unpackedSize) {
  670. // If the sample is stereo, the data is stored for the left and right channel, respectively
  671. // (the exact opposite to the base values)
  672. if (!is16Bits) {
  673. for (int k = 0; k < (isStereo ? 2 : 1); k++) {
  674. int8 delta = (int8) ((int16) audioTrees[k]->getCode(audioBS));
  675. bases[k] = (bases[k] + delta) & 0xFF;
  676. *curPointer++ = bases[k] ^ 0x80;
  677. curPos++;
  678. }
  679. } else {
  680. for (int k = 0; k < (isStereo ? 2 : 1); k++) {
  681. byte lo = audioTrees[k * 2]->getCode(audioBS);
  682. byte hi = audioTrees[k * 2 + 1]->getCode(audioBS);
  683. bases[k] += (int16) (lo | (hi << 8));
  684. WRITE_BE_UINT16(curPointer, bases[k]);
  685. curPointer += 2;
  686. curPos += 2;
  687. }
  688. }
  689. }
  690. for (int k = 0; k < numBytes; k++)
  691. delete audioTrees[k];
  692. queuePCM(unpackedBuffer, unpackedSize);
  693. }
  694. void SmackerDecoder::SmackerAudioTrack::queuePCM(byte *buffer, uint32 bufferSize) {
  695. byte flags = 0;
  696. if (_audioInfo.is16Bits)
  697. flags |= Audio::FLAG_16BITS;
  698. if (_audioInfo.isStereo)
  699. flags |= Audio::FLAG_STEREO;
  700. _audioStream->queueBuffer(buffer, bufferSize, DisposeAfterUse::YES, flags);
  701. }
  702. SmackerDecoder::SmackerVideoTrack *SmackerDecoder::createVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 signature) const {
  703. return new SmackerVideoTrack(width, height, frameCount, frameRate, flags, signature);
  704. }
  705. // ResidualVM-specific function
  706. Common::Rational SmackerDecoder::getFrameRate() const {
  707. const SmackerVideoTrack *videoTrack = (const SmackerVideoTrack *)getTrack(0);
  708. return videoTrack->getFrameRate();
  709. }
  710. } // End of namespace Video