ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

indeo5.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 /* Intel Indeo 5 decompressor, derived from ffmpeg.
00024  *
00025  * Original copyright note: * Intel Indeo 5 (IV51, IV52, etc.) video decoder for ffmpeg
00026  * written, produced, and directed by Alan Smithee
00027  */
00028 
00029 #include "common/memstream.h"
00030 #include "common/textconsole.h"
00031 #include "graphics/yuv_to_rgb.h"
00032 #include "image/codecs/indeo5.h"
00033 #include "image/codecs/indeo/indeo_dsp.h"
00034 #include "image/codecs/indeo/mem.h"
00035 
00036 namespace Image {
00037 
00041 enum {
00042     FRAMETYPE_INTRA       = 0,
00043     FRAMETYPE_INTER       = 1,  
00044     FRAMETYPE_INTER_SCAL  = 2,  
00045     FRAMETYPE_INTER_NOREF = 3,  
00046     FRAMETYPE_NULL        = 4   
00047 };
00048 
00049 #define IVI5_PIC_SIZE_ESC       15
00050 
00051 Indeo5Decoder::Indeo5Decoder(uint16 width, uint16 height, uint bitsPerPixel) :
00052         IndeoDecoderBase(width, height, bitsPerPixel) {
00053     _ctx._isIndeo4 = false;
00054     _ctx._refBuf = 1;
00055     _ctx._bRefBuf = 3;
00056     _ctx._pFrame = new AVFrame();
00057 }
00058 
00059 bool Indeo5Decoder::isIndeo5(Common::SeekableReadStream &stream) {
00060     // Less than 16 bytes? This can't be right
00061     if (stream.size() < 16)
00062         return false;
00063 
00064     // Read in the start of the data
00065     byte buffer[16];
00066     stream.read(buffer, 16);
00067     stream.seek(-16, SEEK_CUR);
00068 
00069     // Validate the first 5-bit word has the correct identifier
00070     Indeo::GetBits gb(buffer, 16 * 8);
00071     bool isIndeo5 = gb.getBits(5) == 0x1F;
00072 
00073     return isIndeo5;
00074 }
00075 
00076 const Graphics::Surface *Indeo5Decoder::decodeFrame(Common::SeekableReadStream &stream) {
00077     // Not Indeo 5? Fail
00078     if (!isIndeo5(stream))
00079         return nullptr;
00080 
00081     // Set up the frame data buffer
00082     byte *frameData = new byte[stream.size()];
00083     stream.read(frameData, stream.size());
00084     _ctx._frameData = frameData;
00085     _ctx._frameSize = stream.size();
00086 
00087     // Set up the GetBits instance for reading the data
00088     _ctx._gb = new GetBits(_ctx._frameData, _ctx._frameSize);
00089 
00090     // Decode the frame
00091     int err = decodeIndeoFrame();
00092 
00093     // Free the bit reader and frame buffer
00094     delete _ctx._gb;
00095     _ctx._gb = nullptr;
00096     delete[] frameData;
00097     _ctx._frameData = nullptr;
00098     _ctx._frameSize = 0;
00099 
00100     return (err < 0) ? nullptr : &_surface;
00101 }
00102 
00103 int Indeo5Decoder::decodePictureHeader() {
00104     IVIPicConfig picConf;
00105     int ret;
00106 
00107     if (_ctx._gb->getBits(5) != 0x1F) {
00108         warning("Invalid picture start code!");
00109         return -1;
00110     }
00111 
00112     _ctx._prevFrameType = _ctx._frameType;
00113     _ctx._frameType = _ctx._gb->getBits(3);
00114     if (_ctx._frameType >= 5) {
00115         warning("Invalid frame type: %d", _ctx._frameType);
00116         return -1;
00117     }
00118 
00119     _ctx._frameNum = _ctx._gb->getBits(8);
00120 
00121     if (_ctx._frameType == FRAMETYPE_INTRA) {
00122         if ((ret = decode_gop_header()) < 0) {
00123             warning("Invalid GOP header, skipping frames.");
00124             _ctx._gopInvalid = true;
00125             return ret;
00126         }
00127         _ctx._gopInvalid = false;
00128     }
00129 
00130     if (_ctx._frameType == FRAMETYPE_INTER_SCAL && !_ctx._isScalable) {
00131         warning("Scalable inter frame in non scalable stream");
00132         _ctx._frameType = FRAMETYPE_INTER;
00133         return -1;
00134     }
00135 
00136     if (_ctx._frameType != FRAMETYPE_NULL) {
00137         _ctx._frameFlags = _ctx._gb->getBits(8);
00138 
00139         _ctx._picHdrSize = (_ctx._frameFlags & 1) ? _ctx._gb->getBits(24) : 0;
00140 
00141         _ctx._checksum = (_ctx._frameFlags & 0x10) ? _ctx._gb->getBits(16) : 0;
00142 
00143         // skip unknown extension if any
00144         if (_ctx._frameFlags & 0x20)
00145             skip_hdr_extension(); // XXX: untested
00146 
00147                                           // decode macroblock huffman codebook
00148         ret = _ctx._mbVlc.decodeHuffDesc(&_ctx, _ctx._frameFlags & 0x40,
00149             IVI_MB_HUFF);
00150         if (ret < 0)
00151             return ret;
00152 
00153         _ctx._gb->skip(3); // FIXME: unknown meaning!
00154     }
00155 
00156     _ctx._gb->align();
00157     return 0;
00158 }
00159 
00160 void Indeo5Decoder::switchBuffers() {
00161     switch (_ctx._prevFrameType) {
00162     case FRAMETYPE_INTRA:
00163     case FRAMETYPE_INTER:
00164         _ctx._bufSwitch ^= 1;
00165         _ctx._dstBuf = _ctx._bufSwitch;
00166         _ctx._refBuf = _ctx._bufSwitch ^ 1;
00167         break;
00168 
00169     case FRAMETYPE_INTER_SCAL:
00170         if (!_ctx._interScal) {
00171             _ctx._ref2Buf = 2;
00172             _ctx._interScal = 1;
00173         }
00174         SWAP(_ctx._dstBuf, _ctx._ref2Buf);
00175         _ctx._refBuf = _ctx._ref2Buf;
00176         break;
00177 
00178     case FRAMETYPE_INTER_NOREF:
00179         break;
00180     }
00181 
00182     switch (_ctx._frameType) {
00183     case FRAMETYPE_INTRA:
00184         _ctx._bufSwitch = 0;
00185         // FALLTHROUGH
00186     case FRAMETYPE_INTER:
00187         _ctx._interScal = 0;
00188         _ctx._dstBuf = _ctx._bufSwitch;
00189         _ctx._refBuf = _ctx._bufSwitch ^ 1;
00190         break;
00191 
00192     case FRAMETYPE_INTER_SCAL:
00193     case FRAMETYPE_INTER_NOREF:
00194     case FRAMETYPE_NULL:
00195         break;
00196     }
00197 }
00198 
00199 bool Indeo5Decoder::isNonNullFrame() const {
00200     return _ctx._frameType != FRAMETYPE_NULL;
00201 }
00202 
00203 int Indeo5Decoder::decodeBandHeader(IVIBandDesc *band) {
00204     int i, ret;
00205     uint8 bandFlags;
00206 
00207     bandFlags = _ctx._gb->getBits(8);
00208 
00209     if (bandFlags & 1) {
00210         band->_isEmpty = true;
00211         return 0;
00212     }
00213 
00214     band->_dataSize = (_ctx._frameFlags & 0x80) ? _ctx._gb->getBits(24) : 0;
00215 
00216     band->_inheritMv = (bandFlags & 2) != 0;
00217     band->_inheritQDelta = (bandFlags & 8) != 0;
00218     band->_qdeltaPresent = (bandFlags & 4) != 0;
00219     if (!band->_qdeltaPresent)
00220         band->_inheritQDelta = 1;
00221 
00222     // decode rvmap probability corrections if any
00223     band->_numCorr = 0; // there are no corrections
00224     if (bandFlags & 0x10) {
00225         band->_numCorr = _ctx._gb->getBits(8); // get number of correction pairs
00226         if (band->_numCorr > 61) {
00227             warning("Too many corrections: %d", band->_numCorr);
00228             return -1;
00229         }
00230 
00231         // read correction pairs
00232         for (i = 0; i < band->_numCorr * 2; i++)
00233             band->_corr[i] = _ctx._gb->getBits(8);
00234     }
00235 
00236     // select appropriate rvmap table for this band
00237     band->_rvmapSel = (bandFlags & 0x40) ? _ctx._gb->getBits(3) : 8;
00238 
00239     // decode block huffman codebook
00240     ret = band->_blkVlc.decodeHuffDesc(&_ctx, bandFlags & 0x80, IVI_BLK_HUFF);
00241     if (ret < 0)
00242         return ret;
00243 
00244     band->_checksumPresent = _ctx._gb->getBit();
00245     if (band->_checksumPresent)
00246         band->_checksum = _ctx._gb->getBits(16);
00247 
00248     band->_globQuant = _ctx._gb->getBits(5);
00249 
00250     // skip unknown extension if any
00251     if (bandFlags & 0x20) { // XXX: untested
00252         _ctx._gb->align();
00253         skip_hdr_extension();
00254     }
00255 
00256     _ctx._gb->align();
00257 
00258     return 0;
00259 }
00260 
00261 int Indeo5Decoder::decodeMbInfo(IVIBandDesc *band, IVITile *tile) {
00262     int x, y, mvX, mvY, mvDelta, offs, mbOffset, mvScale, blksPerMb, s;
00263     IVIMbInfo *mb, *refMb;
00264     int rowOffset = band->_mbSize * band->_pitch;
00265 
00266     mb = tile->_mbs;
00267     refMb = tile->_refMbs;
00268     offs = tile->_yPos * band->_pitch + tile->_xPos;
00269 
00270     if (!refMb &&
00271         ((band->_qdeltaPresent && band->_inheritQDelta) || band->_inheritMv))
00272         return -1;
00273 
00274     if (tile->_numMBs != IVI_MBs_PER_TILE(tile->_width, tile->_height, band->_mbSize)) {
00275         warning("Allocated tile size %d mismatches parameters %d",
00276             tile->_numMBs, IVI_MBs_PER_TILE(tile->_width, tile->_height, band->_mbSize));
00277         return -1;
00278     }
00279 
00280     // scale factor for motion vectors
00281     mvScale = (_ctx._planes[0]._bands[0]._mbSize >> 3) - (band->_mbSize >> 3);
00282     mvX = mvY = 0;
00283 
00284     for (y = tile->_yPos; y < (tile->_yPos + tile->_height); y += band->_mbSize) {
00285         mbOffset = offs;
00286 
00287         for (x = tile->_xPos; x < (tile->_xPos + tile->_width); x += band->_mbSize) {
00288             mb->_xPos = x;
00289             mb->_yPos = y;
00290             mb->_bufOffs = mbOffset;
00291 
00292             if (_ctx._gb->getBit()) {
00293                 if (_ctx._frameType == FRAMETYPE_INTRA) {
00294                     warning("Empty macroblock in an INTRA picture!");
00295                     return -1;
00296                 }
00297                 mb->_type = 1; // empty macroblocks are always INTER
00298                 mb->_cbp = 0; // all blocks are empty
00299 
00300                 mb->_qDelta = 0;
00301                 if (!band->_plane && !band->_bandNum && (_ctx._frameFlags & 8)) {
00302                     mb->_qDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
00303                     mb->_qDelta = IVI_TOSIGNED(mb->_qDelta);
00304                 }
00305 
00306                 mb->_mvX = mb->_mvY = 0; // no motion vector coded
00307                 if (band->_inheritMv && refMb) {
00308                     // motion vector inheritance
00309                     if (mvScale) {
00310                         mb->_mvX = scaleMV(refMb->_mvX, mvScale);
00311                         mb->_mvY = scaleMV(refMb->_mvY, mvScale);
00312                     } else {
00313                         mb->_mvX = refMb->_mvX;
00314                         mb->_mvY = refMb->_mvY;
00315                     }
00316                 }
00317             } else {
00318                 if (band->_inheritMv && refMb) {
00319                     mb->_type = refMb->_type; // copy mb_type from corresponding reference mb
00320                 } else if (_ctx._frameType == FRAMETYPE_INTRA) {
00321                     mb->_type = 0; // mb_type is always INTRA for intra-frames
00322                 } else {
00323                     mb->_type = _ctx._gb->getBit();
00324                 }
00325 
00326                 blksPerMb = band->_mbSize != band->_blkSize ? 4 : 1;
00327                 mb->_cbp = _ctx._gb->getBits(blksPerMb);
00328 
00329                 mb->_qDelta = 0;
00330                 if (band->_qdeltaPresent) {
00331                     if (band->_inheritQDelta) {
00332                         if (refMb) mb->_qDelta = refMb->_qDelta;
00333                     } else if (mb->_cbp || (!band->_plane && !band->_bandNum &&
00334                         (_ctx._frameFlags & 8))) {
00335                         mb->_qDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
00336                         mb->_qDelta = IVI_TOSIGNED(mb->_qDelta);
00337                     }
00338                 }
00339 
00340                 if (!mb->_type) {
00341                     mb->_mvX = mb->_mvY = 0; // there is no motion vector in intra-macroblocks
00342                 } else {
00343                     if (band->_inheritMv && refMb) {
00344                         // motion vector inheritance
00345                         if (mvScale) {
00346                             mb->_mvX = scaleMV(refMb->_mvX, mvScale);
00347                             mb->_mvY = scaleMV(refMb->_mvY, mvScale);
00348                         } else {
00349                             mb->_mvX = refMb->_mvX;
00350                             mb->_mvY = refMb->_mvY;
00351                         }
00352                     } else {
00353                         // decode motion vector deltas
00354                         mvDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
00355                         mvY += IVI_TOSIGNED(mvDelta);
00356                         mvDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table, IVI_VLC_BITS);
00357                         mvX += IVI_TOSIGNED(mvDelta);
00358                         mb->_mvX = mvX;
00359                         mb->_mvY = mvY;
00360                     }
00361                 }
00362             }
00363 
00364             s = band->_isHalfpel;
00365             if (mb->_type)
00366                 if (x + (mb->_mvX >> s) + (y + (mb->_mvY >> s)) * band->_pitch < 0 ||
00367                     x + ((mb->_mvX + s) >> s) + band->_mbSize - 1
00368                     + (y + band->_mbSize - 1 + ((mb->_mvY + s) >> s)) * band->_pitch > band->_bufSize - 1) {
00369                     warning("motion vector %d %d outside reference", x*s + mb->_mvX, y * s + mb->_mvY);
00370                     return -1;
00371                 }
00372 
00373             mb++;
00374             if (refMb)
00375                 refMb++;
00376             mbOffset += band->_mbSize;
00377         }
00378 
00379         offs += rowOffset;
00380     }
00381 
00382     _ctx._gb->align();
00383 
00384     return 0;
00385 }
00386 
00387 int Indeo5Decoder::decode_gop_header() {
00388     int result, i, p, tileSize, picSizeIndx, mbSize, blkSize, isScalable;
00389     int quantMat;
00390     bool blkSizeChanged = false;
00391     IVIBandDesc *band, *band1, *band2;
00392     IVIPicConfig picConf;
00393 
00394     _ctx._gopFlags = _ctx._gb->getBits(8);
00395 
00396     _ctx._gopHdrSize = (_ctx._gopFlags & 1) ? _ctx._gb->getBits(16) : 0;
00397 
00398     if (_ctx._gopFlags & IVI5_IS_PROTECTED)
00399         _ctx._lockWord = _ctx._gb->getBits(32);
00400 
00401     tileSize = (_ctx._gopFlags & 0x40) ? 64 << _ctx._gb->getBits(2) : 0;
00402     if (tileSize > 256) {
00403         warning("Invalid tile size: %d", tileSize);
00404         return -1;
00405     }
00406 
00407     // decode number of wavelet bands
00408     // num_levels * 3 + 1
00409     picConf._lumaBands = _ctx._gb->getBits(2) * 3 + 1;
00410     picConf._chromaBands = _ctx._gb->getBit() * 3 + 1;
00411     isScalable = picConf._lumaBands != 1 || picConf._chromaBands != 1;
00412     if (isScalable && (picConf._lumaBands != 4 || picConf._chromaBands != 1)) {
00413         warning("Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d",
00414             picConf._lumaBands, picConf._chromaBands);
00415         return -1;
00416     }
00417 
00418     picSizeIndx = _ctx._gb->getBits(4);
00419     if (picSizeIndx == IVI5_PIC_SIZE_ESC) {
00420         picConf._picHeight = _ctx._gb->getBits(13);
00421         picConf._picWidth = _ctx._gb->getBits(13);
00422     } else {
00423         picConf._picHeight = _commonPicSizes[picSizeIndx * 2 + 1] << 2;
00424         picConf._picWidth = _commonPicSizes[picSizeIndx * 2] << 2;
00425     }
00426 
00427     if (_ctx._gopFlags & 2) {
00428         warning("YV12 picture format");
00429         return -2;
00430     }
00431 
00432     picConf._chromaHeight = (picConf._picHeight + 3) >> 2;
00433     picConf._chromaWidth = (picConf._picWidth + 3) >> 2;
00434 
00435     if (!tileSize) {
00436         picConf._tileHeight = picConf._picHeight;
00437         picConf._tileWidth = picConf._picWidth;
00438     } else {
00439         picConf._tileHeight = picConf._tileWidth = tileSize;
00440     }
00441 
00442     // check if picture layout was changed and reallocate buffers
00443     if (picConf.ivi_pic_config_cmp(_ctx._picConf) || _ctx._gopInvalid) {
00444         result = IVIPlaneDesc::initPlanes(_ctx._planes, &picConf, 0);
00445         if (result < 0) {
00446             warning("Couldn't reallocate color planes!");
00447             return result;
00448         }
00449         _ctx._picConf = picConf;
00450         _ctx._isScalable = isScalable;
00451         blkSizeChanged = 1; // force reallocation of the internal structures
00452     }
00453 
00454     for (p = 0; p <= 1; p++) {
00455         for (i = 0; i < (!p ? picConf._lumaBands : picConf._chromaBands); i++) {
00456             band = &_ctx._planes[p]._bands[i];
00457 
00458             band->_isHalfpel = _ctx._gb->getBit();
00459 
00460             mbSize = _ctx._gb->getBit();
00461             blkSize = 8 >> _ctx._gb->getBit();
00462             mbSize = blkSize << (!mbSize ? 1 : 0);
00463 
00464             if (p == 0 && blkSize == 4) {
00465                 warning("4x4 luma blocks are unsupported!");
00466                 return -2;
00467             }
00468 
00469             blkSizeChanged = mbSize != band->_mbSize || blkSize != band->_blkSize;
00470             if (blkSizeChanged) {
00471                 band->_mbSize = mbSize;
00472                 band->_blkSize = blkSize;
00473             }
00474 
00475             if (_ctx._gb->getBit()) {
00476                 warning("Extended transform info");
00477                 return -2;
00478             }
00479 
00480             // select transform function and scan pattern according to plane and band number
00481             switch ((p << 2) + i) {
00482             case 0:
00483                 band->_invTransform = IndeoDSP::ffIviInverseSlant8x8;
00484                 band->_dcTransform = IndeoDSP::ffIviDcSlant2d;
00485                 band->_scan = ffZigZagDirect;
00486                 band->_transformSize = 8;
00487                 break;
00488 
00489             case 1:
00490                 band->_invTransform = IndeoDSP::ffIviRowSlant8;
00491                 band->_dcTransform = IndeoDSP::ffIviDcRowSlant;
00492                 band->_scan = _ffIviVerticalScan8x8;
00493                 band->_transformSize = 8;
00494                 break;
00495 
00496             case 2:
00497                 band->_invTransform = IndeoDSP::ffIviColSlant8;
00498                 band->_dcTransform = IndeoDSP::ffIviDcColSlant;
00499                 band->_scan = _ffIviHorizontalScan8x8;
00500                 band->_transformSize = 8;
00501                 break;
00502 
00503             case 3:
00504                 band->_invTransform = IndeoDSP::ffIviPutPixels8x8;
00505                 band->_dcTransform = IndeoDSP::ffIviPutDcPixel8x8;
00506                 band->_scan = _ffIviHorizontalScan8x8;
00507                 band->_transformSize = 8;
00508                 break;
00509 
00510             case 4:
00511                 band->_invTransform = IndeoDSP::ffIviInverseSlant4x4;
00512                 band->_dcTransform = IndeoDSP::ffIviDcSlant2d;
00513                 band->_scan = _ffIviDirectScan4x4;
00514                 band->_transformSize = 4;
00515                 break;
00516             }
00517 
00518             band->_is2dTrans = band->_invTransform == IndeoDSP::ffIviInverseSlant8x8 ||
00519                 band->_invTransform == IndeoDSP::ffIviInverseSlant4x4;
00520 
00521             if (band->_transformSize != band->_blkSize) {
00522                 warning("transform and block size mismatch (%d != %d)", band->_transformSize, band->_blkSize);
00523                 return -1;
00524             }
00525 
00526             // select dequant matrix according to plane and band number
00527             if (!p) {
00528                 quantMat = (picConf._lumaBands > 1) ? i + 1 : 0;
00529             } else {
00530                 quantMat = 5;
00531             }
00532 
00533             if (band->_blkSize == 8) {
00534                 if (quantMat >= 5) {
00535                     warning("_quantMat %d too large!", quantMat);
00536                     return -1;
00537                 }
00538                 band->_intraBase = &_baseQuant8x8Intra[quantMat][0];
00539                 band->_interBase = &_baseQuant8x8Inter[quantMat][0];
00540                 band->_intraScale = &_scaleQuant8x8Intra[quantMat][0];
00541                 band->_interScale = &_scaleQuant8x8Inter[quantMat][0];
00542             } else {
00543                 band->_intraBase = _baseQuant4x4Intra;
00544                 band->_interBase = _baseQuant4x4Inter;
00545                 band->_intraScale = _scaleQuant4x4Intra;
00546                 band->_interScale = _scaleQuant4x4Inter;
00547             }
00548 
00549             if (_ctx._gb->getBits(2)) {
00550                 warning("End marker missing!");
00551                 return -1;
00552             }
00553         }
00554     }
00555 
00556     // copy chroma parameters into the 2nd chroma plane
00557     for (i = 0; i < picConf._chromaBands; i++) {
00558         band1 = &_ctx._planes[1]._bands[i];
00559         band2 = &_ctx._planes[2]._bands[i];
00560 
00561         band2->_width = band1->_width;
00562         band2->_height = band1->_height;
00563         band2->_mbSize = band1->_mbSize;
00564         band2->_blkSize = band1->_blkSize;
00565         band2->_isHalfpel = band1->_isHalfpel;
00566         band2->_intraBase = band1->_intraBase;
00567         band2->_interBase = band1->_interBase;
00568         band2->_intraScale = band1->_intraScale;
00569         band2->_interScale = band1->_interScale;
00570         band2->_scan = band1->_scan;
00571         band2->_invTransform = band1->_invTransform;
00572         band2->_dcTransform = band1->_dcTransform;
00573         band2->_is2dTrans = band1->_is2dTrans;
00574         band2->_transformSize = band1->_transformSize;
00575     }
00576 
00577     // reallocate internal structures if needed
00578     if (blkSizeChanged) {
00579         result = IVIPlaneDesc::initTiles(_ctx._planes, picConf._tileWidth,
00580             picConf._tileHeight);
00581         if (result < 0) {
00582             warning("Couldn't reallocate internal structures!");
00583             return result;
00584         }
00585     }
00586 
00587     if (_ctx._gopFlags & 8) {
00588         if (_ctx._gb->getBits(3)) {
00589             warning("Alignment bits are not zero!");
00590             return -1;
00591         }
00592 
00593         if (_ctx._gb->getBit())
00594             _ctx._gb->skip(24); // skip transparency fill color
00595     }
00596 
00597     _ctx._gb->align();
00598 
00599     _ctx._gb->skip(23);         // FIXME: unknown meaning
00600 
00601     // skip GOP extension if any
00602     if (_ctx._gb->getBit()) {
00603         do {
00604             i = _ctx._gb->getBits(16);
00605         } while (i & 0x8000);
00606     }
00607 
00608     _ctx._gb->align();
00609 
00610     return 0;
00611 }
00612 
00613 int Indeo5Decoder::skip_hdr_extension() {
00614     int i, len;
00615 
00616     do {
00617         len = _ctx._gb->getBits(8);
00618         if (_ctx._gb->eos())
00619             return -1;
00620         for (i = 0; i < len; i++)
00621             _ctx._gb->skip(8);
00622     } while (len);
00623 
00624     return 0;
00625 }
00626 
00627 /*------------------------------------------------------------------------*/
00628 
00629 const uint8 Indeo5Decoder::_commonPicSizes[30] = {
00630     160, 120, 80, 60, 40, 30, 176, 120, 88, 60, 88, 72, 44, 36, 60, 45, 160, 60,
00631     176,  60, 20, 15, 22, 18,   0,   0,  0,  0,  0,  0
00632 };
00633 
00634 const uint16 Indeo5Decoder::_baseQuant8x8Inter[5][64] = {
00635     {0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a, 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
00636      0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62, 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
00637      0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a, 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
00638      0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
00639     },
00640     {0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a, 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
00641      0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62, 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
00642      0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a, 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
00643      0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
00644     },
00645     {0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
00646      0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
00647      0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
00648      0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
00649     },
00650     {0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
00651      0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
00652      0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
00653      0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
00654     },
00655     {0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
00656      0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
00657      0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
00658      0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
00659     }
00660 };
00661 
00662 const uint16 Indeo5Decoder::_baseQuant8x8Intra[5][64] = {
00663     {0x1a, 0x2e, 0x36, 0x42, 0x46, 0x4a, 0x4e, 0x5a, 0x2e, 0x32, 0x3e, 0x42, 0x46, 0x4e, 0x56, 0x6a,
00664      0x36, 0x3e, 0x3e, 0x44, 0x4a, 0x54, 0x66, 0x72, 0x42, 0x42, 0x44, 0x4a, 0x52, 0x62, 0x6c, 0x7a,
00665      0x46, 0x46, 0x4a, 0x52, 0x5e, 0x66, 0x72, 0x8e, 0x4a, 0x4e, 0x54, 0x62, 0x66, 0x6e, 0x86, 0xa6,
00666      0x4e, 0x56, 0x66, 0x6c, 0x72, 0x86, 0x9a, 0xca, 0x5a, 0x6a, 0x72, 0x7a, 0x8e, 0xa6, 0xca, 0xfe,
00667     },
00668     {0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a, 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
00669      0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62, 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
00670      0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a, 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
00671      0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
00672     },
00673     {0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
00674      0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
00675      0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
00676      0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2, 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
00677     },
00678     {0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
00679      0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
00680      0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
00681      0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
00682     },
00683     {0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
00684      0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
00685      0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
00686      0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
00687     }
00688 };
00689 
00690 const uint16 Indeo5Decoder::_baseQuant4x4Inter[16] = {
00691     0x1e, 0x3e, 0x4a, 0x52, 0x3e, 0x4a, 0x52, 0x56, 0x4a, 0x52, 0x56, 0x5e, 0x52, 0x56, 0x5e, 0x66
00692 };
00693 
00694 const uint16 Indeo5Decoder::_baseQuant4x4Intra[16] = {
00695     0x1e, 0x3e, 0x4a, 0x52, 0x3e, 0x4a, 0x52, 0x5e, 0x4a, 0x52, 0x5e, 0x7a, 0x52, 0x5e, 0x7a, 0x92
00696 };
00697 
00698 
00699 const uint8 Indeo5Decoder::_scaleQuant8x8Inter[5][24] = {
00700     {0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
00701      0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
00702     },
00703     {0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
00704      0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
00705     },
00706     {0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
00707      0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
00708     },
00709     {0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
00710      0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
00711     },
00712     {0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
00713      0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba,
00714     },
00715 };
00716 
00717 const uint8 Indeo5Decoder::_scaleQuant8x8Intra[5][24] = {
00718     {0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
00719      0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
00720     },
00721     {0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
00722      0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
00723     },
00724     {0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
00725      0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
00726     },
00727     {0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
00728      0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
00729     },
00730     {0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
00731      0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
00732     }
00733 };
00734 
00735 const uint8 Indeo5Decoder::_scaleQuant4x4Inter[24] = {
00736     0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
00737     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
00738 };
00739 
00740 const uint8 Indeo5Decoder::_scaleQuant4x4Intra[24] = {
00741     0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
00742     0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
00743 };
00744 
00745 } // End of namespace Image


Generated on Sat May 18 2019 05:01:05 for ResidualVM by doxygen 1.7.1
curved edge   curved edge