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 /* Intel Indeo 5 decompressor, derived from ffmpeg.
24 *
25 * Original copyright note: * Intel Indeo 5 (IV51, IV52, etc.) video decoder for ffmpeg
26 * written, produced, and directed by Alan Smithee
27 */
28
29 #include "common/memstream.h"
30 #include "common/textconsole.h"
31 #include "graphics/yuv_to_rgb.h"
32 #include "image/codecs/indeo5.h"
33 #include "image/codecs/indeo/indeo_dsp.h"
34 #include "image/codecs/indeo/mem.h"
35
36 namespace Image {
37
38 /**
39 * Indeo5 frame types.
40 */
41 enum {
42 FRAMETYPE_INTRA = 0,
43 FRAMETYPE_INTER = 1, ///< non-droppable P-frame
44 FRAMETYPE_INTER_SCAL = 2, ///< droppable P-frame used in the scalability mode
45 FRAMETYPE_INTER_NOREF = 3, ///< droppable P-frame
46 FRAMETYPE_NULL = 4 ///< empty frame with no data
47 };
48
49 #define IVI5_PIC_SIZE_ESC 15
50
Indeo5Decoder(uint16 width,uint16 height,uint bitsPerPixel)51 Indeo5Decoder::Indeo5Decoder(uint16 width, uint16 height, uint bitsPerPixel) :
52 IndeoDecoderBase(width, height, bitsPerPixel) {
53 _ctx._isIndeo4 = false;
54 _ctx._refBuf = 1;
55 _ctx._bRefBuf = 3;
56 _ctx._pFrame = new AVFrame();
57 }
58
isIndeo5(Common::SeekableReadStream & stream)59 bool Indeo5Decoder::isIndeo5(Common::SeekableReadStream &stream) {
60 // Less than 16 bytes? This can't be right
61 if (stream.size() < 16)
62 return false;
63
64 // Read in the start of the data
65 byte buffer[16];
66 stream.read(buffer, 16);
67 stream.seek(-16, SEEK_CUR);
68
69 // Validate the first 5-bit word has the correct identifier
70 Indeo::GetBits gb(buffer, 16 * 8);
71 bool isIndeo5 = gb.getBits(5) == 0x1F;
72
73 return isIndeo5;
74 }
75
decodeFrame(Common::SeekableReadStream & stream)76 const Graphics::Surface *Indeo5Decoder::decodeFrame(Common::SeekableReadStream &stream) {
77 // Not Indeo 5? Fail
78 if (!isIndeo5(stream))
79 return nullptr;
80
81 // Set up the frame data buffer
82 byte *frameData = new byte[stream.size()];
83 stream.read(frameData, stream.size());
84 _ctx._frameData = frameData;
85 _ctx._frameSize = stream.size();
86
87 // Set up the GetBits instance for reading the data
88 _ctx._gb = new GetBits(_ctx._frameData, _ctx._frameSize);
89
90 // Decode the frame
91 int err = decodeIndeoFrame();
92
93 // Free the bit reader and frame buffer
94 delete _ctx._gb;
95 _ctx._gb = nullptr;
96 delete[] frameData;
97 _ctx._frameData = nullptr;
98 _ctx._frameSize = 0;
99
100 return (err < 0) ? nullptr : &_surface;
101 }
102
decodePictureHeader()103 int Indeo5Decoder::decodePictureHeader() {
104 IVIPicConfig picConf;
105 int ret;
106
107 if (_ctx._gb->getBits(5) != 0x1F) {
108 warning("Invalid picture start code!");
109 return -1;
110 }
111
112 _ctx._prevFrameType = _ctx._frameType;
113 _ctx._frameType = _ctx._gb->getBits(3);
114 if (_ctx._frameType >= 5) {
115 warning("Invalid frame type: %d", _ctx._frameType);
116 return -1;
117 }
118
119 _ctx._frameNum = _ctx._gb->getBits(8);
120
121 if (_ctx._frameType == FRAMETYPE_INTRA) {
122 if ((ret = decode_gop_header()) < 0) {
123 warning("Invalid GOP header, skipping frames.");
124 _ctx._gopInvalid = true;
125 return ret;
126 }
127 _ctx._gopInvalid = false;
128 }
129
130 if (_ctx._frameType == FRAMETYPE_INTER_SCAL && !_ctx._isScalable) {
131 warning("Scalable inter frame in non scalable stream");
132 _ctx._frameType = FRAMETYPE_INTER;
133 return -1;
134 }
135
136 if (_ctx._frameType != FRAMETYPE_NULL) {
137 _ctx._frameFlags = _ctx._gb->getBits(8);
138
139 _ctx._picHdrSize = (_ctx._frameFlags & 1) ? _ctx._gb->getBits(24) : 0;
140
141 _ctx._checksum = (_ctx._frameFlags & 0x10) ? _ctx._gb->getBits(16) : 0;
142
143 // skip unknown extension if any
144 if (_ctx._frameFlags & 0x20)
145 skip_hdr_extension(); // XXX: untested
146
147 // decode macroblock huffman codebook
148 ret = _ctx._mbVlc.decodeHuffDesc(&_ctx, _ctx._frameFlags & 0x40,
149 IVI_MB_HUFF);
150 if (ret < 0)
151 return ret;
152
153 _ctx._gb->skip(3); // FIXME: unknown meaning!
154 }
155
156 _ctx._gb->align();
157 return 0;
158 }
159
switchBuffers()160 void Indeo5Decoder::switchBuffers() {
161 switch (_ctx._prevFrameType) {
162 case FRAMETYPE_INTRA:
163 case FRAMETYPE_INTER:
164 _ctx._bufSwitch ^= 1;
165 _ctx._dstBuf = _ctx._bufSwitch;
166 _ctx._refBuf = _ctx._bufSwitch ^ 1;
167 break;
168
169 case FRAMETYPE_INTER_SCAL:
170 if (!_ctx._interScal) {
171 _ctx._ref2Buf = 2;
172 _ctx._interScal = 1;
173 }
174 SWAP(_ctx._dstBuf, _ctx._ref2Buf);
175 _ctx._refBuf = _ctx._ref2Buf;
176 break;
177
178 case FRAMETYPE_INTER_NOREF:
179 default:
180 break;
181 }
182
183 switch (_ctx._frameType) {
184 case FRAMETYPE_INTRA:
185 _ctx._bufSwitch = 0;
186 // FALLTHROUGH
187 case FRAMETYPE_INTER:
188 _ctx._interScal = 0;
189 _ctx._dstBuf = _ctx._bufSwitch;
190 _ctx._refBuf = _ctx._bufSwitch ^ 1;
191 break;
192
193 case FRAMETYPE_INTER_SCAL:
194 case FRAMETYPE_INTER_NOREF:
195 case FRAMETYPE_NULL:
196 default:
197 break;
198 }
199 }
200
isNonNullFrame() const201 bool Indeo5Decoder::isNonNullFrame() const {
202 return _ctx._frameType != FRAMETYPE_NULL;
203 }
204
decodeBandHeader(IVIBandDesc * band)205 int Indeo5Decoder::decodeBandHeader(IVIBandDesc *band) {
206 int i, ret;
207 uint8 bandFlags;
208
209 bandFlags = _ctx._gb->getBits(8);
210
211 if (bandFlags & 1) {
212 band->_isEmpty = true;
213 return 0;
214 }
215
216 band->_dataSize = (_ctx._frameFlags & 0x80) ? _ctx._gb->getBits(24) : 0;
217
218 band->_inheritMv = (bandFlags & 2) != 0;
219 band->_inheritQDelta = (bandFlags & 8) != 0;
220 band->_qdeltaPresent = (bandFlags & 4) != 0;
221 if (!band->_qdeltaPresent)
222 band->_inheritQDelta = 1;
223
224 // decode rvmap probability corrections if any
225 band->_numCorr = 0; // there are no corrections
226 if (bandFlags & 0x10) {
227 band->_numCorr = _ctx._gb->getBits(8); // get number of correction pairs
228 if (band->_numCorr > 61) {
229 warning("Too many corrections: %d", band->_numCorr);
230 return -1;
231 }
232
233 // read correction pairs
234 for (i = 0; i < band->_numCorr * 2; i++)
235 band->_corr[i] = _ctx._gb->getBits(8);
236 }
237
238 // select appropriate rvmap table for this band
239 band->_rvmapSel = (bandFlags & 0x40) ? _ctx._gb->getBits(3) : 8;
240
241 // decode block huffman codebook
242 ret = band->_blkVlc.decodeHuffDesc(&_ctx, bandFlags & 0x80, IVI_BLK_HUFF);
243 if (ret < 0)
244 return ret;
245
246 band->_checksumPresent = _ctx._gb->getBit();
247 if (band->_checksumPresent)
248 band->_checksum = _ctx._gb->getBits(16);
249
250 band->_globQuant = _ctx._gb->getBits(5);
251
252 // skip unknown extension if any
253 if (bandFlags & 0x20) { // XXX: untested
254 _ctx._gb->align();
255 skip_hdr_extension();
256 }
257
258 _ctx._gb->align();
259
260 return 0;
261 }
262
decodeMbInfo(IVIBandDesc * band,IVITile * tile)263 int Indeo5Decoder::decodeMbInfo(IVIBandDesc *band, IVITile *tile) {
264 int x, y, mvX, mvY, mvDelta, offs, mbOffset, mvScale, blksPerMb, s;
265 IVIMbInfo *mb, *refMb;
266 int rowOffset = band->_mbSize * band->_pitch;
267
268 mb = tile->_mbs;
269 refMb = tile->_refMbs;
270 offs = tile->_yPos * band->_pitch + tile->_xPos;
271
272 if (!refMb &&
273 ((band->_qdeltaPresent && band->_inheritQDelta) || band->_inheritMv))
274 return -1;
275
276 if (tile->_numMBs != IVI_MBs_PER_TILE(tile->_width, tile->_height, band->_mbSize)) {
277 warning("Allocated tile size %d mismatches parameters %d",
278 tile->_numMBs, IVI_MBs_PER_TILE(tile->_width, tile->_height, band->_mbSize));
279 return -1;
280 }
281
282 // scale factor for motion vectors
283 mvScale = (_ctx._planes[0]._bands[0]._mbSize >> 3) - (band->_mbSize >> 3);
284 mvX = mvY = 0;
285
286 for (y = tile->_yPos; y < (tile->_yPos + tile->_height); y += band->_mbSize) {
287 mbOffset = offs;
288
289 for (x = tile->_xPos; x < (tile->_xPos + tile->_width); x += band->_mbSize) {
290 mb->_xPos = x;
291 mb->_yPos = y;
292 mb->_bufOffs = mbOffset;
293
294 if (_ctx._gb->getBit()) {
295 if (_ctx._frameType == FRAMETYPE_INTRA) {
296 warning("Empty macroblock in an INTRA picture!");
297 return -1;
298 }
299 mb->_type = 1; // empty macroblocks are always INTER
300 mb->_cbp = 0; // all blocks are empty
301
302 mb->_qDelta = 0;
303 if (!band->_plane && !band->_bandNum && (_ctx._frameFlags & 8)) {
304 mb->_qDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
305 mb->_qDelta = IVI_TOSIGNED(mb->_qDelta);
306 }
307
308 mb->_mvX = mb->_mvY = 0; // no motion vector coded
309 if (band->_inheritMv && refMb) {
310 // motion vector inheritance
311 if (mvScale) {
312 mb->_mvX = scaleMV(refMb->_mvX, mvScale);
313 mb->_mvY = scaleMV(refMb->_mvY, mvScale);
314 } else {
315 mb->_mvX = refMb->_mvX;
316 mb->_mvY = refMb->_mvY;
317 }
318 }
319 } else {
320 if (band->_inheritMv && refMb) {
321 mb->_type = refMb->_type; // copy mb_type from corresponding reference mb
322 } else if (_ctx._frameType == FRAMETYPE_INTRA) {
323 mb->_type = 0; // mb_type is always INTRA for intra-frames
324 } else {
325 mb->_type = _ctx._gb->getBit();
326 }
327
328 blksPerMb = band->_mbSize != band->_blkSize ? 4 : 1;
329 mb->_cbp = _ctx._gb->getBits(blksPerMb);
330
331 mb->_qDelta = 0;
332 if (band->_qdeltaPresent) {
333 if (band->_inheritQDelta) {
334 if (refMb) mb->_qDelta = refMb->_qDelta;
335 } else if (mb->_cbp || (!band->_plane && !band->_bandNum &&
336 (_ctx._frameFlags & 8))) {
337 mb->_qDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
338 mb->_qDelta = IVI_TOSIGNED(mb->_qDelta);
339 }
340 }
341
342 if (!mb->_type) {
343 mb->_mvX = mb->_mvY = 0; // there is no motion vector in intra-macroblocks
344 } else {
345 if (band->_inheritMv && refMb) {
346 // motion vector inheritance
347 if (mvScale) {
348 mb->_mvX = scaleMV(refMb->_mvX, mvScale);
349 mb->_mvY = scaleMV(refMb->_mvY, mvScale);
350 } else {
351 mb->_mvX = refMb->_mvX;
352 mb->_mvY = refMb->_mvY;
353 }
354 } else {
355 // decode motion vector deltas
356 mvDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
357 mvY += IVI_TOSIGNED(mvDelta);
358 mvDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
359 mvX += IVI_TOSIGNED(mvDelta);
360 mb->_mvX = mvX;
361 mb->_mvY = mvY;
362 }
363 }
364 }
365
366 s = band->_isHalfpel;
367 if (mb->_type)
368 if (x + (mb->_mvX >> s) + (y + (mb->_mvY >> s)) * band->_pitch < 0 ||
369 x + ((mb->_mvX + s) >> s) + band->_mbSize - 1
370 + (y + band->_mbSize - 1 + ((mb->_mvY + s) >> s)) * band->_pitch > band->_bufSize - 1) {
371 warning("motion vector %d %d outside reference", x*s + mb->_mvX, y * s + mb->_mvY);
372 return -1;
373 }
374
375 mb++;
376 if (refMb)
377 refMb++;
378 mbOffset += band->_mbSize;
379 }
380
381 offs += rowOffset;
382 }
383
384 _ctx._gb->align();
385
386 return 0;
387 }
388
decode_gop_header()389 int Indeo5Decoder::decode_gop_header() {
390 int result, i, p, tileSize, picSizeIndx, mbSize, blkSize, isScalable;
391 int quantMat;
392 bool blkSizeChanged = false;
393 IVIBandDesc *band, *band1, *band2;
394 IVIPicConfig picConf;
395
396 _ctx._gopFlags = _ctx._gb->getBits(8);
397
398 _ctx._gopHdrSize = (_ctx._gopFlags & 1) ? _ctx._gb->getBits(16) : 0;
399
400 if (_ctx._gopFlags & IVI5_IS_PROTECTED)
401 _ctx._lockWord = _ctx._gb->getBits(32);
402
403 tileSize = (_ctx._gopFlags & 0x40) ? 64 << _ctx._gb->getBits(2) : 0;
404 if (tileSize > 256) {
405 warning("Invalid tile size: %d", tileSize);
406 return -1;
407 }
408
409 // decode number of wavelet bands
410 // num_levels * 3 + 1
411 picConf._lumaBands = _ctx._gb->getBits(2) * 3 + 1;
412 picConf._chromaBands = _ctx._gb->getBit() * 3 + 1;
413 isScalable = picConf._lumaBands != 1 || picConf._chromaBands != 1;
414 if (isScalable && (picConf._lumaBands != 4 || picConf._chromaBands != 1)) {
415 warning("Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d",
416 picConf._lumaBands, picConf._chromaBands);
417 return -1;
418 }
419
420 picSizeIndx = _ctx._gb->getBits(4);
421 if (picSizeIndx == IVI5_PIC_SIZE_ESC) {
422 picConf._picHeight = _ctx._gb->getBits(13);
423 picConf._picWidth = _ctx._gb->getBits(13);
424 } else {
425 picConf._picHeight = _commonPicSizes[picSizeIndx * 2 + 1] << 2;
426 picConf._picWidth = _commonPicSizes[picSizeIndx * 2] << 2;
427 }
428
429 if (_ctx._gopFlags & 2) {
430 warning("YV12 picture format");
431 return -2;
432 }
433
434 picConf._chromaHeight = (picConf._picHeight + 3) >> 2;
435 picConf._chromaWidth = (picConf._picWidth + 3) >> 2;
436
437 if (!tileSize) {
438 picConf._tileHeight = picConf._picHeight;
439 picConf._tileWidth = picConf._picWidth;
440 } else {
441 picConf._tileHeight = picConf._tileWidth = tileSize;
442 }
443
444 // check if picture layout was changed and reallocate buffers
445 if (picConf.ivi_pic_config_cmp(_ctx._picConf) || _ctx._gopInvalid) {
446 result = IVIPlaneDesc::initPlanes(_ctx._planes, &picConf, 0);
447 if (result < 0) {
448 warning("Couldn't reallocate color planes!");
449 return result;
450 }
451 _ctx._picConf = picConf;
452 _ctx._isScalable = isScalable;
453 blkSizeChanged = 1; // force reallocation of the internal structures
454 }
455
456 for (p = 0; p <= 1; p++) {
457 for (i = 0; i < (!p ? picConf._lumaBands : picConf._chromaBands); i++) {
458 band = &_ctx._planes[p]._bands[i];
459
460 band->_isHalfpel = _ctx._gb->getBit();
461
462 mbSize = _ctx._gb->getBit();
463 blkSize = 8 >> _ctx._gb->getBit();
464 mbSize = blkSize << (!mbSize ? 1 : 0);
465
466 if (p == 0 && blkSize == 4) {
467 warning("4x4 luma blocks are unsupported!");
468 return -2;
469 }
470
471 blkSizeChanged = mbSize != band->_mbSize || blkSize != band->_blkSize;
472 if (blkSizeChanged) {
473 band->_mbSize = mbSize;
474 band->_blkSize = blkSize;
475 }
476
477 if (_ctx._gb->getBit()) {
478 warning("Extended transform info");
479 return -2;
480 }
481
482 // select transform function and scan pattern according to plane and band number
483 switch ((p << 2) + i) {
484 case 0:
485 band->_invTransform = IndeoDSP::ffIviInverseSlant8x8;
486 band->_dcTransform = IndeoDSP::ffIviDcSlant2d;
487 band->_scan = ffZigZagDirect;
488 band->_transformSize = 8;
489 break;
490
491 case 1:
492 band->_invTransform = IndeoDSP::ffIviRowSlant8;
493 band->_dcTransform = IndeoDSP::ffIviDcRowSlant;
494 band->_scan = _ffIviVerticalScan8x8;
495 band->_transformSize = 8;
496 break;
497
498 case 2:
499 band->_invTransform = IndeoDSP::ffIviColSlant8;
500 band->_dcTransform = IndeoDSP::ffIviDcColSlant;
501 band->_scan = _ffIviHorizontalScan8x8;
502 band->_transformSize = 8;
503 break;
504
505 case 3:
506 band->_invTransform = IndeoDSP::ffIviPutPixels8x8;
507 band->_dcTransform = IndeoDSP::ffIviPutDcPixel8x8;
508 band->_scan = _ffIviHorizontalScan8x8;
509 band->_transformSize = 8;
510 break;
511
512 case 4:
513 band->_invTransform = IndeoDSP::ffIviInverseSlant4x4;
514 band->_dcTransform = IndeoDSP::ffIviDcSlant2d;
515 band->_scan = _ffIviDirectScan4x4;
516 band->_transformSize = 4;
517 break;
518
519 default:
520 break;
521 }
522
523 band->_is2dTrans = band->_invTransform == IndeoDSP::ffIviInverseSlant8x8 ||
524 band->_invTransform == IndeoDSP::ffIviInverseSlant4x4;
525
526 if (band->_transformSize != band->_blkSize) {
527 warning("transform and block size mismatch (%d != %d)", band->_transformSize, band->_blkSize);
528 return -1;
529 }
530
531 // select dequant matrix according to plane and band number
532 if (!p) {
533 quantMat = (picConf._lumaBands > 1) ? i + 1 : 0;
534 } else {
535 quantMat = 5;
536 }
537
538 if (band->_blkSize == 8) {
539 if (quantMat >= 5) {
540 warning("_quantMat %d too large!", quantMat);
541 return -1;
542 }
543 band->_intraBase = &_baseQuant8x8Intra[quantMat][0];
544 band->_interBase = &_baseQuant8x8Inter[quantMat][0];
545 band->_intraScale = &_scaleQuant8x8Intra[quantMat][0];
546 band->_interScale = &_scaleQuant8x8Inter[quantMat][0];
547 } else {
548 band->_intraBase = _baseQuant4x4Intra;
549 band->_interBase = _baseQuant4x4Inter;
550 band->_intraScale = _scaleQuant4x4Intra;
551 band->_interScale = _scaleQuant4x4Inter;
552 }
553
554 if (_ctx._gb->getBits(2)) {
555 warning("End marker missing!");
556 return -1;
557 }
558 }
559 }
560
561 // copy chroma parameters into the 2nd chroma plane
562 for (i = 0; i < picConf._chromaBands; i++) {
563 band1 = &_ctx._planes[1]._bands[i];
564 band2 = &_ctx._planes[2]._bands[i];
565
566 band2->_width = band1->_width;
567 band2->_height = band1->_height;
568 band2->_mbSize = band1->_mbSize;
569 band2->_blkSize = band1->_blkSize;
570 band2->_isHalfpel = band1->_isHalfpel;
571 band2->_intraBase = band1->_intraBase;
572 band2->_interBase = band1->_interBase;
573 band2->_intraScale = band1->_intraScale;
574 band2->_interScale = band1->_interScale;
575 band2->_scan = band1->_scan;
576 band2->_invTransform = band1->_invTransform;
577 band2->_dcTransform = band1->_dcTransform;
578 band2->_is2dTrans = band1->_is2dTrans;
579 band2->_transformSize = band1->_transformSize;
580 }
581
582 // reallocate internal structures if needed
583 if (blkSizeChanged) {
584 result = IVIPlaneDesc::initTiles(_ctx._planes, picConf._tileWidth,
585 picConf._tileHeight);
586 if (result < 0) {
587 warning("Couldn't reallocate internal structures!");
588 return result;
589 }
590 }
591
592 if (_ctx._gopFlags & 8) {
593 if (_ctx._gb->getBits(3)) {
594 warning("Alignment bits are not zero!");
595 return -1;
596 }
597
598 if (_ctx._gb->getBit())
599 _ctx._gb->skip(24); // skip transparency fill color
600 }
601
602 _ctx._gb->align();
603
604 _ctx._gb->skip(23); // FIXME: unknown meaning
605
606 // skip GOP extension if any
607 if (_ctx._gb->getBit()) {
608 do {
609 i = _ctx._gb->getBits(16);
610 } while (i & 0x8000);
611 }
612
613 _ctx._gb->align();
614
615 return 0;
616 }
617
skip_hdr_extension()618 int Indeo5Decoder::skip_hdr_extension() {
619 int i, len;
620
621 do {
622 len = _ctx._gb->getBits(8);
623 if (_ctx._gb->eos())
624 return -1;
625 for (i = 0; i < len; i++)
626 _ctx._gb->skip(8);
627 } while (len);
628
629 return 0;
630 }
631
632 /*------------------------------------------------------------------------*/
633
634 const uint8 Indeo5Decoder::_commonPicSizes[30] = {
635 160, 120, 80, 60, 40, 30, 176, 120, 88, 60, 88, 72, 44, 36, 60, 45, 160, 60,
636 176, 60, 20, 15, 22, 18, 0, 0, 0, 0, 0, 0
637 };
638
639 const uint16 Indeo5Decoder::_baseQuant8x8Inter[5][64] = {
640 {0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a, 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
641 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62, 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
642 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a, 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
643 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
644 },
645 {0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a, 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
646 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62, 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
647 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a, 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
648 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
649 },
650 {0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
651 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
652 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
653 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
654 },
655 {0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
656 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
657 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
658 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
659 },
660 {0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
661 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
662 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
663 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
664 }
665 };
666
667 const uint16 Indeo5Decoder::_baseQuant8x8Intra[5][64] = {
668 {0x1a, 0x2e, 0x36, 0x42, 0x46, 0x4a, 0x4e, 0x5a, 0x2e, 0x32, 0x3e, 0x42, 0x46, 0x4e, 0x56, 0x6a,
669 0x36, 0x3e, 0x3e, 0x44, 0x4a, 0x54, 0x66, 0x72, 0x42, 0x42, 0x44, 0x4a, 0x52, 0x62, 0x6c, 0x7a,
670 0x46, 0x46, 0x4a, 0x52, 0x5e, 0x66, 0x72, 0x8e, 0x4a, 0x4e, 0x54, 0x62, 0x66, 0x6e, 0x86, 0xa6,
671 0x4e, 0x56, 0x66, 0x6c, 0x72, 0x86, 0x9a, 0xca, 0x5a, 0x6a, 0x72, 0x7a, 0x8e, 0xa6, 0xca, 0xfe,
672 },
673 {0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a, 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
674 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62, 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
675 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a, 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
676 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
677 },
678 {0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
679 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
680 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
681 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
682 },
683 {0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
684 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
685 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
686 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
687 },
688 {0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
689 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
690 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
691 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
692 }
693 };
694
695 const uint16 Indeo5Decoder::_baseQuant4x4Inter[16] = {
696 0x1e, 0x3e, 0x4a, 0x52, 0x3e, 0x4a, 0x52, 0x56, 0x4a, 0x52, 0x56, 0x5e, 0x52, 0x56, 0x5e, 0x66
697 };
698
699 const uint16 Indeo5Decoder::_baseQuant4x4Intra[16] = {
700 0x1e, 0x3e, 0x4a, 0x52, 0x3e, 0x4a, 0x52, 0x5e, 0x4a, 0x52, 0x5e, 0x7a, 0x52, 0x5e, 0x7a, 0x92
701 };
702
703
704 const uint8 Indeo5Decoder::_scaleQuant8x8Inter[5][24] = {
705 {0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
706 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
707 },
708 {0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
709 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
710 },
711 {0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
712 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
713 },
714 {0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
715 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
716 },
717 {0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
718 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba,
719 },
720 };
721
722 const uint8 Indeo5Decoder::_scaleQuant8x8Intra[5][24] = {
723 {0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
724 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
725 },
726 {0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
727 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
728 },
729 {0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
730 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
731 },
732 {0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
733 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
734 },
735 {0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
736 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
737 }
738 };
739
740 const uint8 Indeo5Decoder::_scaleQuant4x4Inter[24] = {
741 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
742 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
743 };
744
745 const uint8 Indeo5Decoder::_scaleQuant4x4Intra[24] = {
746 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
747 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
748 };
749
750 } // End of namespace Image
751