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

vima.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 
00025 namespace Grim {
00026 
00027 static int16 imcTable1[] = {
00028       7,     8,     9,    10,    11,    12,    13,    14,    16,    17,
00029      19,    21,    23,    25,    28,    31,    34,    37,    41,    45,
00030      50,    55,    60,    66,    73,    80,    88,    97,   107,   118,
00031     130,   143,   157,   173,   190,   209,   230,   253,   279,   307,
00032     337,   371,   408,   449,   494,   544,   598,   658,   724,   796,
00033     876,   963,  1060,  1166,  1282,  1411,  1552,  1707,  1878,  2066,
00034     2272,  2499,  2749,  3024,  3327,  3660,  4026,  4428,  4871,  5358,
00035     5894,  6484,  7132,  7845,  8630,  9493, 10442, 11487, 12635, 13899,
00036     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
00037 };
00038 
00039 static int8 imcTable2[] = {
00040     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00041     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00042     4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00043     5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00044     6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
00045 };
00046 
00047 static int8 imcOtherTable1[] = {
00048     -1, 4, -1, 4
00049 };
00050 
00051 static int8 imcOtherTable2[] = {
00052     -1, -1, 2, 6, -1, -1, 2, 6
00053 };
00054 
00055 static int8 imcOtherTable3[] = {
00056     -1, -1, -1, -1, 1, 2, 4, 6,
00057     -1, -1, -1, -1, 1, 2, 4, 6
00058 };
00059 
00060 static int8 imcOtherTable4[] = {
00061     -1, -1, -1, -1, -1, -1, -1, -1,
00062     1, 1, 1, 2, 2, 4, 5, 6,
00063     -1, -1, -1, -1, -1, -1, -1, -1,
00064     1, 1, 1, 2, 2, 4, 5, 6
00065 };
00066 
00067 static int8 imcOtherTable5[] = {
00068     -1, -1, -1, -1, -1, -1, -1, -1,
00069     -1, -1, -1, -1, -1, -1, -1, -1,
00070      1, 1, 1, 1, 1, 2, 2, 2,
00071      2, 4, 4, 4, 5, 5, 6, 6,
00072     -1, -1, -1, -1, -1, -1, -1, -1,
00073     -1, -1, -1, -1, -1, -1, -1, -1,
00074      1, 1, 1, 1, 1, 2, 2, 2,
00075      2, 4, 4, 4, 5, 5, 6, 6
00076 };
00077 
00078 static int8 imcOtherTable6[] = {
00079     -1, -1, -1, -1, -1, -1, -1, -1,
00080     -1, -1, -1, -1, -1, -1, -1, -1,
00081     -1, -1, -1, -1, -1, -1, -1, -1,
00082     -1, -1, -1, -1, -1, -1, -1, -1,
00083      1, 1, 1, 1, 1, 1, 1, 1,
00084      1, 1, 2, 2, 2, 2, 2, 2,
00085      2, 2, 4, 4, 4, 4, 4, 4,
00086      5, 5, 5, 5, 6, 6, 6, 6,
00087     -1, -1, -1, -1, -1, -1, -1, -1,
00088     -1, -1, -1, -1, -1, -1, -1, -1,
00089     -1, -1, -1, -1, -1, -1, -1, -1,
00090     -1, -1, -1, -1, -1, -1, -1, -1,
00091      1, 1, 1, 1, 1, 1, 1, 1,
00092      1, 1, 2, 2, 2, 2, 2, 2,
00093      2, 2, 4, 4, 4, 4, 4, 4,
00094      5, 5, 5, 5, 6, 6, 6, 6
00095 };
00096 
00097 static int8 *offsets[] = {
00098     imcOtherTable1, imcOtherTable2, imcOtherTable3,
00099     imcOtherTable4, imcOtherTable5, imcOtherTable6
00100 };
00101 
00102 void vimaInit(uint16 *destTable) {
00103     int destTableStartPos, incer;
00104 
00105     for (destTableStartPos = 0, incer = 0; destTableStartPos < 64; destTableStartPos++, incer++) {
00106         unsigned int destTablePos, imcTable1Pos;
00107         for (imcTable1Pos = 0, destTablePos = destTableStartPos;
00108                 imcTable1Pos < sizeof(imcTable1) / sizeof(imcTable1[0]); imcTable1Pos++, destTablePos += 64) {
00109             int put = 0, count, tableValue;
00110             for (count = 32, tableValue = imcTable1[imcTable1Pos]; count != 0; count >>= 1, tableValue >>= 1) {
00111                 if (incer & count) {
00112                     put += tableValue;
00113                 }
00114             }
00115             destTable[destTablePos] = put;
00116         }
00117     }
00118 }
00119 
00120 void decompressVima(const byte *src, int16 *dest, int destLen, uint16 *destTable) {
00121     int numChannels = 1;
00122     byte sBytes[2];
00123     int16 sWords[2];
00124 
00125     sBytes[0] = *src++;
00126     if (sBytes[0] & 0x80) {
00127         sBytes[0] = ~sBytes[0];
00128         numChannels = 2;
00129     }
00130     sWords[0] = READ_BE_UINT16(src);
00131     src += 2;
00132     if (numChannels > 1) {
00133         sBytes[1] = *src++;
00134         sWords[1] = READ_BE_UINT16(src);
00135         src += 2;
00136     }
00137 
00138     int numSamples = destLen / (numChannels * 2);
00139     int bits = READ_BE_UINT16(src);
00140     int bitPtr = 0;
00141     src += 2;
00142 
00143     for (int channel = 0; channel < numChannels; channel++) {
00144         int16 *destPos = dest + channel;
00145         int currTablePos = sBytes[channel];
00146         int outputWord = sWords[channel];
00147 
00148         for (int sample = 0; sample < numSamples; sample++) {
00149             int numBits = imcTable2[currTablePos];
00150             bitPtr += numBits;
00151             int highBit = 1 << (numBits - 1);
00152             int lowBits = highBit - 1;
00153             int val = (bits >> (16 - bitPtr)) & (highBit | lowBits);
00154 
00155             if (bitPtr > 7) {
00156                 bits = ((bits & 0xff) << 8) | *src++;
00157                 bitPtr -= 8;
00158             }
00159 
00160             if (val & highBit)
00161                 val ^= highBit;
00162             else
00163                 highBit = 0;
00164 
00165             if (val == lowBits) {
00166                 outputWord = ((int16)(bits << bitPtr) & 0xffffff00);
00167                 bits = ((bits & 0xff) << 8) | *src++;
00168                 outputWord |= ((bits >> (8 - bitPtr)) & 0xff);
00169                 bits = ((bits & 0xff) << 8) | *src++;
00170             } else {
00171                 int index = (val << (7 - numBits)) | (currTablePos << 6);
00172                 int delta = destTable[index];
00173 
00174                 if (val)
00175                     delta += (imcTable1[currTablePos] >> (numBits - 1));
00176                 if (highBit)
00177                     delta = -delta;
00178 
00179                 outputWord += delta;
00180                 if (outputWord < -0x8000)
00181                     outputWord = -0x8000;
00182                 else if (outputWord > 0x7fff)
00183                     outputWord = 0x7fff;
00184             }
00185 
00186             WRITE_BE_UINT16(destPos, outputWord);
00187             destPos += numChannels;
00188 
00189             currTablePos += offsets[numBits - 2][val];
00190 
00191             if (currTablePos < 0)
00192                 currTablePos = 0;
00193             else if (currTablePos > 88)
00194                 currTablePos = 88;
00195         }
00196     }
00197 }
00198 
00199 } // end of namespace Grim


Generated on Sat Jul 13 2019 05:01:07 for ResidualVM by doxygen 1.7.1
curved edge   curved edge