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     default:
00255         break;
00256     }
00257 
00258     switch (_ctx._frameType) {
00259     case IVI4_FRAMETYPE_INTRA:
00260     case IVI4_FRAMETYPE_INTRA1:
00261     case IVI4_FRAMETYPE_INTER:
00262         isRef = 1;
00263         break;
00264 
00265     default:
00266         break;
00267     }
00268 
00269     if (isPrevRef && isRef) {
00270         SWAP(_ctx._dstBuf, _ctx._refBuf);
00271     } else if (isPrevRef) {
00272         SWAP(_ctx._refBuf, _ctx._bRefBuf);
00273         SWAP(_ctx._dstBuf, _ctx._refBuf);
00274     }
00275 }
00276 
00277 bool Indeo4Decoder::isNonNullFrame() const {
00278     return _ctx._frameType < IVI4_FRAMETYPE_NULL_FIRST;
00279 }
00280 
00281 int Indeo4Decoder::decodeBandHeader(IVIBandDesc *band) {
00282     int plane, bandNum, indx, transformId, scanIndx;
00283     int i;
00284     int quantMat;
00285 
00286     plane = _ctx._gb->getBits(2);
00287     bandNum = _ctx._gb->getBits(4);
00288     if (band->_plane != plane || band->_bandNum != bandNum) {
00289         warning("Invalid band header sequence!");
00290         return -1;
00291     }
00292 
00293     band->_isEmpty = _ctx._gb->getBit();
00294     if (!band->_isEmpty) {
00295         int old_blk_size = band->_blkSize;
00296         // skip header size
00297         // If header size is not given, header size is 4 bytes.
00298         if (_ctx._gb->getBit())
00299             _ctx._gb->skip(16);
00300 
00301         band->_isHalfpel = _ctx._gb->getBits(2);
00302         if (band->_isHalfpel >= 2) {
00303             warning("Invalid/unsupported mv resolution: %d!",
00304                 band->_isHalfpel);
00305             return -1;
00306         }
00307         if (!band->_isHalfpel)
00308             _ctx._usesFullpel = true;
00309 
00310         band->_checksumPresent = _ctx._gb->getBit();
00311         if (band->_checksumPresent)
00312             band->_checksum = _ctx._gb->getBits(16);
00313 
00314         indx = _ctx._gb->getBits(2);
00315         if (indx == 3) {
00316             warning("Invalid block size!");
00317             return -1;
00318         }
00319         band->_mbSize = 16 >> indx;
00320         band->_blkSize = 8 >> (indx >> 1);
00321 
00322         band->_inheritMv = _ctx._gb->getBit();
00323         band->_inheritQDelta = _ctx._gb->getBit();
00324 
00325         band->_globQuant = _ctx._gb->getBits(5);
00326 
00327         if (!_ctx._gb->getBit() || _ctx._frameType == IVI4_FRAMETYPE_INTRA) {
00328             transformId = _ctx._gb->getBits(5);
00329             if ((uint)transformId >= FF_ARRAY_ELEMS(_transforms) ||
00330                 !_transforms[transformId]._invTrans) {
00331                 warning("Transform %d", transformId);
00332                 return -3;
00333             }
00334             if ((transformId >= 7 && transformId <= 9) ||
00335                 transformId == 17) {
00336                 warning("DCT transform");
00337                 return -3;
00338             }
00339 
00340             if (transformId < 10 && band->_blkSize < 8) {
00341                 warning("wrong transform size!");
00342                 return -1;
00343             }
00344             if ((transformId >= 0 && transformId <= 2) || transformId == 10)
00345                 _ctx._usesHaar = true;
00346 
00347             band->_invTransform = _transforms[transformId]._invTrans;
00348             band->_dcTransform = _transforms[transformId]._dcTrans;
00349             band->_is2dTrans = _transforms[transformId]._is2dTrans;
00350 
00351             if (transformId < 10)
00352                 band->_transformSize = 8;
00353             else
00354                 band->_transformSize = 4;
00355 
00356             if (band->_blkSize != band->_transformSize) {
00357                 warning("transform and block size mismatch (%d != %d)", band->_transformSize, band->_blkSize);
00358                 return -1;
00359             }
00360 
00361             scanIndx = _ctx._gb->getBits(4);
00362             if (scanIndx == 15) {
00363                 warning("Custom scan pattern encountered!");
00364                 return -1;
00365             }
00366             if (scanIndx > 4 && scanIndx < 10) {
00367                 if (band->_blkSize != 4) {
00368                     warning("mismatching scan table!");
00369                     return -1;
00370                 }
00371             } else if (band->_blkSize != 8) {
00372                 warning("mismatching scan table!");
00373                 return -1;
00374             }
00375 
00376             band->_scan = _scan_index_to_tab[scanIndx];
00377             band->_scanSize = band->_blkSize;
00378 
00379             quantMat = _ctx._gb->getBits(5);
00380             if (quantMat == 31) {
00381                 warning("Custom quant matrix encountered!");
00382                 return -1;
00383             }
00384             if ((uint)quantMat >= FF_ARRAY_ELEMS(_quant_index_to_tab)) {
00385                 warning("Quantization matrix %d", quantMat);
00386                 return -1;
00387             }
00388             band->_quantMat = quantMat;
00389         } else {
00390             if (old_blk_size != band->_blkSize) {
00391                 warning("The band block size does not match the configuration inherited");
00392                 return -1;
00393             }
00394         }
00395         if (_quant_index_to_tab[band->_quantMat] > 4 && band->_blkSize == 4) {
00396             warning("Invalid quant matrix for 4x4 block encountered!");
00397             band->_quantMat = 0;
00398             return -1;
00399         }
00400         if (band->_scanSize != band->_blkSize) {
00401             warning("mismatching scan table!");
00402             return -1;
00403         }
00404         if (band->_transformSize == 8 && band->_blkSize < 8) {
00405             warning("mismatching _transformSize!");
00406             return -1;
00407         }
00408 
00409         // decode block huffman codebook
00410         if (!_ctx._gb->getBit())
00411             band->_blkVlc._tab = _ctx._blkVlc._tab;
00412         else
00413             if (band->_blkVlc.decodeHuffDesc(&_ctx, 1, IVI_BLK_HUFF))
00414                 return -1;
00415 
00416         // select appropriate rvmap table for this band
00417         band->_rvmapSel = _ctx._gb->getBit() ? _ctx._gb->getBits(3) : 8;
00418 
00419         // decode rvmap probability corrections if any
00420         band->_numCorr = 0; // there is no corrections
00421         if (_ctx._gb->getBit()) {
00422             band->_numCorr = _ctx._gb->getBits(8); // get number of correction pairs
00423             if (band->_numCorr > 61) {
00424                 warning("Too many corrections: %d",
00425                     band->_numCorr);
00426                 return -1;
00427             }
00428 
00429             // read correction pairs
00430             for (i = 0; i < band->_numCorr * 2; i++)
00431                 band->_corr[i] = _ctx._gb->getBits(8);
00432         }
00433     }
00434 
00435     if (band->_blkSize == 8) {
00436         band->_intraBase = &_ivi4_quant_8x8_intra[_quant_index_to_tab[band->_quantMat]][0];
00437         band->_interBase = &_ivi4_quant_8x8_inter[_quant_index_to_tab[band->_quantMat]][0];
00438     } else {
00439         band->_intraBase = &_ivi4_quant_4x4_intra[_quant_index_to_tab[band->_quantMat]][0];
00440         band->_interBase = &_ivi4_quant_4x4_inter[_quant_index_to_tab[band->_quantMat]][0];
00441     }
00442 
00443     // Indeo 4 doesn't use scale tables
00444     band->_intraScale = NULL;
00445     band->_interScale = NULL;
00446 
00447     _ctx._gb->align();
00448 
00449     if (!band->_scan) {
00450         warning("band->_scan not set");
00451         return -1;
00452     }
00453 
00454     return 0;
00455 }
00456 
00457 int Indeo4Decoder::decodeMbInfo(IVIBandDesc *band, IVITile *tile) {
00458     int x, y, mvX, mvY, mvDelta, offs, mbOffset, blksPerMb,
00459         mvScale, mbTypeBits, s;
00460     IVIMbInfo *mb, *refMb;
00461     int row_offset = band->_mbSize * band->_pitch;
00462 
00463     mb = tile->_mbs;
00464     refMb = tile->_refMbs;
00465     offs = tile->_yPos * band->_pitch + tile->_xPos;
00466 
00467     blksPerMb = band->_mbSize != band->_blkSize ? 4 : 1;
00468     mbTypeBits = _ctx._frameType == IVI4_FRAMETYPE_BIDIR ? 2 : 1;
00469 
00470     // scale factor for motion vectors
00471     mvScale = (_ctx._planes[0]._bands[0]._mbSize >> 3) - (band->_mbSize >> 3);
00472     mvX = mvY = 0;
00473 
00474     if (((tile->_width + band->_mbSize - 1) / band->_mbSize) * ((tile->_height + band->_mbSize - 1) / band->_mbSize) != tile->_numMBs) {
00475         warning("numMBs mismatch %d %d %d %d", tile->_width, tile->_height, band->_mbSize, tile->_numMBs);
00476         return -1;
00477     }
00478 
00479     for (y = tile->_yPos; y < tile->_yPos + tile->_height; y += band->_mbSize) {
00480         mbOffset = offs;
00481 
00482         for (x = tile->_xPos; x < tile->_xPos + tile->_width; x += band->_mbSize) {
00483             mb->_xPos = x;
00484             mb->_yPos = y;
00485             mb->_bufOffs = mbOffset;
00486             mb->_bMvX = mb->_bMvY = 0;
00487 
00488             if (_ctx._gb->getBit()) {
00489                 if (_ctx._frameType == IVI4_FRAMETYPE_INTRA) {
00490                     warning("Empty macroblock in an INTRA picture!");
00491                     return -1;
00492                 }
00493                 mb->_type = 1; // empty macroblocks are always INTER
00494                 mb->_cbp = 0;  // all blocks are empty
00495 
00496                 mb->_qDelta = 0;
00497                 if (!band->_plane && !band->_bandNum && _ctx._inQ) {
00498                     mb->_qDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table,
00499                         IVI_VLC_BITS);
00500                     mb->_qDelta = IVI_TOSIGNED(mb->_qDelta);
00501                 }
00502 
00503                 mb->_mvX = mb->_mvY = 0; // no motion vector coded
00504                 if (band->_inheritMv && refMb) {
00505                     // motion vector inheritance
00506                     if (mvScale) {
00507                         mb->_mvX = scaleMV(refMb->_mvX, mvScale);
00508                         mb->_mvY = scaleMV(refMb->_mvY, mvScale);
00509                     } else {
00510                         mb->_mvX = refMb->_mvX;
00511                         mb->_mvY = refMb->_mvY;
00512                     }
00513                 }
00514             } else {
00515                 if (band->_inheritMv) {
00516                     // copy mb_type from corresponding reference mb
00517                     if (!refMb) {
00518                         warning("refMb unavailable");
00519                         return -1;
00520                     }
00521                     mb->_type = refMb->_type;
00522                 } else if (_ctx._frameType == IVI4_FRAMETYPE_INTRA ||
00523                     _ctx._frameType == IVI4_FRAMETYPE_INTRA1) {
00524                     mb->_type = 0; // mb_type is always INTRA for intra-frames
00525                 } else {
00526                     mb->_type = _ctx._gb->getBits(mbTypeBits);
00527                 }
00528 
00529                 mb->_cbp = _ctx._gb->getBits(blksPerMb);
00530 
00531                 mb->_qDelta = 0;
00532                 if (band->_inheritQDelta) {
00533                     if (refMb) mb->_qDelta = refMb->_qDelta;
00534                 } else if (mb->_cbp || (!band->_plane && !band->_bandNum &&
00535                     _ctx._inQ)) {
00536                     mb->_qDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table,
00537                         IVI_VLC_BITS);
00538                     mb->_qDelta = IVI_TOSIGNED(mb->_qDelta);
00539                 }
00540 
00541                 if (!mb->_type) {
00542                     mb->_mvX = mb->_mvY = 0; // there is no motion vector in intra-macroblocks
00543                 } else {
00544                     if (band->_inheritMv) {
00545                         if (refMb) {
00546                             // motion vector inheritance
00547                             if (mvScale) {
00548                                 mb->_mvX = scaleMV(refMb->_mvX, mvScale);
00549                                 mb->_mvY = scaleMV(refMb->_mvY, mvScale);
00550                             } else {
00551                                 mb->_mvX = refMb->_mvX;
00552                                 mb->_mvY = refMb->_mvY;
00553                             }
00554                         }
00555                     } else {
00556                         // decode motion vector deltas
00557                         mvDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table,
00558                             IVI_VLC_BITS);
00559                         mvY += IVI_TOSIGNED(mvDelta);
00560                         mvDelta = _ctx._gb->getVLC2<1>(_ctx._mbVlc._tab->_table,
00561                             IVI_VLC_BITS);
00562                         mvX += IVI_TOSIGNED(mvDelta);
00563                         mb->_mvX = mvX;
00564                         mb->_mvY = mvY;
00565                         if (mb->_type == 3) {
00566                             mvDelta = _ctx._gb->getVLC2<1>(
00567                                 _ctx._mbVlc._tab->_table,
00568                                 IVI_VLC_BITS);
00569                             mvY += IVI_TOSIGNED(mvDelta);
00570                             mvDelta = _ctx._gb->getVLC2<1>(
00571                                 _ctx._mbVlc._tab->_table,
00572                                 IVI_VLC_BITS);
00573                             mvX += IVI_TOSIGNED(mvDelta);
00574                             mb->_bMvX = -mvX;
00575                             mb->_bMvY = -mvY;
00576                         }
00577                     }
00578                     if (mb->_type == 2) {
00579                         mb->_bMvX = -mb->_mvX;
00580                         mb->_bMvY = -mb->_mvY;
00581                         mb->_mvX = 0;
00582                         mb->_mvY = 0;
00583                     }
00584                 }
00585             }
00586 
00587             s = band->_isHalfpel;
00588             if (mb->_type)
00589                 if (x + (mb->_mvX >> s) + (y + (mb->_mvY >> s))*band->_pitch < 0 ||
00590                     x + ((mb->_mvX + s) >> s) + band->_mbSize - 1
00591                     + (y + band->_mbSize - 1 + ((mb->_mvY + s) >> s))*band->_pitch > band->_bufSize - 1) {
00592                     warning("motion vector %d %d outside reference", x*s + mb->_mvX, y*s + mb->_mvY);
00593                     return -1;
00594                 }
00595 
00596             mb++;
00597             if (refMb)
00598                 refMb++;
00599             mbOffset += band->_mbSize;
00600         }
00601 
00602         offs += row_offset;
00603     }
00604 
00605     _ctx._gb->align();
00606     return 0;
00607 }
00608 
00609 int Indeo4Decoder::decodeRLETransparency(VLC_TYPE (*table)[2]) {
00610     const uint32 startPos = _ctx._gb->pos();
00611 
00612     _ctx._gb->align();
00613 
00614     bool runIsOpaque = _ctx._gb->getBit();
00615     bool nextRunIsOpaque = !runIsOpaque;
00616 
00617     uint32 *pixel = (uint32 *)_surface.getPixels();
00618     const int surfacePixelPitch = _surface.pitch / _surface.format.bytesPerPixel;
00619     const int surfacePadding = surfacePixelPitch - _surface.w;
00620     const uint32 *endOfVisibleRow = pixel + _surface.w;
00621     const uint32 *endOfVisibleArea = pixel + surfacePixelPitch * _surface.h - surfacePadding;
00622 
00623     const int codecAlignedWidth = (_surface.w + 31) & ~31;
00624     const int codecPaddingSize = codecAlignedWidth - _surface.w;
00625 
00626     int numPixelsToRead = codecAlignedWidth * _surface.h;
00627     int numPixelsToSkip = 0;
00628     while (numPixelsToRead > 0) {
00629         int value = _ctx._gb->getVLC2<1>(table, IVI_VLC_BITS);
00630 
00631         if (value == -1) {
00632             warning("Transparency VLC code read failed");
00633             return -1;
00634         }
00635 
00636         if (value == 0) {
00637             value = 255;
00638             nextRunIsOpaque = runIsOpaque;
00639         }
00640 
00641         numPixelsToRead -= value;
00642 
00643         debugN(9, "%d%s ", value, runIsOpaque ? "O" : "T");
00644 
00645         // The rest of the transparency data must be consumed but it will not
00646         // participate in writing any more pixels
00647         if (pixel == endOfVisibleArea) {
00648             debug(5, "Indeo4: Done writing transparency, but still need to consume %d pixels", numPixelsToRead + value);
00649             continue;
00650         }
00651 
00652         // If a run ends in the padding area of a row, the next run needs to
00653         // be partially consumed by the remaining pixels of the padding area
00654         if (numPixelsToSkip) {
00655             value -= numPixelsToSkip;
00656             if (value < 0) {
00657                 numPixelsToSkip = -value;
00658                 value = 0;
00659             } else {
00660                 numPixelsToSkip = 0;
00661             }
00662         }
00663 
00664         while (value > 0) {
00665             const int length = MIN<int>(value, endOfVisibleRow - pixel);
00666             if (!runIsOpaque) {
00667                 Common::fill(pixel, pixel + length, _ctx._transKeyColor);
00668             }
00669             value -= length;
00670             pixel += length;
00671 
00672             if (pixel == endOfVisibleRow) {
00673                 pixel += surfacePadding;
00674                 endOfVisibleRow += surfacePixelPitch;
00675                 value -= codecPaddingSize;
00676 
00677                 if (value < 0) {
00678                     numPixelsToSkip = -value;
00679                     break;
00680                 }
00681 
00682                 if (pixel == endOfVisibleArea) {
00683                     break;
00684                 }
00685             }
00686         }
00687 
00688         runIsOpaque = nextRunIsOpaque;
00689         nextRunIsOpaque = !runIsOpaque;
00690     }
00691 
00692     debugN(9, "\n");
00693 
00694     if (numPixelsToRead != 0) {
00695         warning("Wrong number of transparency pixels read; delta = %d", numPixelsToRead);
00696     }
00697 
00698     _ctx._gb->align();
00699 
00700     return (_ctx._gb->pos() - startPos) / 8;
00701 }
00702 
00703 int Indeo4Decoder::decodeTransparency() {
00704     if (_ctx._gb->getBits(2) != 3 || _ctx._gb->getBits(3) != 0) {
00705         warning("Invalid transparency marker");
00706         return -1;
00707     }
00708 
00709     Common::Rect drawRect;
00710 
00711     for (int numRects = _ctx._gb->getBits(8); numRects; --numRects) {
00712         const int x1 = _ctx._gb->getBits(16);
00713         const int y1 = _ctx._gb->getBits(16);
00714         const int x2 = x1 + _ctx._gb->getBits(16);
00715         const int y2 = y1 + _ctx._gb->getBits(16);
00716         drawRect.extend(Common::Rect(x1, y1, x2, y2));
00717     }
00718 
00719     debug(4, "Indeo4: Transparency rect is (%d, %d, %d, %d)", drawRect.left, drawRect.top, drawRect.right, drawRect.bottom);
00720 
00721     if (_ctx._gb->getBit()) { /* @350 */
00722         /* @358 */
00723         _ctx._transKeyColor = _surface.format.ARGBToColor(0, _ctx._gb->getBits(8), _ctx._gb->getBits(8), _ctx._gb->getBits(8));
00724         debug(4, "Indeo4: Key color is %08x", _ctx._transKeyColor);
00725         /* @477 */
00726     }
00727 
00728     if (_ctx._gb->getBit() == 0) { /* @4D9 */
00729         warning("Invalid transparency band?");
00730         return -1;
00731     }
00732 
00733     IVIHuffDesc huffDesc;
00734 
00735     const int numHuffRows = huffDesc._numRows = _ctx._gb->getBits(4);
00736     if (numHuffRows == 0 || numHuffRows > IVI_VLC_BITS - 1) {
00737         warning("Invalid codebook row count %d", numHuffRows);
00738         return -1;
00739     }
00740 
00741     for (int i = 0; i < numHuffRows; ++i) {
00742         huffDesc._xBits[i] = _ctx._gb->getBits(4);
00743     }
00744 
00745     /* @5E2 */
00746     _ctx._gb->align();
00747 
00748     IVIHuffTab &huffTable = _ctx._transVlc;
00749 
00750     if (huffDesc.huffDescCompare(&huffTable._custDesc) || !huffTable._custTab._table) {
00751         if (huffTable._custTab._table) {
00752             huffTable._custTab.freeVlc();
00753         }
00754 
00755         huffTable._custDesc = huffDesc;
00756         huffTable._tabSel = 7;
00757         huffTable._tab = &huffTable._custTab;
00758         if (huffTable._custDesc.createHuffFromDesc(huffTable._tab, false)) {
00759             // reset faulty description
00760             huffTable._custDesc._numRows = 0;
00761             warning("Error while initializing transparency VLC table");
00762             return -1;
00763         }
00764     }
00765 
00766     // FIXME: The transparency plane can be split, apparently for local decoding
00767     // mode (y459.avi in Titanic has the scalable flag and its transparency
00768     // plane seems to be decoded successfully, so the split transparency plane
00769     // does not seem to be related to scaling mode). This adds complexity to the
00770     // implementation, so avoid supporting unless it turns out to actually be
00771     // necessary for correct decoding of game videos.
00772     assert(!_ctx._usesTiling);
00773 
00774     assert(_surface.format.bytesPerPixel == 4);
00775     assert((_surface.pitch % 4) == 0);
00776 
00777     const uint32 startByte = _ctx._gb->pos() / 8;
00778 
00779     /* @68D */
00780     const bool useFillTransparency = _ctx._gb->getBit();
00781     if (useFillTransparency) {
00782         /* @6F2 */
00783         const bool runIsOpaque = _ctx._gb->getBit();
00784         if (!runIsOpaque) {
00785             // It should only be necessary to draw transparency here since the
00786             // data from the YUV planes gets drawn to the output surface on each
00787             // frame, which resets the surface pixels to be fully opaque
00788             _surface.fillRect(Common::Rect(_surface.w, _surface.h), _ctx._transKeyColor);
00789         }
00790 
00791         // No alignment here
00792     } else {
00793         /* @7BF */
00794         const bool hasDataSize = _ctx._gb->getBit();
00795         if (hasDataSize) { /* @81A */
00796             /* @822 */
00797             int expectedSize = _ctx._gb->getBits(8);
00798             if (expectedSize == 0xFF) {
00799                 expectedSize = _ctx._gb->getBits(24);
00800             }
00801 
00802             expectedSize -= ((_ctx._gb->pos() + 7) / 8) - startByte;
00803 
00804             const int bytesRead = decodeRLETransparency(huffTable._tab->_table);
00805             if (bytesRead == -1) {
00806                 // A more specific warning should have been emitted already
00807                 return -1;
00808             } else if (bytesRead != expectedSize) {
00809                 warning("Mismatched read %u != %u", bytesRead, expectedSize);
00810                 return -1;
00811             }
00812         } else {
00813             /* @95B */
00814             if (decodeRLETransparency(huffTable._tab->_table) == -1) {
00815                 warning("Transparency data read failure");
00816                 return -1;
00817             }
00818         }
00819 
00820         _ctx._gb->align();
00821     }
00822 
00823     return 0;
00824 }
00825 
00826 int Indeo4Decoder::scaleTileSize(int defSize, int sizeFactor) {
00827     return sizeFactor == 15 ? defSize : (sizeFactor + 1) << 5;
00828 }
00829 
00830 int Indeo4Decoder::decodePlaneSubdivision() {
00831     int i;
00832 
00833     switch (_ctx._gb->getBits(2)) {
00834     case 3:
00835         return 1;
00836 
00837     case 2:
00838         for (i = 0; i < 4; i++)
00839             if (_ctx._gb->getBits(2) != 3)
00840                 return 0;
00841         return 4;
00842 
00843     default:
00844         return 0;
00845     }
00846 }
00847 
00848 /*------------------------------------------------------------------------*/
00849 
00853 static const uint8 ivi4AlternateScan8x8[64] = {
00854     0,  8,  1,  9, 16, 24,  2,  3, 17, 25, 10, 11, 32, 40, 48, 56,
00855     4,  5,  6,  7, 33, 41, 49, 57, 18, 19, 26, 27, 12, 13, 14, 15,
00856     34, 35, 43, 42, 50, 51, 59, 58, 20, 21, 22, 23, 31, 30, 29, 28,
00857     36, 37, 38, 39, 47, 46, 45, 44, 52, 53, 54, 55, 63, 62, 61, 60
00858 };
00859 
00860 static const uint8 ivi4AlternateScan4x4[16] = {
00861     0, 1, 4, 5, 8, 12, 2, 3, 9, 13, 6, 7, 10, 11, 14, 15
00862 };
00863 
00864 static const uint8 ivi4VerticalScan4x4[16] = {
00865     0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15
00866 };
00867 
00868 static const uint8 ivi4HorizontalScan4x4[16] = {
00869     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
00870 };
00871 
00872 const uint Indeo4Decoder::_ivi4_common_pic_sizes[14] = {
00873     640, 480, 320, 240, 160, 120, 704, 480, 352, 240, 352, 288, 176, 144
00874 };
00875 
00876 Indeo4Decoder::Transform Indeo4Decoder::_transforms[18] = {
00877     { IndeoDSP::ffIviInverseHaar8x8,  IndeoDSP::ffIviDcHaar2d,       1 },
00878     { IndeoDSP::ffIviRowHaar8,         IndeoDSP::ffIviDcHaar2d,       0 },
00879     { IndeoDSP::ffIviColHaar8,         IndeoDSP::ffIviDcHaar2d,       0 },
00880     { IndeoDSP::ffIviPutPixels8x8,    IndeoDSP::ffIviPutDcPixel8x8, 1 },
00881     { IndeoDSP::ffIviInverseSlant8x8, IndeoDSP::ffIviDcSlant2d,      1 },
00882     { IndeoDSP::ffIviRowSlant8,        IndeoDSP::ffIviDcRowSlant,     1 },
00883     { IndeoDSP::ffIviColSlant8,        IndeoDSP::ffIviDcColSlant,     1 },
00884     { NULL, NULL, 0 }, // inverse DCT 8x8
00885     { NULL, NULL, 0 }, // inverse DCT 8x1
00886     { NULL, NULL, 0 }, // inverse DCT 1x8
00887     { IndeoDSP::ffIviInverseHaar4x4,  IndeoDSP::ffIviDcHaar2d,       1 },
00888     { IndeoDSP::ffIviInverseSlant4x4, IndeoDSP::ffIviDcSlant2d,      1 },
00889     { NULL, NULL, 0 }, // no transform 4x4
00890     { IndeoDSP::ffIviRowHaar4,         IndeoDSP::ffIviDcHaar2d,       0 },
00891     { IndeoDSP::ffIviColHaar4,         IndeoDSP::ffIviDcHaar2d,       0 },
00892     { IndeoDSP::ffIviRowSlant4,        IndeoDSP::ffIviDcRowSlant,     0 },
00893     { IndeoDSP::ffIviColSlant4,        IndeoDSP::ffIviDcColSlant,     0 },
00894     { NULL, NULL, 0 }, // inverse DCT 4x4
00895 };
00896 
00897 const uint8 *const Indeo4Decoder::_scan_index_to_tab[15] = {
00898     // for 8x8 transforms
00899     ffZigZagDirect,
00900     ivi4AlternateScan8x8,
00901     _ffIviHorizontalScan8x8,
00902     _ffIviVerticalScan8x8,
00903     ffZigZagDirect,
00904 
00905     // for 4x4 transforms
00906     _ffIviDirectScan4x4,
00907     ivi4AlternateScan4x4,
00908     ivi4VerticalScan4x4,
00909     ivi4HorizontalScan4x4,
00910     _ffIviDirectScan4x4,
00911 
00912     // TODO: check if those are needed
00913     _ffIviHorizontalScan8x8,
00914     _ffIviHorizontalScan8x8,
00915     _ffIviHorizontalScan8x8,
00916     _ffIviHorizontalScan8x8,
00917     _ffIviHorizontalScan8x8
00918 };
00919 
00923 const uint16 Indeo4Decoder::_ivi4_quant_8x8_intra[9][64] = {
00924     {
00925       43,  342,  385,  470,  555,  555,  598,  726,
00926      342,  342,  470,  513,  555,  598,  726,  769,
00927      385,  470,  555,  555,  598,  726,  726,  811,
00928      470,  470,  555,  555,  598,  726,  769,  854,
00929      470,  555,  555,  598,  683,  726,  854, 1025,
00930      555,  555,  598,  683,  726,  854, 1025, 1153,
00931      555,  555,  598,  726,  811,  982, 1195, 1451,
00932      555,  598,  726,  811,  982, 1195, 1451, 1793
00933     },
00934     {
00935       86, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
00936     1195, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
00937     2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
00938     2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
00939     4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
00940     4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
00941     4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
00942     4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827
00943     },
00944     {
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      235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
00952      235, 1067, 1195, 1323, 1451, 1579, 1707, 1835
00953     },
00954     {
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     1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
00962     1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414
00963     },
00964     {
00965      897,  897,  897,  897,  897,  897,  897,  897,
00966     1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067,
00967     1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
00968     1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409,
00969     1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579,
00970     1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750,
00971     1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921,
00972     2091, 2091, 2091, 2091, 2091, 2091, 2091, 2091
00973     },
00974     {
00975     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
00976     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
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     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
00982     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414
00983     },
00984     {
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     2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
00992     2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390
00993     },
00994     {
00995       22,  171,  214,  257,  257,  299,  299,  342,
00996      171,  171,  257,  257,  299,  299,  342,  385,
00997      214,  257,  257,  299,  299,  342,  342,  385,
00998      257,  257,  257,  299,  299,  342,  385,  427,
00999      257,  257,  299,  299,  342,  385,  427,  513,
01000      257,  299,  299,  342,  385,  427,  513,  598,
01001      299,  299,  299,  385,  385,  470,  598,  726,
01002      299,  299,  385,  385,  470,  598,  726,  897
01003     },
01004     {
01005       86,  598, 1195, 1195, 2390, 2390, 2390, 2390,
01006      598,  598, 1195, 1195, 2390, 2390, 2390, 2390,
01007     1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
01008     1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
01009     2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
01010     2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
01011     2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
01012     2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414
01013     }
01014 };
01015 
01016 const uint16 Indeo4Decoder::_ivi4_quant_8x8_inter[9][64] = {
01017     {
01018      427,  427,  470,  427,  427,  427,  470,  470,
01019      427,  427,  470,  427,  427,  427,  470,  470,
01020      470,  470,  470,  470,  470,  470,  470,  470,
01021      427,  427,  470,  470,  427,  427,  470,  470,
01022      427,  427,  470,  427,  427,  427,  470,  470,
01023      427,  427,  470,  427,  427,  427,  470,  470,
01024      470,  470,  470,  470,  470,  470,  470,  470,
01025      470,  470,  470,  470,  470,  470,  470,  470
01026     },
01027     {
01028     1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
01029     1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
01030     2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
01031     2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
01032     3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
01033     3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
01034     3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
01035     3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414
01036     },
01037     {
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     1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
01045     1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281
01046     },
01047     {
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     2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
01055     2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433
01056     },
01057     {
01058     1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
01059     1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
01060     1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
01061     1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
01062     1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
01063     1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
01064     1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
01065     1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281
01066     },
01067     {
01068     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
01069     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
01070     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
01071     3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
01072     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
01073     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
01074     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
01075     2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433
01076     },
01077     {
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     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
01085     1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707
01086     },
01087     {
01088       86,  171,  171,  214,  214,  214,  214,  257,
01089      171,  171,  214,  214,  214,  214,  257,  257,
01090      171,  214,  214,  214,  214,  257,  257,  257,
01091      214,  214,  214,  214,  257,  257,  257,  299,
01092      214,  214,  214,  257,  257,  257,  299,  299,
01093      214,  214,  257,  257,  257,  299,  299,  299,
01094      214,  257,  257,  257,  299,  299,  299,  342,
01095      257,  257,  257,  299,  299,  299,  342,  342
01096     },
01097     {
01098      854,  854, 1195, 1195, 1707, 1707, 1707, 1707,
01099      854,  854, 1195, 1195, 1707, 1707, 1707, 1707,
01100     1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
01101     1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
01102     1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
01103     1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
01104     1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
01105     1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707
01106     }
01107 };
01108 
01109 const uint16 Indeo4Decoder::_ivi4_quant_4x4_intra[5][16] = {
01110     {
01111       22,  214,  257,  299,
01112      214,  257,  299,  342,
01113      257,  299,  342,  427,
01114      299,  342,  427,  513
01115     },
01116     {
01117      129, 1025, 1451, 1451,
01118     1025, 1025, 1451, 1451,
01119     1451, 1451, 2049, 2049,
01120     1451, 1451, 2049, 2049
01121     },
01122     {
01123       43,  171,  171,  171,
01124       43,  171,  171,  171,
01125       43,  171,  171,  171,
01126       43,  171,  171,  171
01127     },
01128     {
01129       43,   43,   43,   43,
01130      171,  171,  171,  171,
01131      171,  171,  171,  171,
01132      171,  171,  171,  171
01133     },
01134     {
01135       43,   43,   43,   43,
01136       43,   43,   43,   43,
01137       43,   43,   43,   43,
01138       43,   43,   43,   43
01139     }
01140 };
01141 
01142 const uint16 Indeo4Decoder::_ivi4_quant_4x4_inter[5][16] = {
01143     {
01144      107,  214,  257,  299,
01145      214,  257,  299,  299,
01146      257,  299,  299,  342,
01147      299,  299,  342,  342
01148     },
01149     {
01150      513, 1025, 1238, 1238,
01151     1025, 1025, 1238, 1238,
01152     1238, 1238, 1451, 1451,
01153     1238, 1238, 1451, 1451
01154     },
01155     {
01156       43,  171,  171,  171,
01157       43,  171,  171,  171,
01158       43,  171,  171,  171,
01159       43,  171,  171,  171
01160     },
01161     {
01162       43,   43,   43,   43,
01163      171,  171,  171,  171,
01164      171,  171,  171,  171,
01165      171,  171,  171,  171
01166     },
01167     {
01168       43,   43,   43,   43,
01169       43,   43,   43,   43,
01170       43,   43,   43,   43,
01171       43,   43,   43,   43
01172     }
01173 };
01174 
01175 const uint8 Indeo4Decoder::_quant_index_to_tab[22] = {
01176     0, 1, 0, 2, 1, 3, 0, 4, 1, 5, 0, 1, 6, 7, 8, // for 8x8 quant matrixes
01177     0, 1, 2, 2, 3, 3, 4                          // for 4x4 quant matrixes
01178 };
01179 
01180 } // End of namespace Image


Generated on Sat Jul 11 2020 05:01:26 for ResidualVM by doxygen 1.7.1
curved edge   curved edge