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