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

indeo4.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 4 decompressor, derived from ffmpeg.
00024  *
00025  * Original copyright note: * Intel Indeo 4 (IV41, IV42, etc.) video decoder for ffmpeg
00026  * written, produced, and directed by Alan Smithee
00027  */
00028 
00029 #include "common/algorithm.h"
00030 #include "common/debug.h"
00031 #include "common/memstream.h"
00032 #include "common/rect.h"
00033 #include "common/textconsole.h"
00034 #include "graphics/yuv_to_rgb.h"
00035 #include "image/codecs/indeo4.h"
00036 #include "image/codecs/indeo/indeo_dsp.h"
00037 #include "image/codecs/indeo/mem.h"
00038 
00039 namespace Image {
00040 
00041 #define IVI4_PIC_SIZE_ESC   7
00042 
00043 Indeo4Decoder::Indeo4Decoder(uint16 width, uint16 height, uint bitsPerPixel) :
00044         IndeoDecoderBase(width, height, bitsPerPixel) {
00045     _ctx._isIndeo4 = true;
00046     _ctx._refBuf = 1;
00047     _ctx._bRefBuf = 3;
00048     _ctx._pFrame = new AVFrame();
00049 }
00050 
00051 bool Indeo4Decoder::isIndeo4(Common::SeekableReadStream &stream) {
00052     // Less than 16 bytes? This can't be right
00053     if (stream.size() < 16)
00054         return false;
00055 
00056     // Read in the start of the data
00057     byte buffer[16];
00058     stream.read(buffer, 16);
00059     stream.seek(-16, SEEK_CUR);
00060 
00061     // Validate the first 18-bit word has the correct identifier
00062     Indeo::GetBits gb(buffer, 16 * 8);
00063     bool isIndeo4 = gb.getBits(18) == 0x3FFF8;
00064 
00065     return isIndeo4;
00066 }
00067 
00068 const Graphics::Surface *Indeo4Decoder::decodeFrame(Common::SeekableReadStream &stream) {
00069     // Not Indeo 4? Fail
00070     if (!isIndeo4(stream))
00071         return nullptr;
00072 
00073     // Set up the frame data buffer
00074     byte *frameData = new byte[stream.size()];
00075     stream.read(frameData, stream.size());
00076     _ctx._frameData = frameData;
00077     _ctx._frameSize = stream.size();
00078 
00079     // Set up the GetBits instance for reading the data
00080     _ctx._gb = new GetBits(_ctx._frameData, _ctx._frameSize);
00081 
00082     // Decode the frame
00083     int err = decodeIndeoFrame();
00084 
00085     // Free the bit reader and frame buffer
00086     delete _ctx._gb;
00087     _ctx._gb = nullptr;
00088     delete[] frameData;
00089     _ctx._frameData = nullptr;
00090     _ctx._frameSize = 0;
00091 
00092     return (err < 0) ? nullptr : &_surface;
00093 }
00094 
00095 int Indeo4Decoder::decodePictureHeader() {
00096     int pic_size_indx, i, p;
00097     IVIPicConfig picConf;
00098 
00099     if (_ctx._gb->getBits(18) != 0x3FFF8) {
00100         warning("Invalid picture start code!");
00101         return -1;
00102     }
00103 
00104     _ctx._prevFrameType = _ctx._frameType;
00105     _ctx._frameType = _ctx._gb->getBits(3);
00106     if (_ctx._frameType == 7) {
00107         warning("Invalid frame type: %d", _ctx._frameType);
00108         return -1;
00109     }
00110 
00111     if (_ctx._frameType == IVI4_FRAMETYPE_BIDIR)
00112         _ctx._hasBFrames = true;
00113 
00114     _ctx._hasTransp = _ctx._gb->getBit();
00115     if (_ctx._hasTransp && _surface.format.aBits() == 0) {
00116         // Surface is 4 bytes per pixel, but only RGB. So promote the
00117         // surface to full RGBA, and convert all the existing pixels
00118         _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
00119         _surface.convertToInPlace(_pixelFormat);
00120     }
00121 
00122     // unknown bit: Mac decoder ignores this bit, XANIM returns error
00123     if (_ctx._gb->getBit()) {
00124         warning("Sync bit is set!");
00125         return -1;
00126     }
00127 
00128     _ctx._dataSize = _ctx._gb->getBit() ? _ctx._gb->getBits(24) : 0;
00129 
00130     // null frames don't contain anything else so we just return
00131     if (_ctx._frameType >= IVI4_FRAMETYPE_NULL_FIRST) {
00132         warning("Null frame encountered!");
00133         return 0;
00134     }
00135 
00136     // Check key lock status. If enabled - ignore lock word.
00137     // Usually we have to prompt the user for the password, but
00138     // we don't do that because Indeo 4 videos can be decoded anyway
00139     if (_ctx._gb->getBit()) {
00140         _ctx._gb->skip(32);
00141         warning("Password-protected clip!");
00142     }
00143 
00144     pic_size_indx = _ctx._gb->getBits(3);
00145     if (pic_size_indx == IVI4_PIC_SIZE_ESC) {
00146         picConf._picHeight = _ctx._gb->getBits(16);
00147         picConf._picWidth = _ctx._gb->getBits(16);
00148     } else {
00149         picConf._picHeight = _ivi4_common_pic_sizes[pic_size_indx * 2 + 1];
00150         picConf._picWidth = _ivi4_common_pic_sizes[pic_size_indx * 2];
00151     }
00152 
00153     // Decode tile dimensions.
00154     _ctx._usesTiling = _ctx._gb->getBit();
00155     if (_ctx._usesTiling) {
00156         picConf._tileHeight = scaleTileSize(picConf._picHeight, _ctx._gb->getBits(4));
00157         picConf._tileWidth = scaleTileSize(picConf._picWidth, _ctx._gb->getBits(4));
00158     } else {
00159         picConf._tileHeight = picConf._picHeight;
00160         picConf._tileWidth = picConf._picWidth;
00161     }
00162 
00163     // Decode chroma subsampling. We support only 4:4 aka YVU9.
00164     if (_ctx._gb->getBits(2)) {
00165         warning("Only YVU9 picture format is supported!");
00166         return -1;
00167     }
00168     picConf._chromaHeight = (picConf._picHeight + 3) >> 2;
00169     picConf._chromaWidth = (picConf._picWidth + 3) >> 2;
00170 
00171     // decode subdivision of the planes
00172     picConf._lumaBands = decodePlaneSubdivision();
00173     picConf._chromaBands = 0;
00174     if (picConf._lumaBands)
00175         picConf._chromaBands = decodePlaneSubdivision();
00176     _ctx._isScalable = picConf._lumaBands != 1 || picConf._chromaBands != 1;
00177     if (_ctx._isScalable && (picConf._lumaBands != 4 || picConf._chromaBands != 1)) {
00178         warning("Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d",
00179             picConf._lumaBands, picConf._chromaBands);
00180         return -1;
00181     }
00182 
00183     // check if picture layout was changed and reallocate buffers
00184     if (picConf.ivi_pic_config_cmp(_ctx._picConf)) {
00185         if (IVIPlaneDesc::initPlanes(_ctx._planes, &picConf, 1)) {
00186             warning("Couldn't reallocate color planes!");
00187             _ctx._picConf._lumaBands = 0;
00188             return -2;
00189         }
00190 
00191         _ctx._picConf = picConf;
00192 
00193         // set default macroblock/block dimensions
00194         for (p = 0; p <= 2; p++) {
00195             for (i = 0; i < (!p ? picConf._lumaBands : picConf._chromaBands); i++) {
00196                 _ctx._planes[p]._bands[i]._mbSize = !p ? (!_ctx._isScalable ? 16 : 8) : 4;
00197                 _ctx._planes[p]._bands[i]._blkSize = !p ? 8 : 4;
00198             }
00199         }
00200 
00201         if (IVIPlaneDesc::initTiles(_ctx._planes, _ctx._picConf._tileWidth,
00202             _ctx._picConf._tileHeight)) {
00203             warning("Couldn't reallocate internal structures!");
00204             return -2;
00205         }
00206     }
00207 
00208     _ctx._frameNum = _ctx._gb->getBit() ? _ctx._gb->getBits(20) : 0;
00209 
00210     // skip decTimeEst field if present
00211     if (_ctx._gb->getBit())
00212         _ctx._gb->skip(8);
00213 
00214     // decode macroblock and block huffman codebooks
00215     if (_ctx._mbVlc.decodeHuffDesc(&_ctx, _ctx._gb->getBit(), IVI_MB_HUFF) ||
00216         _ctx._blkVlc.decodeHuffDesc(&_ctx, _ctx._gb->getBit(), IVI_BLK_HUFF))
00217         return -1;
00218 
00219     _ctx._rvmapSel = _ctx._gb->getBit() ? _ctx._gb->getBits(3) : 8;
00220 
00221     _ctx._inImf = _ctx._gb->getBit();
00222     _ctx._inQ = _ctx._gb->getBit();
00223 
00224     _ctx._picGlobQuant = _ctx._gb->getBits(5);
00225 
00226     // TODO: ignore this parameter if unused
00227     _ctx._unknown1 = _ctx._gb->getBit() ? _ctx._gb->getBits(3) : 0;
00228 
00229     _ctx._checksum = _ctx._gb->getBit() ? _ctx._gb->getBits(16) : 0;
00230 
00231     // skip picture header extension if any
00232     while (_ctx._gb->getBit()) {
00233         _ctx._gb->skip(8);
00234     }
00235 
00236     if (_ctx._gb->getBit()) {
00237         warning("Bad blocks bits encountered!");
00238     }
00239 
00240     _ctx._gb->align();
00241 
00242     return 0;
00243 }
00244 
00245 void Indeo4Decoder::switchBuffers() {
00246     int isPrevRef = 0, isRef = 0;
00247 
00248     switch (_ctx._prevFrameType) {
00249     case IVI4_FRAMETYPE_INTRA:
00250     case IVI4_FRAMETYPE_INTRA1:
00251     case IVI4_FRAMETYPE_INTER:
00252         isPrevRef = 1;
00253         break;
00254     }
00255 
00256     switch (_ctx._frameType) {
00257     case IVI4_FRAMETYPE_INTRA:
00258     case IVI4_FRAMETYPE_INTRA1:
00259     case IVI4_FRAMETYPE_INTER:
00260         isRef = 1;
00261         break;
00262 
00263     default:
00264         break;
00265     }
00266 
00267     if (isPrevRef && isRef) {
00268         SWAP(_ctx._dstBuf, _ctx._refBuf);
00269     } else if (isPrevRef) {
00270         SWAP(_ctx._refBuf, _ctx._bRefBuf);
00271         SWAP(_ctx._dstBuf, _ctx._refBuf);
00272     }
00273 }
00274 
00275 bool Indeo4Decoder::isNonNullFrame() const {
00276     return _ctx._frameType < IVI4_FRAMETYPE_NULL_FIRST;
00277 }
00278 
00279 int Indeo4Decoder::decodeBandHeader(IVIBandDesc *band) {
00280     int plane, bandNum, indx, transformId, scanIndx;
00281     int i;
00282     int quantMat;
00283 
00284     plane = _ctx._gb->getBits(2);
00285     bandNum = _ctx._gb->getBits(4);
00286     if (band->_plane != plane || band->_bandNum != bandNum) {
00287         warning("Invalid band header sequence!");
00288         return -1;
00289     }
00290 
00291     band->_isEmpty = _ctx._gb->getBit();
00292     if (!band->_isEmpty) {
00293         int old_blk_size = band->_blkSize;
00294         // skip header size
00295         // If header size is not given, header size is 4 bytes.
00296         if (_ctx._gb->getBit())
00297             _ctx._gb->skip(16);
00298 
00299         band->_isHalfpel = _ctx._gb->getBits(2);
00300         if (band->_isHalfpel >= 2) {
00301             warning("Invalid/unsupported mv resolution: %d!",
00302                 band->_isHalfpel);
00303             return -1;
00304         }
00305         if (!band->_isHalfpel)
00306             _ctx._usesFullpel = true;
00307 
00308         band->_checksumPresent = _ctx._gb->getBit();
00309         if (band->_checksumPresent)
00310             band->_checksum = _ctx._gb->getBits(16);
00311 
00312         indx = _ctx._gb->getBits(2);
00313         if (indx == 3) {
00314             warning("Invalid block size!");
00315             return -1;
00316         }
00317         band->_mbSize = 16 >> indx;
00318         band->_blkSize = 8 >> (indx >> 1);
00319 
00320         band->_inheritMv = _ctx._gb->getBit();
00321         band->_inheritQDelta = _ctx._gb->getBit();
00322 
00323         band->_globQuant = _ctx._gb->getBits(5);
00324 
00325         if (!_ctx._gb->getBit() || _ctx._frameType == IVI4_FRAMETYPE_INTRA) {
00326             transformId = _ctx._gb->getBits(5);
00327             if ((uint)transformId >= FF_ARRAY_ELEMS(_transforms) ||
00328                 !_transforms[transformId]._invTrans) {
00329                 warning("Transform %d", transformId);
00330                 return -3;
00331             }
00332             if ((transformId >= 7 && transformId <= 9) ||
00333                 transformId == 17) {
00334                 warning("DCT transform");
00335                 return -3;
00336             }
00337 
00338             if (transformId < 10 && band->_blkSize < 8) {
00339                 warning("wrong transform size!");
00340                 return -1;
00341             }
00342             if ((transformId >= 0 && transformId <= 2) || transformId == 10)
00343                 _ctx._usesHaar = true;
00344 
00345             band->_invTransform = _transforms[transformId]._invTrans;
00346             band->_dcTransform = _transforms[transformId]._dcTrans;
00347             band->_is2dTrans = _transforms[transformId]._is2dTrans;
00348 
00349             if (transformId < 10)
00350                 band->_transformSize = 8;
00351             else
00352                 band->_transformSize = 4;
00353 
00354             if (band->_blkSize != band->_transformSize) {
00355                 warning("transform and block size mismatch (%d != %d)", band->_transformSize, band->_blkSize);
00356                 return -1;
00357             }
00358 
00359             scanIndx = _ctx._gb->getBits(4);
00360             if (scanIndx == 15) {
00361                 warning("Custom scan pattern encountered!");
00362                 return -1;
00363             }
00364             if (scanIndx > 4 && scanIndx < 10) {
00365                 if (band->_blkSize != 4) {
00366                     warning("mismatching scan table!");
00367                     return -1;
00368                 }
00369             } else if (band->_blkSize != 8) {
00370                 warning("mismatching scan table!");
00371                 return -1;
00372             }
00373 
00374             band->_scan = _scan_index_to_tab[scanIndx];
00375             band->_scanSize = band->_blkSize;
00376 
00377             quantMat = _ctx._gb->getBits(5);
00378             if (quantMat == 31) {
00379                 warning("Custom quant matrix encountered!");
00380                 return -1;
00381             }
00382             if ((uint)quantMat >= FF_ARRAY_ELEMS(_quant_index_to_tab)) {
00383                 warning("Quantization matrix %d", quantMat);
00384                 return -1;
00385             }
00386             band->_quantMat = quantMat;
00387         } else {
00388             if (old_blk_size != band->_blkSize) {
00389                 warning("The band block size does not match the configuration inherited");
00390                 return -1;
00391             }
00392         }
00393         if (_quant_index_to_tab[band->_quantMat] > 4 && band->_blkSize == 4) {
00394             warning("Invalid quant matrix for 4x4 block encountered!");
00395             band->_quantMat = 0;
00396             return -1;
00397         }
00398         if (band->_scanSize != band->_blkSize) {
00399             warning("mismatching scan table!");
00400             return -1;
00401         }
00402         if (band->_transformSize == 8 && band->_blkSize < 8) {
00403             warning("mismatching _transformSize!");
00404             return -1;
00405         }
00406 
00407         // decode block huffman codebook
00408         if (!_ctx._gb->getBit())
00409             band->_blkVlc._tab = _ctx._blkVlc._tab;
00410         else
00411             if (band->_blkVlc.decodeHuffDesc(&_ctx, 1, IVI_BLK_HUFF))
00412                 return -1;
00413 
00414         // select appropriate rvmap table for this band
00415         band->_rvmapSel = _ctx._gb->getBit() ? _ctx._gb->getBits(3) : 8;
00416 
00417         // decode rvmap probability corrections if any
00418         band->_numCorr = 0; // there is no corrections
00419         if (_ctx._gb->getBit()) {
00420             band->_numCorr = _ctx._gb->getBits(8); // get number of correction pairs
00421             if (band->_numCorr > 61) {
00422                 warning("Too many corrections: %d",
00423                     band->_numCorr);
00424                 return -1;
00425             }
00426 
00427             // read correction pairs
00428             for (i = 0; i < band->_numCorr * 2; i++)
00429                 band->_corr[i] = _ctx._gb->getBits(8);
00430         }
00431     }
00432 
00433     if (band->_blkSize == 8) {
00434         band->_intraBase = &_ivi4_quant_8x8_intra[_quant_index_to_tab[band->_quantMat]][0];
00435         band->_interBase = &_ivi4_quant_8x8_inter[_quant_index_to_tab[band->_quantMat]][0];
00436     } else {
00437         band->_intraBase = &_ivi4_quant_4x4_intra[_quant_index_to_tab[band->_quantMat]][0];
00438         band->_interBase = &_ivi4_quant_4x4_inter[_quant_index_to_tab[band->_quantMat]][0];
00439     }
00440 
00441     // Indeo 4 doesn't use scale tables
00442     band->_intraScale = NULL;
00443     band->_interScale = NULL;
00444 
00445     _ctx._gb->align();
00446 
00447     if (!band->_scan) {
00448         warning("band->_scan not set");
00449         return -1;
00450     }
00451 
00452     return 0;
00453 }
00454 
00455 int Indeo4Decoder::decodeMbInfo(IVIBandDesc *band, IVITile *tile) {
00456     int x, y, mvX, mvY, mvDelta, offs, mbOffset, blksPerMb,
00457         mvScale, mbTypeBits, s;
00458     IVIMbInfo *mb, *refMb;
00459     int row_offset = band->_mbSize * band->_pitch;
00460 
00461     mb = tile->_mbs;
00462     refMb = tile->_refMbs;
00463     offs = tile->_yPos * band->_pitch + tile->_xPos;
00464 
00465     blksPerMb = band->_mbSize != band->_blkSize ? 4 : 1;
00466     mbTypeBits = _ctx._frameType == IVI4_FRAMETYPE_BIDIR ? 2 : 1;
00467 
00468     // scale factor for motion vectors
00469     mvScale = (_ctx._planes[0]._bands[0]._mbSize >> 3) - (band->_mbSize >> 3);
00470     mvX = mvY = 0;
00471 
00472     if (((tile->_width + band->_mbSize - 1) / band->_mbSize) * ((tile->_height + band->_mbSize - 1) / band->_mbSize) != tile->_numMBs) {
00473         warning("numMBs mismatch %d %d %d %d", tile->_width, tile->_height, band->_mbSize, tile->_numMBs);
00474         return -1;
00475     }
00476 
00477     for (y = tile->_yPos; y < tile->_yPos + tile->_height; y += band->_mbSize) {
00478         mbOffset = offs;
00479 
00480         for (x = tile->_xPos; x < tile->_xPos + tile->_width; x += band->_mbSize) {
00481             mb->_xPos = x;
00482             mb->_yPos = y;
00483             mb->_bufOffs = mbOffset;
00484             mb->_bMvX = mb->_bMvY = 0;
00485 
00486             if (_ctx._gb->getBit()) {
00487                 if (_ctx._frameType == IVI4_FRAMETYPE_INTRA) {
00488                     warning("Empty macroblock in an INTRA picture!");
00489                     return -1;
00490                 }
00491                 mb->_type = 1; // empty macroblocks are always INTER
00492                 mb->_cbp = 0;  // all blocks are empty
00493 
00494                 mb->_qDelta = 0;
00495                 if (!band->_plane && !band->_bandNum && _ctx._inQ) {
00496                     mb->_qDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table,
00497                         IVI_VLC_BITS);
00498                     mb->_qDelta = IVI_TOSIGNED(mb->_qDelta);
00499                 }
00500 
00501                 mb->_mvX = mb->_mvY = 0; // no motion vector coded
00502                 if (band->_inheritMv && refMb) {
00503                     // motion vector inheritance
00504                     if (mvScale) {
00505                         mb->_mvX = scaleMV(refMb->_mvX, mvScale);
00506                         mb->_mvY = scaleMV(refMb->_mvY, mvScale);
00507                     } else {
00508                         mb->_mvX = refMb->_mvX;
00509                         mb->_mvY = refMb->_mvY;
00510                     }
00511                 }
00512             } else {
00513                 if (band->_inheritMv) {
00514                     // copy mb_type from corresponding reference mb
00515                     if (!refMb) {
00516                         warning("refMb unavailable");
00517                         return -1;
00518                     }
00519                     mb->_type = refMb->_type;
00520                 } else if (_ctx._frameType == IVI4_FRAMETYPE_INTRA ||
00521                     _ctx._frameType == IVI4_FRAMETYPE_INTRA1) {
00522                     mb->_type = 0; // mb_type is always INTRA for intra-frames
00523                 } else {
00524                     mb->_type = _ctx._gb->getBits(mbTypeBits);
00525                 }
00526 
00527                 mb->_cbp = _ctx._gb->getBits(blksPerMb);
00528 
00529                 mb->_qDelta = 0;
00530                 if (band->_inheritQDelta) {
00531                     if (refMb) mb->_qDelta = refMb->_qDelta;
00532                 } else if (mb->_cbp || (!band->_plane && !band->_bandNum &&
00533                     _ctx._inQ)) {
00534                     mb->_qDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table,
00535                         IVI_VLC_BITS);
00536                     mb->_qDelta = IVI_TOSIGNED(mb->_qDelta);
00537                 }
00538 
00539                 if (!mb->_type) {
00540                     mb->_mvX = mb->_mvY = 0; // there is no motion vector in intra-macroblocks
00541                 } else {
00542                     if (band->_inheritMv) {
00543                         if (refMb) {
00544                             // motion vector inheritance
00545                             if (mvScale) {
00546                                 mb->_mvX = scaleMV(refMb->_mvX, mvScale);
00547                                 mb->_mvY = scaleMV(refMb->_mvY, mvScale);
00548                             } else {
00549                                 mb->_mvX = refMb->_mvX;
00550                                 mb->_mvY = refMb->_mvY;
00551                             }
00552                         }
00553                     } else {
00554                         // decode motion vector deltas
00555                         mvDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table,
00556                             IVI_VLC_BITS);
00557                         mvY += IVI_TOSIGNED(mvDelta);
00558                         mvDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table,
00559                             IVI_VLC_BITS);
00560                         mvX += IVI_TOSIGNED(mvDelta);
00561                         mb->_mvX = mvX;
00562                         mb->_mvY = mvY;
00563                         if (mb->_type == 3) {
00564                             mvDelta = _ctx._gb->getVLC2<1>(
00565                                 _ctx._mbVlc._tab->_table,
00566                                 IVI_VLC_BITS);
00567                             mvY += IVI_TOSIGNED(mvDelta);
00568                             mvDelta = _ctx._gb->getVLC2<1>(
00569                                 _ctx._mbVlc._tab->_table,
00570                                 IVI_VLC_BITS);
00571                             mvX += IVI_TOSIGNED(mvDelta);
00572                             mb->_bMvX = -mvX;
00573                             mb->_bMvY = -mvY;
00574                         }
00575                     }
00576                     if (mb->_type == 2) {
00577                         mb->_bMvX = -mb->_mvX;
00578                         mb->_bMvY = -mb->_mvY;
00579                         mb->_mvX = 0;
00580                         mb->_mvY = 0;
00581                     }
00582                 }
00583             }
00584 
00585             s = band->_isHalfpel;
00586             if (mb->_type)
00587                 if (x + (mb->_mvX >> s) + (y + (mb->_mvY >> s))*band->_pitch < 0 ||
00588                     x + ((mb->_mvX + s) >> s) + band->_mbSize - 1
00589                     + (y + band->_mbSize - 1 + ((mb->_mvY + s) >> s))*band->_pitch > band->_bufSize - 1) {
00590                     warning("motion vector %d %d outside reference", x*s + mb->_mvX, y*s + mb->_mvY);
00591                     return -1;
00592                 }
00593 
00594             mb++;
00595             if (refMb)
00596                 refMb++;
00597             mbOffset += band->_mbSize;
00598         }
00599 
00600         offs += row_offset;
00601     }
00602 
00603     _ctx._gb->align();
00604     return 0;
00605 }
00606 
00607 int Indeo4Decoder::decodeRLETransparency(VLC_TYPE (*table)[2]) {
00608     const uint32 startPos = _ctx._gb->pos();
00609 
00610     _ctx._gb->align();
00611 
00612     bool runIsOpaque = _ctx._gb->getBit();
00613     bool nextRunIsOpaque = !runIsOpaque;
00614 
00615     uint32 *pixel = (uint32 *)_surface.getPixels();
00616     const int surfacePixelPitch = _surface.pitch / _surface.format.bytesPerPixel;
00617     const int surfacePadding = surfacePixelPitch - _surface.w;
00618     const uint32 *endOfVisibleRow = pixel + _surface.w;
00619     const uint32 *endOfVisibleArea = pixel + surfacePixelPitch * _surface.h - surfacePadding;
00620 
00621     const int codecAlignedWidth = (_surface.w + 31) & ~31;
00622     const int codecPaddingSize = codecAlignedWidth - _surface.w;
00623 
00624     int numPixelsToRead = codecAlignedWidth * _surface.h;
00625     int numPixelsToSkip = 0;
00626     while (numPixelsToRead > 0) {
00627         int value = _ctx._gb->getVLC2<1>(table, IVI_VLC_BITS);
00628 
00629         if (value == -1) {
00630             warning("Transparency VLC code read failed");
00631             return -1;
00632         }
00633 
00634         if (value == 0) {
00635             value = 255;
00636             nextRunIsOpaque = runIsOpaque;
00637         }
00638 
00639         numPixelsToRead -= value;
00640 
00641         debugN(9, "%d%s ", value, runIsOpaque ? "O" : "T");
00642 
00643         // The rest of the transparency data must be consumed but it will not
00644         // participate in writing any more pixels
00645         if (pixel == endOfVisibleArea) {
00646             debug(5, "Indeo4: Done writing transparency, but still need to consume %d pixels", numPixelsToRead + value);
00647             continue;
00648         }
00649 
00650         // If a run ends in the padding area of a row, the next run needs to
00651         // be partially consumed by the remaining pixels of the padding area
00652         if (numPixelsToSkip) {
00653             value -= numPixelsToSkip;
00654             if (value < 0) {
00655                 numPixelsToSkip = -value;
00656                 value = 0;
00657             } else {
00658                 numPixelsToSkip = 0;
00659             }
00660         }
00661 
00662         while (value > 0) {
00663             const int length = MIN<int>(value, endOfVisibleRow - pixel);
00664             if (!runIsOpaque) {
00665                 Common::fill(pixel, pixel + length, _ctx._transKeyColor);
00666             }
00667             value -= length;
00668             pixel += length;
00669 
00670             if (pixel == endOfVisibleRow) {
00671                 pixel += surfacePadding;
00672                 endOfVisibleRow += surfacePixelPitch;
00673                 value -= codecPaddingSize;
00674 
00675                 if (value < 0) {
00676                     numPixelsToSkip = -value;
00677                     break;
00678                 }
00679 
00680                 if (pixel == endOfVisibleArea) {
00681                     break;
00682                 }
00683             }
00684         }
00685 
00686         runIsOpaque = nextRunIsOpaque;
00687         nextRunIsOpaque = !runIsOpaque;
00688     }
00689 
00690     debugN(9, "\n");
00691 
00692     if (numPixelsToRead != 0) {
00693         warning("Wrong number of transparency pixels read; delta = %d", numPixelsToRead);
00694     }
00695 
00696     _ctx._gb->align();
00697 
00698     return (_ctx._gb->pos() - startPos) / 8;
00699 }
00700 
00701 int Indeo4Decoder::decodeTransparency() {
00702     if (_ctx._gb->getBits(2) != 3 || _ctx._gb->getBits(3) != 0) {
00703         warning("Invalid transparency marker");
00704         return -1;
00705     }
00706 
00707     Common::Rect drawRect;
00708 
00709     for (int numRects = _ctx._gb->getBits(8); numRects; --numRects) {
00710         const int x1 = _ctx._gb->getBits(16);
00711         const int y1 = _ctx._gb->getBits(16);
00712         const int x2 = x1 + _ctx._gb->getBits(16);
00713         const int y2 = y1 + _ctx._gb->getBits(16);
00714         drawRect.extend(Common::Rect(x1, y1, x2, y2));
00715     }
00716 
00717     debug(4, "Indeo4: Transparency rect is (%d, %d, %d, %d)", drawRect.left, drawRect.top, drawRect.right, drawRect.bottom);
00718 
00719     if (_ctx._gb->getBit()) { /* @350 */
00720         /* @358 */
00721         _ctx._transKeyColor = _surface.format.ARGBToColor(0, _ctx._gb->getBits(8), _ctx._gb->getBits(8), _ctx._gb->getBits(8));
00722         debug(4, "Indeo4: Key color is %08x", _ctx._transKeyColor);
00723         /* @477 */
00724     }
00725 
00726     if (_ctx._gb->getBit() == 0) { /* @4D9 */
00727         warning("Invalid transparency band?");
00728         return -1;
00729     }
00730 
00731     IVIHuffDesc huffDesc;
00732 
00733     const int numHuffRows = huffDesc._numRows = _ctx._gb->getBits(4);
00734     if (numHuffRows == 0 || numHuffRows > IVI_VLC_BITS - 1) {
00735         warning("Invalid codebook row count %d", numHuffRows);
00736         return -1;
00737     }
00738 
00739     for (int i = 0; i < numHuffRows; ++i) {
00740         huffDesc._xBits[i] = _ctx._gb->getBits(4);
00741     }
00742 
00743     /* @5E2 */
00744     _ctx._gb->align();
00745 
00746     IVIHuffTab &huffTable = _ctx._transVlc;
00747 
00748     if (huffDesc.huffDescCompare(&huffTable._custDesc) || !huffTable._custTab._table) {
00749         if (huffTable._custTab._table) {
00750             huffTable._custTab.freeVlc();
00751         }
00752 
00753         huffTable._custDesc = huffDesc;
00754         huffTable._tabSel = 7;
00755         huffTable._tab = &huffTable._custTab;
00756         if (huffTable._custDesc.createHuffFromDesc(huffTable._tab, false)) {
00757             // reset faulty description
00758             huffTable._custDesc._numRows = 0;
00759             warning("Error while initializing transparency VLC table");
00760             return -1;
00761         }
00762     }
00763 
00764     // FIXME: The transparency plane can be split, apparently for local decoding
00765     // mode (y459.avi in Titanic has the scalable flag and its transparency
00766     // plane seems to be decoded successfully, so the split transparency plane
00767     // does not seem to be related to scaling mode). This adds complexity to the
00768     // implementation, so avoid supporting unless it turns out to actually be
00769     // necessary for correct decoding of game videos.
00770     assert(!_ctx._usesTiling);
00771 
00772     assert(_surface.format.bytesPerPixel == 4);
00773     assert((_surface.pitch % 4) == 0);
00774 
00775     const uint32 startByte = _ctx._gb->pos() / 8;
00776 
00777     /* @68D */
00778     const bool useFillTransparency = _ctx._gb->getBit();
00779     if (useFillTransparency) {
00780         /* @6F2 */
00781         const bool runIsOpaque = _ctx._gb->getBit();
00782         if (!runIsOpaque) {
00783             // It should only be necessary to draw transparency here since the
00784             // data from the YUV planes gets drawn to the output surface on each
00785             // frame, which resets the surface pixels to be fully opaque
00786             _surface.fillRect(Common::Rect(_surface.w, _surface.h), _ctx._transKeyColor);
00787         }
00788 
00789         // No alignment here
00790     } else {
00791         /* @7BF */
00792         const bool hasDataSize = _ctx._gb->getBit();
00793         if (hasDataSize) { /* @81A */
00794             /* @822 */
00795             int expectedSize = _ctx._gb->getBits(8);
00796             if (expectedSize == 0xFF) {
00797                 expectedSize = _ctx._gb->getBits(24);
00798             }
00799 
00800             expectedSize -= ((_ctx._gb->pos() + 7) / 8) - startByte;
00801 
00802             const int bytesRead = decodeRLETransparency(huffTable._tab->_table);
00803             if (bytesRead == -1) {
00804                 // A more specific warning should have been emitted already
00805                 return -1;
00806             } else if (bytesRead != expectedSize) {
00807                 warning("Mismatched read %u != %u", bytesRead, expectedSize);
00808                 return -1;
00809             }
00810         } else {
00811             /* @95B */
00812             if (decodeRLETransparency(huffTable._tab->_table) == -1) {
00813                 warning("Transparency data read failure");
00814                 return -1;
00815             }
00816         }
00817 
00818         _ctx._gb->align();
00819     }
00820 
00821     return 0;
00822 }
00823 
00824 int Indeo4Decoder::scaleTileSize(int defSize, int sizeFactor) {
00825     return sizeFactor == 15 ? defSize : (sizeFactor + 1) << 5;
00826 }
00827 
00828 int Indeo4Decoder::decodePlaneSubdivision() {
00829     int i;
00830 
00831     switch (_ctx._gb->getBits(2)) {
00832     case 3:
00833         return 1;
00834 
00835     case 2:
00836         for (i = 0; i < 4; i++)
00837             if (_ctx._gb->getBits(2) != 3)
00838                 return 0;
00839         return 4;
00840 
00841     default:
00842         return 0;
00843     }
00844 }
00845 
00846 /*------------------------------------------------------------------------*/
00847 
00851 static const uint8 ivi4AlternateScan8x8[64] = {
00852     0,  8,  1,  9, 16, 24,  2,  3, 17, 25, 10, 11, 32, 40, 48, 56,
00853     4,  5,  6,  7, 33, 41, 49, 57, 18, 19, 26, 27, 12, 13, 14, 15,
00854     34, 35, 43, 42, 50, 51, 59, 58, 20, 21, 22, 23, 31, 30, 29, 28,
00855     36, 37, 38, 39, 47, 46, 45, 44, 52, 53, 54, 55, 63, 62, 61, 60
00856 };
00857 
00858 static const uint8 ivi4AlternateScan4x4[16] = {
00859     0, 1, 4, 5, 8, 12, 2, 3, 9, 13, 6, 7, 10, 11, 14, 15
00860 };
00861 
00862 static const uint8 ivi4VerticalScan4x4[16] = {
00863     0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15
00864 };
00865 
00866 static const uint8 ivi4HorizontalScan4x4[16] = {
00867     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
00868 };
00869 
00870 const uint Indeo4Decoder::_ivi4_common_pic_sizes[14] = {
00871     640, 480, 320, 240, 160, 120, 704, 480, 352, 240, 352, 288, 176, 144
00872 };
00873 
00874 Indeo4Decoder::Transform Indeo4Decoder::_transforms[18] = {
00875     { IndeoDSP::ffIviInverseHaar8x8,  IndeoDSP::ffIviDcHaar2d,       1 },
00876     { IndeoDSP::ffIviRowHaar8,         IndeoDSP::ffIviDcHaar2d,       0 },
00877     { IndeoDSP::ffIviColHaar8,         IndeoDSP::ffIviDcHaar2d,       0 },
00878     { IndeoDSP::ffIviPutPixels8x8,    IndeoDSP::ffIviPutDcPixel8x8, 1 },
00879     { IndeoDSP::ffIviInverseSlant8x8, IndeoDSP::ffIviDcSlant2d,      1 },
00880     { IndeoDSP::ffIviRowSlant8,        IndeoDSP::ffIviDcRowSlant,     1 },
00881     { IndeoDSP::ffIviColSlant8,        IndeoDSP::ffIviDcColSlant,     1 },
00882     { NULL, NULL, 0 }, // inverse DCT 8x8
00883     { NULL, NULL, 0 }, // inverse DCT 8x1
00884     { NULL, NULL, 0 }, // inverse DCT 1x8
00885     { IndeoDSP::ffIviInverseHaar4x4,  IndeoDSP::ffIviDcHaar2d,       1 },
00886     { IndeoDSP::ffIviInverseSlant4x4, IndeoDSP::ffIviDcSlant2d,      1 },
00887     { NULL, NULL, 0 }, // no transform 4x4
00888     { IndeoDSP::ffIviRowHaar4,         IndeoDSP::ffIviDcHaar2d,       0 },
00889     { IndeoDSP::ffIviColHaar4,         IndeoDSP::ffIviDcHaar2d,       0 },
00890     { IndeoDSP::ffIviRowSlant4,        IndeoDSP::ffIviDcRowSlant,     0 },
00891     { IndeoDSP::ffIviColSlant4,        IndeoDSP::ffIviDcColSlant,     0 },
00892     { NULL, NULL, 0 }, // inverse DCT 4x4
00893 };
00894 
00895 const uint8 *const Indeo4Decoder::_scan_index_to_tab[15] = {
00896     // for 8x8 transforms
00897     ffZigZagDirect,
00898     ivi4AlternateScan8x8,
00899     _ffIviHorizontalScan8x8,
00900     _ffIviVerticalScan8x8,
00901     ffZigZagDirect,
00902 
00903     // for 4x4 transforms
00904     _ffIviDirectScan4x4,
00905     ivi4AlternateScan4x4,
00906     ivi4VerticalScan4x4,
00907     ivi4HorizontalScan4x4,
00908     _ffIviDirectScan4x4,
00909 
00910     // TODO: check if those are needed
00911     _ffIviHorizontalScan8x8,
00912     _ffIviHorizontalScan8x8,
00913     _ffIviHorizontalScan8x8,
00914     _ffIviHorizontalScan8x8,
00915     _ffIviHorizontalScan8x8
00916 };
00917 
00921 const uint16 Indeo4Decoder::_ivi4_quant_8x8_intra[9][64] = {
00922     {
00923       43,  342,  385,  470,  555,  555,  598,  726,
00924      342,  342,  470,  513,  555,  598,  726,  769,
00925      385,  470,  555,  555,  598,  726,  726,  811,
00926      470,  470,  555,  555,  598,  726,  769,  854,
00927      470,  555,  555,  598,  683,  726,  854, 1025,
00928      555,  555,  598,  683,  726,  854, 1025, 1153,
00929      555,  555,  598,  726,  811,  982, 1195, 1451,
00930      555,  598,  726,  811,  982, 1195, 1451, 1793
00931     },
00932     {
00933       86, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
00934     1195, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
00935     2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
00936     2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
00937     4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
00938     4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
00939     4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
00940     4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827
00941     },
00942     {
00943      235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
00944      235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
00945      235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
00946      235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
00947      235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
00948      235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
00949      235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
00950      235, 1067, 1195, 1323, 1451, 1579, 1707, 1835
00951     },
00952     {
00953     1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
00954     1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
00955     1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
00956     1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
00957     1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
00958     1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
00959     1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
00960     1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414
00961     },
00962     {
00963      897,  897,  897,  897,  897,  897,  897,  897,
00964     1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067,
00965     1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
00966     1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409,
00967     1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579,
00968     1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750,
00969     1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921,
00970     2091, 2091, 2091, 2091, 2091, 2091, 2091, 2091
00971     },
00972     {
00973     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
00974     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
00975     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
00976     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
00977     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
00978     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
00979     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
00980     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414
00981     },
00982     {
00983     2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
00984     2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
00985     2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
00986     2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
00987     2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
00988     2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
00989     2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
00990     2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390
00991     },
00992     {
00993       22,  171,  214,  257,  257,  299,  299,  342,
00994      171,  171,  257,  257,  299,  299,  342,  385,
00995      214,  257,  257,  299,  299,  342,  342,  385,
00996      257,  257,  257,  299,  299,  342,  385,  427,
00997      257,  257,  299,  299,  342,  385,  427,  513,
00998      257,  299,  299,  342,  385,  427,  513,  598,
00999      299,  299,  299,  385,  385,  470,  598,  726,
01000      299,  299,  385,  385,  470,  598,  726,  897
01001     },
01002     {
01003       86,  598, 1195, 1195, 2390, 2390, 2390, 2390,
01004      598,  598, 1195, 1195, 2390, 2390, 2390, 2390,
01005     1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
01006     1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
01007     2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
01008     2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
01009     2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
01010     2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414
01011     }
01012 };
01013 
01014 const uint16 Indeo4Decoder::_ivi4_quant_8x8_inter[9][64] = {
01015     {
01016      427,  427,  470,  427,  427,  427,  470,  470,
01017      427,  427,  470,  427,  427,  427,  470,  470,
01018      470,  470,  470,  470,  470,  470,  470,  470,
01019      427,  427,  470,  470,  427,  427,  470,  470,
01020      427,  427,  470,  427,  427,  427,  470,  470,
01021      427,  427,  470,  427,  427,  427,  470,  470,
01022      470,  470,  470,  470,  470,  470,  470,  470,
01023      470,  470,  470,  470,  470,  470,  470,  470
01024     },
01025     {
01026     1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
01027     1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
01028     2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
01029     2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
01030     3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
01031     3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
01032     3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
01033     3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414
01034     },
01035     {
01036     1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
01037     1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
01038     1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
01039     1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
01040     1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
01041     1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
01042     1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
01043     1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281
01044     },
01045     {
01046     2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
01047     2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
01048     2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
01049     2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
01050     2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
01051     2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
01052     2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
01053     2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433
01054     },
01055     {
01056     1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
01057     1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
01058     1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
01059     1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
01060     1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
01061     1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
01062     1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
01063     1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281
01064     },
01065     {
01066     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
01067     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
01068     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
01069     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
01070     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
01071     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
01072     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
01073     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433
01074     },
01075     {
01076     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
01077     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
01078     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
01079     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
01080     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
01081     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
01082     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
01083     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707
01084     },
01085     {
01086       86,  171,  171,  214,  214,  214,  214,  257,
01087      171,  171,  214,  214,  214,  214,  257,  257,
01088      171,  214,  214,  214,  214,  257,  257,  257,
01089      214,  214,  214,  214,  257,  257,  257,  299,
01090      214,  214,  214,  257,  257,  257,  299,  299,
01091      214,  214,  257,  257,  257,  299,  299,  299,
01092      214,  257,  257,  257,  299,  299,  299,  342,
01093      257,  257,  257,  299,  299,  299,  342,  342
01094     },
01095     {
01096      854,  854, 1195, 1195, 1707, 1707, 1707, 1707,
01097      854,  854, 1195, 1195, 1707, 1707, 1707, 1707,
01098     1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
01099     1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
01100     1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
01101     1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
01102     1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
01103     1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707
01104     }
01105 };
01106 
01107 const uint16 Indeo4Decoder::_ivi4_quant_4x4_intra[5][16] = {
01108     {
01109       22,  214,  257,  299,
01110      214,  257,  299,  342,
01111      257,  299,  342,  427,
01112      299,  342,  427,  513
01113     },
01114     {
01115      129, 1025, 1451, 1451,
01116     1025, 1025, 1451, 1451,
01117     1451, 1451, 2049, 2049,
01118     1451, 1451, 2049, 2049
01119     },
01120     {
01121       43,  171,  171,  171,
01122       43,  171,  171,  171,
01123       43,  171,  171,  171,
01124       43,  171,  171,  171
01125     },
01126     {
01127       43,   43,   43,   43,
01128      171,  171,  171,  171,
01129      171,  171,  171,  171,
01130      171,  171,  171,  171
01131     },
01132     {
01133       43,   43,   43,   43,
01134       43,   43,   43,   43,
01135       43,   43,   43,   43,
01136       43,   43,   43,   43
01137     }
01138 };
01139 
01140 const uint16 Indeo4Decoder::_ivi4_quant_4x4_inter[5][16] = {
01141     {
01142      107,  214,  257,  299,
01143      214,  257,  299,  299,
01144      257,  299,  299,  342,
01145      299,  299,  342,  342
01146     },
01147     {
01148      513, 1025, 1238, 1238,
01149     1025, 1025, 1238, 1238,
01150     1238, 1238, 1451, 1451,
01151     1238, 1238, 1451, 1451
01152     },
01153     {
01154       43,  171,  171,  171,
01155       43,  171,  171,  171,
01156       43,  171,  171,  171,
01157       43,  171,  171,  171
01158     },
01159     {
01160       43,   43,   43,   43,
01161      171,  171,  171,  171,
01162      171,  171,  171,  171,
01163      171,  171,  171,  171
01164     },
01165     {
01166       43,   43,   43,   43,
01167       43,   43,   43,   43,
01168       43,   43,   43,   43,
01169       43,   43,   43,   43
01170     }
01171 };
01172 
01173 const uint8 Indeo4Decoder::_quant_index_to_tab[22] = {
01174     0, 1, 0, 2, 1, 3, 0, 4, 1, 5, 0, 1, 6, 7, 8, // for 8x8 quant matrixes
01175     0, 1, 2, 2, 3, 3, 4                          // for 4x4 quant matrixes
01176 };
01177 
01178 } // End of namespace Image


Generated on Sat Mar 16 2019 05:01:38 for ResidualVM by doxygen 1.7.1
curved edge   curved edge