xoreos  0.0.5
bink.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos 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 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos 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 xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 /* Based on the Bink implementation in FFmpeg (<https://ffmpeg.org/)>,
26  * which is released under the terms of version 2 or later of the GNU
27  * Lesser General Public License.
28  *
29  * The original copyright notes in the files
30  * - libavformat/bink.c
31  * - libavcodec/bink.c
32  * - libavcodec/binkdata.h
33  * - libavcodec/binkdsp.c
34  * - libavcodec/binkdsp.h
35  * - libavcodec/binkaudio.c
36  * read as follows:
37  *
38  * Bink demuxer
39  * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org)
40  * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
41  *
42  * Bink video decoder
43  * Copyright (c) 2009 Konstantin Shishkov
44  * Copyright (C) 2011 Peter Ross <pross@xvid.org>
45  *
46  * Bink video decoder
47  * Copyright (C) 2009 Konstantin Shishkov
48  *
49  * Bink DSP routines
50  * Copyright (c) 2009 Konstantin Shishkov
51  *
52  * Bink Audio decoder
53  * Copyright (c) 2007-2011 Peter Ross (pross@xvid.org)
54  * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
55  *
56  * FFmpeg is free software; you can redistribute it and/or
57  * modify it under the terms of the GNU Lesser General Public
58  * License as published by the Free Software Foundation; either
59  * version 2.1 of the License, or (at your option) any later version.
60  *
61  * FFmpeg is distributed in the hope that it will be useful,
62  * but WITHOUT ANY WARRANTY; without even the implied warranty of
63  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
64  * Lesser General Public License for more details.
65  *
66  * You should have received a copy of the GNU Lesser General Public
67  * License along with FFmpeg; if not, write to the Free Software
68  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
69  */
70 
71 #include <cassert>
72 #include <cmath>
73 #include <cstring>
74 
75 #include "src/common/util.h"
76 #include "src/common/error.h"
77 #include "src/common/maths.h"
79 #include "src/common/strutil.h"
80 #include "src/common/readstream.h"
81 #include "src/common/bitstream.h"
82 #include "src/common/huffman.h"
83 #include "src/common/rdft.h"
84 #include "src/common/dct.h"
85 
87 
89 
90 #include "src/sound/audiostream.h"
91 #include "src/sound/decoders/pcm.h"
93 
94 #include "src/video/bink.h"
95 #include "src/video/binkdata.h"
96 
97 static const uint32 kBIKfID = MKTAG('B', 'I', 'K', 'f');
98 static const uint32 kBIKgID = MKTAG('B', 'I', 'K', 'g');
99 static const uint32 kBIKhID = MKTAG('B', 'I', 'K', 'h');
100 static const uint32 kBIKiID = MKTAG('B', 'I', 'K', 'i');
101 
102 static const uint32 kBIKbID = MKTAG('B', 'I', 'K', 'b');
103 static const uint32 kBIKkID = MKTAG('B', 'I', 'K', 'k');
104 
105 static const uint32 kKB2aID = MKTAG('K', 'B', '2', 'a');
106 static const uint32 kKB2dID = MKTAG('K', 'B', '2', 'd');
107 static const uint32 kKB2fID = MKTAG('K', 'B', '2', 'f');
108 static const uint32 kKB2gID = MKTAG('K', 'B', '2', 'g');
109 static const uint32 kKB2hID = MKTAG('K', 'B', '2', 'h');
110 static const uint32 kKB2iID = MKTAG('K', 'B', '2', 'i');
111 static const uint32 kKB2jID = MKTAG('K', 'B', '2', 'j');
112 static const uint32 kKB2kID = MKTAG('K', 'B', '2', 'k');
113 
114 static const uint32 kVideoFlagAlpha = 0x00100000;
115 
116 static const uint16 kAudioFlagDCT = 0x1000;
117 static const uint16 kAudioFlagStereo = 0x2000;
118 
119 // Number of bits used to store first DC value in bundle
120 static const uint32 kDCStartBits = 11;
121 
122 namespace Video {
123 
125  for (size_t i = 0; i < 16; i++)
126  symbols[i] = i;
127 }
128 
129 
130 Bink::BinkVideoTrack::Bundle::Bundle() : countLength(0), dataEnd(0), curDec(0), curPtr(0) {
131  countLengths[0] = countLengths[1] = 0;
132 }
133 
134 
136 }
137 
139  delete bits;
140 }
141 
142 
143 Bink::AudioInfo::AudioInfo() : bands(0), rdft(0), dct(0) {
144 }
145 
147  delete[] bands;
148 
149  delete rdft;
150  delete dct;
151 }
152 
153 
155  assert(_bink);
156 
157  load();
158 }
159 
161 }
162 
164  BinkVideoTrack &videoTrack = static_cast<BinkVideoTrack &>(track);
165 
166  VideoFrame &frame = _frames[videoTrack.getCurFrame() + 1];
167 
168  _bink->seek(frame.offset);
169  uint32 frameSize = frame.size;
170 
171  // Skip over the audio tracks
172  for (size_t i = 0; i < _audioTracks.size(); i++) {
173  uint32 audioPacketLength = _bink->readUint32LE();
174  frameSize -= 4;
175 
176  if (audioPacketLength > frameSize)
177  throw Common::Exception("Audio packet too big for the frame");
178 
179  _bink->skip(audioPacketLength);
180  frameSize -= audioPacketLength;
181  }
182 
183  size_t videoPacketStart = _bink->pos();
184  size_t videoPacketEnd = _bink->pos() + frameSize;
185 
186  frame.bits =
188  videoPacketStart, videoPacketEnd), true);
189 
190  assert(_surface);
191  videoTrack.decodePacket(*_surface, frame);
192 
193  delete frame.bits;
194  frame.bits = 0;
195 
196  _needCopy = true;
197 }
198 
200  static_cast<BinkAudioTrack &>(track).decodeAudio(*_bink, _frames, _audioTracks, endTime);
201 }
202 
204  assert(video.bits);
205 
206  if (_hasAlpha) {
207  if (_id == kBIKiID)
208  video.bits->skip(32);
209 
210  decodePlane(video, 3, false);
211  }
212 
213  if (_id == kBIKiID)
214  video.bits->skip(32);
215 
216  for (int i = 0; i < 3; i++) {
217  int planeIdx = ((i == 0) || !_swapPlanes) ? i : (i ^ 3);
218 
219  decodePlane(video, planeIdx, i != 0);
220 
221  if (video.bits->pos() >= video.bits->size())
222  break;
223  }
224 
225  // Convert the YUVA data we have to BGRA
226  assert(_curPlanes[0] && _curPlanes[1] && _curPlanes[2] && _curPlanes[3]);
228  surface.getData(), surface.getWidth() * 4,
229  _curPlanes[0].get(), _curPlanes[1].get(), _curPlanes[2].get(), _curPlanes[3].get(),
230  _width, _height, _width, _width >> 1);
231 
232  // And swap the planes with the reference planes
233  for (int i = 0; i < 4; i++)
234  _oldPlanes[i].swap(_curPlanes[i]);
235 
236  _curFrame++;
237 }
238 
239 void Bink::BinkVideoTrack::decodePlane(VideoFrame &video, int planeIdx, bool isChroma) {
240  uint32 blockWidth = isChroma ? ((_width + 15) >> 4) : ((_width + 7) >> 3);
241  uint32 blockHeight = isChroma ? ((_height + 15) >> 4) : ((_height + 7) >> 3);
242  uint32 width = isChroma ? (_width >> 1) : _width;
243  uint32 height = isChroma ? (_height >> 1) : _height;
244 
245  DecodeContext ctx;
246 
247  ctx.video = &video;
248  ctx.planeIdx = planeIdx;
249  ctx.destStart = _curPlanes[planeIdx].get();
250  ctx.destEnd = _curPlanes[planeIdx].get() + width * height;
251  ctx.prevStart = _oldPlanes[planeIdx].get();
252  ctx.prevEnd = _oldPlanes[planeIdx].get() + width * height;
253  ctx.pitch = width;
254 
255  for (int i = 0; i < 64; i++) {
256  ctx.coordMap[i] = (i & 7) + (i >> 3) * ctx.pitch;
257 
258  ctx.coordScaledMap1[i] = ((i & 7) * 2 + 0) + (((i >> 3) * 2 + 0) * ctx.pitch);
259  ctx.coordScaledMap2[i] = ((i & 7) * 2 + 1) + (((i >> 3) * 2 + 0) * ctx.pitch);
260  ctx.coordScaledMap3[i] = ((i & 7) * 2 + 0) + (((i >> 3) * 2 + 1) * ctx.pitch);
261  ctx.coordScaledMap4[i] = ((i & 7) * 2 + 1) + (((i >> 3) * 2 + 1) * ctx.pitch);
262  }
263 
264  for (int i = 0; i < kSourceMAX; i++) {
265  _bundles[i].countLength = _bundles[i].countLengths[isChroma ? 1 : 0];
266 
267  readBundle(video, (Source) i);
268  }
269 
270  for (ctx.blockY = 0; ctx.blockY < blockHeight; ctx.blockY++) {
271  readBlockTypes (video, _bundles[kSourceBlockTypes]);
272  readBlockTypes (video, _bundles[kSourceSubBlockTypes]);
273  readColors (video, _bundles[kSourceColors]);
274  readPatterns (video, _bundles[kSourcePattern]);
275  readMotionValues(video, _bundles[kSourceXOff]);
276  readMotionValues(video, _bundles[kSourceYOff]);
277  readDCS (video, _bundles[kSourceIntraDC], kDCStartBits, false);
278  readDCS (video, _bundles[kSourceInterDC], kDCStartBits, true);
279  readRuns (video, _bundles[kSourceRun]);
280 
281  ctx.dest = ctx.destStart + 8 * ctx.blockY * ctx.pitch;
282  ctx.prev = ctx.prevStart + 8 * ctx.blockY * ctx.pitch;
283 
284  for (ctx.blockX = 0; ctx.blockX < blockWidth; ctx.blockX++, ctx.dest += 8, ctx.prev += 8) {
285  BlockType blockType = (BlockType) getBundleValue(kSourceBlockTypes);
286 
287  // 16x16 block type on odd line means part of the already decoded block, so skip it
288  if ((ctx.blockY & 1) && (blockType == kBlockScaled)) {
289  ctx.blockX += 1;
290  ctx.dest += 8;
291  ctx.prev += 8;
292  continue;
293  }
294 
295  switch (blockType) {
296  case kBlockSkip:
297  blockSkip(ctx);
298  break;
299 
300  case kBlockScaled:
301  blockScaled(ctx);
302  break;
303 
304  case kBlockMotion:
305  blockMotion(ctx);
306  break;
307 
308  case kBlockRun:
309  blockRun(ctx);
310  break;
311 
312  case kBlockResidue:
313  blockResidue(ctx);
314  break;
315 
316  case kBlockIntra:
317  blockIntra(ctx);
318  break;
319 
320  case kBlockFill:
321  blockFill(ctx);
322  break;
323 
324  case kBlockInter:
325  blockInter(ctx);
326  break;
327 
328  case kBlockPattern:
329  blockPattern(ctx);
330  break;
331 
332  case kBlockRaw:
333  blockRaw(ctx);
334  break;
335 
336  default:
337  throw Common::Exception("Unknown block type: %d", blockType);
338  }
339 
340  }
341 
342  }
343 
344  if (video.bits->pos() & 0x1F) // next plane data starts at 32-bit boundary
345  video.bits->skip(32 - (video.bits->pos() & 0x1F));
346 
347 }
348 
350  if (source == kSourceColors) {
351  for (int i = 0; i < 16; i++)
352  readHuffman(video, _colHighHuffman[i]);
353 
354  _colLastVal = 0;
355  }
356 
357  if ((source != kSourceIntraDC) && (source != kSourceInterDC))
358  readHuffman(video, _bundles[source].huffman);
359 
360  _bundles[source].curDec = _bundles[source].data.get();
361  _bundles[source].curPtr = _bundles[source].data.get();
362 }
363 
365  huffman.index = video.bits->getBits(4);
366 
367  if (huffman.index == 0) {
368  // The first tree always gives raw nibbles
369 
370  for (int i = 0; i < 16; i++)
371  huffman.symbols[i] = i;
372 
373  return;
374  }
375 
376  byte hasSymbol[16];
377 
378  if (video.bits->getBit()) {
379  // Symbol selection
380 
381  std::memset(hasSymbol, 0, 16);
382 
383  uint8 length = video.bits->getBits(3);
384  for (int i = 0; i <= length; i++) {
385  huffman.symbols[i] = video.bits->getBits(4);
386  hasSymbol[huffman.symbols[i]] = 1;
387  }
388 
389  for (int i = 0; i < 16; i++)
390  if (hasSymbol[i] == 0)
391  huffman.symbols[++length] = i;
392 
393  return;
394  }
395 
396  // Symbol shuffling
397 
398  byte tmp1[16], tmp2[16];
399  byte *in = tmp1, *out = tmp2;
400 
401  uint8 depth = video.bits->getBits(2);
402 
403  for (int i = 0; i < 16; i++)
404  in[i] = i;
405 
406  for (int i = 0; i <= depth; i++) {
407  int size = 1 << i;
408 
409  for (int j = 0; j < 16; j += (size << 1))
410  mergeHuffmanSymbols(video, out + j, in + j, size);
411 
412  SWAP(in, out);
413  }
414 
415  std::memcpy(huffman.symbols, in, 16);
416 }
417 
418 void Bink::BinkVideoTrack::mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size) {
419  const byte *src2 = src + size;
420  int size2 = size;
421 
422  do {
423  if (!video.bits->getBit()) {
424  *dst++ = *src++;
425  size--;
426  } else {
427  *dst++ = *src2++;
428  size2--;
429  }
430 
431  } while (size && size2);
432 
433  while (size--)
434  *dst++ = *src++;
435  while (size2--)
436  *dst++ = *src2++;
437 }
438 
439 void Bink::load() {
440  uint32 id = _bink->readUint32BE();
441  if ((id == kKB2aID) || (id == kKB2dID) || (id == kKB2fID) || (id == kKB2gID) ||
442  (id == kKB2hID) || (id == kKB2iID) || (id == kKB2jID) || (id == kKB2kID))
443  throw Common::Exception("Bink 2 (%s) is not supported", Common::debugTag(id).c_str());
444  if ((id == kBIKbID) || (id == kBIKkID))
445  throw Common::Exception("Untested Bink version %s", Common::debugTag(id).c_str());
446  if ((id != kBIKfID) && (id != kBIKgID) && (id != kBIKhID) && (id != kBIKiID))
447  throw Common::Exception("Unknown Bink FourCC %s", Common::debugTag(id).c_str());
448 
449  uint32 fileSize = _bink->readUint32LE() + 8;
450  uint32 frameCount = _bink->readUint32LE();
451  uint32 largestFrameSize = _bink->readUint32LE();
452 
453  if (largestFrameSize > fileSize)
454  throw Common::Exception("Largest frame size greater than file size");
455 
456  _bink->skip(4);
457 
458  uint32 width = _bink->readUint32LE();
459  uint32 height = _bink->readUint32LE();
460 
461  uint32 fpsNum = _bink->readUint32LE();
462  uint32 fpsDen = _bink->readUint32LE();
463 
464  if ((fpsNum == 0) || (fpsDen == 0))
465  throw Common::Exception("Invalid FPS (%d/%d)", fpsNum, fpsDen);
466 
467  uint32 videoFlags = _bink->readUint32LE();
468 
469  addTrack(new BinkVideoTrack(width, height, frameCount, Common::Rational(fpsNum, fpsDen), (id == kBIKhID || id == kBIKiID), (videoFlags & kVideoFlagAlpha) != 0, id));
470 
471  uint32 audioTrackCount = _bink->readUint32LE();
472 
473  if (audioTrackCount > 1) {
474  warning("More than one audio track found. Using the first one");
475 
476  _audioTrack = 0;
477  }
478 
479  if (audioTrackCount > 0) {
480  _audioTracks.resize(audioTrackCount);
481 
482  _bink->skip(4 * audioTrackCount);
483 
484  // Reading audio track properties
485  for (uint32 i = 0; i < audioTrackCount; i++) {
486  AudioInfo &track = _audioTracks[i];
487 
488  track.sampleRate = _bink->readUint16LE();
489  track.flags = _bink->readUint16LE();
490 
491  initAudioTrack(track);
492  }
493 
494  _bink->skip(4 * audioTrackCount);
495  }
496 
497  // Reading video frame properties
498  _frames.resize(frameCount);
499  for (uint32 i = 0; i < frameCount; i++) {
500  _frames[i].offset = _bink->readUint32LE();
501  _frames[i].keyFrame = _frames[i].offset & 1;
502 
503  _frames[i].offset &= ~1;
504 
505  if (i != 0)
506  _frames[i - 1].size = _frames[i].offset - _frames[i - 1].offset;
507 
508  _frames[i].bits = 0;
509  }
510 
511  _frames[frameCount - 1].size = _bink->size() - _frames[frameCount - 1].offset;
512 
513  initVideo();
514 
515  if (_audioTrack < _audioTracks.size())
517 }
518 
520  audio.channels = ((audio.flags & kAudioFlagStereo) != 0) ? 2 : 1;
521  audio.codec = ((audio.flags & kAudioFlagDCT ) != 0) ? kAudioCodecDCT : kAudioCodecRDFT;
522 
523  if (audio.channels > kAudioChannelsMax)
524  throw Common::Exception("Too many audio channels: %d", audio.channels);
525 
526  uint32 frameLenBits;
527  // Calculate frame length
528  if (audio.sampleRate < 22050)
529  frameLenBits = 9;
530  else if (audio.sampleRate < 44100)
531  frameLenBits = 10;
532  else
533  frameLenBits = 11;
534 
535  audio.frameLen = 1 << frameLenBits;
536 
537  audio.outSampleRate = audio.sampleRate;
538  audio.outChannels = audio.channels;
539 
540  if (audio.codec == kAudioCodecRDFT) {
541  // RDFT audio already interleaves the samples correctly
542 
543  if (audio.channels == 2)
544  frameLenBits++;
545 
546  audio.sampleRate *= audio.channels;
547  audio.frameLen *= audio.channels;
548  audio.channels = 1;
549  }
550 
551  audio.overlapLen = audio.frameLen / 16;
552  audio.blockSize = (audio.frameLen - audio.overlapLen) * audio.channels;
553  audio.root = 2.0 / sqrt((double) audio.frameLen);
554 
555  uint32 sampleRateHalf = (audio.sampleRate + 1) / 2;
556 
557  // Calculate number of bands
558  for (audio.bandCount = 1; audio.bandCount < 25; audio.bandCount++)
559  if (sampleRateHalf <= binkCriticalFreqs[audio.bandCount - 1])
560  break;
561 
562  audio.bands = new uint32[audio.bandCount + 1];
563 
564  // Populate bands
565  audio.bands[0] = 1;
566  for (uint32 i = 1; i < audio.bandCount; i++)
567  audio.bands[i] = binkCriticalFreqs[i - 1] * (audio.frameLen / 2) / sampleRateHalf;
568  audio.bands[audio.bandCount] = audio.frameLen / 2;
569 
570  audio.first = true;
571 
572  for (uint8 i = 0; i < audio.channels; i++)
573  audio.coeffsPtr[i] = audio.coeffs + i * audio.frameLen;
574 
575  audio.codec = ((audio.flags & kAudioFlagDCT) != 0) ? kAudioCodecDCT : kAudioCodecRDFT;
576 
577  if (audio.codec == kAudioCodecRDFT)
578  audio.rdft = new Common::RDFT(frameLenBits, Common::RDFT::DFT_C2R);
579  else if (audio.codec == kAudioCodecDCT)
580  audio.dct = new Common::DCT(frameLenBits, Common::DCT::DCT_III);
581 }
582 
584  uint32 bw = (_width + 7) >> 3;
585  uint32 bh = (_height + 7) >> 3;
586  uint32 blocks = bw * bh;
587 
588  for (int i = 0; i < kSourceMAX; i++) {
589  _bundles[i].data.reset(new byte[blocks * 64]);
590  _bundles[i].dataEnd = _bundles[i].data.get() + blocks * 64;
591  }
592 
593  uint32 cbw[2] = { (_width + 7) >> 3, (_width + 15) >> 4 };
594  uint32 cw [2] = { _width , _width >> 1 };
595 
596  // Calculate the lengths of an element count in bits
597  for (int i = 0; i < 2; i++) {
598  int width = MAX<uint32>(cw[i], 8);
599 
600  _bundles[kSourceBlockTypes ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
601  _bundles[kSourceSubBlockTypes].countLengths[i] = Common::intLog2(((width + 7) >> 4) + 511) + 1;
602  _bundles[kSourceColors ].countLengths[i] = Common::intLog2((cbw[i]) * 64 + 511) + 1;
603  _bundles[kSourceIntraDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
604  _bundles[kSourceInterDC ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
605  _bundles[kSourceXOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
606  _bundles[kSourceYOff ].countLengths[i] = Common::intLog2((width >> 3) + 511) + 1;
607  _bundles[kSourcePattern ].countLengths[i] = Common::intLog2((cbw[i] << 3) + 511) + 1;
608  _bundles[kSourceRun ].countLengths[i] = Common::intLog2((cbw[i]) * 48 + 511) + 1;
609  }
610 }
611 
613  for (int i = 0; i < 16; i++)
614  _huffman[i].reset(new Common::Huffman(binkHuffmanLengths[i][15], 16, binkHuffmanCodes[i], binkHuffmanLengths[i]));
615 }
616 
618  return huffman.symbols[_huffman[huffman.index]->getSymbol(*video.bits)];
619 }
620 
622  if ((source < kSourceXOff) || (source == kSourceRun))
623  return *_bundles[source].curPtr++;
624 
625  if ((source == kSourceXOff) || (source == kSourceYOff))
626  return (int8) *_bundles[source].curPtr++;
627 
628  int16 ret = *reinterpret_cast<int16 *>(_bundles[source].curPtr);
629 
630  _bundles[source].curPtr += 2;
631 
632  return ret;
633 }
634 
636  if (!bundle.curDec || (bundle.curDec > bundle.curPtr))
637  return 0;
638 
639  uint32 n = video.bits->getBits(bundle.countLength);
640  if (n == 0)
641  bundle.curDec = 0;
642 
643  return n;
644 }
645 
647  byte *dest = ctx.dest;
648  byte *prev = ctx.prev;
649 
650  for (int j = 0; j < 8; j++, dest += ctx.pitch, prev += ctx.pitch)
651  std::memcpy(dest, prev, 8);
652 }
653 
655  byte *dest = ctx.dest;
656  byte *prev = ctx.prev;
657 
658  for (int j = 0; j < 16; j++, dest += ctx.pitch, prev += ctx.pitch)
659  std::memcpy(dest, prev, 16);
660 }
661 
663  const uint8 *scan = binkPatterns[ctx.video->bits->getBits(4)];
664 
665  int i = 0;
666  do {
667  int run = getBundleValue(kSourceRun) + 1;
668 
669  i += run;
670  if (i > 64)
671  throw Common::Exception("Run went out of bounds");
672 
673  if (ctx.video->bits->getBit()) {
674 
675  byte v = getBundleValue(kSourceColors);
676  for (int j = 0; j < run; j++, scan++)
677  ctx.dest[ctx.coordScaledMap1[*scan]] =
678  ctx.dest[ctx.coordScaledMap2[*scan]] =
679  ctx.dest[ctx.coordScaledMap3[*scan]] =
680  ctx.dest[ctx.coordScaledMap4[*scan]] = v;
681 
682  } else
683  for (int j = 0; j < run; j++, scan++)
684  ctx.dest[ctx.coordScaledMap1[*scan]] =
685  ctx.dest[ctx.coordScaledMap2[*scan]] =
686  ctx.dest[ctx.coordScaledMap3[*scan]] =
687  ctx.dest[ctx.coordScaledMap4[*scan]] = getBundleValue(kSourceColors);
688 
689  } while (i < 63);
690 
691  if (i == 63)
692  ctx.dest[ctx.coordScaledMap1[*scan]] =
693  ctx.dest[ctx.coordScaledMap2[*scan]] =
694  ctx.dest[ctx.coordScaledMap3[*scan]] =
695  ctx.dest[ctx.coordScaledMap4[*scan]] = getBundleValue(kSourceColors);
696 }
697 
699  int16 block[64];
700  std::memset(block, 0, 64 * sizeof(int16));
701 
702  block[0] = getBundleValue(kSourceIntraDC);
703 
704  readDCTCoeffs(*ctx.video, block, true);
705 
706  IDCT(block);
707 
708  int16 *src = block;
709  byte *dest1 = ctx.dest;
710  byte *dest2 = ctx.dest + ctx.pitch;
711  for (int j = 0; j < 8; j++, dest1 += (ctx.pitch << 1) - 16, dest2 += (ctx.pitch << 1) - 16, src += 8) {
712 
713  for (int i = 0; i < 8; i++, dest1 += 2, dest2 += 2)
714  dest1[0] = dest1[1] = dest2[0] = dest2[1] = src[i];
715 
716  }
717 }
718 
720  byte v = getBundleValue(kSourceColors);
721 
722  byte *dest = ctx.dest;
723  for (int i = 0; i < 16; i++, dest += ctx.pitch)
724  std::memset(dest, v, 16);
725 }
726 
728  byte col[2];
729 
730  for (int i = 0; i < 2; i++)
731  col[i] = getBundleValue(kSourceColors);
732 
733  byte *dest1 = ctx.dest;
734  byte *dest2 = ctx.dest + ctx.pitch;
735  for (int j = 0; j < 8; j++, dest1 += (ctx.pitch << 1) - 16, dest2 += (ctx.pitch << 1) - 16) {
736  byte v = getBundleValue(kSourcePattern);
737 
738  for (int i = 0; i < 8; i++, dest1 += 2, dest2 += 2, v >>= 1)
739  dest1[0] = dest1[1] = dest2[0] = dest2[1] = col[v & 1];
740  }
741 }
742 
744  byte row[8];
745 
746  byte *dest1 = ctx.dest;
747  byte *dest2 = ctx.dest + ctx.pitch;
748  for (int j = 0; j < 8; j++, dest1 += (ctx.pitch << 1) - 16, dest2 += (ctx.pitch << 1) - 16) {
749  std::memcpy(row, _bundles[kSourceColors].curPtr, 8);
750 
751  for (int i = 0; i < 8; i++, dest1 += 2, dest2 += 2)
752  dest1[0] = dest1[1] = dest2[0] = dest2[1] = row[i];
753 
754  _bundles[kSourceColors].curPtr += 8;
755  }
756 }
757 
759  BlockType blockType = (BlockType) getBundleValue(kSourceSubBlockTypes);
760 
761  switch (blockType) {
762  case kBlockRun:
763  blockScaledRun(ctx);
764  break;
765 
766  case kBlockIntra:
767  blockScaledIntra(ctx);
768  break;
769 
770  case kBlockFill:
771  blockScaledFill(ctx);
772  break;
773 
774  case kBlockPattern:
775  blockScaledPattern(ctx);
776  break;
777 
778  case kBlockRaw:
779  blockScaledRaw(ctx);
780  break;
781 
782  default:
783  throw Common::Exception("Invalid 16x16 block type: %d", blockType);
784  }
785 
786  ctx.blockX += 1;
787  ctx.dest += 8;
788  ctx.prev += 8;
789 }
790 
792  int8 xOff = getBundleValue(kSourceXOff);
793  int8 yOff = getBundleValue(kSourceYOff);
794 
795  byte *dest = ctx.dest;
796  byte *prev = ctx.prev + yOff * ((int32) ctx.pitch) + xOff;
797  if ((prev < ctx.prevStart) || (prev > ctx.prevEnd))
798  throw Common::Exception("Copy out of bounds (%d | %d)", ctx.blockX * 8 + xOff, ctx.blockY * 8 + yOff);
799 
800  for (int j = 0; j < 8; j++, dest += ctx.pitch, prev += ctx.pitch)
801  std::memcpy(dest, prev, 8);
802 }
803 
805  const uint8 *scan = binkPatterns[ctx.video->bits->getBits(4)];
806 
807  int i = 0;
808  do {
809  int run = getBundleValue(kSourceRun) + 1;
810 
811  i += run;
812  if (i > 64)
813  throw Common::Exception("Run went out of bounds");
814 
815  if (ctx.video->bits->getBit()) {
816 
817  byte v = getBundleValue(kSourceColors);
818  for (int j = 0; j < run; j++)
819  ctx.dest[ctx.coordMap[*scan++]] = v;
820 
821  } else
822  for (int j = 0; j < run; j++)
823  ctx.dest[ctx.coordMap[*scan++]] = getBundleValue(kSourceColors);
824 
825  } while (i < 63);
826 
827  if (i == 63)
828  ctx.dest[ctx.coordMap[*scan++]] = getBundleValue(kSourceColors);
829 }
830 
832  blockMotion(ctx);
833 
834  byte v = ctx.video->bits->getBits(7);
835 
836  int16 block[64];
837  std::memset(block, 0, 64 * sizeof(int16));
838 
839  readResidue(*ctx.video, block, v);
840 
841  byte *dst = ctx.dest;
842  int16 *src = block;
843  for (int i = 0; i < 8; i++, dst += ctx.pitch, src += 8)
844  for (int j = 0; j < 8; j++)
845  dst[j] += src[j];
846 }
847 
849  int16 block[64];
850  std::memset(block, 0, 64 * sizeof(int16));
851 
852  block[0] = getBundleValue(kSourceIntraDC);
853 
854  readDCTCoeffs(*ctx.video, block, true);
855 
856  IDCTPut(ctx, block);
857 }
858 
860  byte v = getBundleValue(kSourceColors);
861 
862  byte *dest = ctx.dest;
863  for (int i = 0; i < 8; i++, dest += ctx.pitch)
864  std::memset(dest, v, 8);
865 }
866 
868  blockMotion(ctx);
869 
870  int16 block[64];
871  std::memset(block, 0, 64 * sizeof(int16));
872 
873  block[0] = getBundleValue(kSourceInterDC);
874 
875  readDCTCoeffs(*ctx.video, block, false);
876 
877  IDCTAdd(ctx, block);
878 }
879 
881  byte col[2];
882 
883  for (int i = 0; i < 2; i++)
884  col[i] = getBundleValue(kSourceColors);
885 
886  byte *dest = ctx.dest;
887  for (int i = 0; i < 8; i++, dest += ctx.pitch - 8) {
888  byte v = getBundleValue(kSourcePattern);
889 
890  for (int j = 0; j < 8; j++, v >>= 1)
891  *dest++ = col[v & 1];
892  }
893 }
894 
896  byte *dest = ctx.dest;
897  byte *data = _bundles[kSourceColors].curPtr;
898  for (int i = 0; i < 8; i++, dest += ctx.pitch, data += 8)
899  std::memcpy(dest, data, 8);
900 
901  _bundles[kSourceColors].curPtr += 64;
902 }
903 
905  uint32 n = readBundleCount(video, bundle);
906  if (n == 0)
907  return;
908 
909  byte *decEnd = bundle.curDec + n;
910  if (decEnd > bundle.dataEnd)
911  throw Common::Exception("Run value went out of bounds");
912 
913  if (video.bits->getBit()) {
914  byte v = video.bits->getBits(4);
915 
916  std::memset(bundle.curDec, v, n);
917  bundle.curDec += n;
918 
919  } else
920  while (bundle.curDec < decEnd)
921  *bundle.curDec++ = getHuffmanSymbol(video, bundle.huffman);
922 }
923 
925  uint32 n = readBundleCount(video, bundle);
926  if (n == 0)
927  return;
928 
929  byte *decEnd = bundle.curDec + n;
930  if (decEnd > bundle.dataEnd)
931  throw Common::Exception("Too many motion values");
932 
933  if (video.bits->getBit()) {
934  byte v = video.bits->getBits(4);
935 
936  if (v) {
937  int sign = -((int)video.bits->getBit());
938  v = (v ^ sign) - sign;
939  }
940 
941  std::memset(bundle.curDec, v, n);
942 
943  bundle.curDec += n;
944  return;
945  }
946 
947  do {
948  byte v = getHuffmanSymbol(video, bundle.huffman);
949 
950  if (v) {
951  int sign = -((int)video.bits->getBit());
952  v = (v ^ sign) - sign;
953  }
954 
955  *bundle.curDec++ = v;
956 
957  } while (bundle.curDec < decEnd);
958 }
959 
960 const uint8 rleLens[4] = { 4, 8, 12, 32 };
962  uint32 n = readBundleCount(video, bundle);
963  if (n == 0)
964  return;
965 
966  byte *decEnd = bundle.curDec + n;
967  if (decEnd > bundle.dataEnd)
968  throw Common::Exception("Too many block type values");
969 
970  if (video.bits->getBit()) {
971  byte v = video.bits->getBits(4);
972 
973  std::memset(bundle.curDec, v, n);
974 
975  bundle.curDec += n;
976  return;
977  }
978 
979  byte last = 0;
980  do {
981 
982  byte v = getHuffmanSymbol(video, bundle.huffman);
983 
984  if (v < 12) {
985  last = v;
986  *bundle.curDec++ = v;
987  } else {
988  int run = rleLens[v - 12];
989 
990  std::memset(bundle.curDec, last, run);
991 
992  bundle.curDec += run;
993  }
994 
995  } while (bundle.curDec < decEnd);
996 }
997 
999  uint32 n = readBundleCount(video, bundle);
1000  if (n == 0)
1001  return;
1002 
1003  byte *decEnd = bundle.curDec + n;
1004  if (decEnd > bundle.dataEnd)
1005  throw Common::Exception("Too many pattern values");
1006 
1007  byte v;
1008  while (bundle.curDec < decEnd) {
1009  v = getHuffmanSymbol(video, bundle.huffman);
1010  v |= getHuffmanSymbol(video, bundle.huffman) << 4;
1011  *bundle.curDec++ = v;
1012  }
1013 }
1014 
1015 
1017  uint32 n = readBundleCount(video, bundle);
1018  if (n == 0)
1019  return;
1020 
1021  byte *decEnd = bundle.curDec + n;
1022  if (decEnd > bundle.dataEnd)
1023  throw Common::Exception("Too many color values");
1024 
1025  if (video.bits->getBit()) {
1026  _colLastVal = getHuffmanSymbol(video, _colHighHuffman[_colLastVal]);
1027 
1028  byte v;
1029  v = getHuffmanSymbol(video, bundle.huffman);
1030  v = (_colLastVal << 4) | v;
1031 
1032  if (_id != kBIKiID) {
1033  int sign = ((int8) v) >> 7;
1034  v = ((v & 0x7F) ^ sign) - sign;
1035  v += 0x80;
1036  }
1037 
1038  std::memset(bundle.curDec, v, n);
1039  bundle.curDec += n;
1040 
1041  return;
1042  }
1043 
1044  while (bundle.curDec < decEnd) {
1045  _colLastVal = getHuffmanSymbol(video, _colHighHuffman[_colLastVal]);
1046 
1047  byte v;
1048  v = getHuffmanSymbol(video, bundle.huffman);
1049  v = (_colLastVal << 4) | v;
1050 
1051  if (_id != kBIKiID) {
1052  int sign = ((int8) v) >> 7;
1053  v = ((v & 0x7F) ^ sign) - sign;
1054  v += 0x80;
1055  }
1056  *bundle.curDec++ = v;
1057  }
1058 }
1059 
1060 void Bink::BinkVideoTrack::readDCS(VideoFrame &video, Bundle &bundle, int startBits, bool hasSign) {
1061  uint32 length = readBundleCount(video, bundle);
1062  if (length == 0)
1063  return;
1064 
1065  int16 *dest = reinterpret_cast<int16 *>(bundle.curDec);
1066 
1067  int32 v = video.bits->getBits(startBits - (hasSign ? 1 : 0));
1068  if (v && hasSign) {
1069  int sign = -((int)video.bits->getBit());
1070  v = (v ^ sign) - sign;
1071  }
1072 
1073  *dest++ = v;
1074  length--;
1075 
1076  for (uint32 i = 0; i < length; i += 8) {
1077  uint32 length2 = MIN<uint32>(length - i, 8);
1078 
1079  byte bSize = video.bits->getBits(4);
1080 
1081  if (bSize) {
1082 
1083  for (uint32 j = 0; j < length2; j++) {
1084  int16 v2 = video.bits->getBits(bSize);
1085  if (v2) {
1086  int sign = -((int)video.bits->getBit());
1087  v2 = (v2 ^ sign) - sign;
1088  }
1089 
1090  v += v2;
1091  *dest++ = v;
1092 
1093  if ((v < -32768) || (v > 32767))
1094  throw Common::Exception("DC value went out of bounds: %d", v);
1095  }
1096 
1097  } else
1098  for (uint32 j = 0; j < length2; j++)
1099  *dest++ = v;
1100  }
1101 
1102  bundle.curDec = reinterpret_cast<byte *>(dest);
1103 }
1104 
1105 /* WORKAROUND: This fixes the NWN2 WotC logo.
1106  * [cf. ffmpeg 47b71eea099b3fe2c7e16644878ad9b7067974e3] */
1107 static inline int16 dequant(int16 in, uint32 quant, bool dc) {
1108  /* Note: multiplication is unsigned but we want signed shift
1109  * otherwise clipping breaks.
1110  *
1111  * TODO: The official decoder does not use clipping at all
1112  * but instead uses the full 32-bit result.
1113  * However clipping at least gets rid of the case that a
1114  * half-black half-white intra block gets black and white swapped
1115  * and should cause at most minor differences (except for DC).
1116  */
1117 
1118  int32 res = ((int32) (in * quant)) >> 11;
1119  if (!dc)
1120  res = CLIP(res, -32768, 32767);
1121 
1122  return res;
1123 }
1124 
1126 void Bink::BinkVideoTrack::readDCTCoeffs(VideoFrame &video, int16 *block, bool isIntra) {
1127  int coefCount = 0;
1128  int coefIdx[64];
1129 
1130  int listStart = 64;
1131  int listEnd = 64;
1132 
1133  int coefList[128]; int modeList[128];
1134  coefList[listEnd] = 4; modeList[listEnd++] = 0;
1135  coefList[listEnd] = 24; modeList[listEnd++] = 0;
1136  coefList[listEnd] = 44; modeList[listEnd++] = 0;
1137  coefList[listEnd] = 1; modeList[listEnd++] = 3;
1138  coefList[listEnd] = 2; modeList[listEnd++] = 3;
1139  coefList[listEnd] = 3; modeList[listEnd++] = 3;
1140 
1141  int bits = video.bits->getBits(4) - 1;
1142  for (int mask = 1 << (MAX<int>(bits, 0)); bits >= 0; mask >>= 1, bits--) {
1143  int listPos = listStart;
1144 
1145  while (listPos < listEnd) {
1146 
1147  if (!(modeList[listPos] | coefList[listPos]) || !video.bits->getBit()) {
1148  listPos++;
1149  continue;
1150  }
1151 
1152  int ccoef = coefList[listPos];
1153  int mode = modeList[listPos];
1154 
1155  switch (mode) {
1156  case 0:
1157  coefList[listPos] = ccoef + 4;
1158  modeList[listPos] = 1;
1160  case 2:
1161  if (mode == 2) {
1162  coefList[listPos] = 0;
1163  modeList[listPos++] = 0;
1164  }
1165  for (int i = 0; i < 4; i++, ccoef++) {
1166  if (video.bits->getBit()) {
1167  coefList[--listStart] = ccoef;
1168  modeList[ listStart] = 3;
1169  } else {
1170  int t;
1171  if (!bits) {
1172  t = 1 - (video.bits->getBit() << 1);
1173  } else {
1174  t = video.bits->getBits(bits) | mask;
1175 
1176  int sign = -((int)video.bits->getBit());
1177  t = (t ^ sign) - sign;
1178  }
1179  block[binkScan[ccoef]] = t;
1180  coefIdx[coefCount++] = ccoef;
1181  }
1182  }
1183  break;
1184 
1185  case 1:
1186  modeList[listPos] = 2;
1187  for (int i = 0; i < 3; i++) {
1188  ccoef += 4;
1189  coefList[listEnd] = ccoef;
1190  modeList[listEnd++] = 2;
1191  }
1192  break;
1193 
1194  case 3:
1195  int t;
1196  if (!bits) {
1197  t = 1 - (video.bits->getBit() << 1);
1198  } else {
1199  t = video.bits->getBits(bits) | mask;
1200 
1201  int sign = -((int)video.bits->getBit());
1202  t = (t ^ sign) - sign;
1203  }
1204  block[binkScan[ccoef]] = t;
1205  coefIdx[coefCount++] = ccoef;
1206  coefList[listPos] = 0;
1207  modeList[listPos++] = 0;
1208  break;
1209  }
1210  }
1211  }
1212 
1213  uint8 quantIdx = video.bits->getBits(4);
1214  const uint32 *quant = isIntra ? binkIntraQuant[quantIdx] : binkInterQuant[quantIdx];
1215  block[0] = dequant(block[0], quant[0], true);
1216 
1217  for (int i = 0; i < coefCount; i++) {
1218  int idx = coefIdx[i];
1219  block[binkScan[idx]] = dequant(block[binkScan[idx]], quant[idx], false);
1220  }
1221 
1222 }
1223 
1225 void Bink::BinkVideoTrack::readResidue(VideoFrame &video, int16 *block, int masksCount) {
1226  int nzCoeff[64];
1227  int nzCoeffCount = 0;
1228 
1229  int listStart = 64;
1230  int listEnd = 64;
1231 
1232  int coefList[128]; int modeList[128];
1233  coefList[listEnd] = 4; modeList[listEnd++] = 0;
1234  coefList[listEnd] = 24; modeList[listEnd++] = 0;
1235  coefList[listEnd] = 44; modeList[listEnd++] = 0;
1236  coefList[listEnd] = 0; modeList[listEnd++] = 2;
1237 
1238  for (int mask = 1 << video.bits->getBits(3); mask; mask >>= 1) {
1239 
1240  for (int i = 0; i < nzCoeffCount; i++) {
1241  if (!video.bits->getBit())
1242  continue;
1243  if (block[nzCoeff[i]] < 0)
1244  block[nzCoeff[i]] -= mask;
1245  else
1246  block[nzCoeff[i]] += mask;
1247  masksCount--;
1248  if (masksCount < 0)
1249  return;
1250  }
1251 
1252  int listPos = listStart;
1253  while (listPos < listEnd) {
1254 
1255  if (!(coefList[listPos] | modeList[listPos]) || !video.bits->getBit()) {
1256  listPos++;
1257  continue;
1258  }
1259 
1260  int ccoef = coefList[listPos];
1261  int mode = modeList[listPos];
1262 
1263  switch (mode) {
1264  case 0:
1265  coefList[listPos] = ccoef + 4;
1266  modeList[listPos] = 1;
1268  case 2:
1269  if (mode == 2) {
1270  coefList[listPos] = 0;
1271  modeList[listPos++] = 0;
1272  }
1273 
1274  for (int i = 0; i < 4; i++, ccoef++) {
1275  if (video.bits->getBit()) {
1276  coefList[--listStart] = ccoef;
1277  modeList[ listStart] = 3;
1278  } else {
1279  nzCoeff[nzCoeffCount++] = binkScan[ccoef];
1280 
1281  int sign = -((int)video.bits->getBit());
1282  block[binkScan[ccoef]] = (mask ^ sign) - sign;
1283 
1284  masksCount--;
1285  if (masksCount < 0)
1286  return;
1287  }
1288  }
1289  break;
1290 
1291  case 1:
1292  modeList[listPos] = 2;
1293  for (int i = 0; i < 3; i++) {
1294  ccoef += 4;
1295  coefList[listEnd] = ccoef;
1296  modeList[listEnd++] = 2;
1297  }
1298  break;
1299 
1300  case 3:
1301  nzCoeff[nzCoeffCount++] = binkScan[ccoef];
1302 
1303  int sign = -((int)video.bits->getBit());
1304  block[binkScan[ccoef]] = (mask ^ sign) - sign;
1305 
1306  coefList[listPos] = 0;
1307  modeList[listPos++] = 0;
1308  masksCount--;
1309  if (masksCount < 0)
1310  return;
1311  break;
1312  }
1313  }
1314  }
1315 }
1316 
1318  _index(index),
1319  _info(audio),
1320  _audioStream(Sound::makePacketizedPCMStream(_info.outSampleRate, Sound::FLAG_16BITS | Sound::FLAG_NATIVE_ENDIAN, _info.outChannels)),
1321  _curFrame(0),
1322  _audioBuffered(0, _info.sampleRate) {
1323 }
1324 
1326  delete _audioStream;
1327 }
1328 
1330  return _audioStream;
1331 }
1332 
1333 void Bink::BinkAudioTrack::decodeAudio(Common::SeekableReadStream& bink, const std::vector<VideoFrame>& frames, const std::vector<AudioInfo>& audioTracks, const Common::Timestamp& endTime) {
1334  while (_audioBuffered < endTime && _curFrame < frames.size()) {
1335  const VideoFrame &frame = frames[_curFrame++];
1336  bink.seek(frame.offset);
1337  uint32 frameSize = frame.size;
1338 
1339  uint32 audioPacketLength = 0;
1340 
1341  for (size_t i = 0; i < audioTracks.size(); i++) {
1342  audioPacketLength = bink.readUint32LE();
1343  frameSize -= 4;
1344 
1345  if (audioPacketLength > frameSize)
1346  throw Common::Exception("Audio packet too big for the frame");
1347 
1348  frameSize -= audioPacketLength;
1349 
1350  if (i != _index) {
1351  bink.skip(audioPacketLength);
1352  continue;
1353  }
1354 
1355  // We found what we were looking for
1356  break;
1357  }
1358 
1359  if (audioPacketLength < 4)
1360  continue;
1361 
1362  // Number of samples in bytes
1363  uint32 sampleCount = bink.readUint32LE() / (2 * _info.channels);
1364 
1365  // Create a substream for these bits
1366  Common::BitStream32LELSB bits(new Common::SeekableSubReadStream(&bink, bink.pos(), bink.pos() + audioPacketLength - 4), true);
1367 
1368  int outSize = _info.frameLen * _info.channels;
1369 
1370  while (bits.pos() < bits.size()) {
1371  Common::ScopedArray<int16> out(new int16[outSize]);
1372  memset(out.get(), 0, outSize * 2);
1373 
1374  audioBlock(bits, out.get());
1375 
1376  _audioStream->queuePacket(new Common::MemoryReadStream(reinterpret_cast<byte *>(out.release()), _info.blockSize * 2, true));
1377 
1378  if (bits.pos() & 0x1F) // next data block starts at a 32-byte boundary
1379  bits.skip(32 - (bits.pos() & 0x1F));
1380  }
1381 
1382  _audioBuffered = _audioBuffered.addFrames(sampleCount);
1383  }
1384 
1385  // If we have reached the end, mark us as finished
1386  if (_curFrame >= frames.size())
1387  _audioStream->finish();
1388 }
1389 
1391  int power = bits.getBits(5);
1392 
1393  float f = ldexpf(bits.getBits(23), power - 23);
1394 
1395  if (bits.getBit())
1396  f = -f;
1397 
1398  return f;
1399 }
1400 
1402  return !_audioStream->isFinished();
1403 }
1404 
1406  if (_info.codec == kAudioCodecDCT)
1407  audioBlockDCT (bits);
1408  else if (_info.codec == kAudioCodecRDFT)
1409  audioBlockRDFT(bits);
1410 
1411  Sound::floatToInt16Interleave(out, const_cast<const float **>(_info.coeffsPtr),
1412  _info.frameLen, _info.channels);
1413 
1414  if (!_info.first) {
1415  int count = _info.overlapLen * _info.channels;
1416  int shift = Common::intLog2(count);
1417  for (int i = 0; i < count; i++) {
1418  out[i] = (_info.prevCoeffs[i] * (count - i) + out[i] * i) >> shift;
1419  }
1420  }
1421 
1422  std::memcpy(_info.prevCoeffs, out + _info.blockSize, _info.overlapLen * _info.channels * sizeof(*out));
1423 
1424  _info.first = false;
1425 }
1426 
1428  bits.skip(2);
1429 
1430  for (uint8 i = 0; i < _info.channels; i++) {
1431  float *coeffs = _info.coeffsPtr[i];
1432 
1433  readAudioCoeffs(bits, coeffs);
1434 
1435  coeffs[0] /= 0.5f;
1436 
1437  _info.dct->calc(coeffs);
1438 
1439  for (uint32 j = 0; j < _info.frameLen; j++)
1440  coeffs[j] *= (_info.frameLen / 2.0f);
1441  }
1442 
1443 }
1444 
1446  for (uint8 i = 0; i < _info.channels; i++) {
1447  float *coeffs = _info.coeffsPtr[i];
1448 
1449  readAudioCoeffs(bits, coeffs);
1450 
1451  _info.rdft->calc(coeffs);
1452  }
1453 }
1454 
1455 static const uint8 rleLengthTab[16] = {
1456  2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64
1457 };
1458 
1460  coeffs[0] = getFloat(bits) * _info.root;
1461  coeffs[1] = getFloat(bits) * _info.root;
1462 
1463  float quant[25];
1464 
1465  for (uint32 i = 0; i < _info.bandCount; i++) {
1466  int value = bits.getBits(8);
1467 
1468  // 0.066399999 / log10(M_E)
1469  quant[i] = expf(MIN(value, 95) * 0.15289164787221953823f) * _info.root;
1470  }
1471 
1472  float q = 0.0f;
1473 
1474  // Find band (k)
1475  int k;
1476  for (k = 0; _info.bands[k] < 1; k++)
1477  q = quant[k];
1478 
1479  // Parse coefficients
1480  uint32 i = 2;
1481  while (i < _info.frameLen) {
1482 
1483  uint32 j = 0;
1484  if (bits.getBit())
1485  j = i + rleLengthTab[bits.getBits(4)] * 8;
1486  else
1487  j = i + 8;
1488 
1489  j = MIN(j, _info.frameLen);
1490 
1491  int width = bits.getBits(4);
1492  if (width == 0) {
1493 
1494  std::memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
1495  i = j;
1496  while (_info.bands[k] * 2 < i)
1497  q = quant[k++];
1498 
1499  } else {
1500 
1501  while (i < j) {
1502  if (_info.bands[k] * 2 == i)
1503  q = quant[k++];
1504 
1505  int coeff = bits.getBits(width);
1506  if (coeff) {
1507 
1508  if (bits.getBit())
1509  coeffs[i] = -q * coeff;
1510  else
1511  coeffs[i] = q * coeff;
1512 
1513  } else {
1514  coeffs[i] = 0.0f;
1515  }
1516  i++;
1517  }
1518 
1519  }
1520 
1521  }
1522 
1523 }
1524 
1525 #define A1 2896 /* (1/sqrt(2))<<12 */
1526 #define A2 2217
1527 #define A3 3784
1528 #define A4 -5352
1529 
1530 #define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\
1531  const int a0 = (src)[s0] + (src)[s4]; \
1532  const int a1 = (src)[s0] - (src)[s4]; \
1533  const int a2 = (src)[s2] + (src)[s6]; \
1534  const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \
1535  const int a4 = (src)[s5] + (src)[s3]; \
1536  const int a5 = (src)[s5] - (src)[s3]; \
1537  const int a6 = (src)[s1] + (src)[s7]; \
1538  const int a7 = (src)[s1] - (src)[s7]; \
1539  const int b0 = a4 + a6; \
1540  const int b1 = (A3*(a5 + a7)) >> 11; \
1541  const int b2 = ((A4*a5) >> 11) - b0 + b1; \
1542  const int b3 = (A1*(a6 - a4) >> 11) - b2; \
1543  const int b4 = ((A2*a7) >> 11) + b3 - b1; \
1544  (dest)[d0] = munge(a0+a2 +b0); \
1545  (dest)[d1] = munge(a1+a3-a2+b2); \
1546  (dest)[d2] = munge(a1-a3+a2+b3); \
1547  (dest)[d3] = munge(a0-a2 -b4); \
1548  (dest)[d4] = munge(a0-a2 +b4); \
1549  (dest)[d5] = munge(a1-a3+a2-b3); \
1550  (dest)[d6] = munge(a1+a3-a2-b2); \
1551  (dest)[d7] = munge(a0+a2 -b0); \
1552 }
1553 /* end IDCT_TRANSFORM macro */
1554 
1555 #define MUNGE_NONE(x) (x)
1556 #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)
1557 
1558 #define MUNGE_ROW(x) (((x) + 0x7F)>>8)
1559 #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)
1560 
1561 static inline void IDCTCol(int16 *dest, const int16 *src)
1562 {
1563  if ((src[8] | src[16] | src[24] | src[32] | src[40] | src[48] | src[56]) == 0) {
1564  dest[ 0] =
1565  dest[ 8] =
1566  dest[16] =
1567  dest[24] =
1568  dest[32] =
1569  dest[40] =
1570  dest[48] =
1571  dest[56] = src[0];
1572  } else {
1573  IDCT_COL(dest, src);
1574  }
1575 }
1576 
1578  int i;
1579  int16 temp[64];
1580 
1581  for (i = 0; i < 8; i++)
1582  IDCTCol(&temp[i], &block[i]);
1583  for (i = 0; i < 8; i++) {
1584  IDCT_ROW( (&block[8*i]), (&temp[8*i]) );
1585  }
1586 }
1587 
1589  int i, j;
1590 
1591  IDCT(block);
1592  byte *dest = ctx.dest;
1593  for (i = 0; i < 8; i++, dest += ctx.pitch, block += 8)
1594  for (j = 0; j < 8; j++)
1595  dest[j] += block[j];
1596 }
1597 
1599  int i;
1600  int16 temp[64];
1601  for (i = 0; i < 8; i++)
1602  IDCTCol(&temp[i], &block[i]);
1603  for (i = 0; i < 8; i++) {
1604  IDCT_ROW( (&ctx.dest[i*ctx.pitch]), (&temp[8*i]) );
1605  }
1606 }
1607 
1608 Bink::BinkVideoTrack::BinkVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id) :
1609  _width(width), _height(height), _curFrame(-1), _frameCount(frameCount), _frameRate(frameRate), _swapPlanes(swapPlanes), _hasAlpha(hasAlpha), _id(id) {
1610  // Give the planes a bit extra space
1611  width = _width + 32;
1612  height = _height + 32;
1613 
1614  _curPlanes[0].reset(new byte[ width * height ]); // Y
1615  _curPlanes[1].reset(new byte[(width >> 1) * (height >> 1)]); // U, 1/4 resolution
1616  _curPlanes[2].reset(new byte[(width >> 1) * (height >> 1)]); // V, 1/4 resolution
1617  _curPlanes[3].reset(new byte[ width * height ]); // A
1618  _oldPlanes[0].reset(new byte[ width * height ]); // Y
1619  _oldPlanes[1].reset(new byte[(width >> 1) * (height >> 1)]); // U, 1/4 resolution
1620  _oldPlanes[2].reset(new byte[(width >> 1) * (height >> 1)]); // V, 1/4 resolution
1621  _oldPlanes[3].reset(new byte[ width * height ]); // A
1622 
1623  // Initialize the video with solid black
1624  std::memset(_curPlanes[0].get(), 0, width * height );
1625  std::memset(_curPlanes[1].get(), 0, (width >> 1) * (height >> 1));
1626  std::memset(_curPlanes[2].get(), 0, (width >> 1) * (height >> 1));
1627  std::memset(_curPlanes[3].get(), 255, width * height );
1628  std::memset(_oldPlanes[0].get(), 0, width * height );
1629  std::memset(_oldPlanes[1].get(), 0, (width >> 1) * (height >> 1));
1630  std::memset(_oldPlanes[2].get(), 0, (width >> 1) * (height >> 1));
1631  std::memset(_oldPlanes[3].get(), 255, width * height );
1632 
1633  initBundles();
1634  initHuffman();
1635 }
1636 
1637 } // End of namespace Video
uint32 outSampleRate
Definition: bink.h:123
Common::ScopedPtr< Graphics::Surface > _surface
The video&#39;s surface.
Definition: decoder.h:393
static const uint32 kBIKkID
Definition: bink.cpp:103
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
Huffman huffman
Huffman codebook.
Definition: bink.h:257
void readPatterns(VideoFrame &video, Bundle &bundle)
Definition: bink.cpp:998
byte * getData()
Definition: surface.cpp:61
static const uint32 binkIntraQuant[16][64]
Definition: binkdata.h:296
Common::RDFT * rdft
Definition: bink.h:145
int countLength
Length of number of entries to decode (in bits) for the current plane.
Definition: bink.h:255
static int intLog2(uint32 v)
Definition: maths.h:83
static const uint32 binkHuffmanCodes[16][16]
Definition: binkdata.h:95
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:133
void readHuffman(VideoFrame &video, Huffman &huffman)
Read the symbols for a Huffman code.
Definition: bink.cpp:364
static const uint16 kAudioFlagStereo
Definition: bink.cpp:117
Common::BitStream * bits
Definition: bink.h:159
PacketizedAudioStream * makePacketizedPCMStream(int rate, byte flags, int channels)
Creates a PacketizedAudioStream that will automatically queue packets as individual AudioStreams like...
Definition: pcm.cpp:171
An abstract representation of an audio track.
Definition: decoder.h:302
Luminance values range from [0, 255].
Definition: yuv_to_rgb.h:42
A video frame.
Definition: bink.h:153
void readResidue(VideoFrame &video, int16 *block, int masksCount)
Reads 8x8 block with residue after motion compensation.
Definition: bink.cpp:1225
static const uint32 kKB2fID
Definition: bink.cpp:107
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
A simple rational class that holds fractions.
Definition: rational.h:56
void blockMotion(DecodeContext &ctx)
Definition: bink.cpp:791
void reset(PointerType o=0)
Resets the pointer with the new value.
Definition: scopedptr.h:87
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
Definition: scopedptr.h:103
uint32 readBundleCount(VideoFrame &video, Bundle &bundle)
Read a count value out of a bundle.
Definition: bink.cpp:635
static const uint32 kKB2kID
Definition: bink.cpp:112
void addTrack(Track *track, bool isExternal=false)
Define a track to be used by this class.
Definition: decoder.cpp:152
static int16 dequant(int16 in, uint32 quant, bool dc)
Definition: bink.cpp:1107
static const uint32 kKB2gID
Definition: bink.cpp:108
void decodePacket(Graphics::Surface &surface, VideoFrame &frame)
Decode a video packet.
Definition: bink.cpp:203
bool _needCopy
Is new frame content available that needs to by copied?
Definition: decoder.h:391
(Inverse) Discrete Cosine Transforms.
Definition: dct.h:66
uint8_t uint8
Definition: types.h:200
void blockRaw(DecodeContext &ctx)
Definition: bink.cpp:895
virtual size_t pos() const =0
Return the stream position in bits.
void readAudioCoeffs(Common::BitStream &bits, float *coeffs)
Definition: bink.cpp:1459
void blockScaledPattern(DecodeContext &ctx)
Definition: bink.cpp:727
Mathematical helpers.
void readRuns(VideoFrame &video, Bundle &bundle)
Definition: bink.cpp:904
AudioCodec codec
Definition: bink.h:126
Implementing the reading stream interfaces for plain memory blocks.
static const uint32 kBIKfID
Definition: bink.cpp:97
static const uint32 kBIKhID
Definition: bink.cpp:99
bool canBufferData() const
Definition: bink.cpp:1401
Decoding PCM (Pulse Code Modulation).
void blockScaledSkip(DecodeContext &ctx)
Definition: bink.cpp:654
byte * curPtr
Pointer to the data that wasn&#39;t yet read.
Definition: bink.h:263
static const uint8 rleLengthTab[16]
Definition: bink.cpp:1455
int getCurFrame() const
Definition: bink.h:181
size_t pos() const
Return the stream position in bits.
Definition: bitstream.h:227
void audioBlockRDFT(Common::BitStream &bits)
Decode a RDFT&#39;d audio block.
Definition: bink.cpp:1445
Utility templates and functions for working with strings and streams.
static const uint8 binkPatterns[16][64]
Definition: binkdata.h:133
int16_t int16
Definition: types.h:201
BitStreamImpl< 32, true, false > BitStream32LELSB
32-bit little-endian data, LSB to MSB.
Definition: bitstream.h:264
void blockScaledIntra(DecodeContext &ctx)
Definition: bink.cpp:698
uint32 * bands
Definition: bink.h:136
void blockRun(DecodeContext &ctx)
Definition: bink.cpp:804
void initVideo()
Create a surface for video of these dimensions.
Definition: decoder.cpp:71
int32 getBundleValue(Source source)
Get a direct value out of a bundle.
Definition: bink.cpp:621
uint32 _audioTrack
Audio track to use.
Definition: bink.h:170
void blockScaledFill(DecodeContext &ctx)
Definition: bink.cpp:719
Definition: game.h:37
Basic exceptions to throw.
const uint8 rleLens[4]
Definition: bink.cpp:960
void blockScaledRun(DecodeContext &ctx)
Definition: bink.cpp:662
void IDCTPut(DecodeContext &ctx, int16 *block)
Definition: bink.cpp:1598
int getWidth() const
Definition: surface.cpp:53
(Inverse) Discrete Cosine Transforms.
void readBlockTypes(VideoFrame &video, Bundle &bundle)
Definition: bink.cpp:961
bool _hasAlpha
Do video frames have alpha?
Definition: bink.h:277
static const uint32 kBIKiID
Definition: bink.cpp:100
Source
IDs for different data types used in Bink video codec.
Definition: bink.h:216
void initBundles()
Initialize the bundles.
Definition: bink.cpp:583
uint16_t uint16
Definition: types.h:202
Utility templates and functions.
void readColors(VideoFrame &video, Bundle &bundle)
Definition: bink.cpp:1016
BlockType
Bink video block types.
Definition: bink.h:231
static const uint32 kDCStartBits
Definition: bink.cpp:120
Decoding RAD Game Tools&#39; Bink videos.
An audio track.
Definition: bink.h:117
#define IDCT_COL(dest, src)
Definition: bink.cpp:1556
static const uint32 kBIKgID
Definition: bink.cpp:98
Decode a Huffman&#39;d bitstream.
Definition: huffman.h:47
virtual uint32 getBit()=0
Read a bit from the bit stream.
T MIN(T a, T b)
Definition: util.h:70
virtual size_t skip(ptrdiff_t offset)
Skip the specified number of bytes, adding that offset to the current position in the stream...
Definition: readstream.h:317
Simple memory based &#39;stream&#39;, which implements the ReadStream interface for a plain memory block...
Definition: memreadstream.h:66
std::vector< VideoFrame > _frames
All video frames.
Definition: bink.h:168
bool _swapPlanes
Are the planes ordered (A)YVU instead of (A)YUV?
Definition: bink.h:276
#define YUVToRGBMan
Definition: yuv_to_rgb.h:91
StackException Exception
Definition: error.h:59
uint32 _id
The BIK FourCC.
Definition: bink.h:279
An abstract representation of a video track.
Definition: decoder.h:226
Efficient YUV to RGB conversion.
BinkAudioTrack(size_t index, AudioInfo &audio)
Definition: bink.cpp:1317
Common::ScopedArray< byte > _curPlanes[4]
The 4 color planes, YUVA, current frame.
Definition: bink.h:290
Common::DCT * dct
Definition: bink.h:146
float * coeffsPtr[kAudioChannelsMax]
Definition: bink.h:143
void warning(const char *s,...)
Definition: util.cpp:33
static const uint16 kAudioFlagDCT
Definition: bink.cpp:116
Basic reading stream interfaces.
virtual size_t pos() const =0
Obtains the current value of the stream position indicator of the stream.
static const uint32 kKB2aID
Definition: bink.cpp:105
byte * curDec
Pointer to the data that wasn&#39;t yet decoded.
Definition: bink.h:262
void blockFill(DecodeContext &ctx)
Definition: bink.cpp:859
void blockPattern(DecodeContext &ctx)
Definition: bink.cpp:880
static const uint32 kBIKbID
Definition: bink.cpp:102
A bit stream.
Sound::AudioStream * getAudioStream() const
Definition: bink.cpp:1329
void skip(size_t n)
Skip the specified amount of bits.
Definition: bitstream.h:221
sound is 16 bits wide (default: 8bit)
Definition: pcm.h:72
Generic audio input stream.
Definition: audiostream.h:70
#define XOREOS_FALLTHROUGH
Definition: fallthrough.h:60
Common::ScopedPtr< Common::SeekableReadStream > _bink
Definition: bink.h:165
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
void initHuffman()
Initialize the Huffman decoders.
Definition: bink.cpp:612
void readMotionValues(VideoFrame &video, Bundle &bundle)
Definition: bink.cpp:924
int countLengths[2]
Lengths of number of entries to decode (in bits).
Definition: bink.h:254
Data structure used for decoding a single Bink data type.
Definition: bink.h:253
size_t size() const
Return the stream size in bits.
Definition: bitstream.h:236
float coeffs[16 *kAudioBlockSizeMax]
Definition: bink.h:140
An image surface, in BGRA format.
uint32 _height
Definition: h263.cpp:54
int8_t int8
Definition: types.h:199
void readDCS(VideoFrame &video, Bundle &bundle, int startBits, bool hasSign)
Definition: bink.cpp:1060
Decompressing Huffman codes.
samples are in native endianness
Definition: pcm.h:81
(Inverse) Real Discrete Fourier Transform.
virtual void skip(size_t n)=0
Skip the specified amount of bits.
static const uint8 binkHuffmanLengths[16][16]
Definition: binkdata.h:114
byte * dataEnd
Pointer to the data end end.
Definition: bink.h:261
uint32_t uint32
Definition: types.h:204
UString debugTag(uint32 tag, bool trim)
Create an elaborate string from an integer tag, for debugging purposes.
Definition: strutil.cpp:117
static const uint32 kKB2iID
Definition: bink.cpp:110
void readBundle(VideoFrame &video, Source source)
Read/Initialize a bundle for decoding a plane.
Definition: bink.cpp:349
void decodeNextTrackFrame(VideoTrack &track)
Decode enough data for the next frame.
Definition: bink.cpp:163
Timestamps allow specifying points in time and measuring time intervals with a sub-millisecond granul...
Definition: timestamp.h:108
void blockInter(DecodeContext &ctx)
Definition: bink.cpp:867
byte symbols[16]
Huffman symbol => Bink symbol translation list.
Definition: bink.h:247
int _curFrame
Current Frame.
Definition: bink.h:271
static void floatToInt16Interleave(int16 *dst, const float **src, uint32 length, uint8 channels)
Definition: util.h:39
byte getHuffmanSymbol(VideoFrame &video, Huffman &huffman)
Read and translate a symbol out of a Huffman code.
Definition: bink.cpp:617
virtual uint32 getBits(size_t n)=0
Read a multi-bit value from the bit stream.
static const uint8 binkScan[64]
Bink DCT and residue 8x8 block scan order.
Definition: binkdata.h:84
Static data used for decoding RAD Game Tools&#39; Bink videos.
void load()
Load a Bink file.
Definition: bink.cpp:439
void checkAudioBuffer(AudioTrack &track, const Common::Timestamp &endTime)
Ensure that there is enough audio buffered in the given track to reach the given timestamp.
Definition: bink.cpp:199
void IDCTAdd(DecodeContext &ctx, int16 *block)
Definition: bink.cpp:1588
static const int kAudioChannelsMax
Definition: bink.h:108
A template implementing a bit stream for different data memory layouts.
Definition: bitstream.h:85
void blockScaledRaw(DecodeContext &ctx)
Definition: bink.cpp:743
Data structure for decoding and translating Huffman&#39;d data.
Definition: bink.h:245
A scoped array pointer, allowing array-y access and array deletion.
Definition: scopedptr.h:137
const uint16 binkCriticalFreqs[25]
Definition: binkdata.h:76
#define IDCT_ROW(dest, src)
Definition: bink.cpp:1559
void audioBlock(Common::BitStream &bits, int16 *out)
Decode an audio block.
Definition: bink.cpp:1405
void IDCT(int16 *block)
Definition: bink.cpp:1577
BinkVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id)
Definition: bink.cpp:1608
SeekableSubReadStream provides access to a SeekableReadStream restricted to the range [begin...
Definition: readstream.h:359
void decodeAudio(Common::SeekableReadStream &bink, const std::vector< VideoFrame > &frames, const std::vector< AudioInfo > &audioTracks, const Common::Timestamp &endTime)
Decode audio data up to endTime.
Definition: bink.cpp:1333
uint32 _width
Definition: h263.cpp:53
(Inverse) Real Discrete Fourier Transform.
Definition: rdft.h:64
T CLIP(T v, T amin, T amax)
Definition: util.h:72
void blockResidue(DecodeContext &ctx)
Definition: bink.cpp:831
void decodePlane(VideoFrame &video, int planeIdx, bool isChroma)
Decode a plane.
Definition: bink.cpp:239
static const uint32 kKB2jID
Definition: bink.cpp:111
static void IDCTCol(int16 *dest, const int16 *src)
Definition: bink.cpp:1561
Common::ScopedArray< byte > _oldPlanes[4]
The 4 color planes, YUVA, last frame.
Definition: bink.h:291
float getFloat(Common::BitStream &bits)
Definition: bink.cpp:1390
Interface for a seekable & readable data stream.
Definition: readstream.h:265
Streaming audio.
void initAudioTrack(AudioInfo &audio)
Definition: bink.cpp:519
static const uint32 kKB2dID
Definition: bink.cpp:106
Bink(Common::SeekableReadStream *bink)
Definition: bink.cpp:154
static const uint32 binkInterQuant[16][64]
Definition: binkdata.h:459
void audioBlockDCT(Common::BitStream &bits)
Decode a DCT&#39;d audio block.
Definition: bink.cpp:1427
void blockSkip(DecodeContext &ctx)
Definition: bink.cpp:646
A bit stream.
Definition: bitstream.h:40
std::vector< AudioInfo > _audioTracks
All audio tracks.
Definition: bink.h:167
uint8 byte
Definition: types.h:209
int index
Index of the Huffman codebook to use.
Definition: bink.h:246
static const uint32 kKB2hID
Definition: bink.cpp:109
virtual size_t size() const =0
Return the stream size in bits.
void blockIntra(DecodeContext &ctx)
Definition: bink.cpp:848
void blockScaled(DecodeContext &ctx)
Definition: bink.cpp:758
void readDCTCoeffs(VideoFrame &video, int16 *block, bool isIntra)
Reads 8x8 block of DCT coefficients.
Definition: bink.cpp:1126
void SWAP(T &a, T &b)
Template method which swaps the values of its two parameters.
Definition: util.h:78
int32_t int32
Definition: types.h:203
static const uint32 kVideoFlagAlpha
Definition: bink.cpp:114
void mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size)
Merge two Huffman symbol lists.
Definition: bink.cpp:418
Sound decoding utility functions.