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