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 break;
180 }
181
182 switch (_ctx._frameType) {
183 case FRAMETYPE_INTRA:
184 _ctx._bufSwitch = 0;
185 // FALLTHROUGH
186 case FRAMETYPE_INTER:
187 _ctx._interScal = 0;
188 _ctx._dstBuf = _ctx._bufSwitch;
189 _ctx._refBuf = _ctx._bufSwitch ^ 1;
190 break;
191
192 case FRAMETYPE_INTER_SCAL:
193 case FRAMETYPE_INTER_NOREF:
194 case FRAMETYPE_NULL:
195 break;
196 }
197 }
198
isNonNullFrame() const199 bool Indeo5Decoder::isNonNullFrame() const {
200 return _ctx._frameType != FRAMETYPE_NULL;
201 }
202
decodeBandHeader(IVIBandDesc * band)203 int Indeo5Decoder::decodeBandHeader(IVIBandDesc *band) {
204 int i, ret;
205 uint8 bandFlags;
206
207 bandFlags = _ctx._gb->getBits(8);
208
209 if (bandFlags & 1) {
210 band->_isEmpty = true;
211 return 0;
212 }
213
214 band->_dataSize = (_ctx._frameFlags & 0x80) ? _ctx._gb->getBits(24) : 0;
215
216 band->_inheritMv = (bandFlags & 2) != 0;
217 band->_inheritQDelta = (bandFlags & 8) != 0;
218 band->_qdeltaPresent = (bandFlags & 4) != 0;
219 if (!band->_qdeltaPresent)
220 band->_inheritQDelta = 1;
221
222 // decode rvmap probability corrections if any
223 band->_numCorr = 0; // there are no corrections
224 if (bandFlags & 0x10) {
225 band->_numCorr = _ctx._gb->getBits(8); // get number of correction pairs
226 if (band->_numCorr > 61) {
227 warning("Too many corrections: %d", band->_numCorr);
228 return -1;
229 }
230
231 // read correction pairs
232 for (i = 0; i < band->_numCorr * 2; i++)
233 band->_corr[i] = _ctx._gb->getBits(8);
234 }
235
236 // select appropriate rvmap table for this band
237 band->_rvmapSel = (bandFlags & 0x40) ? _ctx._gb->getBits(3) : 8;
238
239 // decode block huffman codebook
240 ret = band->_blkVlc.decodeHuffDesc(&_ctx, bandFlags & 0x80, IVI_BLK_HUFF);
241 if (ret < 0)
242 return ret;
243
244 band->_checksumPresent = _ctx._gb->getBit();
245 if (band->_checksumPresent)
246 band->_checksum = _ctx._gb->getBits(16);
247
248 band->_globQuant = _ctx._gb->getBits(5);
249
250 // skip unknown extension if any
251 if (bandFlags & 0x20) { // XXX: untested
252 _ctx._gb->align();
253 skip_hdr_extension();
254 }
255
256 _ctx._gb->align();
257
258 return 0;
259 }
260
decodeMbInfo(IVIBandDesc * band,IVITile * tile)261 int Indeo5Decoder::decodeMbInfo(IVIBandDesc *band, IVITile *tile) {
262 int x, y, mvX, mvY, mvDelta, offs, mbOffset, mvScale, blksPerMb, s;
263 IVIMbInfo *mb, *refMb;
264 int rowOffset = band->_mbSize * band->_pitch;
265
266 mb = tile->_mbs;
267 refMb = tile->_refMbs;
268 offs = tile->_yPos * band->_pitch + tile->_xPos;
269
270 if (!refMb &&
271 ((band->_qdeltaPresent && band->_inheritQDelta) || band->_inheritMv))
272 return -1;
273
274 if (tile->_numMBs != IVI_MBs_PER_TILE(tile->_width, tile->_height, band->_mbSize)) {
275 warning("Allocated tile size %d mismatches parameters %d",
276 tile->_numMBs, IVI_MBs_PER_TILE(tile->_width, tile->_height, band->_mbSize));
277 return -1;
278 }
279
280 // scale factor for motion vectors
281 mvScale = (_ctx._planes[0]._bands[0]._mbSize >> 3) - (band->_mbSize >> 3);
282 mvX = mvY = 0;
283
284 for (y = tile->_yPos; y < (tile->_yPos + tile->_height); y += band->_mbSize) {
285 mbOffset = offs;
286
287 for (x = tile->_xPos; x < (tile->_xPos + tile->_width); x += band->_mbSize) {
288 mb->_xPos = x;
289 mb->_yPos = y;
290 mb->_bufOffs = mbOffset;
291
292 if (_ctx._gb->getBit()) {
293 if (_ctx._frameType == FRAMETYPE_INTRA) {
294 warning("Empty macroblock in an INTRA picture!");
295 return -1;
296 }
297 mb->_type = 1; // empty macroblocks are always INTER
298 mb->_cbp = 0; // all blocks are empty
299
300 mb->_qDelta = 0;
301 if (!band->_plane && !band->_bandNum && (_ctx._frameFlags & 8)) {
302 mb->_qDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
303 mb->_qDelta = IVI_TOSIGNED(mb->_qDelta);
304 }
305
306 mb->_mvX = mb->_mvY = 0; // no motion vector coded
307 if (band->_inheritMv && refMb) {
308 // motion vector inheritance
309 if (mvScale) {
310 mb->_mvX = scaleMV(refMb->_mvX, mvScale);
311 mb->_mvY = scaleMV(refMb->_mvY, mvScale);
312 } else {
313 mb->_mvX = refMb->_mvX;
314 mb->_mvY = refMb->_mvY;
315 }
316 }
317 } else {
318 if (band->_inheritMv && refMb) {
319 mb->_type = refMb->_type; // copy mb_type from corresponding reference mb
320 } else if (_ctx._frameType == FRAMETYPE_INTRA) {
321 mb->_type = 0; // mb_type is always INTRA for intra-frames
322 } else {
323 mb->_type = _ctx._gb->getBit();
324 }
325
326 blksPerMb = band->_mbSize != band->_blkSize ? 4 : 1;
327 mb->_cbp = _ctx._gb->getBits(blksPerMb);
328
329 mb->_qDelta = 0;
330 if (band->_qdeltaPresent) {
331 if (band->_inheritQDelta) {
332 if (refMb) mb->_qDelta = refMb->_qDelta;
333 } else if (mb->_cbp || (!band->_plane && !band->_bandNum &&
334 (_ctx._frameFlags & 8))) {
335 mb->_qDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
336 mb->_qDelta = IVI_TOSIGNED(mb->_qDelta);
337 }
338 }
339
340 if (!mb->_type) {
341 mb->_mvX = mb->_mvY = 0; // there is no motion vector in intra-macroblocks
342 } else {
343 if (band->_inheritMv && refMb) {
344 // motion vector inheritance
345 if (mvScale) {
346 mb->_mvX = scaleMV(refMb->_mvX, mvScale);
347 mb->_mvY = scaleMV(refMb->_mvY, mvScale);
348 } else {
349 mb->_mvX = refMb->_mvX;
350 mb->_mvY = refMb->_mvY;
351 }
352 } else {
353 // decode motion vector deltas
354 mvDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
355 mvY += IVI_TOSIGNED(mvDelta);
356 mvDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
357 mvX += IVI_TOSIGNED(mvDelta);
358 mb->_mvX = mvX;
359 mb->_mvY = mvY;
360 }
361 }
362 }
363
364 s = band->_isHalfpel;
365 if (mb->_type)
366 if (x + (mb->_mvX >> s) + (y + (mb->_mvY >> s)) * band->_pitch < 0 ||
367 x + ((mb->_mvX + s) >> s) + band->_mbSize - 1
368 + (y + band->_mbSize - 1 + ((mb->_mvY + s) >> s)) * band->_pitch > band->_bufSize - 1) {
369 warning("motion vector %d %d outside reference", x*s + mb->_mvX, y * s + mb->_mvY);
370 return -1;
371 }
372
373 mb++;
374 if (refMb)
375 refMb++;
376 mbOffset += band->_mbSize;
377 }
378
379 offs += rowOffset;
380 }
381
382 _ctx._gb->align();
383
384 return 0;
385 }
386
decode_gop_header()387 int Indeo5Decoder::decode_gop_header() {
388 int result, i, p, tileSize, picSizeIndx, mbSize, blkSize, isScalable;
389 int quantMat;
390 bool blkSizeChanged = false;
391 IVIBandDesc *band, *band1, *band2;
392 IVIPicConfig picConf;
393
394 _ctx._gopFlags = _ctx._gb->getBits(8);
395
396 _ctx._gopHdrSize = (_ctx._gopFlags & 1) ? _ctx._gb->getBits(16) : 0;
397
398 if (_ctx._gopFlags & IVI5_IS_PROTECTED)
399 _ctx._lockWord = _ctx._gb->getBits(32);
400
401 tileSize = (_ctx._gopFlags & 0x40) ? 64 << _ctx._gb->getBits(2) : 0;
402 if (tileSize > 256) {
403 warning("Invalid tile size: %d", tileSize);
404 return -1;
405 }
406
407 // decode number of wavelet bands
408 // num_levels * 3 + 1
409 picConf._lumaBands = _ctx._gb->getBits(2) * 3 + 1;
410 picConf._chromaBands = _ctx._gb->getBit() * 3 + 1;
411 isScalable = picConf._lumaBands != 1 || picConf._chromaBands != 1;
412 if (isScalable && (picConf._lumaBands != 4 || picConf._chromaBands != 1)) {
413 warning("Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d",
414 picConf._lumaBands, picConf._chromaBands);
415 return -1;
416 }
417
418 picSizeIndx = _ctx._gb->getBits(4);
419 if (picSizeIndx == IVI5_PIC_SIZE_ESC) {
420 picConf._picHeight = _ctx._gb->getBits(13);
421 picConf._picWidth = _ctx._gb->getBits(13);
422 } else {
423 picConf._picHeight = _commonPicSizes[picSizeIndx * 2 + 1] << 2;
424 picConf._picWidth = _commonPicSizes[picSizeIndx * 2] << 2;
425 }
426
427 if (_ctx._gopFlags & 2) {
428 warning("YV12 picture format");
429 return -2;
430 }
431
432 picConf._chromaHeight = (picConf._picHeight + 3) >> 2;
433 picConf._chromaWidth = (picConf._picWidth + 3) >> 2;
434
435 if (!tileSize) {
436 picConf._tileHeight = picConf._picHeight;
437 picConf._tileWidth = picConf._picWidth;
438 } else {
439 picConf._tileHeight = picConf._tileWidth = tileSize;
440 }
441
442 // check if picture layout was changed and reallocate buffers
443 if (picConf.ivi_pic_config_cmp(_ctx._picConf) || _ctx._gopInvalid) {
444 result = IVIPlaneDesc::initPlanes(_ctx._planes, &picConf, 0);
445 if (result < 0) {
446 warning("Couldn't reallocate color planes!");
447 return result;
448 }
449 _ctx._picConf = picConf;
450 _ctx._isScalable = isScalable;
451 blkSizeChanged = 1; // force reallocation of the internal structures
452 }
453
454 for (p = 0; p <= 1; p++) {
455 for (i = 0; i < (!p ? picConf._lumaBands : picConf._chromaBands); i++) {
456 band = &_ctx._planes[p]._bands[i];
457
458 band->_isHalfpel = _ctx._gb->getBit();
459
460 mbSize = _ctx._gb->getBit();
461 blkSize = 8 >> _ctx._gb->getBit();
462 mbSize = blkSize << (!mbSize ? 1 : 0);
463
464 if (p == 0 && blkSize == 4) {
465 warning("4x4 luma blocks are unsupported!");
466 return -2;
467 }
468
469 blkSizeChanged = mbSize != band->_mbSize || blkSize != band->_blkSize;
470 if (blkSizeChanged) {
471 band->_mbSize = mbSize;
472 band->_blkSize = blkSize;
473 }
474
475 if (_ctx._gb->getBit()) {
476 warning("Extended transform info");
477 return -2;
478 }
479
480 // select transform function and scan pattern according to plane and band number
481 switch ((p << 2) + i) {
482 case 0:
483 band->_invTransform = IndeoDSP::ffIviInverseSlant8x8;
484 band->_dcTransform = IndeoDSP::ffIviDcSlant2d;
485 band->_scan = ffZigZagDirect;
486 band->_transformSize = 8;
487 break;
488
489 case 1:
490 band->_invTransform = IndeoDSP::ffIviRowSlant8;
491 band->_dcTransform = IndeoDSP::ffIviDcRowSlant;
492 band->_scan = _ffIviVerticalScan8x8;
493 band->_transformSize = 8;
494 break;
495
496 case 2:
497 band->_invTransform = IndeoDSP::ffIviColSlant8;
498 band->_dcTransform = IndeoDSP::ffIviDcColSlant;
499 band->_scan = _ffIviHorizontalScan8x8;
500 band->_transformSize = 8;
501 break;
502
503 case 3:
504 band->_invTransform = IndeoDSP::ffIviPutPixels8x8;
505 band->_dcTransform = IndeoDSP::ffIviPutDcPixel8x8;
506 band->_scan = _ffIviHorizontalScan8x8;
507 band->_transformSize = 8;
508 break;
509
510 case 4:
511 band->_invTransform = IndeoDSP::ffIviInverseSlant4x4;
512 band->_dcTransform = IndeoDSP::ffIviDcSlant2d;
513 band->_scan = _ffIviDirectScan4x4;
514 band->_transformSize = 4;
515 break;
516 }
517
518 band->_is2dTrans = band->_invTransform == IndeoDSP::ffIviInverseSlant8x8 ||
519 band->_invTransform == IndeoDSP::ffIviInverseSlant4x4;
520
521 if (band->_transformSize != band->_blkSize) {
522 warning("transform and block size mismatch (%d != %d)", band->_transformSize, band->_blkSize);
523 return -1;
524 }
525
526 // select dequant matrix according to plane and band number
527 if (!p) {
528 quantMat = (picConf._lumaBands > 1) ? i + 1 : 0;
529 } else {
530 quantMat = 5;
531 }
532
533 if (band->_blkSize == 8) {
534 if (quantMat >= 5) {
535 warning("_quantMat %d too large!", quantMat);
536 return -1;
537 }
538 band->_intraBase = &_baseQuant8x8Intra[quantMat][0];
539 band->_interBase = &_baseQuant8x8Inter[quantMat][0];
540 band->_intraScale = &_scaleQuant8x8Intra[quantMat][0];
541 band->_interScale = &_scaleQuant8x8Inter[quantMat][0];
542 } else {
543 band->_intraBase = _baseQuant4x4Intra;
544 band->_interBase = _baseQuant4x4Inter;
545 band->_intraScale = _scaleQuant4x4Intra;
546 band->_interScale = _scaleQuant4x4Inter;
547 }
548
549 if (_ctx._gb->getBits(2)) {
550 warning("End marker missing!");
551 return -1;
552 }
553 }
554 }
555
556 // copy chroma parameters into the 2nd chroma plane
557 for (i = 0; i < picConf._chromaBands; i++) {
558 band1 = &_ctx._planes[1]._bands[i];
559 band2 = &_ctx._planes[2]._bands[i];
560
561 band2->_width = band1->_width;
562 band2->_height = band1->_height;
563 band2->_mbSize = band1->_mbSize;
564 band2->_blkSize = band1->_blkSize;
565 band2->_isHalfpel = band1->_isHalfpel;
566 band2->_intraBase = band1->_intraBase;
567 band2->_interBase = band1->_interBase;
568 band2->_intraScale = band1->_intraScale;
569 band2->_interScale = band1->_interScale;
570 band2->_scan = band1->_scan;
571 band2->_invTransform = band1->_invTransform;
572 band2->_dcTransform = band1->_dcTransform;
573 band2->_is2dTrans = band1->_is2dTrans;
574 band2->_transformSize = band1->_transformSize;
575 }
576
577 // reallocate internal structures if needed
578 if (blkSizeChanged) {
579 result = IVIPlaneDesc::initTiles(_ctx._planes, picConf._tileWidth,
580 picConf._tileHeight);
581 if (result < 0) {
582 warning("Couldn't reallocate internal structures!");
583 return result;
584 }
585 }
586
587 if (_ctx._gopFlags & 8) {
588 if (_ctx._gb->getBits(3)) {
589 warning("Alignment bits are not zero!");
590 return -1;
591 }
592
593 if (_ctx._gb->getBit())
594 _ctx._gb->skip(24); // skip transparency fill color
595 }
596
597 _ctx._gb->align();
598
599 _ctx._gb->skip(23); // FIXME: unknown meaning
600
601 // skip GOP extension if any
602 if (_ctx._gb->getBit()) {
603 do {
604 i = _ctx._gb->getBits(16);
605 } while (i & 0x8000);
606 }
607
608 _ctx._gb->align();
609
610 return 0;
611 }
612
skip_hdr_extension()613 int Indeo5Decoder::skip_hdr_extension() {
614 int i, len;
615
616 do {
617 len = _ctx._gb->getBits(8);
618 if (_ctx._gb->eos())
619 return -1;
620 for (i = 0; i < len; i++)
621 _ctx._gb->skip(8);
622 } while (len);
623
624 return 0;
625 }
626
627 /*------------------------------------------------------------------------*/
628
629 const uint8 Indeo5Decoder::_commonPicSizes[30] = {
630 160, 120, 80, 60, 40, 30, 176, 120, 88, 60, 88, 72, 44, 36, 60, 45, 160, 60,
631 176, 60, 20, 15, 22, 18, 0, 0, 0, 0, 0, 0
632 };
633
634 const uint16 Indeo5Decoder::_baseQuant8x8Inter[5][64] = {
635 {0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a, 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
636 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62, 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
637 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a, 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
638 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
639 },
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 {0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
646 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
647 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
648 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
649 },
650 {0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
651 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
652 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
653 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
654 },
655 {0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
656 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
657 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
658 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
659 }
660 };
661
662 const uint16 Indeo5Decoder::_baseQuant8x8Intra[5][64] = {
663 {0x1a, 0x2e, 0x36, 0x42, 0x46, 0x4a, 0x4e, 0x5a, 0x2e, 0x32, 0x3e, 0x42, 0x46, 0x4e, 0x56, 0x6a,
664 0x36, 0x3e, 0x3e, 0x44, 0x4a, 0x54, 0x66, 0x72, 0x42, 0x42, 0x44, 0x4a, 0x52, 0x62, 0x6c, 0x7a,
665 0x46, 0x46, 0x4a, 0x52, 0x5e, 0x66, 0x72, 0x8e, 0x4a, 0x4e, 0x54, 0x62, 0x66, 0x6e, 0x86, 0xa6,
666 0x4e, 0x56, 0x66, 0x6c, 0x72, 0x86, 0x9a, 0xca, 0x5a, 0x6a, 0x72, 0x7a, 0x8e, 0xa6, 0xca, 0xfe,
667 },
668 {0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a, 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
669 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62, 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
670 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a, 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
671 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
672 },
673 {0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
674 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
675 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
676 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
677 },
678 {0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
679 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
680 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
681 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
682 },
683 {0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
684 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
685 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
686 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
687 }
688 };
689
690 const uint16 Indeo5Decoder::_baseQuant4x4Inter[16] = {
691 0x1e, 0x3e, 0x4a, 0x52, 0x3e, 0x4a, 0x52, 0x56, 0x4a, 0x52, 0x56, 0x5e, 0x52, 0x56, 0x5e, 0x66
692 };
693
694 const uint16 Indeo5Decoder::_baseQuant4x4Intra[16] = {
695 0x1e, 0x3e, 0x4a, 0x52, 0x3e, 0x4a, 0x52, 0x5e, 0x4a, 0x52, 0x5e, 0x7a, 0x52, 0x5e, 0x7a, 0x92
696 };
697
698
699 const uint8 Indeo5Decoder::_scaleQuant8x8Inter[5][24] = {
700 {0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
701 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
702 },
703 {0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
704 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
705 },
706 {0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
707 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
708 },
709 {0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
710 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
711 },
712 {0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
713 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba,
714 },
715 };
716
717 const uint8 Indeo5Decoder::_scaleQuant8x8Intra[5][24] = {
718 {0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
719 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
720 },
721 {0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
722 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
723 },
724 {0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
725 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
726 },
727 {0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
728 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
729 },
730 {0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
731 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
732 }
733 };
734
735 const uint8 Indeo5Decoder::_scaleQuant4x4Inter[24] = {
736 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
737 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
738 };
739
740 const uint8 Indeo5Decoder::_scaleQuant4x4Intra[24] = {
741 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
742 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
743 };
744
745 } // End of namespace Image
746