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

blocky8.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 
00024 #include "common/endian.h"
00025 #include "common/util.h"
00026 #include "common/textconsole.h"
00027 
00028 #include "engines/grim/movie/codecs/blocky8.h"
00029 
00030 namespace Grim {
00031 
00032 #if defined(SYSTEM_NEED_ALIGNMENT)
00033 
00034 #define COPY_4X1_LINE(dst, src)         \
00035     do {                    \
00036         (dst)[0] = (src)[0];    \
00037         (dst)[1] = (src)[1];    \
00038         (dst)[2] = (src)[2];    \
00039         (dst)[3] = (src)[3];    \
00040     } while (0)
00041 
00042 #define COPY_2X1_LINE(dst, src)         \
00043     do {                    \
00044         (dst)[0] = (src)[0];    \
00045         (dst)[1] = (src)[1];    \
00046     } while (0)
00047 
00048 
00049 #else /* SYSTEM_NEED_ALIGNMENT */
00050 
00051 #define COPY_4X1_LINE(dst, src)         \
00052     *(uint32 *)(dst) = *(const uint32 *)(src)
00053 
00054 #define COPY_2X1_LINE(dst, src)         \
00055     *(uint16 *)(dst) = *(const uint16 *)(src)
00056 
00057 #endif
00058 
00059 #define FILL_4X1_LINE(dst, val)         \
00060     do {                    \
00061         (dst)[0] = val; \
00062         (dst)[1] = val; \
00063         (dst)[2] = val; \
00064         (dst)[3] = val; \
00065     } while (0)
00066 
00067 #define FILL_2X1_LINE(dst, val)         \
00068     do {                    \
00069         (dst)[0] = val; \
00070         (dst)[1] = val; \
00071     } while (0)
00072 
00073 static const int8 blocky8_table_small1[] = {
00074   0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 2, 1,
00075 };
00076 
00077 static const int8 blocky8_table_small2[] = {
00078   0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2,
00079 };
00080 
00081 static const int8 blocky8_table_big1[] = {
00082   0, 2, 5, 7, 7, 7, 7, 7, 7, 5, 2, 0, 0, 0, 0, 0,
00083 };
00084 
00085 static const int8 blocky8_table_big2[] = {
00086   0, 0, 0, 0, 1, 3, 4, 6, 7, 7, 7, 7, 6, 4, 3, 1,
00087 };
00088 
00089 static const int8 blocky8_table[] = {
00090       0,   0,  -1, -43,   6, -43,  -9, -42,  13, -41,
00091     -16, -40,  19, -39, -23, -36,  26, -34,  -2, -33,
00092       4, -33, -29, -32,  -9, -32,  11, -31, -16, -29,
00093      32, -29,  18, -28, -34, -26, -22, -25,  -1, -25,
00094       3, -25,  -7, -24,   8, -24,  24, -23,  36, -23,
00095     -12, -22,  13, -21, -38, -20,   0, -20, -27, -19,
00096      -4, -19,   4, -19, -17, -18,  -8, -17,   8, -17,
00097      18, -17,  28, -17,  39, -17, -12, -15,  12, -15,
00098     -21, -14,  -1, -14,   1, -14, -41, -13,  -5, -13,
00099       5, -13,  21, -13, -31, -12, -15, -11,  -8, -11,
00100       8, -11,  15, -11,  -2, -10,   1, -10,  31, -10,
00101     -23,  -9, -11,  -9,  -5,  -9,   4,  -9,  11,  -9,
00102      42,  -9,   6,  -8,  24,  -8, -18,  -7,  -7,  -7,
00103      -3,  -7,  -1,  -7,   2,  -7,  18,  -7, -43,  -6,
00104     -13,  -6,  -4,  -6,   4,  -6,   8,  -6, -33,  -5,
00105      -9,  -5,  -2,  -5,   0,  -5,   2,  -5,   5,  -5,
00106      13,  -5, -25,  -4,  -6,  -4,  -3,  -4,   3,  -4,
00107       9,  -4, -19,  -3,  -7,  -3,  -4,  -3,  -2,  -3,
00108      -1,  -3,   0,  -3,   1,  -3,   2,  -3,   4,  -3,
00109       6,  -3,  33,  -3, -14,  -2, -10,  -2,  -5,  -2,
00110      -3,  -2,  -2,  -2,  -1,  -2,   0,  -2,   1,  -2,
00111       2,  -2,   3,  -2,   5,  -2,   7,  -2,  14,  -2,
00112      19,  -2,  25,  -2,  43,  -2,  -7,  -1,  -3,  -1,
00113      -2,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,
00114       3,  -1,  10,  -1,  -5,   0,  -3,   0,  -2,   0,
00115      -1,   0,   1,   0,   2,   0,   3,   0,   5,   0,
00116       7,   0, -10,   1,  -7,   1,  -3,   1,  -2,   1,
00117      -1,   1,   0,   1,   1,   1,   2,   1,   3,   1,
00118     -43,   2, -25,   2, -19,   2, -14,   2,  -5,   2,
00119      -3,   2,  -2,   2,  -1,   2,   0,   2,   1,   2,
00120       2,   2,   3,   2,   5,   2,   7,   2,  10,   2,
00121      14,   2, -33,   3,  -6,   3,  -4,   3,  -2,   3,
00122      -1,   3,   0,   3,   1,   3,   2,   3,   4,   3,
00123      19,   3,  -9,   4,  -3,   4,   3,   4,   7,   4,
00124      25,   4, -13,   5,  -5,   5,  -2,   5,   0,   5,
00125       2,   5,   5,   5,   9,   5,  33,   5,  -8,   6,
00126      -4,   6,   4,   6,  13,   6,  43,   6, -18,   7,
00127      -2,   7,   0,   7,   2,   7,   7,   7,  18,   7,
00128     -24,   8,  -6,   8, -42,   9, -11,   9,  -4,   9,
00129       5,   9,  11,   9,  23,   9, -31,  10,  -1,  10,
00130       2,  10, -15,  11,  -8,  11,   8,  11,  15,  11,
00131      31,  12, -21,  13,  -5,  13,   5,  13,  41,  13,
00132      -1,  14,   1,  14,  21,  14, -12,  15,  12,  15,
00133     -39,  17, -28,  17, -18,  17,  -8,  17,   8,  17,
00134      17,  18,  -4,  19,   0,  19,   4,  19,  27,  19,
00135      38,  20, -13,  21,  12,  22, -36,  23, -24,  23,
00136      -8,  24,   7,  24,  -3,  25,   1,  25,  22,  25,
00137      34,  26, -18,  28, -32,  29,  16,  29, -11,  31,
00138       9,  32,  29,  32,  -4,  33,   2,  33, -26,  34,
00139      23,  36, -19,  39,  16,  40, -13,  41,   9,  42,
00140      -6,  43,   1,  43,   0,   0,   0,   0,   0,   0,
00141       0,   0,   0
00142 };
00143 
00144 void Blocky8::makeTablesInterpolation(int param) {
00145     int32 variable1, variable2;
00146     int32 b1, b2;
00147     int32 value_table47_1_2, value_table47_1_1, value_table47_2_2, value_table47_2_1;
00148     int32 tableSmallBig[64], tmp, s;
00149     const int8 *table47_1 = nullptr, *table47_2 = nullptr;
00150     int32 *ptr_small_big;
00151     byte *ptr;
00152     int i, x, y;
00153 
00154     if (param == 8) {
00155         table47_1 = blocky8_table_big1;
00156         table47_2 = blocky8_table_big2;
00157         ptr = _tableBig;
00158         for (i = 0; i < 256; i++) {
00159             ptr[384] = 0;
00160             ptr[385] = 0;
00161             ptr += 388;
00162         }
00163     } else if (param == 4) {
00164         table47_1 = blocky8_table_small1;
00165         table47_2 = blocky8_table_small2;
00166         ptr = _tableSmall;
00167         for (i = 0; i < 256; i++) {
00168             ptr[96] = 0;
00169             ptr[97] = 0;
00170             ptr += 128;
00171         }
00172     } else {
00173         error("Blocky8::makeTablesInterpolation: unknown param %d", param);
00174     }
00175 
00176     s = 0;
00177     for (x = 0; x < 16; x++) {
00178         value_table47_1_1 = table47_1[x];
00179         value_table47_2_1 = table47_2[x];
00180         for (y = 0; y < 16; y++) {
00181             value_table47_1_2 = table47_1[y];
00182             value_table47_2_2 = table47_2[y];
00183 
00184             if (value_table47_2_1 == 0) {
00185                 b1 = 0;
00186             } else if (value_table47_2_1 == param - 1) {
00187                 b1 = 1;
00188             } else if (value_table47_1_1 == 0) {
00189                 b1 = 2;
00190             } else if (value_table47_1_1 == param - 1) {
00191                 b1 = 3;
00192             } else {
00193                 b1 = 4;
00194             }
00195 
00196             if (value_table47_2_2 == 0) {
00197                 b2 = 0;
00198             } else if (value_table47_2_2 == param - 1) {
00199                 b2 = 1;
00200             } else if (value_table47_1_2 == 0) {
00201                 b2 = 2;
00202             } else if (value_table47_1_2 == param - 1) {
00203                 b2 = 3;
00204             } else {
00205                 b2 = 4;
00206             }
00207 
00208             memset(tableSmallBig, 0, param * param * 4);
00209 
00210             variable2 = ABS(value_table47_2_2 - value_table47_2_1);
00211             tmp = ABS(value_table47_1_2 - value_table47_1_1);
00212             if (variable2 <= tmp) {
00213                 variable2 = tmp;
00214             }
00215 
00216             for (variable1 = 0; variable1 <= variable2; variable1++) {
00217                 int32 variable3, variable4;
00218 
00219                 if (variable2 > 0) {
00220                     // Linearly interpolate between value_table47_1_1 and value_table47_1_2
00221                     // respectively value_table47_2_1 and value_table47_2_2.
00222                     variable4 = (value_table47_1_1 * variable1 + value_table47_1_2 * (variable2 - variable1) + variable2 / 2) / variable2;
00223                     variable3 = (value_table47_2_1 * variable1 + value_table47_2_2 * (variable2 - variable1) + variable2 / 2) / variable2;
00224                 } else {
00225                     variable4 = value_table47_1_1;
00226                     variable3 = value_table47_2_1;
00227                 }
00228                 ptr_small_big = &tableSmallBig[param * variable3 + variable4];
00229                 *ptr_small_big = 1;
00230 
00231                 if ((b1 == 2 && b2 == 3) || (b2 == 2 && b1 == 3) ||
00232                     (b1 == 0 && b2 != 1) || (b2 == 0 && b1 != 1)) {
00233                     if (variable3 >= 0) {
00234                         i = variable3 + 1;
00235                         while (i--) {
00236                             *ptr_small_big = 1;
00237                             ptr_small_big -= param;
00238                         }
00239                     }
00240                 } else if ((b2 != 0 && b1 == 1) || (b1 != 0 && b2 == 1)) {
00241                     if (param > variable3) {
00242                         i = param - variable3;
00243                         while (i--) {
00244                             *ptr_small_big = 1;
00245                             ptr_small_big += param;
00246                         }
00247                     }
00248                 } else if ((b1 == 2 && b2 != 3) || (b2 == 2 && b1 != 3)) {
00249                     if (variable4 >= 0) {
00250                         i = variable4 + 1;
00251                         while (i--) {
00252                             *(ptr_small_big--) = 1;
00253                         }
00254                     }
00255                 } else if ((b1 == 0 && b2 == 1) || (b2 == 0 && b1 == 1) ||
00256                            (b1 == 3 && b2 != 2) || (b2 == 3 && b1 != 2)) {
00257                     if (param > variable4) {
00258                         i = param - variable4;
00259                         while (i--) {
00260                             *(ptr_small_big++) = 1;
00261                         }
00262                     }
00263                 }
00264             }
00265 
00266             if (param == 8) {
00267                 for (i = 64 - 1; i >= 0; i--) {
00268                     if (tableSmallBig[i] != 0) {
00269                         _tableBig[256 + s + _tableBig[384 + s]] = (byte)i;
00270                         _tableBig[384 + s]++;
00271                     } else {
00272                         _tableBig[320 + s + _tableBig[385 + s]] = (byte)i;
00273                         _tableBig[385 + s]++;
00274                     }
00275                 }
00276                 s += 388;
00277             }
00278             if (param == 4) {
00279                 for (i = 16 - 1; i >= 0; i--) {
00280                     if (tableSmallBig[i] != 0) {
00281                         _tableSmall[64 + s + _tableSmall[96 + s]] = (byte)i;
00282                         _tableSmall[96 + s]++;
00283                     } else {
00284                         _tableSmall[80 + s + _tableSmall[97 + s]] = (byte)i;
00285                         _tableSmall[97 + s]++;
00286                     }
00287                 }
00288                 s += 128;
00289             }
00290         }
00291     }
00292 }
00293 
00294 void Blocky8::makeTables47(int width) {
00295     if (_lastTableWidth == width)
00296         return;
00297 
00298     _lastTableWidth = width;
00299 
00300     int32 a, c, d;
00301     int16 tmp;
00302 
00303     for (int l = 0; l < 512; l += 2) {
00304         _table[l / 2] = (int16)(blocky8_table[l + 1] * width + blocky8_table[l]);
00305     }
00306 
00307     a = 0;
00308     c = 0;
00309     do {
00310         for (d = 0; d < _tableSmall[96 + c]; d++) {
00311             tmp = _tableSmall[64 + c + d];
00312             tmp = (int16)((byte)(tmp >> 2) * width + (tmp & 3));
00313             _tableSmall[c + d * 2] = (byte)tmp;
00314             _tableSmall[c + d * 2 + 1] = tmp >> 8;
00315         }
00316         for (d = 0; d < _tableSmall[97 + c]; d++) {
00317             tmp = _tableSmall[80 + c + d];
00318             tmp = (int16)((byte)(tmp >> 2) * width + (tmp & 3));
00319             _tableSmall[32 + c + d * 2] = (byte)tmp;
00320             _tableSmall[32 + c + d * 2 + 1] = tmp >> 8;
00321         }
00322         for (d = 0; d < _tableBig[384 + a]; d++) {
00323             tmp = _tableBig[256 + a + d];
00324             tmp = (int16)((byte)(tmp >> 3) * width + (tmp & 7));
00325             _tableBig[a + d * 2] = (byte)tmp;
00326             _tableBig[a + d * 2 + 1] = tmp >> 8;
00327         }
00328         for (d = 0; d < _tableBig[385 + a]; d++) {
00329             tmp = _tableBig[320 + a + d];
00330             tmp = (int16)((byte)(tmp >> 3) * width + (tmp & 7));
00331             _tableBig[128 + a + d * 2] = (byte)tmp;
00332             _tableBig[128 + a + d * 2 + 1] = tmp >> 8;
00333         }
00334 
00335         a += 388;
00336         c += 128;
00337     } while (c < 32768);
00338 }
00339 
00340 #ifdef USE_ARM_SMUSH_ASM
00341 
00342 extern "C" {
00343 #ifndef IPHONE
00344 #define ARM_Blocky8_decode2 _ARM_Blocky8_decode2
00345 #endif
00346 }
00347 
00348 extern "C" void ARM_Blocky8_decode2(      byte  *dst,
00349                                   const byte  *src,
00350                                         int    width,
00351                                         int    height,
00352                                   const byte  *param_ptr,
00353                                         int16 *_table,
00354                                         byte  *_tableBig,
00355                                         int32  offset1,
00356                                         int32  offset2,
00357                                         byte  *_tableSmall);
00358 
00359 #define decode2(SRC,DST,WIDTH,HEIGHT,PARAM) \
00360  ARM_Blocky8_decode2(SRC,DST,WIDTH,HEIGHT,PARAM,_table,_tableBig, \
00361                    _offset1,_offset2,_tableSmall)
00362 
00363 #else
00364 void Blocky8::level3(byte *d_dst) {
00365     int32 tmp;
00366     byte code = *_d_src++;
00367 
00368     if (code < 0xF8) {
00369         tmp = _table[code] + _offset1;
00370         COPY_2X1_LINE(d_dst, d_dst + tmp);
00371         COPY_2X1_LINE(d_dst + _d_pitch, d_dst + _d_pitch + tmp);
00372     } else if (code == 0xFF) {
00373         COPY_2X1_LINE(d_dst, _d_src + 0);
00374         COPY_2X1_LINE(d_dst + _d_pitch, _d_src + 2);
00375         _d_src += 4;
00376     } else if (code == 0xFE) {
00377         byte t = *_d_src++;
00378         FILL_2X1_LINE(d_dst, t);
00379         FILL_2X1_LINE(d_dst + _d_pitch, t);
00380     } else if (code == 0xFC) {
00381         tmp = _offset2;
00382         COPY_2X1_LINE(d_dst, d_dst + tmp);
00383         COPY_2X1_LINE(d_dst + _d_pitch, d_dst + _d_pitch + tmp);
00384     } else {
00385         byte t = _paramPtr[code];
00386         FILL_2X1_LINE(d_dst, t);
00387         FILL_2X1_LINE(d_dst + _d_pitch, t);
00388     }
00389 }
00390 
00391 void Blocky8::level2(byte *d_dst) {
00392     int32 tmp;
00393     byte code = *_d_src++;
00394     int i;
00395 
00396     if (code < 0xF8) {
00397         tmp = _table[code] + _offset1;
00398         for (i = 0; i < 4; i++) {
00399             COPY_4X1_LINE(d_dst, d_dst + tmp);
00400             d_dst += _d_pitch;
00401         }
00402     } else if (code == 0xFF) {
00403         level3(d_dst);
00404         d_dst += 2;
00405         level3(d_dst);
00406         d_dst += _d_pitch * 2 - 2;
00407         level3(d_dst);
00408         d_dst += 2;
00409         level3(d_dst);
00410     } else if (code == 0xFE) {
00411         byte t = *_d_src++;
00412         for (i = 0; i < 4; i++) {
00413             FILL_4X1_LINE(d_dst, t);
00414             d_dst += _d_pitch;
00415         }
00416     } else if (code == 0xFD) {
00417         byte *tmp_ptr = _tableSmall + *_d_src++ * 128;
00418         int32 l = tmp_ptr[96];
00419         byte val = *_d_src++;
00420         int16 *tmp_ptr2 = (int16 *)tmp_ptr;
00421         while (l--) {
00422             *(d_dst + READ_LE_UINT16(tmp_ptr2)) = val;
00423             tmp_ptr2++;
00424         }
00425         l = tmp_ptr[97];
00426         val = *_d_src++;
00427         tmp_ptr2 = (int16 *)(tmp_ptr + 32);
00428         while (l--) {
00429             *(d_dst + READ_LE_UINT16(tmp_ptr2)) = val;
00430             tmp_ptr2++;
00431         }
00432     } else if (code == 0xFC) {
00433         tmp = _offset2;
00434         for (i = 0; i < 4; i++) {
00435             COPY_4X1_LINE(d_dst, d_dst + tmp);
00436             d_dst += _d_pitch;
00437         }
00438     } else {
00439         byte t = _paramPtr[code];
00440         for (i = 0; i < 4; i++) {
00441             FILL_4X1_LINE(d_dst, t);
00442             d_dst += _d_pitch;
00443         }
00444     }
00445 }
00446 
00447 void Blocky8::level1(byte *d_dst) {
00448     int32 tmp, tmp2;
00449     byte code = *_d_src++;
00450     int i;
00451 
00452     if (code < 0xF8) {
00453         tmp2 = _table[code] + _offset1;
00454         for (i = 0; i < 8; i++) {
00455             COPY_4X1_LINE(d_dst + 0, d_dst + tmp2);
00456             COPY_4X1_LINE(d_dst + 4, d_dst + tmp2 + 4);
00457             d_dst += _d_pitch;
00458         }
00459     } else if (code == 0xFF) {
00460         level2(d_dst);
00461         d_dst += 4;
00462         level2(d_dst);
00463         d_dst += _d_pitch * 4 - 4;
00464         level2(d_dst);
00465         d_dst += 4;
00466         level2(d_dst);
00467     } else if (code == 0xFE) {
00468         byte t = *_d_src++;
00469         for (i = 0; i < 8; i++) {
00470             FILL_4X1_LINE(d_dst, t);
00471             FILL_4X1_LINE(d_dst + 4, t);
00472             d_dst += _d_pitch;
00473         }
00474     } else if (code == 0xFD) {
00475         tmp = *_d_src++;
00476         byte *tmp_ptr = _tableBig + tmp * 388;
00477         byte l = tmp_ptr[384];
00478         byte val = *_d_src++;
00479         int16 *tmp_ptr2 = (int16 *)tmp_ptr;
00480         while (l--) {
00481             *(d_dst + READ_LE_UINT16(tmp_ptr2)) = val;
00482             tmp_ptr2++;
00483         }
00484         l = tmp_ptr[385];
00485         val = *_d_src++;
00486         tmp_ptr2 = (int16 *)(tmp_ptr + 128);
00487         while (l--) {
00488             *(d_dst + READ_LE_UINT16(tmp_ptr2)) = val;
00489             tmp_ptr2++;
00490         }
00491     } else if (code == 0xFC) {
00492         tmp2 = _offset2;
00493         for (i = 0; i < 8; i++) {
00494             COPY_4X1_LINE(d_dst + 0, d_dst + tmp2);
00495             COPY_4X1_LINE(d_dst + 4, d_dst + tmp2 + 4);
00496             d_dst += _d_pitch;
00497         }
00498     } else {
00499         byte t = _paramPtr[code];
00500         for (i = 0; i < 8; i++) {
00501             FILL_4X1_LINE(d_dst, t);
00502             FILL_4X1_LINE(d_dst + 4, t);
00503             d_dst += _d_pitch;
00504         }
00505     }
00506 }
00507 
00508 void Blocky8::decode2(byte *dst, const byte *src, int width, int height, const byte *param_ptr) {
00509     _d_src = src;
00510     _paramPtr = param_ptr - 0xf8;
00511     int bw = (width + 7) / 8;
00512     int bh = (height + 7) / 8;
00513     int next_line = width * 7;
00514     _d_pitch = width;
00515 
00516     do {
00517         int tmp_bw = bw;
00518         do {
00519             level1(dst);
00520             dst += 8;
00521         } while (--tmp_bw);
00522         dst += next_line;
00523     } while (--bh);
00524 }
00525 #endif
00526 
00527 static void bompDecodeLine(byte *dst, const byte *src, int len) {
00528     assert(len > 0);
00529 
00530     int num;
00531     byte code, color;
00532 
00533     while (len > 0) {
00534         code = *src++;
00535         num = (code >> 1) + 1;
00536         if (num > len)
00537             num = len;
00538         len -= num;
00539         if (code & 1) {
00540             color = *src++;
00541             memset(dst, color, num);
00542         } else {
00543             memcpy(dst, src, num);
00544             src += num;
00545         }
00546         dst += num;
00547     }
00548 }
00549 
00550 Blocky8::Blocky8() {
00551     _tableBig = new byte[99328];
00552     _tableSmall = new byte[32768];
00553     memset(_tableBig, 0, 99328);
00554     memset(_tableSmall, 0, 32768);
00555     _deltaBuf = nullptr;
00556     _width = -1;
00557     _height = -1;
00558     _frameSize = 0;
00559     _offset1 = 0;
00560     _offset2 = 0;
00561     _prevSeqNb = 0;
00562     _lastTableWidth = 0;
00563     _deltaBufs[0] = nullptr;
00564     _deltaBufs[1] = nullptr;
00565     _curBuf = nullptr;
00566     _d_pitch = 0;
00567     _d_src = nullptr;
00568     _paramPtr = nullptr;
00569 }
00570 
00571 void Blocky8::init(int width, int height) {
00572     if (_width == width && _height == height)
00573         return;
00574     deinit();
00575     _width = width;
00576     _height = height;
00577     makeTablesInterpolation(4);
00578     makeTablesInterpolation(8);
00579 
00580     _frameSize = _width * _height;
00581     uint32 deltaSize = _frameSize * 3;
00582     _deltaBuf = new byte[deltaSize];
00583     memset(_deltaBuf, 0, deltaSize);
00584     _deltaBufs[0] = _deltaBuf;
00585     _deltaBufs[1] = _deltaBuf + _frameSize;
00586     _curBuf = _deltaBuf + _frameSize * 2;
00587 }
00588 
00589 void Blocky8::deinit() {
00590     _lastTableWidth = -1;
00591     if (_deltaBuf) {
00592         delete[] _deltaBuf;
00593         _deltaBuf = nullptr;
00594         _deltaBufs[0] = nullptr;
00595         _deltaBufs[1] = nullptr;
00596     }
00597 }
00598 
00599 Blocky8::~Blocky8() {
00600     deinit();
00601     if (_tableBig) {
00602         delete[] _tableBig;
00603         _tableBig = nullptr;
00604     }
00605     if (_tableSmall) {
00606         delete[] _tableSmall;
00607         _tableSmall = nullptr;
00608     }
00609 }
00610 
00611 bool Blocky8::decode(byte *dst, const byte *src) {
00612     if ((_tableBig == nullptr) || (_tableSmall == nullptr) || (_deltaBuf == nullptr))
00613         return false;
00614 
00615     _offset1 = _deltaBufs[1] - _curBuf;
00616     _offset2 = _deltaBufs[0] - _curBuf;
00617 
00618     int32 seq_nb = READ_LE_UINT16(src + 0);
00619 
00620     const byte *gfx_data = src + 26;
00621 
00622     if (seq_nb == 0) {
00623         makeTables47(_width);
00624         memset(_deltaBufs[0], src[12], _frameSize);
00625         memset(_deltaBufs[1], src[13], _frameSize);
00626         _prevSeqNb = -1;
00627     }
00628 
00629     if ((src[4] & 1) != 0) {
00630         gfx_data += 32896;
00631     }
00632 
00633     switch (src[2]) {
00634     case 0:
00635         memcpy(_curBuf, gfx_data, _frameSize);
00636         break;
00637     case 1:
00638         // Used by Outlaws, but not by any SCUMM game.
00639         error("blocky8: not implemented decode1 proc");
00640         break;
00641     case 2:
00642         if (seq_nb == _prevSeqNb + 1) {
00643             decode2(_curBuf, gfx_data, _width, _height, src + 8);
00644         }
00645         break;
00646     case 3:
00647         memcpy(_curBuf, _deltaBufs[1], _frameSize);
00648         break;
00649     case 4:
00650         memcpy(_curBuf, _deltaBufs[0], _frameSize);
00651         break;
00652     case 5:
00653         bompDecodeLine(_curBuf, gfx_data, READ_LE_UINT32(src + 14));
00654         break;
00655     }
00656 
00657     memcpy(dst, _curBuf, _frameSize);
00658 
00659     if (seq_nb == _prevSeqNb + 1) {
00660         if (src[3] == 1) {
00661             SWAP(_curBuf, _deltaBufs[1]);
00662         } else if (src[3] == 2) {
00663             SWAP(_deltaBufs[0], _deltaBufs[1]);
00664             SWAP(_deltaBufs[1], _curBuf);
00665         }
00666     }
00667     _prevSeqNb = seq_nb;
00668 
00669     return true;
00670 }
00671 
00672 } // End of namespace Grim


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