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

codec48.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM 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 #include "common/endian.h"
00024 #include "common/util.h"
00025 #include "common/textconsole.h"
00026 
00027 #include "engines/grim/movie/codecs/codec48.h"
00028 
00029 namespace Grim {
00030 
00031 Codec48Decoder::Codec48Decoder() {
00032     _frameSize = 640 * 480; // Yes, this is correct. Looks like the buffers are always this size
00033 
00034     _curBuf = 0;
00035     _deltaBuf[0] = new byte[_frameSize * 2];
00036     _deltaBuf[1] = _deltaBuf[0] + _frameSize;
00037 
00038     _offsetTable = new int16[255];
00039     _tableLastPitch = -1;
00040     _tableLastIndex = -1;
00041 
00042     _interTable = nullptr;
00043 }
00044 
00045 void Codec48Decoder::init(int width, int height) {
00046     if (_width == width && _height == height)
00047         return;
00048     deinit();
00049     _width = width;
00050     _height = height;
00051 
00052     _blockX = (_width + 7) / 8;
00053     _blockY = (_height + 7) / 8;
00054     _pitch = _blockX * 8;
00055 
00056     // don't support when this is not equal yet
00057     assert(_width == _pitch);
00058 }
00059 
00060 void Codec48Decoder::deinit() {
00061 }
00062 
00063 Codec48Decoder::~Codec48Decoder() {
00064     delete[] _deltaBuf[0];
00065     delete[] _offsetTable;
00066     delete[] _interTable;
00067 }
00068 
00069 bool Codec48Decoder::decode(byte *dst, const byte *src) {
00070     // The header is identical to codec 37, except the flags field is somewhat different
00071 
00072     const byte *gfxData = src + 0x10;
00073 
00074     makeTable(_pitch, src[1]);
00075 
00076     int16 seqNb = READ_LE_UINT16(src + 2);
00077 
00078     if (seqNb == 0)
00079         memset(_deltaBuf[0], 0, _frameSize * 2);
00080 
00081     if (src[12] & (1 << 3)) {
00082         // Interpolation table present
00083         if (!_interTable)
00084             _interTable = new byte[65536];
00085 
00086         byte *ptr = _interTable;
00087 
00088         for (int i = 0; i < 256; i++) {
00089             byte *ptr1 = ptr + i;
00090             byte *ptr2 = ptr + i;
00091 
00092             for (int j = 256 - i; j > 0; j--) {
00093                 byte pixel = *gfxData++;
00094                 *ptr2 = pixel;
00095                 *ptr1++ = pixel;
00096                 ptr2 += 256;
00097             }
00098 
00099             ptr += 256;
00100         }
00101     }
00102 
00103     switch (src[0]) {
00104     case 0:
00105         // Raw frame
00106         memcpy(_deltaBuf[_curBuf], gfxData, READ_LE_UINT32(src + 4));
00107         break;
00108     case 2:
00109         // Blast object
00110         bompDecodeLine(_deltaBuf[_curBuf], gfxData, _width * _height);
00111         break;
00112     case 3:
00113         // 8x8 block encoding
00114         if (!(seqNb && seqNb != _prevSeqNb + 1)) {
00115             if (seqNb & 1 || !(src[12] & 1) || src[12] & 0x10)
00116                 _curBuf ^= 1;
00117 
00118             decode3(_deltaBuf[_curBuf], gfxData, _deltaBuf[_curBuf ^ 1] - _deltaBuf[_curBuf]);
00119         }
00120         break;
00121     case 5:
00122         // Some other encoding, but it's unused. (Good)
00123         warning("SmushDecoder::decode() codec 48 frame type 5 encountered! Please report!\n");
00124         break;
00125     default:
00126         warning("SmushDecoder::decode() Unknown codec 48 frame type %d\n", src[0]);
00127         break;
00128     }
00129 
00130     _prevSeqNb = seqNb;
00131     memcpy(dst, _deltaBuf[_curBuf], _pitch * _height);
00132     return true;
00133 }
00134 
00135 void Codec48Decoder::bompDecodeLine(byte *dst, const byte *src, int len) {
00136     while (len > 0) {
00137         byte code = *src++;
00138         byte num = (code >> 1) + 1;
00139 
00140         if (num > len)
00141             num = len;
00142 
00143         len -= num;
00144 
00145         if (code & 1) {
00146             byte color = *src++;
00147             memset(dst, color, num);
00148         } else {
00149             memcpy(dst, src, num);
00150             src += num;
00151         }
00152 
00153         dst += num;
00154     }
00155 }
00156 
00157 void Codec48Decoder::makeTable(int pitch, int index) {
00158     // codec48's table is codec47's table appended by the first
00159     // part of codec37's table
00160 
00161     // This is essentially Codec37Decoder::makeTable() with a different table
00162 
00163     static const int8 table[] = {
00164         0,   0,  -1, -43,   6, -43,  -9, -42,  13, -41,
00165         -16, -40,  19, -39, -23, -36,  26, -34,  -2, -33,
00166         4, -33, -29, -32,  -9, -32,  11, -31, -16, -29,
00167         32, -29,  18, -28, -34, -26, -22, -25,  -1, -25,
00168         3, -25,  -7, -24,   8, -24,  24, -23,  36, -23,
00169         -12, -22,  13, -21, -38, -20,   0, -20, -27, -19,
00170         -4, -19,   4, -19, -17, -18,  -8, -17,   8, -17,
00171         18, -17,  28, -17,  39, -17, -12, -15,  12, -15,
00172         -21, -14,  -1, -14,   1, -14, -41, -13,  -5, -13,
00173         5, -13,  21, -13, -31, -12, -15, -11,  -8, -11,
00174         8, -11,  15, -11,  -2, -10,   1, -10,  31, -10,
00175         -23,  -9, -11,  -9,  -5,  -9,   4,  -9,  11,  -9,
00176         42,  -9,   6,  -8,  24,  -8, -18,  -7,  -7,  -7,
00177         -3,  -7,  -1,  -7,   2,  -7,  18,  -7, -43,  -6,
00178         -13,  -6,  -4,  -6,   4,  -6,   8,  -6, -33,  -5,
00179         -9,  -5,  -2,  -5,   0,  -5,   2,  -5,   5,  -5,
00180         13,  -5, -25,  -4,  -6,  -4,  -3,  -4,   3,  -4,
00181         9,  -4, -19,  -3,  -7,  -3,  -4,  -3,  -2,  -3,
00182         -1,  -3,   0,  -3,   1,  -3,   2,  -3,   4,  -3,
00183         6,  -3,  33,  -3, -14,  -2, -10,  -2,  -5,  -2,
00184         -3,  -2,  -2,  -2,  -1,  -2,   0,  -2,   1,  -2,
00185         2,  -2,   3,  -2,   5,  -2,   7,  -2,  14,  -2,
00186         19,  -2,  25,  -2,  43,  -2,  -7,  -1,  -3,  -1,
00187         -2,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,
00188         3,  -1,  10,  -1,  -5,   0,  -3,   0,  -2,   0,
00189         -1,   0,   1,   0,   2,   0,   3,   0,   5,   0,
00190         7,   0, -10,   1,  -7,   1,  -3,   1,  -2,   1,
00191         -1,   1,   0,   1,   1,   1,   2,   1,   3,   1,
00192         -43,   2, -25,   2, -19,   2, -14,   2,  -5,   2,
00193         -3,   2,  -2,   2,  -1,   2,   0,   2,   1,   2,
00194         2,   2,   3,   2,   5,   2,   7,   2,  10,   2,
00195         14,   2, -33,   3,  -6,   3,  -4,   3,  -2,   3,
00196         -1,   3,   0,   3,   1,   3,   2,   3,   4,   3,
00197         19,   3,  -9,   4,  -3,   4,   3,   4,   7,   4,
00198         25,   4, -13,   5,  -5,   5,  -2,   5,   0,   5,
00199         2,   5,   5,   5,   9,   5,  33,   5,  -8,   6,
00200         -4,   6,   4,   6,  13,   6,  43,   6, -18,   7,
00201         -2,   7,   0,   7,   2,   7,   7,   7,  18,   7,
00202         -24,   8,  -6,   8, -42,   9, -11,   9,  -4,   9,
00203         5,   9,  11,   9,  23,   9, -31,  10,  -1,  10,
00204         2,  10, -15,  11,  -8,  11,   8,  11,  15,  11,
00205         31,  12, -21,  13,  -5,  13,   5,  13,  41,  13,
00206         -1,  14,   1,  14,  21,  14, -12,  15,  12,  15,
00207         -39,  17, -28,  17, -18,  17,  -8,  17,   8,  17,
00208         17,  18,  -4,  19,   0,  19,   4,  19,  27,  19,
00209         38,  20, -13,  21,  12,  22, -36,  23, -24,  23,
00210         -8,  24,   7,  24,  -3,  25,   1,  25,  22,  25,
00211         34,  26, -18,  28, -32,  29,  16,  29, -11,  31,
00212         9,  32,  29,  32,  -4,  33,   2,  33, -26,  34,
00213         23,  36, -19,  39,  16,  40, -13,  41,   9,  42,
00214         -6,  43,   1,  43,   0,   0,   0,   0,   0,   0,
00215         0,   0,   1,   0,   2,   0,   3,   0,   5,   0,
00216         8,   0,  13,   0,  21,   0,  -1,   0,  -2,   0,
00217         -3,   0,  -5,   0,  -8,   0, -13,   0, -17,   0,
00218         -21,   0,   0,   1,   1,   1,   2,   1,   3,   1,
00219         5,   1,   8,   1,  13,   1,  21,   1,  -1,   1,
00220         -2,   1,  -3,   1,  -5,   1,  -8,   1, -13,   1,
00221         -17,   1, -21,   1,   0,   2,   1,   2,   2,   2,
00222         3,   2,   5,   2,   8,   2,  13,   2,  21,   2,
00223         -1,   2,  -2,   2,  -3,   2,  -5,   2,  -8,   2,
00224         -13,   2, -17,   2, -21,   2,   0,   3,   1,   3,
00225         2,   3,   3,   3,   5,   3,   8,   3,  13,   3,
00226         21,   3,  -1,   3,  -2,   3,  -3,   3,  -5,   3,
00227         -8,   3, -13,   3, -17,   3, -21,   3,   0,   5,
00228         1,   5,   2,   5,   3,   5,   5,   5,   8,   5,
00229         13,   5,  21,   5,  -1,   5,  -2,   5,  -3,   5,
00230         -5,   5,  -8,   5, -13,   5, -17,   5, -21,   5,
00231         0,   8,   1,   8,   2,   8,   3,   8,   5,   8,
00232         8,   8,  13,   8,  21,   8,  -1,   8,  -2,   8,
00233         -3,   8,  -5,   8,  -8,   8, -13,   8, -17,   8,
00234         -21,   8,   0,  13,   1,  13,   2,  13,   3,  13,
00235         5,  13,   8,  13,  13,  13,  21,  13,  -1,  13,
00236         -2,  13,  -3,  13,  -5,  13,  -8,  13, -13,  13,
00237         -17,  13, -21,  13,   0,  21,   1,  21,   2,  21,
00238         3,  21,   5,  21,   8,  21,  13,  21,  21,  21,
00239         -1,  21,  -2,  21,  -3,  21,  -5,  21,  -8,  21,
00240         -13,  21, -17,  21, -21,  21,   0,  -1,   1,  -1,
00241         2,  -1,   3,  -1,   5,  -1,   8,  -1,  13,  -1,
00242         21,  -1,  -1,  -1,  -2,  -1,  -3,  -1,  -5,  -1,
00243         -8,  -1, -13,  -1, -17,  -1, -21,  -1,   0,  -2,
00244         1,  -2,   2,  -2,   3,  -2,   5,  -2,   8,  -2,
00245         13,  -2,  21,  -2,  -1,  -2,  -2,  -2,  -3,  -2,
00246         -5,  -2,  -8,  -2, -13,  -2, -17,  -2, -21,  -2,
00247         0,  -3,   1,  -3,   2,  -3,   3,  -3,   5,  -3,
00248         8,  -3,  13,  -3,  21,  -3,  -1,  -3,  -2,  -3,
00249         -3,  -3,  -5,  -3,  -8,  -3, -13,  -3, -17,  -3,
00250         -21,  -3,   0,  -5,   1,  -5,   2,  -5,   3,  -5,
00251         5,  -5,   8,  -5,  13,  -5,  21,  -5,  -1,  -5,
00252         -2,  -5,  -3,  -5,  -5,  -5,  -8,  -5, -13,  -5,
00253         -17,  -5, -21,  -5,   0,  -8,   1,  -8,   2,  -8,
00254         3,  -8,   5,  -8,   8,  -8,  13,  -8,  21,  -8,
00255         -1,  -8,  -2,  -8,  -3,  -8,  -5,  -8,  -8,  -8,
00256         -13,  -8, -17,  -8, -21,  -8,   0, -13,   1, -13,
00257         2, -13,   3, -13,   5, -13,   8, -13,  13, -13,
00258         21, -13,  -1, -13,  -2, -13,  -3, -13,  -5, -13,
00259         -8, -13, -13, -13, -17, -13, -21, -13,   0, -17,
00260         1, -17,   2, -17,   3, -17,   5, -17,   8, -17,
00261         13, -17,  21, -17,  -1, -17,  -2, -17,  -3, -17,
00262         -5, -17,  -8, -17, -13, -17, -17, -17, -21, -17,
00263         0, -21,   1, -21,   2, -21,   3, -21,   5, -21,
00264         8, -21,  13, -21,  21, -21,  -1, -21,  -2, -21,
00265         -3, -21,  -5, -21,  -8, -21, -13, -21, -17, -21
00266     };
00267 
00268     if (_tableLastPitch == pitch && _tableLastIndex == index)
00269         return;
00270 
00271     _tableLastPitch = pitch;
00272     _tableLastIndex = index;
00273     index *= 255;
00274     assert(index + 254 < (int32)(sizeof(table) / 2));
00275 
00276     for (int32 i = 0; i < 255; i++) {
00277         int32 j = (i + index) * 2;
00278         _offsetTable[i] = table[j + 1] * pitch + table[j];
00279     }
00280 }
00281 
00282 void Codec48Decoder::decode3(byte *dst, const byte *src, int bufOffset) {
00283     for (int i = 0; i < _blockY; i++) {
00284         for (int j = 0; j < _blockX; j++) {
00285             byte opcode = *src++;
00286             
00287 
00288             switch (opcode) {
00289             case 0xFF: {
00290                 // Interpolate a 4x4 block based on 1 pixel, then scale to 8x8
00291                 byte scaleBuffer[16];
00292                 scaleBuffer[15] = *src++;
00293                 scaleBuffer[7] = _interTable[(dst[-_pitch + 7] << 8) | scaleBuffer[15]];
00294                 scaleBuffer[3] = _interTable[(dst[-_pitch + 7] << 8) | scaleBuffer[7]];
00295                 scaleBuffer[11] = _interTable[(scaleBuffer[15] << 8) | scaleBuffer[7]];
00296 
00297                 scaleBuffer[1] = _interTable[(dst[-1] << 8) | scaleBuffer[3]];
00298                 scaleBuffer[0] = _interTable[(dst[-1] << 8) | scaleBuffer[1]];
00299                 scaleBuffer[2] = _interTable[(scaleBuffer[3] << 8) | scaleBuffer[1]];
00300 
00301                 scaleBuffer[5] = _interTable[(dst[_pitch * 2 - 1] << 8) | scaleBuffer[7]];
00302                 scaleBuffer[4] = _interTable[(dst[_pitch * 2 - 1] << 8) | scaleBuffer[5]];
00303                 scaleBuffer[6] = _interTable[(scaleBuffer[7] << 8) | scaleBuffer[5]];
00304 
00305                 scaleBuffer[9] = _interTable[(dst[_pitch * 3 - 1] << 8) | scaleBuffer[11]];
00306                 scaleBuffer[8] = _interTable[(dst[_pitch * 3 - 1] << 8) | scaleBuffer[9]];
00307                 scaleBuffer[10] = _interTable[(scaleBuffer[11] << 8) | scaleBuffer[9]];
00308 
00309                 scaleBuffer[13] = _interTable[(dst[_pitch * 4 - 1] << 8) | scaleBuffer[15]];
00310                 scaleBuffer[12] = _interTable[(dst[_pitch * 4 - 1] << 8) | scaleBuffer[13]];
00311                 scaleBuffer[14] = _interTable[(scaleBuffer[15] << 8) | scaleBuffer[13]];
00312 
00313                 scaleBlock(dst, scaleBuffer);
00314                 break;
00315             }
00316             case 0xFE:
00317                 // Copy a block using an absolute offset
00318                 copyBlock(dst, bufOffset, (int16)READ_LE_UINT16(src));
00319                 src += 2;
00320                 break;
00321             case 0xFD: {
00322                 // Interpolate a 4x4 block based on 4 pixels, then scale to 8x8
00323                 byte scaleBuffer[16];
00324                 scaleBuffer[5] = src[0];
00325                 scaleBuffer[7] = src[1];
00326                 scaleBuffer[13] = src[2];
00327                 scaleBuffer[15] = src[3];
00328 
00329                 scaleBuffer[1] = _interTable[(dst[-_pitch + 3] << 8) | scaleBuffer[5]];
00330                 scaleBuffer[3] = _interTable[(dst[-_pitch + 7] << 8) | scaleBuffer[7]];
00331                 scaleBuffer[11] = _interTable[(scaleBuffer[15] << 8) | scaleBuffer[7]];
00332                 scaleBuffer[9] = _interTable[(scaleBuffer[13] << 8) | scaleBuffer[5]];
00333 
00334                 scaleBuffer[0] = _interTable[(dst[-1] << 8) | scaleBuffer[1]];
00335                 scaleBuffer[2] = _interTable[(scaleBuffer[3] << 8) | scaleBuffer[1]];
00336                 scaleBuffer[4] = _interTable[(dst[_pitch * 2 - 1] << 8) | scaleBuffer[5]];
00337                 scaleBuffer[6] = _interTable[(scaleBuffer[7] << 8) | scaleBuffer[5]];
00338 
00339                 scaleBuffer[8] = _interTable[(dst[_pitch * 3 - 1] << 8) | scaleBuffer[9]];
00340                 scaleBuffer[10] = _interTable[(scaleBuffer[11] << 8) | scaleBuffer[9]];
00341                 scaleBuffer[12] = _interTable[(dst[_pitch * 4 - 1] << 8) | scaleBuffer[13]];
00342                 scaleBuffer[14] = _interTable[(scaleBuffer[15] << 8) | scaleBuffer[13]];
00343                 
00344                 scaleBlock(dst, scaleBuffer);
00345 
00346                 src += 4;
00347                 break;
00348             }
00349             case 0xFC:
00350                 // Copy 4 4x4 blocks using the offset table
00351                 *((uint32 *)dst) = *((uint32 *)(dst + bufOffset + _offsetTable[src[0]]));
00352                 *((uint32 *)(dst + _pitch)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[0]] + _pitch));
00353                 *((uint32 *)(dst + _pitch * 2)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[0]] + _pitch * 2));
00354                 *((uint32 *)(dst + _pitch * 3)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[0]] + _pitch * 3));
00355 
00356                 *((uint32 *)(dst + 4)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[1]] + 4));
00357                 *((uint32 *)(dst + _pitch + 4)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[1]] + _pitch + 4));
00358                 *((uint32 *)(dst + _pitch * 2 + 4)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[1]] + _pitch * 2 + 4));
00359                 *((uint32 *)(dst + _pitch * 3 + 4)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[1]] + _pitch * 3 + 4));
00360 
00361                 *((uint32 *)(dst + _pitch * 4)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[2]] + _pitch * 4));
00362                 *((uint32 *)(dst + _pitch * 5)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[2]] + _pitch * 5));
00363                 *((uint32 *)(dst + _pitch * 6)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[2]] + _pitch * 6));
00364                 *((uint32 *)(dst + _pitch * 7)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[2]] + _pitch * 7));
00365 
00366                 *((uint32 *)(dst + _pitch * 4 + 4)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[3]] + _pitch * 4 + 4));
00367                 *((uint32 *)(dst + _pitch * 5 + 4)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[3]] + _pitch * 5 + 4));
00368                 *((uint32 *)(dst + _pitch * 6 + 4)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[3]] + _pitch * 6 + 4));
00369                 *((uint32 *)(dst + _pitch * 7 + 4)) = *((uint32 *)(dst + bufOffset + _offsetTable[src[3]] + _pitch * 7 + 4));
00370 
00371                 src += 4;
00372                 break;
00373             case 0xFB:
00374                 // Copy 4 4x4 blocks using absolute offsets
00375                 *((uint32 *)dst) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src)));
00376                 *((uint32 *)(dst + _pitch)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src) + _pitch));
00377                 *((uint32 *)(dst + _pitch * 2)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src) + _pitch * 2));
00378                 *((uint32 *)(dst + _pitch * 3)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src) + _pitch * 3));
00379 
00380                 *((uint32 *)(dst + 4)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 2) + 4));
00381                 *((uint32 *)(dst + _pitch + 4)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 2) + _pitch + 4));
00382                 *((uint32 *)(dst + _pitch * 2 + 4)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 2) + _pitch * 2 + 4));
00383                 *((uint32 *)(dst + _pitch * 3 + 4)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 2) + _pitch * 3 + 4));
00384 
00385                 *((uint32 *)(dst + _pitch * 4)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 4) + _pitch * 4));
00386                 *((uint32 *)(dst + _pitch * 5)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 4) + _pitch * 5));
00387                 *((uint32 *)(dst + _pitch * 6)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 4) + _pitch * 6));
00388                 *((uint32 *)(dst + _pitch * 7)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 4) + _pitch * 7));
00389 
00390                 *((uint32 *)(dst + _pitch * 4 + 4)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 6) + _pitch * 4 + 4));
00391                 *((uint32 *)(dst + _pitch * 5 + 4)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 6) + _pitch * 5 + 4));
00392                 *((uint32 *)(dst + _pitch * 6 + 4)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 6) + _pitch * 6 + 4));
00393                 *((uint32 *)(dst + _pitch * 7 + 4)) = *((uint32 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 6) + _pitch * 7 + 4));
00394                 src += 8;
00395                 break;
00396             case 0xFA:
00397                 // Scale a 4x4 block to an 8x8 block
00398                 scaleBlock(dst, src);
00399                 src += 16;
00400                 break;
00401             case 0xF9:
00402                 // Copy 16 2x2 blocks using the offset table
00403                 *((uint16 *)dst) = *((uint16 *)(dst + bufOffset + _offsetTable[src[0]]));
00404                 *((uint16 *)(dst + _pitch)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[0]] + _pitch));
00405 
00406                 *((uint16 *)(dst + 2)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[1]] + 2));
00407                 *((uint16 *)(dst + _pitch + 2)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[1]] + _pitch + 2));
00408 
00409                 *((uint16 *)(dst + 4)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[2]] + 4));
00410                 *((uint16 *)(dst + _pitch + 4)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[2]] + _pitch + 4));
00411 
00412                 *((uint16 *)(dst + 6)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[3]] + 6));
00413                 *((uint16 *)(dst + _pitch + 6)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[3]] + _pitch + 6));
00414 
00415                 *((uint16 *)(dst + _pitch * 2)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[4]] + _pitch * 2));
00416                 *((uint16 *)(dst + _pitch * 3)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[4]] + _pitch * 3));
00417 
00418                 *((uint16 *)(dst + _pitch * 2 + 2)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[5]] + _pitch * 2 + 2));
00419                 *((uint16 *)(dst + _pitch * 3 + 2)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[5]] + _pitch * 3 + 2));
00420 
00421                 *((uint16 *)(dst + _pitch * 2 + 4)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[6]] + _pitch * 2 + 4));
00422                 *((uint16 *)(dst + _pitch * 3 + 4)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[6]] + _pitch * 3 + 4));
00423 
00424                 *((uint16 *)(dst + _pitch * 2 + 6)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[7]] + _pitch * 2 + 6));
00425                 *((uint16 *)(dst + _pitch * 3 + 6)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[7]] + _pitch * 3 + 6));
00426 
00427                 *((uint16 *)(dst + _pitch * 4)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[8]] + _pitch * 4));
00428                 *((uint16 *)(dst + _pitch * 5)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[8]] + _pitch * 5));
00429 
00430                 *((uint16 *)(dst + _pitch * 4 + 2)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[9]] + _pitch * 4 + 2));
00431                 *((uint16 *)(dst + _pitch * 5 + 2)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[9]] + _pitch * 5 + 2));
00432 
00433                 *((uint16 *)(dst + _pitch * 4 + 4)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[10]] + _pitch * 4 + 4));
00434                 *((uint16 *)(dst + _pitch * 5 + 4)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[10]] + _pitch * 5 + 4));
00435 
00436                 *((uint16 *)(dst + _pitch * 4 + 6)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[11]] + _pitch * 4 + 6));
00437                 *((uint16 *)(dst + _pitch * 5 + 6)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[11]] + _pitch * 5 + 6));
00438 
00439                 *((uint16 *)(dst + _pitch * 6)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[12]] + _pitch * 6));
00440                 *((uint16 *)(dst + _pitch * 7)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[12]] + _pitch * 7));
00441 
00442                 *((uint16 *)(dst + _pitch * 6 + 2)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[13]] + _pitch * 6 + 2));
00443                 *((uint16 *)(dst + _pitch * 7 + 2)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[13]] + _pitch * 7 + 2));
00444 
00445                 *((uint16 *)(dst + _pitch * 6 + 4)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[14]] + _pitch * 6 + 4));
00446                 *((uint16 *)(dst + _pitch * 7 + 4)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[14]] + _pitch * 7 + 4));
00447 
00448                 *((uint16 *)(dst + _pitch * 6 + 6)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[15]] + _pitch * 6 + 6));
00449                 *((uint16 *)(dst + _pitch * 7 + 6)) = *((uint16 *)(dst + bufOffset + _offsetTable[src[15]] + _pitch * 7 + 6));
00450                 src += 16;
00451                 break;
00452             case 0xF8:
00453                 // Copy 16 2x2 blocks using absolute offsets
00454                 *((uint16 *)dst) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src)));
00455                 *((uint16 *)(dst + _pitch)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src) + _pitch));
00456         
00457                 *((uint16 *)(dst + 2)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 2) + 2));
00458                 *((uint16 *)(dst + _pitch + 2)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 2) + _pitch + 2));
00459 
00460                 *((uint16 *)(dst + 4)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 4) + 4));
00461                 *((uint16 *)(dst + _pitch + 4)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 4) + _pitch + 4));
00462 
00463                 *((uint16 *)(dst + 6)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 6) + 6));
00464                 *((uint16 *)(dst + _pitch + 6)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 6) + _pitch + 6));
00465 
00466                 *((uint16 *)(dst + _pitch * 2)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 8) + _pitch * 2));
00467                 *((uint16 *)(dst + _pitch * 3)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 8) + _pitch * 3));
00468 
00469                 *((uint16 *)(dst + _pitch * 2 + 2)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 10) + _pitch * 2 + 2));
00470                 *((uint16 *)(dst + _pitch * 3 + 2)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 10) + _pitch * 3 + 2));
00471 
00472                 *((uint16 *)(dst + _pitch * 2 + 4)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 12) + _pitch * 2 + 4));
00473                 *((uint16 *)(dst + _pitch * 3 + 4)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 12) + _pitch * 3 + 4));
00474 
00475                 *((uint16 *)(dst + _pitch * 2 + 6)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 14) + _pitch * 2 + 6));
00476                 *((uint16 *)(dst + _pitch * 3 + 6)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 14) + _pitch * 3 + 6));
00477 
00478                 *((uint16 *)(dst + _pitch * 4)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 16) + _pitch * 4));
00479                 *((uint16 *)(dst + _pitch * 5)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 16) + _pitch * 5));
00480 
00481                 *((uint16 *)(dst + _pitch * 4 + 2)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 18) + _pitch * 4 + 2));
00482                 *((uint16 *)(dst + _pitch * 5 + 2)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 18) + _pitch * 5 + 2));
00483 
00484                 *((uint16 *)(dst + _pitch * 4 + 4)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 20) + _pitch * 4 + 4));
00485                 *((uint16 *)(dst + _pitch * 5 + 4)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 20) + _pitch * 5 + 4));
00486 
00487                 *((uint16 *)(dst + _pitch * 4 + 6)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 22) + _pitch * 4 + 6));
00488                 *((uint16 *)(dst + _pitch * 5 + 6)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 22) + _pitch * 5 + 6));
00489 
00490                 *((uint16 *)(dst + _pitch * 6)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 24) + _pitch * 6));
00491                 *((uint16 *)(dst + _pitch * 7)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 24) + _pitch * 7));
00492 
00493                 *((uint16 *)(dst + _pitch * 6 + 2)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 26) + _pitch * 6 + 2));
00494                 *((uint16 *)(dst + _pitch * 7 + 2)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 26) + _pitch * 7 + 2));
00495 
00496                 *((uint16 *)(dst + _pitch * 6 + 4)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 28) + _pitch * 6 + 4));
00497                 *((uint16 *)(dst + _pitch * 7 + 4)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 28) + _pitch * 7 + 4));
00498 
00499                 *((uint16 *)(dst + _pitch * 6 + 6)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 30) + _pitch * 6 + 6));
00500                 *((uint16 *)(dst + _pitch * 7 + 6)) = *((uint16 *)(dst + bufOffset + (int16)READ_LE_UINT16(src + 30) + _pitch * 7 + 6));
00501 
00502                 src += 32;
00503                 break;
00504             case 0xF7:
00505                 // Raw 8x8 block
00506                 *((uint32 *)dst) = *((const uint32 *)src);
00507                 *((uint32 *)(dst + 4)) = *((const uint32 *)(src + 4));
00508                 *((uint32 *)(dst + _pitch)) = *((const uint32 *)(src + 8));
00509                 *((uint32 *)(dst + _pitch + 4)) = *((const uint32 *)(src + 12));
00510                 *((uint32 *)(dst + _pitch * 2)) = *((const uint32 *)(src + 16));
00511                 *((uint32 *)(dst + _pitch * 2 + 4)) = *((const uint32 *)(src + 20));
00512                 *((uint32 *)(dst + _pitch * 3)) = *((const uint32 *)(src + 24));
00513                 *((uint32 *)(dst + _pitch * 3 + 4)) = *((const uint32 *)(src + 28));
00514                 *((uint32 *)(dst + _pitch * 4)) = *((const uint32 *)(src + 32));
00515                 *((uint32 *)(dst + _pitch * 4 + 4)) = *((const uint32 *)(src + 36));
00516                 *((uint32 *)(dst + _pitch * 5)) = *((const uint32 *)(src + 40));
00517                 *((uint32 *)(dst + _pitch * 5 + 4)) = *((const uint32 *)(src + 44));
00518                 *((uint32 *)(dst + _pitch * 6)) = *((const uint32 *)(src + 48));
00519                 *((uint32 *)(dst + _pitch * 6 + 4)) = *((const uint32 *)(src + 52));
00520                 *((uint32 *)(dst + _pitch * 7)) = *((const uint32 *)(src + 56));
00521                 *((uint32 *)(dst + _pitch * 7 + 4)) = *((const uint32 *)(src + 60));
00522 
00523                 src += 64;
00524                 break;
00525             default:
00526                 // Copy a block using the offset table
00527                 copyBlock(dst, bufOffset, _offsetTable[opcode]);
00528                 break;
00529             }
00530 
00531             dst += 8;
00532         }
00533 
00534         dst += _pitch * 7;
00535     }
00536 }
00537 
00538 void Codec48Decoder::copyBlock(byte *dst, int deltaBufOffset, int offset) {
00539     const byte *src = dst + deltaBufOffset + offset;
00540 
00541     for (int i = 0; i < 8; i++) {
00542         *((uint32 *)(dst + _pitch * i)) = *((const uint32 *)(src + _pitch * i));
00543         *((uint32 *)(dst + _pitch * i + 4)) = *((const uint32 *)(src + _pitch * i + 4));
00544     }
00545 }
00546 
00547 void Codec48Decoder::scaleBlock(byte *dst, const byte *src) {
00548     // This is doing a 2x scale of data
00549 
00550     for (int i = 0; i < 4; i++) {
00551         uint16 pixels = src[0];
00552         pixels = (pixels << 8) | pixels;
00553         *((uint16 *)dst) = pixels;
00554         *((uint16 *)(dst + _pitch)) = pixels;
00555         pixels = src[1];
00556         pixels = (pixels << 8) | pixels;
00557         *((uint16 *)(dst + 2)) = pixels;
00558         *((uint16 *)(dst + _pitch + 2)) = pixels;
00559         pixels = src[2];
00560         pixels = (pixels << 8) | pixels;
00561         *((uint16 *)(dst + 4)) = pixels;
00562         *((uint16 *)(dst + _pitch + 4)) = pixels;
00563         pixels = src[3];
00564         pixels = (pixels << 8) | pixels;
00565         *((uint16 *)(dst + 6)) = pixels;
00566         *((uint16 *)(dst + _pitch + 6)) = pixels;
00567         src += 4;
00568         dst += _pitch * 2;
00569     }
00570 }
00571 
00572 } // end of namespace Grim


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