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
23 // Based on eos' Bink decoder which is in turn
24 // based quite heavily on the Bink decoder found in FFmpeg.
25 // Many thanks to Kostya Shishkov for doing the hard work.
26
27 #include "audio/audiostream.h"
28 #include "audio/decoders/raw.h"
29
30 #include "common/util.h"
31 #include "common/textconsole.h"
32 #include "common/math.h"
33 #include "common/stream.h"
34 #include "common/substream.h"
35 #include "common/file.h"
36 #include "common/str.h"
37 #include "common/bitstream.h"
38 #include "common/huffman.h"
39 #include "common/rdft.h"
40 #include "common/dct.h"
41 #include "common/system.h"
42
43 #include "graphics/yuv_to_rgb.h"
44 #include "graphics/surface.h"
45
46 #include "video/binkdata.h"
47 #include "video/bink_decoder.h"
48
49 static const uint32 kBIKfID = MKTAG('B', 'I', 'K', 'f');
50 static const uint32 kBIKgID = MKTAG('B', 'I', 'K', 'g');
51 static const uint32 kBIKhID = MKTAG('B', 'I', 'K', 'h');
52 static const uint32 kBIKiID = MKTAG('B', 'I', 'K', 'i');
53
54 static const uint32 kVideoFlagAlpha = 0x00100000;
55
56 static const uint16 kAudioFlagDCT = 0x1000;
57 static const uint16 kAudioFlagStereo = 0x2000;
58
59 // Number of bits used to store first DC value in bundle
60 static const uint32 kDCStartBits = 11;
61
62 namespace Video {
63
BinkDecoder()64 BinkDecoder::BinkDecoder() {
65 _bink = 0;
66 }
67
~BinkDecoder()68 BinkDecoder::~BinkDecoder() {
69 close();
70 }
71
loadStream(Common::SeekableReadStream * stream)72 bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
73 close();
74
75 uint32 id = stream->readUint32BE();
76 if ((id != kBIKfID) && (id != kBIKgID) && (id != kBIKhID) && (id != kBIKiID))
77 return false;
78
79 uint32 fileSize = stream->readUint32LE() + 8;
80 uint32 frameCount = stream->readUint32LE();
81 uint32 largestFrameSize = stream->readUint32LE();
82
83 if (largestFrameSize > fileSize) {
84 warning("Largest frame size greater than file size");
85 return false;
86 }
87
88 stream->skip(4);
89
90 uint32 width = stream->readUint32LE();
91 uint32 height = stream->readUint32LE();
92
93 uint32 frameRateNum = stream->readUint32LE();
94 uint32 frameRateDen = stream->readUint32LE();
95 if (frameRateNum == 0 || frameRateDen == 0) {
96 warning("Invalid frame rate (%d/%d)", frameRateNum, frameRateDen);
97 return false;
98 }
99
100 _bink = stream;
101
102 uint32 videoFlags = _bink->readUint32LE();
103
104 // BIKh and BIKi swap the chroma planes
105 addTrack(new BinkVideoTrack(width, height, getDefaultHighColorFormat(), frameCount,
106 Common::Rational(frameRateNum, frameRateDen), (id == kBIKhID || id == kBIKiID), videoFlags & kVideoFlagAlpha, id));
107
108 uint32 audioTrackCount = _bink->readUint32LE();
109
110 if (audioTrackCount > 0) {
111 _audioTracks.resize(audioTrackCount);
112
113 _bink->skip(4 * audioTrackCount);
114
115 // Reading audio track properties
116 for (uint32 i = 0; i < audioTrackCount; i++) {
117 AudioInfo &track = _audioTracks[i];
118
119 track.sampleRate = _bink->readUint16LE();
120 track.flags = _bink->readUint16LE();
121
122 initAudioTrack(track);
123 }
124
125 _bink->skip(4 * audioTrackCount);
126 }
127
128 // Reading video frame properties
129 _frames.resize(frameCount);
130 for (uint32 i = 0; i < frameCount; i++) {
131 _frames[i].offset = _bink->readUint32LE();
132 _frames[i].keyFrame = _frames[i].offset & 1;
133
134 _frames[i].offset &= ~1;
135
136 if (i != 0)
137 _frames[i - 1].size = _frames[i].offset - _frames[i - 1].offset;
138
139 _frames[i].bits = 0;
140 }
141
142 _frames[frameCount - 1].size = _bink->size() - _frames[frameCount - 1].offset;
143
144 return true;
145 }
146
close()147 void BinkDecoder::close() {
148 VideoDecoder::close();
149
150 delete _bink;
151 _bink = 0;
152
153 _audioTracks.clear();
154 _frames.clear();
155 }
156
readNextPacket()157 void BinkDecoder::readNextPacket() {
158 BinkVideoTrack *videoTrack = (BinkVideoTrack *)getTrack(0);
159
160 if (videoTrack->endOfTrack())
161 return;
162
163 VideoFrame &frame = _frames[videoTrack->getCurFrame() + 1];
164
165 if (!_bink->seek(frame.offset))
166 error("Bad bink seek");
167
168 uint32 frameSize = frame.size;
169
170 for (uint32 i = 0; i < _audioTracks.size(); i++) {
171 AudioInfo &audio = _audioTracks[i];
172
173 uint32 audioPacketLength = _bink->readUint32LE();
174
175 frameSize -= 4;
176
177 if (frameSize < audioPacketLength)
178 error("Audio packet too big for the frame");
179
180 if (audioPacketLength >= 4) {
181 // Get our track - audio index plus one as the first track is video
182 BinkAudioTrack *audioTrack = (BinkAudioTrack *)getTrack(i + 1);
183 uint32 audioPacketStart = _bink->pos();
184 uint32 audioPacketEnd = _bink->pos() + audioPacketLength;
185
186 // Number of samples in bytes
187 audio.sampleCount = _bink->readUint32LE() / (2 * audio.channels);
188
189 audio.bits = new Common::BitStream32LELSB(new Common::SeekableSubReadStream(_bink,
190 audioPacketStart + 4, audioPacketEnd), DisposeAfterUse::YES);
191
192 audioTrack->decodePacket();
193
194 delete audio.bits;
195 audio.bits = 0;
196
197 _bink->seek(audioPacketEnd);
198
199 frameSize -= audioPacketLength;
200 }
201 }
202
203 uint32 videoPacketStart = _bink->pos();
204 uint32 videoPacketEnd = _bink->pos() + frameSize;
205
206 frame.bits = new Common::BitStream32LELSB(new Common::SeekableSubReadStream(_bink,
207 videoPacketStart, videoPacketEnd), DisposeAfterUse::YES);
208
209 videoTrack->decodePacket(frame);
210
211 delete frame.bits;
212 frame.bits = 0;
213 }
214
getAudioTrack(int index)215 VideoDecoder::AudioTrack *BinkDecoder::getAudioTrack(int index) {
216 // Bink audio track indexes are relative to the first audio track
217 Track *track = getTrack(index + 1);
218
219 if (!track || track->getTrackType() != Track::kTrackTypeAudio)
220 return 0;
221
222 return (AudioTrack *)track;
223 }
224
VideoFrame()225 BinkDecoder::VideoFrame::VideoFrame() : bits(0) {
226 }
227
~VideoFrame()228 BinkDecoder::VideoFrame::~VideoFrame() {
229 delete bits;
230 }
231
232
AudioInfo()233 BinkDecoder::AudioInfo::AudioInfo() : bits(0), bands(0), rdft(0), dct(0) {
234 }
235
~AudioInfo()236 BinkDecoder::AudioInfo::~AudioInfo() {
237 delete bits;
238
239 delete[] bands;
240
241 delete rdft;
242 delete dct;
243 }
244
BinkVideoTrack(uint32 width,uint32 height,const Graphics::PixelFormat & format,uint32 frameCount,const Common::Rational & frameRate,bool swapPlanes,bool hasAlpha,uint32 id)245 BinkDecoder::BinkVideoTrack::BinkVideoTrack(uint32 width, uint32 height, const Graphics::PixelFormat &format, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id) :
246 _frameCount(frameCount), _frameRate(frameRate), _swapPlanes(swapPlanes), _hasAlpha(hasAlpha), _id(id) {
247 _curFrame = -1;
248
249 for (int i = 0; i < 16; i++)
250 _huffman[i] = 0;
251
252 for (int i = 0; i < kSourceMAX; i++) {
253 _bundles[i].countLength = 0;
254
255 _bundles[i].huffman.index = 0;
256 for (int j = 0; j < 16; j++)
257 _bundles[i].huffman.symbols[j] = j;
258
259 _bundles[i].data = 0;
260 _bundles[i].dataEnd = 0;
261 _bundles[i].curDec = 0;
262 _bundles[i].curPtr = 0;
263 }
264
265 for (int i = 0; i < 16; i++) {
266 _colHighHuffman[i].index = 0;
267 for (int j = 0; j < 16; j++)
268 _colHighHuffman[i].symbols[j] = j;
269 }
270
271 // Make the surface even-sized:
272 _surfaceHeight = height;
273 _surfaceWidth = width;
274
275 if (height & 1) {
276 _surfaceHeight++;
277 }
278 if (width & 1) {
279 _surfaceWidth++;
280 }
281
282 _surface.create(_surfaceWidth, _surfaceHeight, format);
283 // Since we over-allocate to make surfaces even-sized
284 // we need to set the actual VIDEO size back into the
285 // surface.
286 _surface.h = height;
287 _surface.w = width;
288
289 // Compute the video dimensions in blocks
290 _yBlockWidth = (width + 7) >> 3;
291 _yBlockHeight = (height + 7) >> 3;
292 _uvBlockWidth = (width + 15) >> 4;
293 _uvBlockHeight = (height + 15) >> 4;
294
295 // The planes are sized according to the number of blocks
296 _curPlanes[0] = new byte[_yBlockWidth * 8 * _yBlockHeight * 8]; // Y
297 _curPlanes[1] = new byte[_uvBlockWidth * 8 * _uvBlockHeight * 8]; // U, 1/4 resolution
298 _curPlanes[2] = new byte[_uvBlockWidth * 8 * _uvBlockHeight * 8]; // V, 1/4 resolution
299 _curPlanes[3] = new byte[_yBlockWidth * 8 * _yBlockHeight * 8]; // A
300 _oldPlanes[0] = new byte[_yBlockWidth * 8 * _yBlockHeight * 8]; // Y
301 _oldPlanes[1] = new byte[_uvBlockWidth * 8 * _uvBlockHeight * 8]; // U, 1/4 resolution
302 _oldPlanes[2] = new byte[_uvBlockWidth * 8 * _uvBlockHeight * 8]; // V, 1/4 resolution
303 _oldPlanes[3] = new byte[_yBlockWidth * 8 * _yBlockHeight * 8]; // A
304
305 // Initialize the video with solid green
306 memset(_curPlanes[0], 0, _yBlockWidth * 8 * _yBlockHeight * 8);
307 memset(_curPlanes[1], 0, _uvBlockWidth * 8 * _uvBlockHeight * 8);
308 memset(_curPlanes[2], 0, _uvBlockWidth * 8 * _uvBlockHeight * 8);
309 memset(_curPlanes[3], 255, _yBlockWidth * 8 * _yBlockHeight * 8);
310 memset(_oldPlanes[0], 0, _yBlockWidth * 8 * _yBlockHeight * 8);
311 memset(_oldPlanes[1], 0, _uvBlockWidth * 8 * _uvBlockHeight * 8);
312 memset(_oldPlanes[2], 0, _uvBlockWidth * 8 * _uvBlockHeight * 8);
313 memset(_oldPlanes[3], 255, _yBlockWidth * 8 * _yBlockHeight * 8);
314
315 initBundles();
316 initHuffman();
317 }
318
~BinkVideoTrack()319 BinkDecoder::BinkVideoTrack::~BinkVideoTrack() {
320 for (int i = 0; i < 4; i++) {
321 delete[] _curPlanes[i]; _curPlanes[i] = 0;
322 delete[] _oldPlanes[i]; _oldPlanes[i] = 0;
323 }
324
325 deinitBundles();
326
327 for (int i = 0; i < 16; i++) {
328 delete _huffman[i];
329 _huffman[i] = 0;
330 }
331
332 _surface.free();
333 }
334
decodePacket(VideoFrame & frame)335 void BinkDecoder::BinkVideoTrack::decodePacket(VideoFrame &frame) {
336 assert(frame.bits);
337
338 if (_hasAlpha) {
339 if (_id == kBIKiID)
340 frame.bits->skip(32);
341
342 decodePlane(frame, 3, false);
343 }
344
345 if (_id == kBIKiID)
346 frame.bits->skip(32);
347
348 for (int i = 0; i < 3; i++) {
349 int planeIdx = ((i == 0) || !_swapPlanes) ? i : (i ^ 3);
350
351 decodePlane(frame, planeIdx, i != 0);
352
353 if (frame.bits->pos() >= frame.bits->size())
354 break;
355 }
356
357 // Convert the YUV data we have to our format
358 // We're ignoring alpha for now
359 // The width used here is the surface-width, and not the video-width
360 // to allow for odd-sized videos.
361 assert(_curPlanes[0] && _curPlanes[1] && _curPlanes[2]);
362 YUVToRGBMan.convert420(&_surface, Graphics::YUVToRGBManager::kScaleITU, _curPlanes[0], _curPlanes[1], _curPlanes[2],
363 _surfaceWidth, _surfaceHeight, _yBlockWidth * 8, _uvBlockWidth * 8);
364
365 // And swap the planes with the reference planes
366 for (int i = 0; i < 4; i++)
367 SWAP(_curPlanes[i], _oldPlanes[i]);
368
369 _curFrame++;
370 }
371
decodePlane(VideoFrame & video,int planeIdx,bool isChroma)372 void BinkDecoder::BinkVideoTrack::decodePlane(VideoFrame &video, int planeIdx, bool isChroma) {
373 uint32 blockWidth = isChroma ? _uvBlockWidth : _yBlockWidth;
374 uint32 blockHeight = isChroma ? _uvBlockHeight : _yBlockHeight;
375 uint32 width = blockWidth * 8;
376 uint32 height = blockHeight * 8;
377
378 DecodeContext ctx;
379
380 ctx.video = &video;
381 ctx.planeIdx = planeIdx;
382 ctx.destStart = _curPlanes[planeIdx];
383 ctx.destEnd = _curPlanes[planeIdx] + width * height;
384 ctx.prevStart = _oldPlanes[planeIdx];
385 ctx.prevEnd = _oldPlanes[planeIdx] + width * height;
386 ctx.pitch = width;
387
388 for (int i = 0; i < 64; i++) {
389 ctx.coordMap[i] = (i & 7) + (i >> 3) * ctx.pitch;
390
391 ctx.coordScaledMap1[i] = ((i & 7) * 2 + 0) + (((i >> 3) * 2 + 0) * ctx.pitch);
392 ctx.coordScaledMap2[i] = ((i & 7) * 2 + 1) + (((i >> 3) * 2 + 0) * ctx.pitch);
393 ctx.coordScaledMap3[i] = ((i & 7) * 2 + 0) + (((i >> 3) * 2 + 1) * ctx.pitch);
394 ctx.coordScaledMap4[i] = ((i & 7) * 2 + 1) + (((i >> 3) * 2 + 1) * ctx.pitch);
395 }
396
397 for (int i = 0; i < kSourceMAX; i++) {
398 _bundles[i].countLength = _bundles[i].countLengths[isChroma ? 1 : 0];
399
400 readBundle(video, (Source) i);
401 }
402
403 for (ctx.blockY = 0; ctx.blockY < blockHeight; ctx.blockY++) {
404 readBlockTypes (video, _bundles[kSourceBlockTypes]);
405 readBlockTypes (video, _bundles[kSourceSubBlockTypes]);
406 readColors (video, _bundles[kSourceColors]);
407 readPatterns (video, _bundles[kSourcePattern]);
408 readMotionValues(video, _bundles[kSourceXOff]);
409 readMotionValues(video, _bundles[kSourceYOff]);
410 readDCS (video, _bundles[kSourceIntraDC], kDCStartBits, false);
411 readDCS (video, _bundles[kSourceInterDC], kDCStartBits, true);
412 readRuns (video, _bundles[kSourceRun]);
413
414 ctx.dest = ctx.destStart + 8 * ctx.blockY * ctx.pitch;
415 ctx.prev = ctx.prevStart + 8 * ctx.blockY * ctx.pitch;
416
417 for (ctx.blockX = 0; ctx.blockX < blockWidth; ctx.blockX++, ctx.dest += 8, ctx.prev += 8) {
418 BlockType blockType = (BlockType) getBundleValue(kSourceBlockTypes);
419
420 // 16x16 block type on odd line means part of the already decoded block, so skip it
421 if ((ctx.blockY & 1) && (blockType == kBlockScaled)) {
422 ctx.blockX += 1;
423 ctx.dest += 8;
424 ctx.prev += 8;
425 continue;
426 }
427
428 switch (blockType) {
429 case kBlockSkip:
430 blockSkip(ctx);
431 break;
432 case kBlockScaled:
433 blockScaled(ctx);
434 break;
435 case kBlockMotion:
436 blockMotion(ctx);
437 break;
438 case kBlockRun:
439 blockRun(ctx);
440 break;
441 case kBlockResidue:
442 blockResidue(ctx);
443 break;
444 case kBlockIntra:
445 blockIntra(ctx);
446 break;
447 case kBlockFill:
448 blockFill(ctx);
449 break;
450 case kBlockInter:
451 blockInter(ctx);
452 break;
453 case kBlockPattern:
454 blockPattern(ctx);
455 break;
456 case kBlockRaw:
457 blockRaw(ctx);
458 break;
459 default:
460 error("Unknown block type: %d", blockType);
461 }
462
463 }
464
465 }
466
467 if (video.bits->pos() & 0x1F) // next plane data starts at 32-bit boundary
468 video.bits->skip(32 - (video.bits->pos() & 0x1F));
469
470 }
471
readBundle(VideoFrame & video,Source source)472 void BinkDecoder::BinkVideoTrack::readBundle(VideoFrame &video, Source source) {
473 if (source == kSourceColors) {
474 for (int i = 0; i < 16; i++)
475 readHuffman(video, _colHighHuffman[i]);
476
477 _colLastVal = 0;
478 }
479
480 if ((source != kSourceIntraDC) && (source != kSourceInterDC))
481 readHuffman(video, _bundles[source].huffman);
482
483 _bundles[source].curDec = _bundles[source].data;
484 _bundles[source].curPtr = _bundles[source].data;
485 }
486
readHuffman(VideoFrame & video,Huffman & huffman)487 void BinkDecoder::BinkVideoTrack::readHuffman(VideoFrame &video, Huffman &huffman) {
488 huffman.index = video.bits->getBits(4);
489
490 if (huffman.index == 0) {
491 // The first tree always gives raw nibbles
492 for (int i = 0; i < 16; i++)
493 huffman.symbols[i] = i;
494
495 return;
496 }
497
498 byte hasSymbol[16];
499
500 if (video.bits->getBit()) {
501 // Symbol selection
502 memset(hasSymbol, 0, 16);
503
504 uint8 length = video.bits->getBits(3);
505 for (int i = 0; i <= length; i++) {
506 huffman.symbols[i] = video.bits->getBits(4);
507 hasSymbol[huffman.symbols[i]] = 1;
508 }
509
510 for (int i = 0; i < 16; i++)
511 if (hasSymbol[i] == 0)
512 huffman.symbols[++length] = i;
513
514 return;
515 }
516
517 // Symbol shuffling
518
519 byte tmp1[16], tmp2[16];
520 byte *in = tmp1, *out = tmp2;
521
522 uint8 depth = video.bits->getBits(2);
523
524 for (int i = 0; i < 16; i++)
525 in[i] = i;
526
527 for (int i = 0; i <= depth; i++) {
528 int size = 1 << i;
529
530 for (int j = 0; j < 16; j += (size << 1))
531 mergeHuffmanSymbols(video, out + j, in + j, size);
532
533 SWAP(in, out);
534 }
535
536 memcpy(huffman.symbols, in, 16);
537 }
538
mergeHuffmanSymbols(VideoFrame & video,byte * dst,const byte * src,int size)539 void BinkDecoder::BinkVideoTrack::mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size) {
540 const byte *src2 = src + size;
541 int size2 = size;
542
543 do {
544 if (!video.bits->getBit()) {
545 *dst++ = *src++;
546 size--;
547 } else {
548 *dst++ = *src2++;
549 size2--;
550 }
551
552 } while (size && size2);
553
554 while (size--)
555 *dst++ = *src++;
556
557 while (size2--)
558 *dst++ = *src2++;
559 }
560
initBundles()561 void BinkDecoder::BinkVideoTrack::initBundles() {
562 uint32 bw = (_surface.w + 7) >> 3;
563 uint32 bh = (_surface.h + 7) >> 3;
564 uint32 blocks = bw * bh;
565
566 for (int i = 0; i < kSourceMAX; i++) {
567 _bundles[i].data = new byte[blocks * 64];
568 _bundles[i].dataEnd = _bundles[i].data + blocks * 64;
569 }
570
571 uint32 cbw[2] = { (uint32)((_surface.w + 7) >> 3), (uint32)((_surface.w + 15) >> 4) };
572 uint32 cw [2] = { (uint32)( _surface.w ), (uint32)( _surface.w >> 1) };
573
574 // Calculate the lengths of an element count in bits
575 for (int i = 0; i < 2; i++) {
576 int width = MAX<uint32>(cw[i], 8);
577
578 _bundles[kSourceBlockTypes ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
579 _bundles[kSourceSubBlockTypes].countLengths[i] = Common::intLog2(((width + 7) >> 4) + 511) + 1;
580 _bundles[kSourceColors ].countLengths[i] = Common::intLog2((cbw[i]) * 64 + 511) + 1;
581 _bundles[kSourceIntraDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
582 _bundles[kSourceInterDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
583 _bundles[kSourceXOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
584 _bundles[kSourceYOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
585 _bundles[kSourcePattern ].countLengths[i] = Common::intLog2((cbw[i] << 3) + 511) + 1;
586 _bundles[kSourceRun ].countLengths[i] = Common::intLog2((cbw[i]) * 48 + 511) + 1;
587 }
588 }
589
deinitBundles()590 void BinkDecoder::BinkVideoTrack::deinitBundles() {
591 for (int i = 0; i < kSourceMAX; i++)
592 delete[] _bundles[i].data;
593 }
594
initHuffman()595 void BinkDecoder::BinkVideoTrack::initHuffman() {
596 for (int i = 0; i < 16; i++)
597 _huffman[i] = new Common::Huffman<Common::BitStream32LELSB>(binkHuffmanLengths[i][15], 16, binkHuffmanCodes[i], binkHuffmanLengths[i]);
598 }
599
getHuffmanSymbol(VideoFrame & video,Huffman & huffman)600 byte BinkDecoder::BinkVideoTrack::getHuffmanSymbol(VideoFrame &video, Huffman &huffman) {
601 return huffman.symbols[_huffman[huffman.index]->getSymbol(*video.bits)];
602 }
603
getBundleValue(Source source)604 int32 BinkDecoder::BinkVideoTrack::getBundleValue(Source source) {
605 if ((source < kSourceXOff) || (source == kSourceRun))
606 return *_bundles[source].curPtr++;
607
608 if ((source == kSourceXOff) || (source == kSourceYOff))
609 return (int8) *_bundles[source].curPtr++;
610
611 int16 ret = *((int16 *) _bundles[source].curPtr);
612
613 _bundles[source].curPtr += 2;
614
615 return ret;
616 }
617
readBundleCount(VideoFrame & video,Bundle & bundle)618 uint32 BinkDecoder::BinkVideoTrack::readBundleCount(VideoFrame &video, Bundle &bundle) {
619 if (!bundle.curDec || (bundle.curDec > bundle.curPtr))
620 return 0;
621
622 uint32 n = video.bits->getBits(bundle.countLength);
623 if (n == 0)
624 bundle.curDec = 0;
625
626 return n;
627 }
628
blockSkip(DecodeContext & ctx)629 void BinkDecoder::BinkVideoTrack::blockSkip(DecodeContext &ctx) {
630 byte *dest = ctx.dest;
631 byte *prev = ctx.prev;
632
633 for (int j = 0; j < 8; j++, dest += ctx.pitch, prev += ctx.pitch)
634 memcpy(dest, prev, 8);
635 }
636
blockScaledSkip(DecodeContext & ctx)637 void BinkDecoder::BinkVideoTrack::blockScaledSkip(DecodeContext &ctx) {
638 byte *dest = ctx.dest;
639 byte *prev = ctx.prev;
640
641 for (int j = 0; j < 16; j++, dest += ctx.pitch, prev += ctx.pitch)
642 memcpy(dest, prev, 16);
643 }
644
blockScaledRun(DecodeContext & ctx)645 void BinkDecoder::BinkVideoTrack::blockScaledRun(DecodeContext &ctx) {
646 const uint8 *scan = binkPatterns[ctx.video->bits->getBits(4)];
647
648 int i = 0;
649 do {
650 int run = getBundleValue(kSourceRun) + 1;
651
652 i += run;
653 if (i > 64)
654 error("Run went out of bounds");
655
656 if (ctx.video->bits->getBit()) {
657
658 byte v = getBundleValue(kSourceColors);
659 for (int j = 0; j < run; j++, scan++)
660 ctx.dest[ctx.coordScaledMap1[*scan]] =
661 ctx.dest[ctx.coordScaledMap2[*scan]] =
662 ctx.dest[ctx.coordScaledMap3[*scan]] =
663 ctx.dest[ctx.coordScaledMap4[*scan]] = v;
664
665 } else
666 for (int j = 0; j < run; j++, scan++)
667 ctx.dest[ctx.coordScaledMap1[*scan]] =
668 ctx.dest[ctx.coordScaledMap2[*scan]] =
669 ctx.dest[ctx.coordScaledMap3[*scan]] =
670 ctx.dest[ctx.coordScaledMap4[*scan]] = getBundleValue(kSourceColors);
671
672 } while (i < 63);
673
674 if (i == 63)
675 ctx.dest[ctx.coordScaledMap1[*scan]] =
676 ctx.dest[ctx.coordScaledMap2[*scan]] =
677 ctx.dest[ctx.coordScaledMap3[*scan]] =
678 ctx.dest[ctx.coordScaledMap4[*scan]] = getBundleValue(kSourceColors);
679 }
680
blockScaledIntra(DecodeContext & ctx)681 void BinkDecoder::BinkVideoTrack::blockScaledIntra(DecodeContext &ctx) {
682 int32 block[64];
683 memset(block, 0, 64 * sizeof(int32));
684
685 block[0] = getBundleValue(kSourceIntraDC);
686
687 readDCTCoeffs(*ctx.video, block, true);
688
689 IDCT(block);
690
691 int32 *src = block;
692 byte *dest1 = ctx.dest;
693 byte *dest2 = ctx.dest + ctx.pitch;
694 for (int j = 0; j < 8; j++, dest1 += (ctx.pitch << 1) - 16, dest2 += (ctx.pitch << 1) - 16, src += 8) {
695
696 for (int i = 0; i < 8; i++, dest1 += 2, dest2 += 2)
697 dest1[0] = dest1[1] = dest2[0] = dest2[1] = src[i];
698
699 }
700 }
701
blockScaledFill(DecodeContext & ctx)702 void BinkDecoder::BinkVideoTrack::blockScaledFill(DecodeContext &ctx) {
703 byte v = getBundleValue(kSourceColors);
704
705 byte *dest = ctx.dest;
706 for (int i = 0; i < 16; i++, dest += ctx.pitch)
707 memset(dest, v, 16);
708 }
709
blockScaledPattern(DecodeContext & ctx)710 void BinkDecoder::BinkVideoTrack::blockScaledPattern(DecodeContext &ctx) {
711 byte col[2];
712
713 for (int i = 0; i < 2; i++)
714 col[i] = getBundleValue(kSourceColors);
715
716 byte *dest1 = ctx.dest;
717 byte *dest2 = ctx.dest + ctx.pitch;
718 for (int j = 0; j < 8; j++, dest1 += (ctx.pitch << 1) - 16, dest2 += (ctx.pitch << 1) - 16) {
719 byte v = getBundleValue(kSourcePattern);
720
721 for (int i = 0; i < 8; i++, dest1 += 2, dest2 += 2, v >>= 1)
722 dest1[0] = dest1[1] = dest2[0] = dest2[1] = col[v & 1];
723 }
724 }
725
blockScaledRaw(DecodeContext & ctx)726 void BinkDecoder::BinkVideoTrack::blockScaledRaw(DecodeContext &ctx) {
727 byte row[8];
728
729 byte *dest1 = ctx.dest;
730 byte *dest2 = ctx.dest + ctx.pitch;
731 for (int j = 0; j < 8; j++, dest1 += (ctx.pitch << 1) - 16, dest2 += (ctx.pitch << 1) - 16) {
732 memcpy(row, _bundles[kSourceColors].curPtr, 8);
733
734 for (int i = 0; i < 8; i++, dest1 += 2, dest2 += 2)
735 dest1[0] = dest1[1] = dest2[0] = dest2[1] = row[i];
736
737 _bundles[kSourceColors].curPtr += 8;
738 }
739 }
740
blockScaled(DecodeContext & ctx)741 void BinkDecoder::BinkVideoTrack::blockScaled(DecodeContext &ctx) {
742 BlockType blockType = (BlockType) getBundleValue(kSourceSubBlockTypes);
743
744 switch (blockType) {
745 case kBlockRun:
746 blockScaledRun(ctx);
747 break;
748 case kBlockIntra:
749 blockScaledIntra(ctx);
750 break;
751 case kBlockFill:
752 blockScaledFill(ctx);
753 break;
754 case kBlockPattern:
755 blockScaledPattern(ctx);
756 break;
757 case kBlockRaw:
758 blockScaledRaw(ctx);
759 break;
760 default:
761 error("Invalid 16x16 block type: %d", blockType);
762 }
763
764 ctx.blockX += 1;
765 ctx.dest += 8;
766 ctx.prev += 8;
767 }
768
blockMotion(DecodeContext & ctx)769 void BinkDecoder::BinkVideoTrack::blockMotion(DecodeContext &ctx) {
770 int8 xOff = getBundleValue(kSourceXOff);
771 int8 yOff = getBundleValue(kSourceYOff);
772
773 byte *dest = ctx.dest;
774 byte *prev = ctx.prev + yOff * ((int32) ctx.pitch) + xOff;
775 if ((prev < ctx.prevStart) || (prev > ctx.prevEnd))
776 error("Copy out of bounds (%d | %d)", ctx.blockX * 8 + xOff, ctx.blockY * 8 + yOff);
777
778 for (int j = 0; j < 8; j++, dest += ctx.pitch, prev += ctx.pitch)
779 memcpy(dest, prev, 8);
780 }
781
blockRun(DecodeContext & ctx)782 void BinkDecoder::BinkVideoTrack::blockRun(DecodeContext &ctx) {
783 const uint8 *scan = binkPatterns[ctx.video->bits->getBits(4)];
784
785 int i = 0;
786 do {
787 int run = getBundleValue(kSourceRun) + 1;
788
789 i += run;
790 if (i > 64)
791 error("Run went out of bounds");
792
793 if (ctx.video->bits->getBit()) {
794
795 byte v = getBundleValue(kSourceColors);
796 for (int j = 0; j < run; j++)
797 ctx.dest[ctx.coordMap[*scan++]] = v;
798
799 } else
800 for (int j = 0; j < run; j++)
801 ctx.dest[ctx.coordMap[*scan++]] = getBundleValue(kSourceColors);
802
803 } while (i < 63);
804
805 if (i == 63)
806 ctx.dest[ctx.coordMap[*scan++]] = getBundleValue(kSourceColors);
807 }
808
blockResidue(DecodeContext & ctx)809 void BinkDecoder::BinkVideoTrack::blockResidue(DecodeContext &ctx) {
810 blockMotion(ctx);
811
812 byte v = ctx.video->bits->getBits(7);
813
814 int16 block[64];
815 memset(block, 0, 64 * sizeof(int16));
816
817 readResidue(*ctx.video, block, v);
818
819 byte *dst = ctx.dest;
820 int16 *src = block;
821 for (int i = 0; i < 8; i++, dst += ctx.pitch, src += 8)
822 for (int j = 0; j < 8; j++)
823 dst[j] += src[j];
824 }
825
blockIntra(DecodeContext & ctx)826 void BinkDecoder::BinkVideoTrack::blockIntra(DecodeContext &ctx) {
827 int32 block[64];
828 memset(block, 0, 64 * sizeof(int32));
829
830 block[0] = getBundleValue(kSourceIntraDC);
831
832 readDCTCoeffs(*ctx.video, block, true);
833
834 IDCTPut(ctx, block);
835 }
836
blockFill(DecodeContext & ctx)837 void BinkDecoder::BinkVideoTrack::blockFill(DecodeContext &ctx) {
838 byte v = getBundleValue(kSourceColors);
839
840 byte *dest = ctx.dest;
841 for (int i = 0; i < 8; i++, dest += ctx.pitch)
842 memset(dest, v, 8);
843 }
844
blockInter(DecodeContext & ctx)845 void BinkDecoder::BinkVideoTrack::blockInter(DecodeContext &ctx) {
846 blockMotion(ctx);
847
848 int32 block[64];
849 memset(block, 0, 64 * sizeof(int32));
850
851 block[0] = getBundleValue(kSourceInterDC);
852
853 readDCTCoeffs(*ctx.video, block, false);
854
855 IDCTAdd(ctx, block);
856 }
857
blockPattern(DecodeContext & ctx)858 void BinkDecoder::BinkVideoTrack::blockPattern(DecodeContext &ctx) {
859 byte col[2];
860
861 for (int i = 0; i < 2; i++)
862 col[i] = getBundleValue(kSourceColors);
863
864 byte *dest = ctx.dest;
865 for (int i = 0; i < 8; i++, dest += ctx.pitch - 8) {
866 byte v = getBundleValue(kSourcePattern);
867
868 for (int j = 0; j < 8; j++, v >>= 1)
869 *dest++ = col[v & 1];
870 }
871 }
872
blockRaw(DecodeContext & ctx)873 void BinkDecoder::BinkVideoTrack::blockRaw(DecodeContext &ctx) {
874 byte *dest = ctx.dest;
875 byte *data = _bundles[kSourceColors].curPtr;
876 for (int i = 0; i < 8; i++, dest += ctx.pitch, data += 8)
877 memcpy(dest, data, 8);
878
879 _bundles[kSourceColors].curPtr += 64;
880 }
881
readRuns(VideoFrame & video,Bundle & bundle)882 void BinkDecoder::BinkVideoTrack::readRuns(VideoFrame &video, Bundle &bundle) {
883 uint32 n = readBundleCount(video, bundle);
884 if (n == 0)
885 return;
886
887 byte *decEnd = bundle.curDec + n;
888 if (decEnd > bundle.dataEnd)
889 error("Run value went out of bounds");
890
891 if (video.bits->getBit()) {
892 byte v = video.bits->getBits(4);
893
894 memset(bundle.curDec, v, n);
895 bundle.curDec += n;
896
897 } else
898 while (bundle.curDec < decEnd)
899 *bundle.curDec++ = getHuffmanSymbol(video, bundle.huffman);
900 }
901
readMotionValues(VideoFrame & video,Bundle & bundle)902 void BinkDecoder::BinkVideoTrack::readMotionValues(VideoFrame &video, Bundle &bundle) {
903 uint32 n = readBundleCount(video, bundle);
904 if (n == 0)
905 return;
906
907 byte *decEnd = bundle.curDec + n;
908 if (decEnd > bundle.dataEnd)
909 error("Too many motion values");
910
911 if (video.bits->getBit()) {
912 byte v = video.bits->getBits(4);
913
914 if (v) {
915 int sign = -(int)video.bits->getBit();
916 v = (v ^ sign) - sign;
917 }
918
919 memset(bundle.curDec, v, n);
920
921 bundle.curDec += n;
922 return;
923 }
924
925 do {
926 byte v = getHuffmanSymbol(video, bundle.huffman);
927
928 if (v) {
929 int sign = -(int)video.bits->getBit();
930 v = (v ^ sign) - sign;
931 }
932
933 *bundle.curDec++ = v;
934
935 } while (bundle.curDec < decEnd);
936 }
937
938 const uint8 rleLens[4] = { 4, 8, 12, 32 };
readBlockTypes(VideoFrame & video,Bundle & bundle)939 void BinkDecoder::BinkVideoTrack::readBlockTypes(VideoFrame &video, Bundle &bundle) {
940 uint32 n = readBundleCount(video, bundle);
941 if (n == 0)
942 return;
943
944 byte *decEnd = bundle.curDec + n;
945 if (decEnd > bundle.dataEnd)
946 error("Too many block type values");
947
948 if (video.bits->getBit()) {
949 byte v = video.bits->getBits(4);
950
951 memset(bundle.curDec, v, n);
952
953 bundle.curDec += n;
954 return;
955 }
956
957 byte last = 0;
958 do {
959
960 byte v = getHuffmanSymbol(video, bundle.huffman);
961
962 if (v < 12) {
963 last = v;
964 *bundle.curDec++ = v;
965 } else {
966 int run = rleLens[v - 12];
967
968 memset(bundle.curDec, last, run);
969
970 bundle.curDec += run;
971 }
972
973 } while (bundle.curDec < decEnd);
974 }
975
readPatterns(VideoFrame & video,Bundle & bundle)976 void BinkDecoder::BinkVideoTrack::readPatterns(VideoFrame &video, Bundle &bundle) {
977 uint32 n = readBundleCount(video, bundle);
978 if (n == 0)
979 return;
980
981 byte *decEnd = bundle.curDec + n;
982 if (decEnd > bundle.dataEnd)
983 error("Too many pattern values");
984
985 byte v;
986 while (bundle.curDec < decEnd) {
987 v = getHuffmanSymbol(video, bundle.huffman);
988 v |= getHuffmanSymbol(video, bundle.huffman) << 4;
989 *bundle.curDec++ = v;
990 }
991 }
992
993
readColors(VideoFrame & video,Bundle & bundle)994 void BinkDecoder::BinkVideoTrack::readColors(VideoFrame &video, Bundle &bundle) {
995 uint32 n = readBundleCount(video, bundle);
996 if (n == 0)
997 return;
998
999 byte *decEnd = bundle.curDec + n;
1000 if (decEnd > bundle.dataEnd)
1001 error("Too many color values");
1002
1003 if (video.bits->getBit()) {
1004 _colLastVal = getHuffmanSymbol(video, _colHighHuffman[_colLastVal]);
1005
1006 byte v;
1007 v = getHuffmanSymbol(video, bundle.huffman);
1008 v = (_colLastVal << 4) | v;
1009
1010 if (_id != kBIKiID) {
1011 int sign = ((int8) v) >> 7;
1012 v = ((v & 0x7F) ^ sign) - sign;
1013 v += 0x80;
1014 }
1015
1016 memset(bundle.curDec, v, n);
1017 bundle.curDec += n;
1018
1019 return;
1020 }
1021
1022 while (bundle.curDec < decEnd) {
1023 _colLastVal = getHuffmanSymbol(video, _colHighHuffman[_colLastVal]);
1024
1025 byte v;
1026 v = getHuffmanSymbol(video, bundle.huffman);
1027 v = (_colLastVal << 4) | v;
1028
1029 if (_id != kBIKiID) {
1030 int sign = ((int8) v) >> 7;
1031 v = ((v & 0x7F) ^ sign) - sign;
1032 v += 0x80;
1033 }
1034 *bundle.curDec++ = v;
1035 }
1036 }
1037
readDCS(VideoFrame & video,Bundle & bundle,int startBits,bool hasSign)1038 void BinkDecoder::BinkVideoTrack::readDCS(VideoFrame &video, Bundle &bundle, int startBits, bool hasSign) {
1039 uint32 length = readBundleCount(video, bundle);
1040 if (length == 0)
1041 return;
1042
1043 int16 *dest = (int16 *) bundle.curDec;
1044
1045 int32 v = video.bits->getBits(startBits - (hasSign ? 1 : 0));
1046 if (v && hasSign) {
1047 int sign = -(int)video.bits->getBit();
1048 v = (v ^ sign) - sign;
1049 }
1050
1051 *dest++ = v;
1052 length--;
1053
1054 for (uint32 i = 0; i < length; i += 8) {
1055 uint32 length2 = MIN<uint32>(length - i, 8);
1056
1057 byte bSize = video.bits->getBits(4);
1058
1059 if (bSize) {
1060
1061 for (uint32 j = 0; j < length2; j++) {
1062 int16 v2 = video.bits->getBits(bSize);
1063 if (v2) {
1064 int sign = -(int)video.bits->getBit();
1065 v2 = (v2 ^ sign) - sign;
1066 }
1067
1068 v += v2;
1069 *dest++ = v;
1070
1071 if ((v < -32768) || (v > 32767))
1072 error("DC value went out of bounds: %d", v);
1073 }
1074
1075 } else
1076 for (uint32 j = 0; j < length2; j++)
1077 *dest++ = v;
1078 }
1079
1080 bundle.curDec = (byte *) dest;
1081 }
1082
1083 /** Reads 8x8 block of DCT coefficients. */
readDCTCoeffs(VideoFrame & video,int32 * block,bool isIntra)1084 void BinkDecoder::BinkVideoTrack::readDCTCoeffs(VideoFrame &video, int32 *block, bool isIntra) {
1085 int coefCount = 0;
1086 int coefIdx[64];
1087
1088 int listStart = 64;
1089 int listEnd = 64;
1090
1091 int coefList[128]; int modeList[128];
1092 coefList[listEnd] = 4; modeList[listEnd++] = 0;
1093 coefList[listEnd] = 24; modeList[listEnd++] = 0;
1094 coefList[listEnd] = 44; modeList[listEnd++] = 0;
1095 coefList[listEnd] = 1; modeList[listEnd++] = 3;
1096 coefList[listEnd] = 2; modeList[listEnd++] = 3;
1097 coefList[listEnd] = 3; modeList[listEnd++] = 3;
1098
1099 int bits = video.bits->getBits(4) - 1;
1100 for (int mask = 1 << bits; bits >= 0; mask >>= 1, bits--) {
1101 int listPos = listStart;
1102
1103 while (listPos < listEnd) {
1104
1105 if (!(modeList[listPos] | coefList[listPos]) || !video.bits->getBit()) {
1106 listPos++;
1107 continue;
1108 }
1109
1110 int ccoef = coefList[listPos];
1111 int mode = modeList[listPos];
1112
1113 switch (mode) {
1114 case 0:
1115 coefList[listPos] = ccoef + 4;
1116 modeList[listPos] = 1;
1117 // fall through
1118 case 2:
1119 if (mode == 2) {
1120 coefList[listPos] = 0;
1121 modeList[listPos++] = 0;
1122 }
1123 for (int i = 0; i < 4; i++, ccoef++) {
1124 if (video.bits->getBit()) {
1125 coefList[--listStart] = ccoef;
1126 modeList[ listStart] = 3;
1127 } else {
1128 int t;
1129 if (!bits) {
1130 t = 1 - (video.bits->getBit() << 1);
1131 } else {
1132 t = video.bits->getBits(bits) | mask;
1133
1134 int sign = -(int)video.bits->getBit();
1135 t = (t ^ sign) - sign;
1136 }
1137 block[binkScan[ccoef]] = t;
1138 coefIdx[coefCount++] = ccoef;
1139 }
1140 }
1141 break;
1142
1143 case 1:
1144 modeList[listPos] = 2;
1145 for (int i = 0; i < 3; i++) {
1146 ccoef += 4;
1147 coefList[listEnd] = ccoef;
1148 modeList[listEnd++] = 2;
1149 }
1150 break;
1151
1152 case 3:
1153 int t;
1154 if (!bits) {
1155 t = 1 - (video.bits->getBit() << 1);
1156 } else {
1157 t = video.bits->getBits(bits) | mask;
1158
1159 int sign = -(int)video.bits->getBit();
1160 t = (t ^ sign) - sign;
1161 }
1162 block[binkScan[ccoef]] = t;
1163 coefIdx[coefCount++] = ccoef;
1164 coefList[listPos] = 0;
1165 modeList[listPos++] = 0;
1166 break;
1167 }
1168 }
1169 }
1170
1171 uint8 quantIdx = video.bits->getBits(4);
1172 const int32 *quant = isIntra ? binkIntraQuant[quantIdx] : binkInterQuant[quantIdx];
1173 block[0] = (block[0] * quant[0]) >> 11;
1174
1175 for (int i = 0; i < coefCount; i++) {
1176 int idx = coefIdx[i];
1177 block[binkScan[idx]] = (block[binkScan[idx]] * quant[idx]) >> 11;
1178 }
1179
1180 }
1181
1182 /** Reads 8x8 block with residue after motion compensation. */
readResidue(VideoFrame & video,int16 * block,int masksCount)1183 void BinkDecoder::BinkVideoTrack::readResidue(VideoFrame &video, int16 *block, int masksCount) {
1184 int nzCoeff[64];
1185 int nzCoeffCount = 0;
1186
1187 int listStart = 64;
1188 int listEnd = 64;
1189
1190 int coefList[128]; int modeList[128];
1191 coefList[listEnd] = 4; modeList[listEnd++] = 0;
1192 coefList[listEnd] = 24; modeList[listEnd++] = 0;
1193 coefList[listEnd] = 44; modeList[listEnd++] = 0;
1194 coefList[listEnd] = 0; modeList[listEnd++] = 2;
1195
1196 for (int mask = 1 << video.bits->getBits(3); mask; mask >>= 1) {
1197
1198 for (int i = 0; i < nzCoeffCount; i++) {
1199 if (!video.bits->getBit())
1200 continue;
1201 if (block[nzCoeff[i]] < 0)
1202 block[nzCoeff[i]] -= mask;
1203 else
1204 block[nzCoeff[i]] += mask;
1205 masksCount--;
1206 if (masksCount < 0)
1207 return;
1208 }
1209
1210 int listPos = listStart;
1211 while (listPos < listEnd) {
1212
1213 if (!(coefList[listPos] | modeList[listPos]) || !video.bits->getBit()) {
1214 listPos++;
1215 continue;
1216 }
1217
1218 int ccoef = coefList[listPos];
1219 int mode = modeList[listPos];
1220
1221 switch (mode) {
1222 case 0:
1223 coefList[listPos] = ccoef + 4;
1224 modeList[listPos] = 1;
1225 // fall through
1226 case 2:
1227 if (mode == 2) {
1228 coefList[listPos] = 0;
1229 modeList[listPos++] = 0;
1230 }
1231
1232 for (int i = 0; i < 4; i++, ccoef++) {
1233 if (video.bits->getBit()) {
1234 coefList[--listStart] = ccoef;
1235 modeList[ listStart] = 3;
1236 } else {
1237 nzCoeff[nzCoeffCount++] = binkScan[ccoef];
1238
1239 int sign = -(int)video.bits->getBit();
1240 block[binkScan[ccoef]] = (mask ^ sign) - sign;
1241
1242 masksCount--;
1243 if (masksCount < 0)
1244 return;
1245 }
1246 }
1247 break;
1248
1249 case 1:
1250 modeList[listPos] = 2;
1251 for (int i = 0; i < 3; i++) {
1252 ccoef += 4;
1253 coefList[listEnd] = ccoef;
1254 modeList[listEnd++] = 2;
1255 }
1256 break;
1257
1258 case 3:
1259 nzCoeff[nzCoeffCount++] = binkScan[ccoef];
1260
1261 int sign = -(int)video.bits->getBit();
1262 block[binkScan[ccoef]] = (mask ^ sign) - sign;
1263
1264 coefList[listPos] = 0;
1265 modeList[listPos++] = 0;
1266 masksCount--;
1267 if (masksCount < 0)
1268 return;
1269 break;
1270 }
1271 }
1272 }
1273 }
1274
1275 #define A1 2896 /* (1/sqrt(2))<<12 */
1276 #define A2 2217
1277 #define A3 3784
1278 #define A4 -5352
1279
1280 #define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\
1281 const int a0 = (src)[s0] + (src)[s4]; \
1282 const int a1 = (src)[s0] - (src)[s4]; \
1283 const int a2 = (src)[s2] + (src)[s6]; \
1284 const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \
1285 const int a4 = (src)[s5] + (src)[s3]; \
1286 const int a5 = (src)[s5] - (src)[s3]; \
1287 const int a6 = (src)[s1] + (src)[s7]; \
1288 const int a7 = (src)[s1] - (src)[s7]; \
1289 const int b0 = a4 + a6; \
1290 const int b1 = (A3*(a5 + a7)) >> 11; \
1291 const int b2 = ((A4*a5) >> 11) - b0 + b1; \
1292 const int b3 = (A1*(a6 - a4) >> 11) - b2; \
1293 const int b4 = ((A2*a7) >> 11) + b3 - b1; \
1294 (dest)[d0] = munge(a0+a2 +b0); \
1295 (dest)[d1] = munge(a1+a3-a2+b2); \
1296 (dest)[d2] = munge(a1-a3+a2+b3); \
1297 (dest)[d3] = munge(a0-a2 -b4); \
1298 (dest)[d4] = munge(a0-a2 +b4); \
1299 (dest)[d5] = munge(a1-a3+a2-b3); \
1300 (dest)[d6] = munge(a1+a3-a2-b2); \
1301 (dest)[d7] = munge(a0+a2 -b0); \
1302 }
1303 /* end IDCT_TRANSFORM macro */
1304
1305 #define MUNGE_NONE(x) (x)
1306 #define IDCT_COL(dest,src) IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src)
1307
1308 #define MUNGE_ROW(x) (((x) + 0x7F)>>8)
1309 #define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src)
1310
IDCTCol(int32 * dest,const int32 * src)1311 static inline void IDCTCol(int32 *dest, const int32 *src) {
1312 if ((src[8] | src[16] | src[24] | src[32] | src[40] | src[48] | src[56]) == 0) {
1313 dest[ 0] =
1314 dest[ 8] =
1315 dest[16] =
1316 dest[24] =
1317 dest[32] =
1318 dest[40] =
1319 dest[48] =
1320 dest[56] = src[0];
1321 } else {
1322 IDCT_COL(dest, src);
1323 }
1324 }
1325
IDCT(int32 * block)1326 void BinkDecoder::BinkVideoTrack::IDCT(int32 *block) {
1327 int i;
1328 int32 temp[64];
1329
1330 for (i = 0; i < 8; i++)
1331 IDCTCol(&temp[i], &block[i]);
1332 for (i = 0; i < 8; i++) {
1333 IDCT_ROW( (&block[8*i]), (&temp[8*i]) );
1334 }
1335 }
1336
IDCTAdd(DecodeContext & ctx,int32 * block)1337 void BinkDecoder::BinkVideoTrack::IDCTAdd(DecodeContext &ctx, int32 *block) {
1338 int i, j;
1339
1340 IDCT(block);
1341 byte *dest = ctx.dest;
1342 for (i = 0; i < 8; i++, dest += ctx.pitch, block += 8)
1343 for (j = 0; j < 8; j++)
1344 dest[j] += block[j];
1345 }
1346
IDCTPut(DecodeContext & ctx,int32 * block)1347 void BinkDecoder::BinkVideoTrack::IDCTPut(DecodeContext &ctx, int32 *block) {
1348 int i;
1349 int32 temp[64];
1350 for (i = 0; i < 8; i++)
1351 IDCTCol(&temp[i], &block[i]);
1352 for (i = 0; i < 8; i++) {
1353 IDCT_ROW( (&ctx.dest[i*ctx.pitch]), (&temp[8*i]) );
1354 }
1355 }
1356
BinkAudioTrack(BinkDecoder::AudioInfo & audio,Audio::Mixer::SoundType soundType)1357 BinkDecoder::BinkAudioTrack::BinkAudioTrack(BinkDecoder::AudioInfo &audio, Audio::Mixer::SoundType soundType) :
1358 AudioTrack(soundType),
1359 _audioInfo(&audio) {
1360 _audioStream = Audio::makeQueuingAudioStream(_audioInfo->outSampleRate, _audioInfo->outChannels == 2);
1361 }
1362
~BinkAudioTrack()1363 BinkDecoder::BinkAudioTrack::~BinkAudioTrack() {
1364 delete _audioStream;
1365 }
1366
getAudioStream() const1367 Audio::AudioStream *BinkDecoder::BinkAudioTrack::getAudioStream() const {
1368 return _audioStream;
1369 }
1370
decodePacket()1371 void BinkDecoder::BinkAudioTrack::decodePacket() {
1372 int outSize = _audioInfo->frameLen * _audioInfo->channels;
1373
1374 while (_audioInfo->bits->pos() < _audioInfo->bits->size()) {
1375 int16 *out = (int16 *)malloc(outSize * 2);
1376 memset(out, 0, outSize * 2);
1377
1378 audioBlock(out);
1379
1380 byte flags = Audio::FLAG_16BITS;
1381 if (_audioInfo->outChannels == 2)
1382 flags |= Audio::FLAG_STEREO;
1383
1384 #ifdef SCUMM_LITTLE_ENDIAN
1385 flags |= Audio::FLAG_LITTLE_ENDIAN;
1386 #endif
1387
1388 _audioStream->queueBuffer((byte *)out, _audioInfo->blockSize * 2, DisposeAfterUse::YES, flags);
1389
1390 if (_audioInfo->bits->pos() & 0x1F) // next data block starts at a 32-byte boundary
1391 _audioInfo->bits->skip(32 - (_audioInfo->bits->pos() & 0x1F));
1392 }
1393 }
1394
audioBlock(int16 * out)1395 void BinkDecoder::BinkAudioTrack::audioBlock(int16 *out) {
1396 if (_audioInfo->codec == kAudioCodecDCT)
1397 audioBlockDCT ();
1398 else if (_audioInfo->codec == kAudioCodecRDFT)
1399 audioBlockRDFT();
1400
1401 floatToInt16Interleave(out, const_cast<const float **>(_audioInfo->coeffsPtr), _audioInfo->frameLen, _audioInfo->channels);
1402
1403 if (!_audioInfo->first) {
1404 int count = _audioInfo->overlapLen * _audioInfo->channels;
1405 int shift = Common::intLog2(count);
1406 for (int i = 0; i < count; i++) {
1407 out[i] = (_audioInfo->prevCoeffs[i] * (count - i) + out[i] * i) >> shift;
1408 }
1409 }
1410
1411 memcpy(_audioInfo->prevCoeffs, out + _audioInfo->blockSize, _audioInfo->overlapLen * _audioInfo->channels * sizeof(*out));
1412
1413 _audioInfo->first = false;
1414 }
1415
audioBlockDCT()1416 void BinkDecoder::BinkAudioTrack::audioBlockDCT() {
1417 _audioInfo->bits->skip(2);
1418
1419 for (uint8 i = 0; i < _audioInfo->channels; i++) {
1420 float *coeffs = _audioInfo->coeffsPtr[i];
1421
1422 readAudioCoeffs(coeffs);
1423
1424 coeffs[0] /= 0.5;
1425
1426 _audioInfo->dct->calc(coeffs);
1427
1428 for (uint32 j = 0; j < _audioInfo->frameLen; j++)
1429 coeffs[j] *= (_audioInfo->frameLen / 2.0);
1430 }
1431
1432 }
1433
audioBlockRDFT()1434 void BinkDecoder::BinkAudioTrack::audioBlockRDFT() {
1435 for (uint8 i = 0; i < _audioInfo->channels; i++) {
1436 float *coeffs = _audioInfo->coeffsPtr[i];
1437
1438 readAudioCoeffs(coeffs);
1439
1440 _audioInfo->rdft->calc(coeffs);
1441 }
1442 }
1443
1444 static const uint8 rleLengthTab[16] = {
1445 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64
1446 };
1447
readAudioCoeffs(float * coeffs)1448 void BinkDecoder::BinkAudioTrack::readAudioCoeffs(float *coeffs) {
1449 coeffs[0] = getFloat() * _audioInfo->root;
1450 coeffs[1] = getFloat() * _audioInfo->root;
1451
1452 float quant[25];
1453
1454 for (uint32 i = 0; i < _audioInfo->bandCount; i++) {
1455 int value = _audioInfo->bits->getBits(8);
1456
1457 // 0.066399999 / log10(M_E)
1458 quant[i] = exp(MIN(value, 95) * 0.15289164787221953823f) * _audioInfo->root;
1459 }
1460
1461 float q = 0.0;
1462
1463 // Find band (k)
1464 int k;
1465 for (k = 0; _audioInfo->bands[k] < 1; k++)
1466 q = quant[k];
1467
1468 // Parse coefficients
1469 uint32 i = 2;
1470 while (i < _audioInfo->frameLen) {
1471
1472 uint32 j = 0;
1473 if (_audioInfo->bits->getBit())
1474 j = i + rleLengthTab[_audioInfo->bits->getBits(4)] * 8;
1475 else
1476 j = i + 8;
1477
1478 j = MIN(j, _audioInfo->frameLen);
1479
1480 int width = _audioInfo->bits->getBits(4);
1481 if (width == 0) {
1482
1483 memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
1484 i = j;
1485 while (_audioInfo->bands[k] * 2 < i)
1486 q = quant[k++];
1487
1488 } else {
1489
1490 while (i < j) {
1491 if (_audioInfo->bands[k] * 2 == i)
1492 q = quant[k++];
1493
1494 int coeff = _audioInfo->bits->getBits(width);
1495 if (coeff) {
1496
1497 if (_audioInfo->bits->getBit())
1498 coeffs[i] = -q * coeff;
1499 else
1500 coeffs[i] = q * coeff;
1501
1502 } else {
1503 coeffs[i] = 0.0;
1504 }
1505 i++;
1506 }
1507
1508 }
1509
1510 }
1511
1512 }
1513
floatToInt16One(float src)1514 static inline int floatToInt16One(float src) {
1515 return (int16)CLIP<int>((int)floor(src + 0.5), -32768, 32767);
1516 }
1517
floatToInt16Interleave(int16 * dst,const float ** src,uint32 length,uint8 channels)1518 void BinkDecoder::BinkAudioTrack::floatToInt16Interleave(int16 *dst, const float **src, uint32 length, uint8 channels) {
1519 if (channels == 2) {
1520 for (uint32 i = 0; i < length; i++) {
1521 dst[2 * i ] = floatToInt16One(src[0][i]);
1522 dst[2 * i + 1] = floatToInt16One(src[1][i]);
1523 }
1524 } else {
1525 for(uint8 c = 0; c < channels; c++)
1526 for(uint32 i = 0, j = c; i < length; i++, j += channels)
1527 dst[j] = floatToInt16One(src[c][i]);
1528 }
1529 }
1530
getFloat()1531 float BinkDecoder::BinkAudioTrack::getFloat() {
1532 int power = _audioInfo->bits->getBits(5);
1533
1534 float f = ldexp((float)_audioInfo->bits->getBits(23), power - 23);
1535
1536 if (_audioInfo->bits->getBit())
1537 f = -f;
1538
1539 return f;
1540 }
1541
initAudioTrack(AudioInfo & audio)1542 void BinkDecoder::initAudioTrack(AudioInfo &audio) {
1543 audio.sampleCount = 0;
1544 audio.bits = 0;
1545
1546 audio.channels = ((audio.flags & kAudioFlagStereo) != 0) ? 2 : 1;
1547 audio.codec = ((audio.flags & kAudioFlagDCT ) != 0) ? kAudioCodecDCT : kAudioCodecRDFT;
1548
1549 if (audio.channels > kAudioChannelsMax)
1550 error("Too many audio channels: %d", audio.channels);
1551
1552 uint32 frameLenBits;
1553 // Calculate frame length
1554 if (audio.sampleRate < 22050)
1555 frameLenBits = 9;
1556 else if(audio.sampleRate < 44100)
1557 frameLenBits = 10;
1558 else
1559 frameLenBits = 11;
1560
1561 audio.frameLen = 1 << frameLenBits;
1562
1563 audio.outSampleRate = audio.sampleRate;
1564 audio.outChannels = audio.channels;
1565
1566 if (audio.codec == kAudioCodecRDFT) {
1567 // RDFT audio already interleaves the samples correctly
1568
1569 if (audio.channels == 2)
1570 frameLenBits++;
1571
1572 audio.sampleRate *= audio.channels;
1573 audio.frameLen *= audio.channels;
1574 audio.channels = 1;
1575 }
1576
1577 audio.overlapLen = audio.frameLen / 16;
1578 audio.blockSize = (audio.frameLen - audio.overlapLen) * audio.channels;
1579 audio.root = 2.0 / sqrt((double)audio.frameLen);
1580
1581 uint32 sampleRateHalf = (audio.sampleRate + 1) / 2;
1582
1583 // Calculate number of bands
1584 for (audio.bandCount = 1; audio.bandCount < 25; audio.bandCount++)
1585 if (sampleRateHalf <= binkCriticalFreqs[audio.bandCount - 1])
1586 break;
1587
1588 audio.bands = new uint32[audio.bandCount + 1];
1589
1590 // Populate bands
1591 audio.bands[0] = 1;
1592 for (uint32 i = 1; i < audio.bandCount; i++)
1593 audio.bands[i] = binkCriticalFreqs[i - 1] * (audio.frameLen / 2) / sampleRateHalf;
1594 audio.bands[audio.bandCount] = audio.frameLen / 2;
1595
1596 audio.first = true;
1597
1598 for (uint8 i = 0; i < audio.channels; i++)
1599 audio.coeffsPtr[i] = audio.coeffs + i * audio.frameLen;
1600
1601 audio.codec = ((audio.flags & kAudioFlagDCT) != 0) ? kAudioCodecDCT : kAudioCodecRDFT;
1602
1603 if (audio.codec == kAudioCodecRDFT)
1604 audio.rdft = new Common::RDFT(frameLenBits, Common::RDFT::DFT_C2R);
1605 else if (audio.codec == kAudioCodecDCT)
1606 audio.dct = new Common::DCT(frameLenBits, Common::DCT::DCT_III);
1607
1608 addTrack(new BinkAudioTrack(audio, getSoundType()));
1609 }
1610
1611 } // End of namespace Video
1612