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

indeo.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 /* Common structures, macros, and base class shared by both Indeo4 and
00024  * Indeo5 decoders, derived from ffmpeg.
00025  */
00026 
00027 #include "image/codecs/indeo/indeo.h"
00028 #include "image/codecs/indeo/indeo_dsp.h"
00029 #include "image/codecs/indeo/mem.h"
00030 #include "graphics/yuv_to_rgb.h"
00031 #include "common/system.h"
00032 #include "common/algorithm.h"
00033 #include "common/rect.h"
00034 #include "common/textconsole.h"
00035 #include "common/util.h"
00036 
00037 namespace Image {
00038 namespace Indeo {
00039 
00050 static const IVIHuffDesc ivi_mb_huff_desc[8] = {
00051     {8,  {0, 4, 5, 4, 4, 4, 6, 6}},
00052     {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
00053     {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
00054     {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
00055     {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
00056     {9,  {0, 4, 4, 4, 4, 3, 3, 3, 2}},
00057     {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
00058     {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
00059 };
00060 
00064 static const IVIHuffDesc ivi_blk_huff_desc[8] = {
00065     {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1} },
00066     {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2} },
00067     {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1} },
00068     {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1} },
00069     {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2} },
00070     {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1} },
00071     {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1} },
00072     {9,  {3, 4, 4, 5, 5, 5, 6, 5, 5} }
00073 };
00074 
00075 /*------------------------------------------------------------------------*/
00076 
00080 #define IVI_NUM_TILES(stride, tileSize) (((stride) + (tileSize) - 1) / (tileSize))
00081 
00082 /*------------------------------------------------------------------------*/
00083 
00084 int IVIHuffDesc::createHuffFromDesc(VLC *vlc, bool flag) const {
00085     uint16 codewords[256];
00086     uint8 bits[256];
00087 
00088     int pos = 0; // current position = 0
00089 
00090     for (int i = 0; i < _numRows; i++) {
00091         int codesPerRow = 1 << _xBits[i];
00092         int notLastRow  = (i != _numRows - 1);
00093         int prefix      = ((1 << i) - 1) << (_xBits[i] + notLastRow);
00094 
00095         for (int j = 0; j < codesPerRow; j++) {
00096             if (pos >= 256) // Some Indeo5 codebooks can have more than 256
00097                 break;      // elements, but only 256 codes are allowed!
00098 
00099             bits[pos] = i + _xBits[i] + notLastRow;
00100             if (bits[pos] > IVI_VLC_BITS)
00101                 return -1; // invalid descriptor
00102 
00103             codewords[pos] = invertBits((prefix | j), bits[pos]);
00104             if (!bits[pos])
00105                 bits[pos] = 1;
00106 
00107             pos++;
00108         }//for j
00109     }//for i
00110 
00111     // number of codewords = pos
00112     return vlc->init_vlc(IVI_VLC_BITS, pos, bits, 1, 1, codewords, 2, 2,
00113                     (flag ? INIT_VLC_USE_NEW_STATIC : 0) | INIT_VLC_LE);
00114 }
00115 
00116 /*------------------------------------------------------------------------*/
00117 
00118 bool IVIHuffDesc::huffDescCompare(const IVIHuffDesc *desc2) const {
00119     return _numRows != desc2->_numRows || memcmp(_xBits, desc2->_xBits, _numRows);
00120 }
00121 
00122 void IVIHuffDesc::huffDescCopy(const IVIHuffDesc *src) {
00123     _numRows = src->_numRows;
00124     memcpy(_xBits, src->_xBits, src->_numRows);
00125 }
00126 
00127 /*------------------------------------------------------------------------*/
00128 
00129 IVIHuffTab::IVIHuffTab() : _tab(nullptr) {
00130     _custDesc._numRows = 0;
00131     Common::fill(&_custDesc._xBits[0], &_custDesc._xBits[16], 0);
00132 }
00133 
00134 int IVIHuffTab::decodeHuffDesc(IVI45DecContext *ctx, int descCoded, int whichTab) {
00135     IVIHuffDesc newHuff;
00136 
00137     if (!descCoded) {
00138         // select default table
00139         _tab = (whichTab) ? &ctx->_iviBlkVlcTabs[7]
00140             : &ctx->_iviMbVlcTabs[7];
00141         return 0;
00142     }
00143 
00144     _tabSel = ctx->_gb->getBits(3);
00145     if (_tabSel == 7) {
00146         // custom huffman table (explicitly encoded)
00147         newHuff._numRows = ctx->_gb->getBits(4);
00148         if (!newHuff._numRows) {
00149             warning("Empty custom Huffman table!");
00150             return -1;
00151         }
00152 
00153         for (int i = 0; i < newHuff._numRows; i++)
00154             newHuff._xBits[i] = ctx->_gb->getBits(4);
00155 
00156         // Have we got the same custom table? Rebuild if not.
00157         if (newHuff.huffDescCompare(&_custDesc) || !_custTab._table) {
00158             _custDesc.huffDescCopy(&newHuff);
00159 
00160             if (_custTab._table)
00161                 _custTab.freeVlc();
00162             int result = _custDesc.createHuffFromDesc(&_custTab, false);
00163             if (result) {
00164                 // reset faulty description
00165                 _custDesc._numRows = 0;
00166                 warning("Error while initializing custom vlc table!");
00167                 return result;
00168             }
00169         }
00170         _tab = &_custTab;
00171     } else {
00172         // select one of predefined tables
00173         _tab = (whichTab) ? &ctx->_iviBlkVlcTabs[_tabSel]
00174             : &ctx->_iviMbVlcTabs[_tabSel];
00175     }
00176 
00177     return 0;
00178 }
00179 
00180 /*------------------------------------------------------------------------*/
00181 
00182 IVIMbInfo::IVIMbInfo() : _xPos(0), _yPos(0), _bufOffs(0), _type(0), _cbp(0),
00183         _qDelta(0), _mvX(0), _mvY(0), _bMvX(0), _bMvY(0) {
00184 }
00185 
00186 /*------------------------------------------------------------------------*/
00187 
00188 IVITile::IVITile() : _xPos(0), _yPos(0), _width(0), _height(0), _mbSize(0),
00189         _isEmpty(false), _dataSize(0), _numMBs(0), _mbs(nullptr), _refMbs(nullptr) {
00190 }
00191 
00192 /*------------------------------------------------------------------------*/
00193 
00194 IVIBandDesc::IVIBandDesc() : _plane(0), _bandNum(0), _width(0), _height(0),
00195         _aHeight(0), _dataPtr(nullptr), _dataSize(0), _buf(nullptr),
00196         _refBuf(nullptr), _bRefBuf(nullptr), _pitch(0), _isEmpty(false),
00197         _mbSize(0), _blkSize(0), _isHalfpel(false), _inheritMv(false), _bufSize(0),
00198         _inheritQDelta(false), _qdeltaPresent(false), _quantMat(0), _globQuant(0),
00199         _scan(nullptr), _scanSize(0), _numCorr(0), _rvmapSel(0), _rvMap(nullptr),
00200         _numTiles(0), _tiles(nullptr), _invTransform(nullptr), _transformSize(0),
00201         _dcTransform(nullptr), _is2dTrans(0), _checksum(0), _checksumPresent(false),
00202         _intraBase(nullptr), _interBase(nullptr), _intraScale(nullptr),
00203         _interScale(nullptr) {
00204     Common::fill(&_bufs[0], &_bufs[4], (int16 *)nullptr);
00205     Common::fill(&_corr[0], &_corr[61 * 2], 0);
00206 }
00207 
00208 int IVIBandDesc::initTiles(IVITile *refTile, int p, int b, int tHeight, int tWidth) {
00209     IVITile *tile = _tiles;
00210 
00211     for (int y = 0; y < _height; y += tHeight) {
00212         for (int x = 0; x < _width; x += tWidth) {
00213             tile->_xPos = x;
00214             tile->_yPos = y;
00215             tile->_mbSize = _mbSize;
00216             tile->_width = MIN(_width - x, tWidth);
00217             tile->_height = MIN(_height - y, tHeight);
00218             tile->_dataSize = 0;
00219             tile->_isEmpty = false;
00220 
00221             // calculate number of macroblocks
00222             tile->_numMBs = IVI_MBs_PER_TILE(tile->_width, tile->_height,
00223                 _mbSize);
00224 
00225             avFreeP(&tile->_mbs);
00226             tile->_mbs = (IVIMbInfo *)calloc(tile->_numMBs, sizeof(IVIMbInfo));
00227             if (!tile->_mbs)
00228                 return -2;
00229 
00230             tile->_refMbs = 0;
00231             if (p || b) {
00232                 if (tile->_numMBs != refTile->_numMBs) {
00233                     warning("refTile mismatch");
00234                     return -1;
00235                 }
00236                 tile->_refMbs = refTile->_mbs;
00237                 refTile++;
00238             }
00239             tile++;
00240         }
00241     }
00242 
00243     return 0;
00244 }
00245 
00246 /*------------------------------------------------------------------------*/
00247 
00248 IVIPicConfig::IVIPicConfig() : _picWidth(0), _picHeight(0), _chromaWidth(0),
00249         _chromaHeight(0), _tileWidth(0), _tileHeight(0), _lumaBands(0), _chromaBands(0) {
00250 }
00251 
00252 bool IVIPicConfig::ivi_pic_config_cmp(const IVIPicConfig &cfg2) {
00253     return _picWidth != cfg2._picWidth || _picHeight != cfg2._picHeight ||
00254         _chromaWidth != cfg2._chromaWidth || _chromaHeight != cfg2._chromaHeight ||
00255         _tileWidth != cfg2._tileWidth || _tileHeight != cfg2._tileHeight ||
00256         _lumaBands != cfg2._lumaBands || _chromaBands != cfg2._chromaBands;
00257 }
00258 
00259 /*------------------------------------------------------------------------*/
00260 
00261 IVIPlaneDesc::IVIPlaneDesc() : _width(0), _height(0), _numBands(0), _bands(nullptr) {
00262 }
00263 
00264 int IVIPlaneDesc::initPlanes(IVIPlaneDesc *planes, const IVIPicConfig *cfg, bool isIndeo4) {
00265     uint32 b_width, b_height, align_fac, width_aligned, height_aligned, bufSize;
00266     IVIBandDesc *band;
00267 
00268     freeBuffers(planes);
00269 
00270     if (checkImageSize(cfg->_picWidth, cfg->_picHeight, 0) < 0 ||
00271         cfg->_lumaBands < 1 || cfg->_chromaBands < 1)
00272         return -1;
00273 
00274     // fill in the descriptor of the luminance _plane
00275     planes[0]._width = cfg->_picWidth;
00276     planes[0]._height = cfg->_picHeight;
00277     planes[0]._numBands = cfg->_lumaBands;
00278 
00279     // fill in the descriptors of the chrominance planes
00280     planes[1]._width = planes[2]._width = (cfg->_picWidth + 3) >> 2;
00281     planes[1]._height = planes[2]._height = (cfg->_picHeight + 3) >> 2;
00282     planes[1]._numBands = planes[2]._numBands = cfg->_chromaBands;
00283 
00284     for (int p = 0; p < 3; p++) {
00285         planes[p]._bands = (IVIBandDesc *)calloc(planes[p]._numBands, sizeof(IVIBandDesc));
00286         if (!planes[p]._bands)
00287             return -2;
00288 
00289         // select band dimensions: if there is only one band then it
00290         // has the full size, if there are several bands each of them
00291         // has only half size
00292         b_width = planes[p]._numBands == 1 ? planes[p]._width
00293             : (planes[p]._width + 1) >> 1;
00294         b_height = planes[p]._numBands == 1 ? planes[p]._height
00295             : (planes[p]._height + 1) >> 1;
00296 
00297         // luma   band buffers will be aligned on 16x16 (max macroblock size)
00298         // chroma band buffers will be aligned on   8x8 (max macroblock size)
00299         align_fac = p ? 8 : 16;
00300         width_aligned = FFALIGN(b_width, align_fac);
00301         height_aligned = FFALIGN(b_height, align_fac);
00302         bufSize = width_aligned * height_aligned * sizeof(int16);
00303 
00304         for (int b = 0; b < planes[p]._numBands; b++) {
00305             band = &planes[p]._bands[b]; // select appropriate _plane/band
00306             band->_plane = p;
00307             band->_bandNum = b;
00308             band->_width = b_width;
00309             band->_height = b_height;
00310             band->_pitch = width_aligned;
00311             band->_aHeight = height_aligned;
00312             band->_bufs[0] = (int16 *)calloc(bufSize, 1);
00313             band->_bufs[1] = (int16 *)calloc(bufSize, 1);
00314             band->_bufSize = bufSize / 2;
00315             if (!band->_bufs[0] || !band->_bufs[1])
00316                 return -2;
00317 
00318             // allocate the 3rd band buffer for scalability mode
00319             if (cfg->_lumaBands > 1) {
00320                 band->_bufs[2] = (int16 *)calloc(bufSize, 1);
00321                 if (!band->_bufs[2])
00322                     return -2;
00323             }
00324             if (isIndeo4) {
00325                 band->_bufs[3] = (int16 *)calloc(bufSize, 1);
00326                 if (!band->_bufs[3])
00327                     return -2;
00328             }
00329             // reset custom vlc
00330             planes[p]._bands[0]._blkVlc._custDesc._numRows = 0;
00331         }
00332     }
00333 
00334     return 0;
00335 }
00336 
00337 int IVIPlaneDesc::initTiles(IVIPlaneDesc *planes, int tileWidth, int tileHeight) {
00338     int xTiles, yTiles, tWidth, tHeight, ret;
00339     IVIBandDesc *band;
00340 
00341     for (int p = 0; p < 3; p++) {
00342         tWidth = !p ? tileWidth : (tileWidth + 3) >> 2;
00343         tHeight = !p ? tileHeight : (tileHeight + 3) >> 2;
00344 
00345         if (!p && planes[0]._numBands == 4) {
00346             tWidth >>= 1;
00347             tHeight >>= 1;
00348         }
00349         if (tWidth <= 0 || tHeight <= 0)
00350             return -3;
00351 
00352         for (int b = 0; b < planes[p]._numBands; b++) {
00353             band = &planes[p]._bands[b];
00354             xTiles = IVI_NUM_TILES(band->_width, tWidth);
00355             yTiles = IVI_NUM_TILES(band->_height, tHeight);
00356             band->_numTiles = xTiles * yTiles;
00357 
00358             avFreeP(&band->_tiles);
00359             band->_tiles = (IVITile *)calloc(band->_numTiles, sizeof(IVITile));
00360             if (!band->_tiles)
00361                 return -2;
00362 
00363             // use the first luma band as reference for motion vectors
00364             // and quant
00365             ret = band->initTiles(planes[0]._bands[0]._tiles,
00366                 p, b, tHeight, tWidth);
00367             if (ret < 0)
00368                 return ret;
00369         }
00370     }
00371 
00372     return 0;
00373 }
00374 
00375 void IVIPlaneDesc::freeBuffers(IVIPlaneDesc *planes) {
00376     for (int p = 0; p < 3; p++) {
00377         if (planes[p]._bands)
00378             for (int b = 0; b < planes[p]._numBands; b++) {
00379                 avFreeP(&planes[p]._bands[b]._bufs[0]);
00380                 avFreeP(&planes[p]._bands[b]._bufs[1]);
00381                 avFreeP(&planes[p]._bands[b]._bufs[2]);
00382                 avFreeP(&planes[p]._bands[b]._bufs[3]);
00383 
00384                 if (planes[p]._bands[b]._blkVlc._custTab._table)
00385                     planes[p]._bands[b]._blkVlc._custTab.freeVlc();
00386                 for (int t = 0; t < planes[p]._bands[b]._numTiles; t++)
00387                     avFreeP(&planes[p]._bands[b]._tiles[t]._mbs);
00388                 avFreeP(&planes[p]._bands[b]._tiles);
00389             }
00390         avFreeP(&planes[p]._bands);
00391         planes[p]._numBands = 0;
00392     }
00393 }
00394 
00395 int IVIPlaneDesc::checkImageSize(unsigned int w, unsigned int h, int log_offset) {
00396     if (((w + 128) * (uint64)(h + 128)) < (MAX_INTEGER / 8))
00397         return 0;
00398 
00399     error("Picture size %ux%u is invalid", w, h);
00400 }
00401 
00402 /*------------------------------------------------------------------------*/
00403 
00404 AVFrame::AVFrame() {
00405     Common::fill(&_data[0], &_data[AV_NUM_DATA_POINTERS], (uint8 *)nullptr);
00406     Common::fill(&_linesize[0], &_linesize[AV_NUM_DATA_POINTERS], 0);
00407 }
00408 
00409 int AVFrame::setDimensions(uint16 width, uint16 height) {
00410     _width = width;
00411     _height = height;
00412     _linesize[0] = _linesize[1] = _linesize[2] = width;
00413 
00414     return 0;
00415 }
00416 
00417 int AVFrame::getBuffer(int flags) {
00418     freeFrame();
00419 
00420     // Luminance channel
00421     _data[0] = (uint8 *)calloc(_width * _height, 1);
00422 
00423     // UV Chroma Channels
00424     _data[1] = (uint8 *)malloc(_width * _height);
00425     _data[2] = (uint8 *)malloc(_width * _height);
00426     Common::fill(_data[1], _data[1] + _width * _height, 0x80);
00427     Common::fill(_data[2], _data[2] + _width * _height, 0x80);
00428 
00429     return 0;
00430 }
00431 
00432 void AVFrame::freeFrame() {
00433     avFreeP(&_data[0]);
00434     avFreeP(&_data[1]);
00435     avFreeP(&_data[2]);
00436 }
00437 
00438 /*------------------------------------------------------------------------*/
00439 
00440 IVI45DecContext::IVI45DecContext() : _gb(nullptr), _frameNum(0), _frameType(0),
00441         _prevFrameType(0), _dataSize(0), _isScalable(0), _frameData(0),
00442         _interScal(0), _frameSize(0), _picHdrSize(0), _frameFlags(0),
00443         _checksum(0), _bufSwitch(0), _dstBuf(0), _refBuf(0), _ref2Buf(0),
00444         _bRefBuf(0), _rvmapSel(0), _inImf(false), _inQ(false), _picGlobQuant(0),
00445         _unknown1(0), _gopHdrSize(0), _gopFlags(0), _lockWord(0), _hasBFrames(false),
00446         _hasTransp(false), _usesTiling(false), _usesHaar(false), _usesFullpel(false),
00447         _gopInvalid(false), _isIndeo4(false), _transKeyColor(0), _pFrame(nullptr),
00448         _gotPFrame(false) {
00449     Common::fill(&_bufInvalid[0], &_bufInvalid[4], 0);
00450     Common::copy(&_ff_ivi_rvmap_tabs[0], &_ff_ivi_rvmap_tabs[9], &_rvmapTabs[0]);
00451 
00452     for (int idx = 0; idx < (8192 * 16); ++idx)
00453         _tableData[idx][0] = _tableData[idx][1] = 0;
00454 
00455     for (int i = 0; i < 8; i++) {
00456         _iviMbVlcTabs[i]._table = _tableData + i * 2 * 8192;
00457         _iviMbVlcTabs[i]._tableAllocated = 8192;
00458         ivi_mb_huff_desc[i].createHuffFromDesc(&_iviMbVlcTabs[i], true);
00459         _iviBlkVlcTabs[i]._table = _tableData + (i * 2 + 1) * 8192;
00460         _iviBlkVlcTabs[i]._tableAllocated = 8192;
00461         ivi_blk_huff_desc[i].createHuffFromDesc(&_iviBlkVlcTabs[i], true);
00462     }
00463 }
00464 
00465 /*------------------------------------------------------------------------*/
00466 
00467 IndeoDecoderBase::IndeoDecoderBase(uint16 width, uint16 height, uint bitsPerPixel) : Codec() {
00468     _pixelFormat = g_system->getScreenFormat();
00469 
00470     if (_pixelFormat.bytesPerPixel == 1) {
00471         switch (bitsPerPixel) {
00472         case 15:
00473             _pixelFormat = Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0);
00474             break;
00475         case 16:
00476             _pixelFormat = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
00477             break;
00478         case 24:
00479             _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0);
00480             break;
00481         case 32:
00482             _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
00483             break;
00484         default:
00485             error("Invalid color depth");
00486             break;
00487         }
00488     }
00489 
00490     _surface.create(width, height, _pixelFormat);
00491     _surface.fillRect(Common::Rect(0, 0, width, height), (bitsPerPixel == 32) ? 0xff : 0);
00492     _ctx._bRefBuf = 3; // buffer 2 is used for scalability mode
00493 }
00494 
00495 IndeoDecoderBase::~IndeoDecoderBase() {
00496     _surface.free();
00497     IVIPlaneDesc::freeBuffers(_ctx._planes);
00498     if (_ctx._mbVlc._custTab._table)
00499         _ctx._mbVlc._custTab.freeVlc();
00500     if (_ctx._transVlc._custTab._table)
00501         _ctx._transVlc._custTab.freeVlc();
00502 
00503     delete _ctx._pFrame;
00504 }
00505 
00506 int IndeoDecoderBase::decodeIndeoFrame() {
00507     int result;
00508     AVFrame frameData;
00509     AVFrame *frame = &frameData;
00510 
00511     // Decode the header
00512     if (decodePictureHeader() < 0)
00513         return -1;
00514 
00515     if (_ctx._gopInvalid)
00516         return -1;
00517 
00518     if (_ctx._frameType == IVI4_FRAMETYPE_NULL_LAST) {
00519         // Returning the previous frame, so exit wth success
00520         return 0;
00521     }
00522 
00523     if (_ctx._gopFlags & IVI5_IS_PROTECTED) {
00524         warning("Password-protected clip");
00525         return -1;
00526     }
00527 
00528     if (!_ctx._planes[0]._bands) {
00529         warning("Color planes not initialized yet");
00530         return -1;
00531     }
00532 
00533     switchBuffers();
00534 
00535     //{ START_TIMER;
00536 
00537     if (isNonNullFrame()) {
00538         _ctx._bufInvalid[_ctx._dstBuf] = 1;
00539         for (int p = 0; p < 3; p++) {
00540             for (int b = 0; b < _ctx._planes[p]._numBands; b++) {
00541                 result = decode_band(&_ctx._planes[p]._bands[b]);
00542                 if (result < 0) {
00543                     warning("Error while decoding band: %d, _plane: %d", b, p);
00544                     return result;
00545                 }
00546             }
00547         }
00548         _ctx._bufInvalid[_ctx._dstBuf] = 0;
00549     } else {
00550         if (_ctx._isScalable)
00551             return -1;
00552 
00553         for (int p = 0; p < 3; p++) {
00554             if (!_ctx._planes[p]._bands[0]._buf)
00555                 return -1;
00556         }
00557     }
00558     if (_ctx._bufInvalid[_ctx._dstBuf])
00559         return -1;
00560 
00561     //STOP_TIMER("decode_planes"); }
00562 
00563     if (!isNonNullFrame())
00564         return 0;
00565 
00566     assert(_ctx._planes[0]._width <= _surface.w && _ctx._planes[0]._height <= _surface.h);
00567     result = frame->setDimensions(_ctx._planes[0]._width, _ctx._planes[0]._height);
00568     if (result < 0)
00569         return result;
00570 
00571     if ((result = frame->getBuffer(0)) < 0)
00572         return result;
00573 
00574     if (_ctx._isScalable) {
00575         if (_ctx._isIndeo4)
00576             recomposeHaar(&_ctx._planes[0], frame->_data[0], frame->_linesize[0]);
00577         else
00578             recompose53(&_ctx._planes[0], frame->_data[0], frame->_linesize[0]);
00579     } else {
00580         outputPlane(&_ctx._planes[0], frame->_data[0], frame->_linesize[0]);
00581     }
00582 
00583     outputPlane(&_ctx._planes[2], frame->_data[1], frame->_linesize[1]);
00584     outputPlane(&_ctx._planes[1], frame->_data[2], frame->_linesize[2]);
00585 
00586     // Merge the planes into the final surface
00587     YUVToRGBMan.convert410(&_surface, Graphics::YUVToRGBManager::kScaleITU,
00588         frame->_data[0], frame->_data[1], frame->_data[2], frame->_width, frame->_height,
00589         frame->_width, frame->_width);
00590 
00591     if (_ctx._hasTransp)
00592         decodeTransparency();
00593 
00594     // If the bidirectional mode is enabled, next I and the following P
00595     // frame will be sent together. Unfortunately the approach below seems
00596     // to be the only way to handle the B-frames mode.
00597     // That's exactly the same Intel decoders do.
00598     if (_ctx._isIndeo4 && _ctx._frameType == IVI4_FRAMETYPE_INTRA) {
00599         // TODO: It appears from the reference decoder that this should be
00600         // aligning GetBits to a 32-bit boundary before reading again?
00601 
00602         int left;
00603 
00604         // skip version string
00605         while (_ctx._gb->getBits(8)) {
00606             if (_ctx._gb->getBitsLeft() < 8)
00607                 return -1;
00608         }
00609         left = _ctx._gb->pos() & 0x18;
00610         _ctx._gb->skip(64 - left);
00611         if (_ctx._gb->getBitsLeft() > 18 &&
00612             _ctx._gb->peekBits(21) == 0xBFFF8) { // syncheader + inter _type
00613             error("Indeo decoder: Mode not currently implemented in ScummVM");
00614         }
00615     }
00616 
00617     // Free the now un-needed frame data
00618     frame->freeFrame();
00619 
00620     return 0;
00621 }
00622 
00623 int IndeoDecoderBase::decode_band(IVIBandDesc *band) {
00624     band->_buf = band->_bufs[_ctx._dstBuf];
00625     if (!band->_buf) {
00626         warning("Band buffer points to no data!");
00627         return -1;
00628     }
00629     if (_ctx._isIndeo4 && _ctx._frameType == IVI4_FRAMETYPE_BIDIR) {
00630         band->_refBuf = band->_bufs[_ctx._bRefBuf];
00631         band->_bRefBuf = band->_bufs[_ctx._refBuf];
00632     } else {
00633         band->_refBuf = band->_bufs[_ctx._refBuf];
00634         band->_bRefBuf = 0;
00635     }
00636     band->_dataPtr = _ctx._frameData + (_ctx._gb->pos() >> 3);
00637 
00638     int result = decodeBandHeader(band);
00639     if (result) {
00640         warning("Error while decoding band header: %d",
00641             result);
00642         return result;
00643     }
00644 
00645     if (band->_isEmpty) {
00646         warning("Empty band encountered!");
00647         return -1;
00648     }
00649 
00650     band->_rvMap = &_ctx._rvmapTabs[band->_rvmapSel];
00651 
00652     // apply corrections to the selected rvmap table if present
00653     for (int i = 0; i < band->_numCorr; i++) {
00654         int idx1 = band->_corr[i * 2];
00655         int idx2 = band->_corr[i * 2 + 1];
00656         SWAP(band->_rvMap->_runtab[idx1], band->_rvMap->_runtab[idx2]);
00657         SWAP(band->_rvMap->_valtab[idx1], band->_rvMap->_valtab[idx2]);
00658         if (idx1 == band->_rvMap->_eobSym || idx2 == band->_rvMap->_eobSym)
00659             band->_rvMap->_eobSym ^= idx1 ^ idx2;
00660         if (idx1 == band->_rvMap->_escSym || idx2 == band->_rvMap->_escSym)
00661             band->_rvMap->_escSym ^= idx1 ^ idx2;
00662     }
00663 
00664     int pos = _ctx._gb->pos();
00665 
00666     for (int t = 0; t < band->_numTiles; t++) {
00667         IVITile *tile = &band->_tiles[t];
00668 
00669         if (tile->_mbSize != band->_mbSize) {
00670             warning("MB sizes mismatch: %d vs. %d",
00671                 band->_mbSize, tile->_mbSize);
00672             return -1;
00673         }
00674         tile->_isEmpty = _ctx._gb->getBit();
00675         if (tile->_isEmpty) {
00676             result = processEmptyTile(band, tile,
00677                 (_ctx._planes[0]._bands[0]._mbSize >> 3) - (band->_mbSize >> 3));
00678             if (result < 0)
00679                 break;
00680             warning("Empty tile encountered!");
00681         } else {
00682             tile->_dataSize = decodeTileDataSize(_ctx._gb);
00683             if (!tile->_dataSize) {
00684                 warning("Tile data size is zero!");
00685                 result = -1;
00686                 break;
00687             }
00688 
00689             result = decodeMbInfo(band, tile);
00690             if (result < 0)
00691                 break;
00692 
00693             result = decodeBlocks(_ctx._gb, band, tile);
00694             if (result < 0) {
00695                 warning("Corrupted tile data encountered!");
00696                 break;
00697             }
00698 
00699             if ((((int)_ctx._gb->pos() - pos) >> 3) != tile->_dataSize) {
00700                 warning("Tile _dataSize mismatch!");
00701                 result = -1;
00702                 break;
00703             }
00704 
00705             pos += tile->_dataSize << 3; // skip to next tile
00706         }
00707     }
00708 
00709     // restore the selected rvmap table by applying its corrections in
00710     // reverse order
00711     for (int i = band->_numCorr - 1; i >= 0; i--) {
00712         int idx1 = band->_corr[i * 2];
00713         int idx2 = band->_corr[i * 2 + 1];
00714         SWAP(band->_rvMap->_runtab[idx1], band->_rvMap->_runtab[idx2]);
00715         SWAP(band->_rvMap->_valtab[idx1], band->_rvMap->_valtab[idx2]);
00716         if (idx1 == band->_rvMap->_eobSym || idx2 == band->_rvMap->_eobSym)
00717             band->_rvMap->_eobSym ^= idx1 ^ idx2;
00718         if (idx1 == band->_rvMap->_escSym || idx2 == band->_rvMap->_escSym)
00719             band->_rvMap->_escSym ^= idx1 ^ idx2;
00720     }
00721 
00722     _ctx._gb->align();
00723 
00724     return result;
00725 }
00726 
00727 void IndeoDecoderBase::recomposeHaar(const IVIPlaneDesc *_plane,
00728         uint8 *dst, const int dstPitch) {
00729 
00730     // all bands should have the same _pitch
00731     int32 pitch = _plane->_bands[0]._pitch;
00732 
00733     // get pointers to the wavelet bands
00734     const short *b0Ptr = _plane->_bands[0]._buf;
00735     const short *b1Ptr = _plane->_bands[1]._buf;
00736     const short *b2Ptr = _plane->_bands[2]._buf;
00737     const short *b3Ptr = _plane->_bands[3]._buf;
00738 
00739     for (int y = 0; y < _plane->_height; y += 2) {
00740         for (int x = 0, indx = 0; x < _plane->_width; x += 2, indx++) {
00741             // load coefficients
00742             int b0 = b0Ptr[indx]; //should be: b0 = (_numBands > 0) ? b0Ptr[indx] : 0;
00743             int b1 = b1Ptr[indx]; //should be: b1 = (_numBands > 1) ? b1Ptr[indx] : 0;
00744             int b2 = b2Ptr[indx]; //should be: b2 = (_numBands > 2) ? b2Ptr[indx] : 0;
00745             int b3 = b3Ptr[indx]; //should be: b3 = (_numBands > 3) ? b3Ptr[indx] : 0;
00746 
00747                                // haar wavelet recomposition
00748             int p0 = (b0 + b1 + b2 + b3 + 2) >> 2;
00749             int p1 = (b0 + b1 - b2 - b3 + 2) >> 2;
00750             int p2 = (b0 - b1 + b2 - b3 + 2) >> 2;
00751             int p3 = (b0 - b1 - b2 + b3 + 2) >> 2;
00752 
00753             // bias, convert and output four pixels
00754             dst[x] = avClipUint8(p0 + 128);
00755             dst[x + 1] = avClipUint8(p1 + 128);
00756             dst[dstPitch + x] = avClipUint8(p2 + 128);
00757             dst[dstPitch + x + 1] = avClipUint8(p3 + 128);
00758         }// for x
00759 
00760         dst += dstPitch << 1;
00761 
00762         b0Ptr += pitch;
00763         b1Ptr += pitch;
00764         b2Ptr += pitch;
00765         b3Ptr += pitch;
00766     }// for y
00767 }
00768 
00769 void IndeoDecoderBase::recompose53(const IVIPlaneDesc *_plane,
00770         uint8 *dst, const int dstPitch) {
00771     int32 p0, p1, p2, p3, tmp0, tmp1, tmp2;
00772     int32 b0_1, b0_2, b1_1, b1_2, b1_3, b2_1, b2_2, b2_3, b2_4, b2_5, b2_6;
00773     int32 b3_1, b3_2, b3_3, b3_4, b3_5, b3_6, b3_7, b3_8, b3_9;
00774     const int numBands = 4;
00775 
00776     // all bands should have the same _pitch
00777     int32 pitch_ = _plane->_bands[0]._pitch;
00778 
00779     // pixels at the position "y-1" will be set to pixels at the "y" for the 1st iteration
00780     int32 back_pitch = 0;
00781 
00782     // get pointers to the wavelet bands
00783     const short *b0Ptr = _plane->_bands[0]._buf;
00784     const short *b1Ptr = _plane->_bands[1]._buf;
00785     const short *b2Ptr = _plane->_bands[2]._buf;
00786     const short *b3Ptr = _plane->_bands[3]._buf;
00787 
00788     for (int y = 0; y < _plane->_height; y += 2) {
00789 
00790         if (y + 2 >= _plane->_height)
00791             pitch_ = 0;
00792         // load storage variables with values
00793         if (numBands > 0) {
00794             b0_1 = b0Ptr[0];
00795             b0_2 = b0Ptr[pitch_];
00796         }
00797 
00798         if (numBands > 1) {
00799             b1_1 = b1Ptr[back_pitch];
00800             b1_2 = b1Ptr[0];
00801             b1_3 = b1_1 - b1_2 * 6 + b1Ptr[pitch_];
00802         }
00803 
00804         if (numBands > 2) {
00805             b2_2 = b2Ptr[0];        // b2[x,  y  ]
00806             b2_3 = b2_2;            // b2[x+1,y  ] = b2[x,y]
00807             b2_5 = b2Ptr[pitch_];   // b2[x  ,y+1]
00808             b2_6 = b2_5;            // b2[x+1,y+1] = b2[x,y+1]
00809         }
00810 
00811         if (numBands > 3) {
00812             b3_2 = b3Ptr[back_pitch];   // b3[x  ,y-1]
00813             b3_3 = b3_2;                // b3[x+1,y-1] = b3[x  ,y-1]
00814             b3_5 = b3Ptr[0];            // b3[x  ,y  ]
00815             b3_6 = b3_5;                // b3[x+1,y  ] = b3[x  ,y  ]
00816             b3_8 = b3_2 - b3_5 * 6 + b3Ptr[pitch_];
00817             b3_9 = b3_8;
00818         }
00819 
00820         for (int x = 0, indx = 0; x < _plane->_width; x += 2, indx++) {
00821             if (x + 2 >= _plane->_width) {
00822                 b0Ptr--;
00823                 b1Ptr--;
00824                 b2Ptr--;
00825                 b3Ptr--;
00826             }
00827 
00828             // some values calculated in the previous iterations can
00829             // be reused in the next ones, so do appropriate copying
00830             b2_1 = b2_2; // b2[x-1,y  ] = b2[x,  y  ]
00831             b2_2 = b2_3; // b2[x  ,y  ] = b2[x+1,y  ]
00832             b2_4 = b2_5; // b2[x-1,y+1] = b2[x  ,y+1]
00833             b2_5 = b2_6; // b2[x  ,y+1] = b2[x+1,y+1]
00834             b3_1 = b3_2; // b3[x-1,y-1] = b3[x  ,y-1]
00835             b3_2 = b3_3; // b3[x  ,y-1] = b3[x+1,y-1]
00836             b3_4 = b3_5; // b3[x-1,y  ] = b3[x  ,y  ]
00837             b3_5 = b3_6; // b3[x  ,y  ] = b3[x+1,y  ]
00838             b3_7 = b3_8; // vert_HPF(x-1)
00839             b3_8 = b3_9; // vert_HPF(x  )
00840 
00841             p0 = p1 = p2 = p3 = 0;
00842 
00843             // process the LL-band by applying LPF both vertically and horizontally
00844             if (numBands > 0) {
00845                 tmp0 = b0_1;
00846                 tmp2 = b0_2;
00847                 b0_1 = b0Ptr[indx + 1];
00848                 b0_2 = b0Ptr[pitch_ + indx + 1];
00849                 tmp1 = tmp0 + b0_1;
00850 
00851                 p0 = tmp0 << 4;
00852                 p1 = tmp1 << 3;
00853                 p2 = (tmp0 + tmp2) << 3;
00854                 p3 = (tmp1 + tmp2 + b0_2) << 2;
00855             }
00856 
00857             // process the HL-band by applying HPF vertically and LPF horizontally
00858             if (numBands > 1) {
00859                 tmp0 = b1_2;
00860                 tmp1 = b1_1;
00861                 b1_2 = b1Ptr[indx + 1];
00862                 b1_1 = b1Ptr[back_pitch + indx + 1];
00863 
00864                 tmp2 = tmp1 - tmp0 * 6 + b1_3;
00865                 b1_3 = b1_1 - b1_2 * 6 + b1Ptr[pitch_ + indx + 1];
00866 
00867                 p0 += (tmp0 + tmp1) << 3;
00868                 p1 += (tmp0 + tmp1 + b1_1 + b1_2) << 2;
00869                 p2 += tmp2 << 2;
00870                 p3 += (tmp2 + b1_3) << 1;
00871             }
00872 
00873             // process the LH-band by applying LPF vertically and HPF horizontally
00874             if (numBands > 2) {
00875                 b2_3 = b2Ptr[indx + 1];
00876                 b2_6 = b2Ptr[pitch_ + indx + 1];
00877 
00878                 tmp0 = b2_1 + b2_2;
00879                 tmp1 = b2_1 - b2_2 * 6 + b2_3;
00880 
00881                 p0 += tmp0 << 3;
00882                 p1 += tmp1 << 2;
00883                 p2 += (tmp0 + b2_4 + b2_5) << 2;
00884                 p3 += (tmp1 + b2_4 - b2_5 * 6 + b2_6) << 1;
00885             }
00886 
00887             // process the HH-band by applying HPF both vertically and horizontally
00888             if (numBands > 3) {
00889                 b3_6 = b3Ptr[indx + 1];            // b3[x+1,y  ]
00890                 b3_3 = b3Ptr[back_pitch + indx + 1]; // b3[x+1,y-1]
00891 
00892                 tmp0 = b3_1 + b3_4;
00893                 tmp1 = b3_2 + b3_5;
00894                 tmp2 = b3_3 + b3_6;
00895 
00896                 b3_9 = b3_3 - b3_6 * 6 + b3Ptr[pitch_ + indx + 1];
00897 
00898                 p0 += (tmp0 + tmp1) << 2;
00899                 p1 += (tmp0 - tmp1 * 6 + tmp2) << 1;
00900                 p2 += (b3_7 + b3_8) << 1;
00901                 p3 += b3_7 - b3_8 * 6 + b3_9;
00902             }
00903 
00904             // output four pixels
00905             dst[x] = avClipUint8((p0 >> 6) + 128);
00906             dst[x + 1] = avClipUint8((p1 >> 6) + 128);
00907             dst[dstPitch + x] = avClipUint8((p2 >> 6) + 128);
00908             dst[dstPitch + x + 1] = avClipUint8((p3 >> 6) + 128);
00909         }// for x
00910 
00911         dst += dstPitch << 1;
00912 
00913         back_pitch = -pitch_;
00914 
00915         b0Ptr += pitch_ + 1;
00916         b1Ptr += pitch_ + 1;
00917         b2Ptr += pitch_ + 1;
00918         b3Ptr += pitch_ + 1;
00919     }
00920 }
00921 
00922 void IndeoDecoderBase::outputPlane(IVIPlaneDesc *_plane, uint8 *dst, int dstPitch) {
00923     const int16 *src = _plane->_bands[0]._buf;
00924     uint32 pitch = _plane->_bands[0]._pitch;
00925 
00926     if (!src)
00927         return;
00928 
00929     for (int y = 0; y < _plane->_height; y++) {
00930         for (int x = 0; x < _plane->_width; x++)
00931             dst[x] = avClipUint8(src[x] + 128);
00932         src += pitch;
00933         dst += dstPitch;
00934     }
00935 }
00936 
00937 int IndeoDecoderBase::processEmptyTile(IVIBandDesc *band,
00938             IVITile *tile, int32 mvScale) {
00939     if (tile->_numMBs != IVI_MBs_PER_TILE(tile->_width, tile->_height, band->_mbSize)) {
00940         warning("Allocated tile size %d mismatches "
00941             "parameters %d in processEmptyTile()",
00942             tile->_numMBs, IVI_MBs_PER_TILE(tile->_width, tile->_height, band->_mbSize));
00943         return -1;
00944     }
00945 
00946     int offs = tile->_yPos * band->_pitch + tile->_xPos;
00947     IVIMbInfo *mb = tile->_mbs;
00948     IVIMbInfo *refMb = tile->_refMbs;
00949     int rowOffset = band->_mbSize * band->_pitch;
00950     int needMc = 0; // reset the mc tracking flag
00951 
00952     for (int y = tile->_yPos; y < (tile->_yPos + tile->_height); y += band->_mbSize) {
00953         int mbOffset = offs;
00954 
00955         for (int x = tile->_xPos; x < (tile->_xPos + tile->_width); x += band->_mbSize) {
00956             mb->_xPos = x;
00957             mb->_yPos = y;
00958             mb->_bufOffs = mbOffset;
00959 
00960             mb->_type = 1; // set the macroblocks _type = INTER
00961             mb->_cbp = 0;  // all blocks are empty
00962 
00963             if (!band->_qdeltaPresent && !band->_plane && !band->_bandNum) {
00964                 mb->_qDelta = band->_globQuant;
00965                 mb->_mvX = 0;
00966                 mb->_mvY = 0;
00967             }
00968 
00969             if (band->_inheritQDelta && refMb)
00970                 mb->_qDelta = refMb->_qDelta;
00971 
00972             if (band->_inheritMv && refMb) {
00973                 // motion vector inheritance
00974                 if (mvScale) {
00975                     mb->_mvX = scaleMV(refMb->_mvX, mvScale);
00976                     mb->_mvY = scaleMV(refMb->_mvY, mvScale);
00977                 } else {
00978                     mb->_mvX = refMb->_mvX;
00979                     mb->_mvY = refMb->_mvY;
00980                 }
00981                 needMc |= mb->_mvX || mb->_mvY; // tracking non-zero motion vectors
00982 
00983                 int dmv_x, dmv_y, cx, cy;
00984 
00985                 dmv_x = mb->_mvX >> band->_isHalfpel;
00986                 dmv_y = mb->_mvY >> band->_isHalfpel;
00987                 cx = mb->_mvX &  band->_isHalfpel;
00988                 cy = mb->_mvY &  band->_isHalfpel;
00989 
00990                 if (mb->_xPos + dmv_x < 0
00991                     || mb->_xPos + dmv_x + band->_mbSize + cx > band->_pitch
00992                     || mb->_yPos + dmv_y < 0
00993                     || mb->_yPos + dmv_y + band->_mbSize + cy > band->_aHeight) {
00994                     warning("MV out of bounds");
00995                     return -1;
00996                 }
00997             }
00998 
00999             mb++;
01000             if (refMb)
01001                 refMb++;
01002             mbOffset += band->_mbSize;
01003         } // for x
01004         offs += rowOffset;
01005     } // for y
01006 
01007     if (band->_inheritMv && needMc) { // apply motion compensation if there is at least one non-zero motion vector
01008         int numBlocks = (band->_mbSize != band->_blkSize) ? 4 : 1; // number of blocks per mb
01009         IviMCFunc mcNoDeltaFunc = (band->_blkSize == 8) ? IndeoDSP::ffIviMc8x8NoDelta
01010             : IndeoDSP::ffIviMc4x4NoDelta;
01011 
01012         int mbn;
01013         for (mbn = 0, mb = tile->_mbs; mbn < tile->_numMBs; mb++, mbn++) {
01014             int mvX = mb->_mvX;
01015             int mvY = mb->_mvY;
01016             int mcType;
01017             if (!band->_isHalfpel) {
01018                 mcType = 0; // we have only fullpel vectors
01019             } else {
01020                 mcType = ((mvY & 1) << 1) | (mvX & 1);
01021                 mvX >>= 1;
01022                 mvY >>= 1; // convert halfpel vectors into fullpel ones
01023             }
01024 
01025             for (int blk = 0; blk < numBlocks; blk++) {
01026                 // adjust block position in the buffer according with its number
01027                 offs = mb->_bufOffs + band->_blkSize * ((blk & 1) + !!(blk & 2) * band->_pitch);
01028                 int ret = iviMc(band, mcNoDeltaFunc, nullptr, offs,
01029                     mvX, mvY, 0, 0, mcType, -1);
01030                 if (ret < 0)
01031                     return ret;
01032             }
01033         }
01034     } else {
01035         // copy data from the reference tile into the current one
01036         const int16 *src = band->_refBuf + tile->_yPos * band->_pitch + tile->_xPos;
01037         int16 *dst = band->_buf + tile->_yPos * band->_pitch + tile->_xPos;
01038         for (int y = 0; y < tile->_height; y++) {
01039             memcpy(dst, src, tile->_width*sizeof(band->_buf[0]));
01040             src += band->_pitch;
01041             dst += band->_pitch;
01042         }
01043     }
01044 
01045     return 0;
01046 }
01047 
01048 int IndeoDecoderBase::decodeTileDataSize(GetBits *gb) {
01049     int len = 0;
01050 
01051     if (gb->getBit()) {
01052         len = gb->getBits(8);
01053         if (len == 255)
01054             len = gb->getBits(24);
01055     }
01056 
01057     // align the bitstream reader on the byte boundary
01058     gb->align();
01059 
01060     return len;
01061 }
01062 
01063 int IndeoDecoderBase::decodeBlocks(GetBits *_gb, IVIBandDesc *band, IVITile *tile) {
01064     int ret;
01065     int mcType = 0, mcType2 = -1;
01066     int mvX = 0, mvY = 0, mvX2 = 0, mvY2 = 0;
01067 
01068     // init intra prediction for the DC coefficient
01069     int32 prevDc  = 0;
01070     int blkSize   = band->_blkSize;
01071     // number of blocks per mb
01072     int numBlocks = (band->_mbSize != blkSize) ? 4 : 1;
01073     IviMCFunc mcWithDeltaFunc, mcNoDeltaFunc;
01074     IviMCAvgFunc mcAvgWithDeltaFunc, mcAvgNoDeltaFunc;
01075 
01076     if (blkSize == 8) {
01077         mcWithDeltaFunc     = IndeoDSP::ffIviMc8x8Delta;
01078         mcNoDeltaFunc       = IndeoDSP::ffIviMc8x8NoDelta;
01079         mcAvgWithDeltaFunc = IndeoDSP::ffIviMcAvg8x8Delta;
01080         mcAvgNoDeltaFunc   = IndeoDSP::ffIviMcAvg8x8NoDelta;
01081     } else {
01082         mcWithDeltaFunc     = IndeoDSP::ffIviMc4x4Delta;
01083         mcNoDeltaFunc       = IndeoDSP::ffIviMc4x4NoDelta;
01084         mcAvgWithDeltaFunc = IndeoDSP::ffIviMcAvg4x4Delta;
01085         mcAvgNoDeltaFunc   = IndeoDSP::ffIviMcAvg4x4NoDelta;
01086     }
01087 
01088     int mbn;
01089     IVIMbInfo *mb;
01090 
01091     for (mbn = 0, mb = tile->_mbs; mbn < tile->_numMBs; mb++, mbn++) {
01092         int isIntra    = !mb->_type;
01093         uint32 cbp     = mb->_cbp;
01094         uint32 bufOffs = mb->_bufOffs;
01095 
01096         uint32 quant = band->_globQuant + mb->_qDelta;
01097         if (_ctx._isIndeo4)
01098             quant = avClipUintp2(quant, 5);
01099         else
01100             quant = CLIP((int)quant, 0, 23);
01101 
01102         const uint8 *scaleTab = isIntra ? band->_intraScale : band->_interScale;
01103         if (scaleTab)
01104             quant = scaleTab[quant];
01105 
01106         if (!isIntra) {
01107             mvX  = mb->_mvX;
01108             mvY  = mb->_mvY;
01109             mvX2 = mb->_bMvX;
01110             mvY2 = mb->_bMvY;
01111             if (band->_isHalfpel) {
01112                 mcType  = ((mvY  & 1) << 1) | (mvX  & 1);
01113                 mcType2 = ((mvY2 & 1) << 1) | (mvX2 & 1);
01114                 mvX  >>= 1;
01115                 mvY  >>= 1;
01116                 mvX2 >>= 1;
01117                 mvY2 >>= 1; // convert halfpel vectors into fullpel ones
01118             }
01119             if (mb->_type == 2)
01120                 mcType = -1;
01121             if (mb->_type != 2 && mb->_type != 3)
01122                 mcType2 = -1;
01123             if (mb->_type) {
01124                 int dmv_x, dmv_y, cx, cy;
01125 
01126                 dmv_x = mb->_mvX >> band->_isHalfpel;
01127                 dmv_y = mb->_mvY >> band->_isHalfpel;
01128                 cx    = mb->_mvX &  band->_isHalfpel;
01129                 cy    = mb->_mvY &  band->_isHalfpel;
01130 
01131                 if (mb->_xPos + dmv_x < 0 ||
01132                     mb->_xPos + dmv_x + band->_mbSize + cx > band->_pitch ||
01133                     mb->_yPos + dmv_y < 0 ||
01134                     mb->_yPos + dmv_y + band->_mbSize + cy > band->_aHeight) {
01135                     return -1;
01136                 }
01137             }
01138             if (mb->_type == 2 || mb->_type == 3) {
01139                 int dmv_x, dmv_y, cx, cy;
01140 
01141                 dmv_x = mb->_bMvX >> band->_isHalfpel;
01142                 dmv_y = mb->_bMvY >> band->_isHalfpel;
01143                 cx    = mb->_bMvX &  band->_isHalfpel;
01144                 cy    = mb->_bMvY &  band->_isHalfpel;
01145 
01146                 if (mb->_xPos + dmv_x < 0 ||
01147                     mb->_xPos + dmv_x + band->_mbSize + cx > band->_pitch ||
01148                     mb->_yPos + dmv_y < 0 ||
01149                     mb->_yPos + dmv_y + band->_mbSize + cy > band->_aHeight) {
01150                     return -1;
01151                 }
01152             }
01153         }
01154 
01155         for (int blk = 0; blk < numBlocks; blk++) {
01156             // adjust block position in the buffer according to its number
01157             if (blk & 1) {
01158                 bufOffs += blkSize;
01159             } else if (blk == 2) {
01160                 bufOffs -= blkSize;
01161                 bufOffs += blkSize * band->_pitch;
01162             }
01163 
01164             if (cbp & 1) { // block coded ?
01165                 ret = decodeCodedBlocks(_gb, band, mcWithDeltaFunc,
01166                                               mcAvgWithDeltaFunc,
01167                                               mvX, mvY, mvX2, mvY2,
01168                                               &prevDc, isIntra,
01169                                               mcType, mcType2, quant,
01170                                               bufOffs);
01171                 if (ret < 0)
01172                     return ret;
01173             } else {
01174                 // block not coded
01175                 // for intra blocks apply the dc slant transform
01176                 // for inter - perform the motion compensation without delta
01177                 if (isIntra) {
01178                     ret = iviDcTransform(band, &prevDc, bufOffs, blkSize);
01179                     if (ret < 0)
01180                         return ret;
01181                 } else {
01182                     ret = iviMc(band, mcNoDeltaFunc, mcAvgNoDeltaFunc,
01183                                  bufOffs, mvX, mvY, mvX2, mvY2,
01184                                  mcType, mcType2);
01185                     if (ret < 0)
01186                         return ret;
01187                 }
01188             }
01189 
01190             cbp >>= 1;
01191         }// for blk
01192     }// for mbn
01193 
01194     _gb->align();
01195     return 0;
01196 }
01197 
01198 int IndeoDecoderBase::scaleMV(int mv, int mvScale) {
01199     return (mv + (mv > 0) + (mvScale - 1)) >> mvScale;
01200 }
01201 
01202 int IndeoDecoderBase::iviMc(IVIBandDesc *band, IviMCFunc mc, IviMCAvgFunc mcAvg,
01203                   int offs, int mvX, int mvY, int mvX2, int mvY2,
01204                   int mcType, int mcType2) {
01205     int refOffs = offs + mvY * band->_pitch + mvX;
01206     int bufSize = band->_pitch * band->_aHeight;
01207     int minSize = band->_pitch * (band->_blkSize - 1) + band->_blkSize;
01208     int refSize = (mcType > 1) * band->_pitch + (mcType & 1);
01209 
01210     if (mcType != -1) {
01211         assert(offs >= 0 && refOffs >= 0 && band->_refBuf);
01212         assert(bufSize - minSize >= offs);
01213         assert(bufSize - minSize - refSize >= refOffs);
01214     }
01215 
01216     if (mcType2 == -1) {
01217         mc(band->_buf + offs, band->_refBuf + refOffs, band->_pitch, mcType);
01218     } else {
01219         int ref_offs2 = offs + mvY2 * band->_pitch + mvX2;
01220         int ref_size2 = (mcType2 > 1) * band->_pitch + (mcType2 & 1);
01221         if (offs < 0 || ref_offs2 < 0 || !band->_bRefBuf)
01222             return -1;
01223         if (bufSize - minSize - ref_size2 < ref_offs2)
01224             return -1;
01225 
01226         if (mcType == -1)
01227             mc(band->_buf + offs, band->_bRefBuf + ref_offs2,
01228                band->_pitch, mcType2);
01229         else
01230             mcAvg(band->_buf + offs, band->_refBuf + refOffs,
01231                    band->_bRefBuf + ref_offs2, band->_pitch,
01232                    mcType, mcType2);
01233     }
01234 
01235     return 0;
01236 }
01237 
01238 int IndeoDecoderBase::decodeCodedBlocks(GetBits *gb, IVIBandDesc *band,
01239         IviMCFunc mc, IviMCAvgFunc mcAvg, int mvX, int mvY,
01240         int mvX2, int mvY2, int32 *prevDc, int isIntra,
01241         int mcType, int mcType2, uint32 quant, int offs) {
01242     const uint16 *baseTab = isIntra ? band->_intraBase : band->_interBase;
01243     RVMapDesc *rvmap = band->_rvMap;
01244     uint8 colFlags[8];
01245     int32 trvec[64];
01246     uint32 sym = 0, q;
01247     int lo, hi;
01248     int pos, run, val;
01249     int blkSize = band->_blkSize;
01250     int numCoeffs = blkSize * blkSize;
01251     int colMask = blkSize - 1;
01252     int scanPos = -1;
01253     int minSize = band->_pitch * (band->_transformSize - 1) +
01254         band->_transformSize;
01255     int bufSize = band->_pitch * band->_aHeight - offs;
01256 
01257     if (minSize > bufSize)
01258         return -1;
01259 
01260     if (!band->_scan) {
01261         warning("Scan pattern is not set.");
01262         return -1;
01263     }
01264 
01265     // zero transform vector
01266     memset(trvec, 0, numCoeffs * sizeof(trvec[0]));
01267     // zero column flags
01268     memset(colFlags, 0, sizeof(colFlags));
01269     while (scanPos <= numCoeffs) {
01270         sym = gb->getVLC2<1>(band->_blkVlc._tab->_table, IVI_VLC_BITS);
01271         if (sym == rvmap->_eobSym)
01272             break; // End of block
01273 
01274         // Escape - run/val explicitly coded using 3 vlc codes
01275         if (sym == rvmap->_escSym) {
01276             run = gb->getVLC2<1>(band->_blkVlc._tab->_table, IVI_VLC_BITS) + 1;
01277             lo = gb->getVLC2<1>(band->_blkVlc._tab->_table, IVI_VLC_BITS);
01278             hi = gb->getVLC2<1>(band->_blkVlc._tab->_table, IVI_VLC_BITS);
01279             // merge them and convert into signed val
01280             val = IVI_TOSIGNED((hi << 6) | lo);
01281         } else {
01282             if (sym >= 256U) {
01283                 warning("Invalid sym encountered");
01284                 return -1;
01285             }
01286             run = rvmap->_runtab[sym];
01287             val = rvmap->_valtab[sym];
01288         }
01289 
01290         // de-zigzag and dequantize
01291         scanPos += run;
01292         if (scanPos >= numCoeffs || scanPos < 0)
01293             break;
01294         pos = band->_scan[scanPos];
01295 
01296         if (!val)
01297             warning("Val = 0 encountered!");
01298 
01299         q = (baseTab[pos] * quant) >> 9;
01300         if (q > 1)
01301             val = val * q + FFSIGN(val) * (((q ^ 1) - 1) >> 1);
01302         trvec[pos] = val;
01303         // track columns containing non-zero coeffs
01304         colFlags[pos & colMask] |= !!val;
01305     }
01306 
01307     if (scanPos < 0 || (scanPos >= numCoeffs && sym != rvmap->_eobSym))
01308         return -1; // corrupt block data
01309 
01310     // undoing DC coeff prediction for intra-blocks
01311     if (isIntra && band->_is2dTrans) {
01312         *prevDc += trvec[0];
01313         trvec[0] = *prevDc;
01314         colFlags[0] |= !!*prevDc;
01315     }
01316 
01317     if (band->_transformSize > band->_blkSize) {
01318         warning("Too large transform");
01319         return -1;
01320     }
01321 
01322     // apply inverse transform
01323     band->_invTransform(trvec, band->_buf + offs,
01324         band->_pitch, colFlags);
01325 
01326     // apply motion compensation
01327     if (!isIntra)
01328         return iviMc(band, mc, mcAvg, offs, mvX, mvY, mvX2, mvY2,
01329             mcType, mcType2);
01330 
01331     return 0;
01332 }
01333 
01334 int IndeoDecoderBase::iviDcTransform(IVIBandDesc *band, int32 *prevDc,
01335         int bufOffs, int blkSize) {
01336     int bufSize = band->_pitch * band->_aHeight - bufOffs;
01337     int minSize = (blkSize - 1) * band->_pitch + blkSize;
01338 
01339     if (minSize > bufSize)
01340         return -1;
01341 
01342     band->_dcTransform(prevDc, band->_buf + bufOffs, band->_pitch, blkSize);
01343     return 0;
01344 }
01345 
01346 /*------------------------------------------------------------------------*/
01347 
01348 const uint8 IndeoDecoderBase::_ffIviVerticalScan8x8[64] = {
01349     0,  8, 16, 24, 32, 40, 48, 56,
01350     1,  9, 17, 25, 33, 41, 49, 57,
01351     2, 10, 18, 26, 34, 42, 50, 58,
01352     3, 11, 19, 27, 35, 43, 51, 59,
01353     4, 12, 20, 28, 36, 44, 52, 60,
01354     5, 13, 21, 29, 37, 45, 53, 61,
01355     6, 14, 22, 30, 38, 46, 54, 62,
01356     7, 15, 23, 31, 39, 47, 55, 63
01357 };
01358 
01359 const uint8 IndeoDecoderBase::_ffIviHorizontalScan8x8[64] = {
01360     0,  1,  2,  3,  4,  5,  6,  7,
01361     8,  9, 10, 11, 12, 13, 14, 15,
01362     16, 17, 18, 19, 20, 21, 22, 23,
01363     24, 25, 26, 27, 28, 29, 30, 31,
01364     32, 33, 34, 35, 36, 37, 38, 39,
01365     40, 41, 42, 43, 44, 45, 46, 47,
01366     48, 49, 50, 51, 52, 53, 54, 55,
01367     56, 57, 58, 59, 60, 61, 62, 63
01368 };
01369 
01370 const uint8 IndeoDecoderBase::_ffIviDirectScan4x4[16] = {
01371     0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
01372 };
01373 
01374 const RVMapDesc IVI45DecContext::_ff_ivi_rvmap_tabs[9] = {
01375 {   // MapTab0
01376     5, // _eobSym
01377     2, // _escSym
01378     // run table
01379     {1,  1,  0,  1,  1,  0,  1,  1,  2,  2,  1,  1,  1,  1,  3,  3,
01380      1,  1,  2,  2,  1,  1,  4,  4,  1,  1,  1,  1,  2,  2,  5,  5,
01381      1,  1,  3,  3,  1,  1,  6,  6,  1,  2,  1,  2,  7,  7,  1,  1,
01382      8,  8,  1,  1,  4,  2,  1,  4,  2,  1,  3,  3,  1,  1,  1,  9,
01383      9,  1,  2,  1,  2,  1,  5,  5,  1,  1, 10, 10,  1,  1,  3,  3,
01384      2,  2,  1,  1, 11, 11,  6,  4,  4,  1,  6,  1,  2,  1,  2, 12,
01385      8,  1, 12,  7,  8,  7,  1, 16,  1, 16,  1,  3,  3, 13,  1, 13,
01386      2,  2,  1, 15,  1,  5, 14, 15,  1,  5, 14,  1, 17,  8, 17,  8,
01387      1,  4,  4,  2,  2,  1, 25, 25, 24, 24,  1,  3,  1,  3,  1,  8,
01388      6,  7,  6,  1, 18,  8, 18,  1,  7, 23,  2,  2, 23,  1,  1, 21,
01389     22,  9,  9, 22, 19,  1, 21,  5, 19,  5,  1, 33, 20, 33, 20,  8,
01390      4,  4,  1, 32,  2,  2,  8,  3, 32, 26,  3,  1,  7,  7, 26,  6,
01391      1,  6,  1,  1, 16,  1, 10,  1, 10,  2, 16, 29, 28,  2, 29, 28,
01392      1, 27,  5,  8,  5, 27,  1,  8,  3,  7,  3, 31, 41, 31,  1, 41,
01393      6,  1,  6,  7,  4,  4,  1,  1,  2,  1,  2, 11, 34, 30, 11,  1,
01394     30, 15, 15, 34, 36, 40, 36, 40, 35, 35, 37, 37, 39, 39, 38, 38},
01395 
01396     // value table
01397     { 1,  -1,   0,   2,  -2,   0,   3,  -3,   1,  -1,   4,  -4,   5,  -5,   1,  -1,
01398       6,  -6,   2,  -2,   7,  -7,   1,  -1,   8,  -8,   9,  -9,   3,  -3,   1,  -1,
01399      10, -10,   2,  -2,  11, -11,   1,  -1,  12,   4, -12,  -4,   1,  -1,  13, -13,
01400       1,  -1,  14, -14,   2,   5,  15,  -2,  -5, -15,  -3,   3,  16, -16,  17,   1,
01401      -1, -17,   6,  18,  -6, -18,   2,  -2,  19, -19,   1,  -1,  20, -20,   4,  -4,
01402       7,  -7,  21, -21,   1,  -1,   2,   3,  -3,  22,  -2, -22,   8,  23,  -8,   1,
01403       2, -23,  -1,   2,  -2,  -2,  24,   1, -24,  -1,  25,   5,  -5,   1, -25,  -1,
01404       9,  -9,  26,   1, -26,   3,   1,  -1,  27,  -3,  -1, -27,   1,   3,  -1,  -3,
01405      28,  -4,   4,  10, -10, -28,   1,  -1,   1,  -1,  29,   6, -29,  -6,  30,  -4,
01406       3,   3,  -3, -30,   1,   4,  -1,  31,  -3,   1,  11, -11,  -1, -31,  32,  -1,
01407      -1,   2,  -2,   1,   1, -32,   1,   4,  -1,  -4,  33,  -1,   1,   1,  -1,   5,
01408       5,  -5, -33,  -1, -12,  12,  -5,  -7,   1,   1,   7,  34,   4,  -4,  -1,   4,
01409     -34,  -4,  35,  36,  -2, -35,  -2, -36,   2,  13,   2,  -1,   1, -13,   1,  -1,
01410      37,   1,  -5,   6,   5,  -1,  38,  -6,  -8,   5,   8,  -1,   1,   1, -37,  -1,
01411       5,  39,  -5,  -5,   6,  -6, -38, -39, -14,  40,  14,   2,   1,   1,  -2, -40,
01412      -1,  -2,   2,  -1,  -1,  -1,   1,   1,   1,  -1,   1,  -1,   1,  -1,   1,  -1}
01413 },{
01414     // MapTab1
01415     0,  // _eobSym
01416     38, // _escSym
01417     // run table
01418     {0,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  8,  6,  8,  7,
01419      7,  9,  9, 10, 10, 11, 11,  1, 12,  1, 12, 13, 13, 16, 14, 16,
01420     14, 15, 15, 17, 17, 18,  0, 18, 19, 20, 21, 19, 22, 21, 20, 22,
01421     25, 24,  2, 25, 24, 23, 23,  2, 26, 28, 26, 28, 29, 27, 29, 27,
01422     33, 33,  1, 32,  1,  3, 32, 30, 36,  3, 36, 30, 31, 31, 35, 34,
01423     37, 41, 34, 35, 37,  4, 41,  4, 49,  8,  8, 49, 40, 38,  5, 38,
01424     40, 39,  5, 39, 42, 43, 42,  7, 57,  6, 43, 44,  6, 50,  7, 44,
01425     57, 48, 50, 48, 45, 45, 46, 47, 51, 46, 47, 58,  1, 51, 58,  1,
01426     52, 59, 53,  9, 52, 55, 55, 59, 53, 56, 54, 56, 54,  9, 64, 64,
01427     60, 63, 60, 63, 61, 62, 61, 62,  2, 10,  2, 10, 11,  1, 11, 13,
01428     12,  1, 12, 13, 16, 16,  8,  8, 14,  3,  3, 15, 14, 15,  4,  4,
01429      1, 17, 17,  5,  1,  7,  7,  5,  6,  1,  2,  2,  6, 22,  1, 25,
01430     21, 22,  8, 24,  1, 21, 25, 24,  8, 18, 18, 23,  9, 20, 23, 33,
01431     29, 33, 20,  1, 19,  1, 29, 36,  9, 36, 19, 41, 28, 57, 32,  3,
01432     28,  3,  1, 27, 49, 49,  1, 32, 26, 26,  2,  4,  4,  7, 57, 41,
01433      2,  7, 10,  5, 37, 16, 10, 27,  8,  8, 13, 16, 37, 13,  1,  5},
01434 
01435     // value table
01436     {0,   1,  -1,   1,  -1,   1,  -1,   1,  -1,   1,  -1,   1,   1,  -1,  -1,   1,
01437     -1,   1,  -1,   1,  -1,   1,  -1,   2,   1,  -2,  -1,   1,  -1,   1,   1,  -1,
01438     -1,   1,  -1,   1,  -1,   1,   0,  -1,   1,   1,   1,  -1,   1,  -1,  -1,  -1,
01439      1,   1,   2,  -1,  -1,   1,  -1,  -2,   1,   1,  -1,  -1,   1,   1,  -1,  -1,
01440      1,  -1,   3,   1,  -3,   2,  -1,   1,   1,  -2,  -1,  -1,  -1,   1,   1,   1,
01441      1,   1,  -1,  -1,  -1,   2,  -1,  -2,   1,   2,  -2,  -1,   1,   1,   2,  -1,
01442     -1,   1,  -2,  -1,   1,   1,  -1,   2,   1,   2,  -1,   1,  -2,  -1,  -2,  -1,
01443     -1,   1,   1,  -1,   1,  -1,   1,   1,   1,  -1,  -1,   1,   4,  -1,  -1,  -4,
01444      1,   1,   1,   2,  -1,  -1,   1,  -1,  -1,   1,  -1,  -1,   1,  -2,   1,  -1,
01445      1,   1,  -1,  -1,   1,   1,  -1,  -1,   3,   2,  -3,  -2,   2,   5,  -2,   2,
01446      2,  -5,  -2,  -2,  -2,   2,  -3,   3,   2,   3,  -3,   2,  -2,  -2,   3,  -3,
01447      6,   2,  -2,   3,  -6,   3,  -3,  -3,   3,   7,  -4,   4,  -3,   2,  -7,   2,
01448      2,  -2,  -4,   2,   8,  -2,  -2,  -2,   4,   2,  -2,   2,   3,   2,  -2,  -2,
01449      2,   2,  -2,  -8,  -2,   9,  -2,   2,  -3,  -2,   2,  -2,   2,   2,   2,   4,
01450     -2,  -4,  10,   2,   2,  -2,  -9,  -2,   2,  -2,   5,   4,  -4,   4,  -2,   2,
01451     -5,  -4,  -3,   4,   2,  -3,   3,  -2,  -5,   5,   3,   3,  -2,  -3, -10,  -4}
01452 },{
01453     // MapTab2
01454     2,  // _eobSym
01455     11, // _escSym
01456     // run table
01457     {1,  1,  0,  2,  2,  1,  1,  3,  3,  4,  4,  0,  1,  1,  5,  5,
01458      2,  2,  6,  6,  7,  7,  1,  8,  1,  8,  3,  3,  9,  9,  1,  2,
01459      2,  1,  4, 10,  4, 10, 11, 11,  1,  5, 12, 12,  1,  5, 13, 13,
01460      3,  3,  6,  6,  2,  2, 14, 14, 16, 16, 15,  7, 15,  8,  8,  7,
01461      1,  1, 17, 17,  4,  4,  1,  1, 18, 18,  2,  2,  5,  5, 25,  3,
01462      9,  3, 25,  9, 19, 24, 19, 24,  1, 21, 20,  1, 21, 22, 20, 22,
01463     23, 23,  8,  6, 33,  6,  8, 33,  7,  7, 26, 26,  1, 32,  1, 32,
01464     28,  4, 28, 10, 29, 27, 27, 10, 41,  4, 29,  2,  2, 41, 36, 31,
01465     49, 31, 34, 30, 34, 36, 30, 35,  1, 49, 11,  5, 35, 11,  1,  3,
01466      3,  5, 37, 37,  8, 40,  8, 40, 12, 12, 42, 42,  1, 38, 16, 57,
01467      1,  6, 16, 39, 38,  6,  7,  7, 13, 13, 39, 43,  2, 43, 57,  2,
01468     50,  9, 44,  9, 50,  4, 15, 48, 44,  4,  1, 15, 48, 14, 14,  1,
01469     45, 45,  8,  3,  5,  8, 51, 47,  3, 46, 46, 47,  5, 51,  1, 17,
01470     17, 58,  1, 58,  2, 52, 52,  2, 53,  7, 59,  6,  6, 56, 53, 55,
01471      7, 55,  1, 54, 59, 56, 54, 10,  1, 10,  4, 60,  1, 60,  8,  4,
01472      8, 64, 64, 61,  1, 63,  3, 63, 62, 61,  5, 11,  5,  3, 11, 62},
01473 
01474     // value table
01475     { 1,  -1,   0,   1,  -1,   2,  -2,   1,  -1,   1,  -1,   0,   3,  -3,   1,  -1,
01476       2,  -2,   1,  -1,   1,  -1,   4,   1,  -4,  -1,   2,  -2,   1,  -1,   5,   3,
01477      -3,  -5,   2,   1,  -2,  -1,   1,  -1,   6,   2,   1,  -1,  -6,  -2,   1,  -1,
01478       3,  -3,   2,  -2,   4,  -4,   1,  -1,   1,  -1,   1,   2,  -1,   2,  -2,  -2,
01479       7,  -7,   1,  -1,   3,  -3,   8,  -8,   1,  -1,   5,  -5,   3,  -3,   1,   4,
01480       2,  -4,  -1,  -2,   1,   1,  -1,  -1,   9,   1,   1,  -9,  -1,   1,  -1,  -1,
01481       1,  -1,   3,  -3,   1,   3,  -3,  -1,   3,  -3,   1,  -1,  10,   1, -10,  -1,
01482       1,   4,  -1,   2,   1,  -1,   1,  -2,   1,  -4,  -1,   6,  -6,  -1,   1,   1,
01483       1,  -1,   1,   1,  -1,  -1,  -1,   1,  11,  -1,  -2,   4,  -1,   2, -11,   5,
01484      -5,  -4,  -1,   1,   4,   1,  -4,  -1,  -2,   2,   1,  -1,  12,   1,  -2,   1,
01485     -12,   4,   2,   1,  -1,  -4,   4,  -4,   2,  -2,  -1,   1,   7,  -1,  -1,  -7,
01486      -1,  -3,   1,   3,   1,   5,   2,   1,  -1,  -5,  13,  -2,  -1,   2,  -2, -13,
01487       1,  -1,   5,   6,   5,  -5,   1,   1,  -6,   1,  -1,  -1,  -5,  -1,  14,   2,
01488      -2,   1, -14,  -1,   8,   1,  -1,  -8,   1,   5,   1,   5,  -5,   1,  -1,   1,
01489      -5,  -1,  15,   1,  -1,  -1,  -1,   3, -15,  -3,   6,   1,  16,  -1,   6,  -6,
01490      -6,   1,  -1,   1, -16,   1,   7,  -1,   1,  -1,  -6,  -3,   6,  -7,   3,  -1}
01491 },{
01492     // MapTab3
01493     0,  // _eobSym
01494     35, // _escSym
01495     // run table
01496     {0,  1,  1,  2,  2,  3,  3,  4,  4,  1,  1,  5,  5,  6,  6,  7,
01497      7,  8,  8,  9,  9,  2,  2, 10, 10,  1,  1, 11, 11, 12, 12,  3,
01498      3, 13, 13,  0, 14, 14, 16, 15, 16, 15,  4,  4, 17,  1, 17,  1,
01499      5,  5, 18, 18,  2,  2,  6,  6,  8, 19,  7,  8,  7, 19, 20, 20,
01500     21, 21, 22, 24, 22, 24, 23, 23,  1,  1, 25, 25,  3,  3, 26, 26,
01501      9,  9, 27, 27, 28, 28, 33, 29,  4, 33, 29,  1,  4,  1, 32, 32,
01502      2,  2, 31, 10, 30, 10, 30, 31, 34, 34,  5,  5, 36, 36, 35, 41,
01503     35, 11, 41, 11, 37,  1,  8,  8, 37,  6,  1,  6, 40,  7,  7, 40,
01504     12, 38, 12, 39, 39, 38, 49, 13, 49, 13,  3, 42,  3, 42, 16, 16,
01505     43, 43, 14, 14,  1,  1, 44, 15, 44, 15,  2,  2, 57, 48, 50, 48,
01506     57, 50,  4, 45, 45,  4, 46, 47, 47, 46,  1, 51,  1, 17, 17, 51,
01507      8,  9,  9,  5, 58,  8, 58,  5, 52, 52, 55, 56, 53, 56, 55, 59,
01508     59, 53, 54,  1,  6, 54,  7,  7,  6,  1,  2,  3,  2,  3, 64, 60,
01509     60, 10, 10, 64, 61, 62, 61, 63,  1, 63, 62,  1, 18, 24, 18,  4,
01510     25,  4,  8, 21, 21,  1, 24, 22, 25, 22,  8, 11, 19, 11, 23,  1,
01511     20, 23, 19, 20,  5, 12,  5,  1, 16,  2, 12, 13,  2, 13,  1, 16},
01512 
01513     // value table
01514     { 0,   1,  -1,   1,  -1,   1,  -1,   1,  -1,   2,  -2,   1,  -1,   1,  -1,   1,
01515      -1,   1,  -1,   1,  -1,   2,  -2,   1,  -1,   3,  -3,   1,  -1,   1,  -1,   2,
01516      -2,   1,  -1,   0,   1,  -1,   1,   1,  -1,  -1,   2,  -2,   1,   4,  -1,  -4,
01517       2,  -2,   1,  -1,  -3,   3,   2,  -2,   2,   1,   2,  -2,  -2,  -1,   1,  -1,
01518       1,  -1,   1,   1,  -1,  -1,   1,  -1,   5,  -5,   1,  -1,   3,  -3,   1,  -1,
01519       2,  -2,   1,  -1,   1,  -1,   1,   1,   3,  -1,  -1,   6,  -3,  -6,  -1,   1,
01520       4,  -4,   1,   2,   1,  -2,  -1,  -1,   1,  -1,   3,  -3,   1,  -1,   1,   1,
01521      -1,   2,  -1,  -2,   1,   7,  -3,   3,  -1,   3,  -7,  -3,   1,  -3,   3,  -1,
01522       2,   1,  -2,   1,  -1,  -1,   1,   2,  -1,  -2,  -4,  -1,   4,   1,   2,  -2,
01523       1,  -1,  -2,   2,   8,  -8,  -1,   2,   1,  -2,  -5,   5,   1,  -1,  -1,   1,
01524      -1,   1,   4,  -1,   1,  -4,  -1,  -1,   1,   1,   9,   1,  -9,   2,  -2,  -1,
01525      -4,   3,  -3,  -4,  -1,   4,   1,   4,   1,  -1,   1,  -1,   1,   1,  -1,   1,
01526      -1,  -1,  -1,  10,   4,   1,   4,  -4,  -4, -10,   6,   5,  -6,  -5,   1,  -1,
01527       1,   3,  -3,  -1,   1,  -1,  -1,  -1,  11,   1,   1, -11,  -2,  -2,   2,   5,
01528      -2,  -5,  -5,   2,  -2,  12,   2,  -2,   2,   2,   5,  -3,  -2,   3,  -2, -12,
01529      -2,   2,   2,   2,  -5,   3,   5,  13,  -3,   7,  -3,  -3,  -7,   3, -13,   3}
01530 },{
01531     // MapTab4
01532     0,  // _eobSym
01533     34, // _escSym
01534     // run table
01535     {0,  1,  1,  1,  2,  2,  1,  3,  3,  1,  1,  1,  4,  4,  1,  5,
01536      2,  1,  5,  2,  1,  1,  6,  6,  1,  1,  1,  1,  1,  7,  3,  1,
01537      2,  3,  0,  1,  2,  7,  1,  1,  1,  8,  1,  1,  8,  1,  1,  1,
01538      9,  1,  9,  1,  2,  1,  1,  2,  1,  1, 10,  4,  1, 10,  1,  4,
01539      1,  1,  1,  1,  1,  3,  1,  1,  1,  3,  2,  1,  5,  1,  1,  1,
01540      2,  5,  1, 11,  1, 11,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
01541      2,  1,  6,  1,  6,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1, 12,
01542      3,  1, 12,  1,  1,  1,  2,  1,  1,  3,  1,  1,  1,  1,  1,  1,
01543      4,  1,  1,  1,  2,  1,  1,  4,  1,  1,  1,  1,  1,  1,  2,  1,
01544      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  3,  1,  2,  1,  1,  5,
01545      1,  1,  1,  1,  1,  7,  1,  7,  1,  1,  2,  3,  1,  1,  1,  1,
01546      5,  1,  1,  1,  1,  1,  1,  2, 13,  1,  1,  1,  1,  1,  1,  1,
01547      1,  1,  1,  1,  1,  1,  1,  1, 13,  2,  1,  1,  4,  1,  1,  1,
01548      3,  1,  6,  1,  1,  1, 14,  1,  1,  1,  1,  1, 14,  6,  1,  1,
01549      1,  1, 15,  2,  4,  1,  2,  3, 15,  1,  1,  1,  8,  1,  1,  8,
01550      1,  1,  1,  1,  1,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1},
01551 
01552     // value table
01553     { 0,   1,  -1,   2,   1,  -1,  -2,   1,  -1,   3,  -3,   4,   1,  -1,  -4,   1,
01554       2,   5,  -1,  -2,  -5,   6,   1,  -1,  -6,   7,  -7,   8,  -8,   1,   2,   9,
01555       3,  -2,   0,  -9,  -3,  -1,  10, -10,  11,   1, -11,  12,  -1, -12,  13, -13,
01556       1,  14,  -1, -14,   4,  15, -15,  -4,  16, -16,   1,   2,  17,  -1, -17,  -2,
01557      18, -18,  19, -19,  20,   3, -20,  21, -21,  -3,   5,  22,   2, -22, -23,  23,
01558      -5,  -2,  24,   1, -24,  -1,  25, -25,  26, -26, -27,  27,  28,  29, -28, -29,
01559       6,  30,   2, -31,  -2, -30,  31,  -6, -32,  32,  33, -33,  34, -35, -34,   1,
01560       4, -36,  -1,  35,  37,  36,   7, -37,  38,  -4, -38,  39,  41,  40, -40, -39,
01561       3,  42, -43, -41,  -7, -42,  43,  -3,  44, -44,  45, -45,  46,  47,   8, -47,
01562     -48, -46,  50, -50,  48,  49,  51, -49,  52, -52,   5, -51,  -8, -53,  53,   3,
01563     -56,  56,  55,  54, -54,   2,  60,  -2, -55,  58,   9,  -5,  59,  57, -57, -63,
01564      -3, -58, -60, -61,  61, -59, -62,  -9,   1,  64,  62,  69, -64,  63,  65, -67,
01565     -68,  66, -65,  68, -66, -69,  67, -70,  -1,  10,  71, -71,   4,  73,  72,  70,
01566       6, -76,  -3,  74, -78, -74,   1,  78,  80, -72, -75,  76,  -1,   3, -73,  79,
01567      75,  77,   1,  11,  -4, -79, -10,  -6,  -1, -77, -83, -80,   2,  81, -84,  -2,
01568      83, -81,  82, -82,  84, -87, -86,  85, -11, -85,  86, -89,  87, -88,  88,  89}
01569 },{
01570     // MapTab5
01571     2,  // _eobSym
01572     33, // _escSym
01573     // run table
01574     {1,  1,  0,  2,  1,  2,  1,  3,  3,  1,  1,  4,  4,  2,  2,  1,
01575      1,  5,  5,  6,  1,  6,  1,  7,  7,  3,  3,  2,  8,  2,  8,  1,
01576      1,  0,  9,  9,  1,  1, 10,  4, 10,  4, 11, 11,  2,  1,  2,  1,
01577     12, 12,  3,  3,  1,  1, 13,  5,  5, 13, 14,  1,  1, 14,  2,  2,
01578      6,  6, 15,  1,  1, 15, 16,  4,  7, 16,  4,  7,  1,  1,  3,  3,
01579      8,  8,  2,  2,  1,  1, 17, 17,  1,  1, 18, 18,  5,  5,  2,  2,
01580      1,  1,  9, 19,  9, 19, 20,  3,  3, 20,  1, 10, 21,  1, 10,  4,
01581      4, 21, 22,  6,  6, 22,  1,  1, 23, 24,  2,  2, 23, 24, 11,  1,
01582      1, 11,  7, 25,  7,  1,  1, 25,  8,  8,  3, 26,  3,  1, 12,  2,
01583      2, 26,  1, 12,  5,  5, 27,  4,  1,  4,  1, 27, 28,  1, 28, 13,
01584      1, 13,  2, 29,  2,  1, 32,  6,  1, 30, 14, 29, 14,  6,  3, 31,
01585      3,  1, 30,  1, 32, 31, 33,  9, 33,  1,  1,  7,  9,  7,  2,  2,
01586      1,  1,  4, 36, 34,  4,  5, 10, 10,  5, 34,  1,  1, 35,  8,  8,
01587     36,  3, 35,  1, 15,  3,  2,  1, 16, 15, 16,  2, 37,  1, 37,  1,
01588      1,  1,  6,  6, 38,  1, 38, 11,  1, 39, 39, 40, 11,  2, 41,  4,
01589     40,  1,  2,  4,  1,  1,  1, 41,  3,  1,  3,  1,  5,  7,  5,  7},
01590 
01591     // value table
01592     { 1,  -1,   0,   1,   2,  -1,  -2,   1,  -1,   3,  -3,   1,  -1,   2,  -2,   4,
01593      -4,   1,  -1,   1,   5,  -1,  -5,   1,  -1,   2,  -2,   3,   1,  -3,  -1,   6,
01594      -6,   0,   1,  -1,   7,  -7,   1,   2,  -1,  -2,   1,  -1,   4,   8,  -4,  -8,
01595       1,  -1,   3,  -3,   9,  -9,   1,   2,  -2,  -1,   1,  10, -10,  -1,   5,  -5,
01596       2,  -2,   1,  11, -11,  -1,   1,   3,   2,  -1,  -3,  -2,  12, -12,   4,  -4,
01597       2,  -2,  -6,   6,  13, -13,   1,  -1,  14, -14,   1,  -1,   3,  -3,   7,  -7,
01598      15, -15,   2,   1,  -2,  -1,   1,   5,  -5,  -1, -16,   2,   1,  16,  -2,   4,
01599      -4,  -1,   1,   3,  -3,  -1,  17, -17,   1,   1,  -8,   8,  -1,  -1,   2,  18,
01600     -18,  -2,   3,   1,  -3,  19, -19,  -1,   3,  -3,   6,   1,  -6,  20,   2,   9,
01601      -9,  -1, -20,  -2,   4,  -4,   1,  -5,  21,   5, -21,  -1,   1, -22,  -1,   2,
01602      22,  -2,  10,   1, -10,  23,   1,   4, -23,   1,   2,  -1,  -2,  -4,  -7,   1,
01603       7, -24,  -1,  24,  -1,  -1,   1,   3,  -1, -25,  25,   4,  -3,  -4,  11, -11,
01604      26, -26,   6,   1,   1,  -6,  -5,  -3,   3,   5,  -1, -27,  27,   1,   4,  -4,
01605      -1,  -8,  -1,  28,   2,   8, -12, -28,  -2,  -2,   2,  12,  -1,  29,   1, -29,
01606      30, -30,   5,  -5,   1, -31,  -1,   3,  31,  -1,   1,   1,  -3, -13,   1,  -7,
01607      -1, -32,  13,   7,  32,  33, -33,  -1,  -9, -34,   9,  34,  -6,   5,   6,  -5}
01608 },{
01609     // MapTab6
01610     2,  // _eobSym
01611     13, // _escSym
01612     // run table
01613     {1,  1,  0,  1,  1,  2,  2,  1,  1,  3,  3,  1,  1,  0,  2,  2,
01614      4,  1,  4,  1,  1,  1,  5,  5,  1,  1,  6,  6,  2,  2,  1,  1,
01615      3,  3,  7,  7,  1,  1,  8,  8,  1,  1,  2,  2,  1,  9,  1,  9,
01616      4,  4, 10,  1,  1, 10,  1,  1, 11, 11,  3,  3,  1,  2,  1,  2,
01617      1,  1, 12, 12,  5,  5,  1,  1, 13,  1,  1, 13,  2,  2,  1,  1,
01618      6,  6,  1,  1,  4, 14,  4, 14,  3,  1,  3,  1,  1,  1, 15,  7,
01619     15,  2,  2,  7,  1,  1,  1,  8,  1,  8, 16, 16,  1,  1,  1,  1,
01620      2,  1,  1,  2,  1,  1,  3,  5,  5,  3,  4,  1,  1,  4,  1,  1,
01621     17, 17,  9,  1,  1,  9,  2,  2,  1,  1, 10, 10,  1,  6,  1,  1,
01622      6, 18,  1,  1, 18,  1,  1,  1,  2,  2,  3,  1,  3,  1,  1,  1,
01623      4,  1, 19,  1, 19,  7,  1,  1, 20,  1,  4, 20,  1,  7, 11,  2,
01624      1, 11, 21,  2,  8,  5,  1,  8,  1,  5, 21,  1,  1,  1, 22,  1,
01625      1, 22,  1,  1,  3,  3,  1, 23,  2, 12, 24,  1,  1,  2,  1,  1,
01626     12, 23,  1,  1, 24,  1,  1,  1,  4,  1,  1,  1,  2,  1,  6,  6,
01627      4,  2,  1,  1,  1,  1,  1,  1,  1, 14, 13,  3,  1, 25,  9, 25,
01628     14,  1,  9,  3, 13,  1,  1,  1,  1,  1, 10,  1,  1,  2, 10,  2},
01629 
01630     // value table
01631     {-20,  -1,   0,   2,  -2,   1,  -1,   3,  -3,   1,  -1,   4,  -4,   0,   2,  -2,
01632        1,   5,  -1,  -5,   6,  -6,   1,  -1,   7,  -7,   1,  -1,   3,  -3,   8,  -8,
01633        2,  -2,   1,  -1,   9,  -9,   1,  -1,  10, -10,   4,  -4,  11,   1, -11,  -1,
01634        2,  -2,   1,  12, -12,  -1,  13, -13,   1,  -1,   3,  -3,  14,   5, -14,  -5,
01635      -15,  15,  -1,   1,   2,  -2,  16, -16,   1,  17, -17,  -1,   6,  -6,  18, -18,
01636        2,  -2, -19,  19,  -3,   1,   3,  -1,   4,  20,  -4,   1, -21,  21,   1,   2,
01637       -1,  -7,   7,  -2,  22, -22,  23,   2, -23,  -2,   1,  -1, -24,  24, -25,  25,
01638       -8, -26,  26,   8, -27,  27,   5,   3,  -3,  -5,  -4,  28, -28,   4,  29, -29,
01639        1,  -1,  -2, -30,  30,   2,   9,  -9, -31,  31,   2,  -2, -32,   3,  32, -33,
01640       -3,   1,  33, -34,  -1,  34, -35,  35, -10,  10,  -6,  36,   6, -36,  37, -37,
01641       -5,  38,   1, -38,  -1,   3,  39, -39,  -1,  40,   5,   1, -40,  -3,   2, -11,
01642      -41,  -2,   1,  11,  -3,  -4,  41,   3,  42,   4,  -1, -43, -42,  43,   1, -44,
01643       45,  -1,  44, -45,  -7,   7, -46,   1, -12,   2,   1, -47,  46,  12,  47,  48,
01644       -2,  -1, -48,  49,  -1, -50, -49,  50,  -6, -51,  51,  52, -13,  53,  -4,   4,
01645        6,  13, -53, -52, -54,  55,  54, -55, -56,  -2,   2,  -8,  56,   1,  -3,  -1,
01646        2,  58,   3,   8,  -2,  57, -58, -60, -59, -57,  -3,  60,  59, -14,   3,  14}
01647 },{
01648     // MapTab7
01649     2,  // _eobSym
01650     38, // _escSym
01651     // run table
01652     {1,  1,  0,  2,  2,  1,  1,  3,  3,  4,  4,  5,  5,  1,  1,  6,
01653      6,  2,  2,  7,  7,  8,  8,  1,  1,  3,  3,  9,  9, 10, 10,  1,
01654      1,  2,  2,  4,  4, 11,  0, 11, 12, 12, 13, 13,  1,  1,  5,  5,
01655     14, 14, 15, 16, 15, 16,  3,  3,  1,  6,  1,  6,  2,  2,  7,  7,
01656      8,  8, 17, 17,  1,  1,  4,  4, 18, 18,  2,  2,  1, 19,  1, 20,
01657     19, 20, 21, 21,  3,  3, 22, 22,  5,  5, 24,  1,  1, 23,  9, 23,
01658     24,  9,  2,  2, 10,  1,  1, 10,  6,  6, 25,  4,  4, 25,  7,  7,
01659     26,  8,  1,  8,  3,  1, 26,  3, 11, 11, 27, 27,  2, 28,  1,  2,
01660     28,  1, 12, 12,  5,  5, 29, 13, 13, 29, 32,  1,  1, 33, 31, 30,
01661     32,  4, 30, 33,  4, 31,  3, 14,  1,  1,  3, 34, 34,  2,  2, 14,
01662      6,  6, 35, 36, 35, 36,  1, 15,  1, 16, 16, 15,  7,  9,  7,  9,
01663     37,  8,  8, 37,  1,  1, 39,  2, 38, 39,  2, 40,  5, 38, 40,  5,
01664      3,  3,  4,  4, 10, 10,  1,  1,  1,  1, 41,  2, 41,  2,  6,  6,
01665      1,  1, 11, 42, 11, 43,  3, 42,  3, 17,  4, 43,  1, 17,  7,  1,
01666      8, 44,  4,  7, 44,  5,  8,  2,  5,  1,  2, 48, 45,  1, 12, 45,
01667     12, 48, 13, 13,  1,  9,  9, 46,  1, 46, 47, 47, 49, 18, 18, 49},
01668 
01669     // value table
01670     { 1,  -1,   0,   1,  -1,   2,  -2,   1,  -1,   1,  -1,   1,  -1,   3,  -3,   1,
01671      -1,  -2,   2,   1,  -1,   1,  -1,   4,  -4,  -2,   2,   1,  -1,   1,  -1,   5,
01672      -5,  -3,   3,   2,  -2,   1,   0,  -1,   1,  -1,   1,  -1,   6,  -6,   2,  -2,
01673       1,  -1,   1,   1,  -1,  -1,  -3,   3,   7,   2,  -7,  -2,  -4,   4,   2,  -2,
01674       2,  -2,   1,  -1,   8,  -8,   3,  -3,   1,  -1,  -5,   5,   9,   1,  -9,   1,
01675      -1,  -1,   1,  -1,  -4,   4,   1,  -1,   3,  -3,   1, -10,  10,   1,   2,  -1,
01676      -1,  -2,   6,  -6,   2,  11, -11,  -2,   3,  -3,   1,  -4,   4,  -1,   3,  -3,
01677       1,   3,  12,  -3,  -5, -12,  -1,   5,   2,  -2,   1,  -1,  -7,   1,  13,   7,
01678      -1, -13,   2,  -2,   4,  -4,   1,   2,  -2,  -1,   1,  14, -14,   1,   1,   1,
01679      -1,  -5,  -1,  -1,   5,  -1,  -6,   2, -15,  15,   6,   1,  -1,  -8,   8,  -2,
01680      -4,   4,   1,   1,  -1,  -1,  16,   2, -16,  -2,   2,  -2,   4,   3,  -4,  -3,
01681      -1,  -4,   4,   1, -17,  17,  -1,  -9,   1,   1,   9,   1,  -5,  -1,  -1,   5,
01682      -7,   7,   6,  -6,   3,  -3,  18, -18,  19, -19,   1, -10,  -1,  10,  -5,   5,
01683      20, -20,  -3,   1,   3,   1,   8,  -1,  -8,   2,   7,  -1, -21,  -2,   5,  21,
01684       5,  -1,  -7,  -5,   1,  -6,  -5, -11,   6,  22,  11,   1,   1, -22,  -3,  -1,
01685       3,  -1,   3,  -3, -23,   4,  -4,   1,  23,  -1,   1,  -1,   1,  -2,   2,  -1}
01686 },{
01687     // MapTab8
01688     4,  // _eobSym
01689     11, // _escSym
01690     // run table
01691     {1,  1,  1,  1,  0,  2,  2,  1,  1,  3,  3,  0,  1,  1,  2,  2,
01692      4,  4,  1,  1,  5,  5,  1,  1,  2,  2,  3,  3,  6,  6,  1,  1,
01693      7,  7,  8,  1,  8,  2,  2,  1,  4,  4,  1,  3,  1,  3,  9,  9,
01694      2,  2,  1,  5,  1,  5, 10, 10,  1,  1, 11, 11,  3,  6,  3,  4,
01695      4,  6,  2,  2,  1, 12,  1, 12,  7, 13,  7, 13,  1,  1,  8,  8,
01696      2,  2, 14, 14, 16, 15, 16,  5,  5,  1,  3, 15,  1,  3,  4,  4,
01697      1,  1, 17, 17,  2,  2,  6,  6,  1, 18,  1, 18, 22, 21, 22, 21,
01698     25, 24, 25, 19,  9, 20,  9, 23, 19, 24, 20,  3, 23,  7,  3,  1,
01699      1,  7, 28, 26, 29,  5, 28, 26,  5,  8, 29,  4,  8, 27,  2,  2,
01700      4, 27,  1,  1, 10, 36, 10, 33, 33, 36, 30,  1, 32, 32,  1, 30,
01701      6, 31, 31, 35,  3,  6, 11, 11,  3,  2, 35,  2, 34,  1, 34,  1,
01702     37, 37, 12,  7, 12,  5, 41,  5,  4,  7,  1,  8, 13,  4,  1, 41,
01703     13, 38,  8, 38,  9,  1, 40, 40,  9,  1, 39,  2,  2, 49, 39, 42,
01704      3,  3, 14, 16, 49, 14, 16, 42, 43, 43,  6,  6, 15,  1,  1, 15,
01705     44, 44,  1,  1, 50, 48,  4,  5,  4,  7,  5,  2, 10, 10, 48,  7,
01706     50, 45,  2,  1, 45,  8,  8,  1, 46, 46,  3, 47, 47,  3,  1,  1},
01707 
01708     // value table
01709     { 1,  -1,   2,  -2,   0,   1,  -1,   3,  -3,   1,  -1,   0,   4,  -4,   2,  -2,
01710       1,  -1,   5,  -5,   1,  -1,   6,  -6,   3,  -3,   2,  -2,   1,  -1,   7,  -7,
01711       1,  -1,   1,   8,  -1,   4,  -4,  -8,   2,  -2,   9,   3,  -9,  -3,   1,  -1,
01712       5,  -5,  10,   2, -10,  -2,   1,  -1,  11, -11,   1,  -1,  -4,   2,   4,   3,
01713      -3,  -2,   6,  -6,  12,   1, -12,  -1,   2,   1,  -2,  -1,  13, -13,   2,  -2,
01714       7,  -7,   1,  -1,   1,   1,  -1,   3,  -3,  14,   5,  -1, -14,  -5,   4,  -4,
01715      15, -15,   1,  -1,   8,  -8,  -3,   3,  16,   1, -16,  -1,   1,   1,  -1,  -1,
01716       1,   1,  -1,   1,   2,   1,  -2,   1,  -1,  -1,  -1,   6,  -1,   3,  -6,  17,
01717     -17,  -3,   1,   1,   1,   4,  -1,  -1,  -4,   3,  -1,   5,  -3,  -1,  -9,   9,
01718      -5,   1,  18, -18,   2,   1,  -2,   1,  -1,  -1,   1,  19,  -1,   1, -19,  -1,
01719       4,   1,  -1,   1,   7,  -4,  -2,   2,  -7,  10,  -1, -10,   1,  20,  -1, -20,
01720       1,  -1,   2,   4,  -2,   5,   1,  -5,   6,  -4,  21,   4,   2,  -6, -21,  -1,
01721      -2,   1,  -4,  -1,  -3,  22,  -1,   1,   3, -22,  -1,  11, -11,   1,   1,   1,
01722       8,  -8,   2,   2,  -1,  -2,  -2,  -1,   1,  -1,  -5,   5,   2,  23, -23,  -2,
01723       1,  -1,  24, -24,  -1,  -1,   7,   6,  -7,   5,  -6,  12,  -3,   3,   1,  -5,
01724       1,   1, -12,  25,  -1,  -5,   5, -25,  -1,   1,   9,   1,  -1,  -9,  26, -26}
01725 }
01726 };
01727 
01728 } // End of namespace Indeo
01729 } // End of namespace Image


Generated on Sat May 25 2019 05:00:47 for ResidualVM by doxygen 1.7.1
curved edge   curved edge