1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23
24 #include "common/endian.h"
25 #include "common/textconsole.h"
26 #include "common/util.h"
27 #include "scumm/bomp.h"
28 #include "scumm/smush/codec37.h"
29
30 namespace Scumm {
31
Codec37Decoder(int width,int height)32 Codec37Decoder::Codec37Decoder(int width, int height) {
33 _width = width;
34 _height = height;
35 _frameSize = _width * _height;
36 _deltaSize = _frameSize * 3 + 0x13600;
37 _deltaBuf = (byte *)calloc(_deltaSize, sizeof(byte));
38 if (_deltaBuf == 0)
39 error("unable to allocate decoder buffer");
40 _deltaBufs[0] = _deltaBuf + 0x4D80;
41 _deltaBufs[1] = _deltaBuf + 0xE880 + _frameSize;
42 _offsetTable = new int16[255];
43 if (_offsetTable == 0)
44 error("unable to allocate decoder offset table");
45 _curtable = 0;
46 _prevSeqNb = 0;
47 _tableLastPitch = -1;
48 _tableLastIndex = -1;
49 }
50
~Codec37Decoder()51 Codec37Decoder::~Codec37Decoder() {
52 if (_offsetTable) {
53 delete[] _offsetTable;
54 _offsetTable = 0;
55 _tableLastPitch = -1;
56 _tableLastIndex = -1;
57 }
58 if (_deltaBuf) {
59 free(_deltaBuf);
60 _deltaSize = 0;
61 _deltaBuf = 0;
62 _deltaBufs[0] = 0;
63 _deltaBufs[1] = 0;
64 }
65 }
66
maketable(int pitch,int index)67 void Codec37Decoder::maketable(int pitch, int index) {
68 static const int8 maketable_bytes[] = {
69 0, 0, 1, 0, 2, 0, 3, 0, 5, 0,
70 8, 0, 13, 0, 21, 0, -1, 0, -2, 0,
71 -3, 0, -5, 0, -8, 0, -13, 0, -17, 0,
72 -21, 0, 0, 1, 1, 1, 2, 1, 3, 1,
73 5, 1, 8, 1, 13, 1, 21, 1, -1, 1,
74 -2, 1, -3, 1, -5, 1, -8, 1, -13, 1,
75 -17, 1, -21, 1, 0, 2, 1, 2, 2, 2,
76 3, 2, 5, 2, 8, 2, 13, 2, 21, 2,
77 -1, 2, -2, 2, -3, 2, -5, 2, -8, 2,
78 -13, 2, -17, 2, -21, 2, 0, 3, 1, 3,
79 2, 3, 3, 3, 5, 3, 8, 3, 13, 3,
80 21, 3, -1, 3, -2, 3, -3, 3, -5, 3,
81 -8, 3, -13, 3, -17, 3, -21, 3, 0, 5,
82 1, 5, 2, 5, 3, 5, 5, 5, 8, 5,
83 13, 5, 21, 5, -1, 5, -2, 5, -3, 5,
84 -5, 5, -8, 5, -13, 5, -17, 5, -21, 5,
85 0, 8, 1, 8, 2, 8, 3, 8, 5, 8,
86 8, 8, 13, 8, 21, 8, -1, 8, -2, 8,
87 -3, 8, -5, 8, -8, 8, -13, 8, -17, 8,
88 -21, 8, 0, 13, 1, 13, 2, 13, 3, 13,
89 5, 13, 8, 13, 13, 13, 21, 13, -1, 13,
90 -2, 13, -3, 13, -5, 13, -8, 13, -13, 13,
91 -17, 13, -21, 13, 0, 21, 1, 21, 2, 21,
92 3, 21, 5, 21, 8, 21, 13, 21, 21, 21,
93 -1, 21, -2, 21, -3, 21, -5, 21, -8, 21,
94 -13, 21, -17, 21, -21, 21, 0, -1, 1, -1,
95 2, -1, 3, -1, 5, -1, 8, -1, 13, -1,
96 21, -1, -1, -1, -2, -1, -3, -1, -5, -1,
97 -8, -1, -13, -1, -17, -1, -21, -1, 0, -2,
98 1, -2, 2, -2, 3, -2, 5, -2, 8, -2,
99 13, -2, 21, -2, -1, -2, -2, -2, -3, -2,
100 -5, -2, -8, -2, -13, -2, -17, -2, -21, -2,
101 0, -3, 1, -3, 2, -3, 3, -3, 5, -3,
102 8, -3, 13, -3, 21, -3, -1, -3, -2, -3,
103 -3, -3, -5, -3, -8, -3, -13, -3, -17, -3,
104 -21, -3, 0, -5, 1, -5, 2, -5, 3, -5,
105 5, -5, 8, -5, 13, -5, 21, -5, -1, -5,
106 -2, -5, -3, -5, -5, -5, -8, -5, -13, -5,
107 -17, -5, -21, -5, 0, -8, 1, -8, 2, -8,
108 3, -8, 5, -8, 8, -8, 13, -8, 21, -8,
109 -1, -8, -2, -8, -3, -8, -5, -8, -8, -8,
110 -13, -8, -17, -8, -21, -8, 0, -13, 1, -13,
111 2, -13, 3, -13, 5, -13, 8, -13, 13, -13,
112 21, -13, -1, -13, -2, -13, -3, -13, -5, -13,
113 -8, -13, -13, -13, -17, -13, -21, -13, 0, -17,
114 1, -17, 2, -17, 3, -17, 5, -17, 8, -17,
115 13, -17, 21, -17, -1, -17, -2, -17, -3, -17,
116 -5, -17, -8, -17, -13, -17, -17, -17, -21, -17,
117 0, -21, 1, -21, 2, -21, 3, -21, 5, -21,
118 8, -21, 13, -21, 21, -21, -1, -21, -2, -21,
119 -3, -21, -5, -21, -8, -21, -13, -21, -17, -21,
120 0, 0, -8, -29, 8, -29, -18, -25, 17, -25,
121 0, -23, -6, -22, 6, -22, -13, -19, 12, -19,
122 0, -18, 25, -18, -25, -17, -5, -17, 5, -17,
123 -10, -15, 10, -15, 0, -14, -4, -13, 4, -13,
124 19, -13, -19, -12, -8, -11, -2, -11, 0, -11,
125 2, -11, 8, -11, -15, -10, -4, -10, 4, -10,
126 15, -10, -6, -9, -1, -9, 1, -9, 6, -9,
127 -29, -8, -11, -8, -8, -8, -3, -8, 3, -8,
128 8, -8, 11, -8, 29, -8, -5, -7, -2, -7,
129 0, -7, 2, -7, 5, -7, -22, -6, -9, -6,
130 -6, -6, -3, -6, -1, -6, 1, -6, 3, -6,
131 6, -6, 9, -6, 22, -6, -17, -5, -7, -5,
132 -4, -5, -2, -5, 0, -5, 2, -5, 4, -5,
133 7, -5, 17, -5, -13, -4, -10, -4, -5, -4,
134 -3, -4, -1, -4, 0, -4, 1, -4, 3, -4,
135 5, -4, 10, -4, 13, -4, -8, -3, -6, -3,
136 -4, -3, -3, -3, -2, -3, -1, -3, 0, -3,
137 1, -3, 2, -3, 4, -3, 6, -3, 8, -3,
138 -11, -2, -7, -2, -5, -2, -3, -2, -2, -2,
139 -1, -2, 0, -2, 1, -2, 2, -2, 3, -2,
140 5, -2, 7, -2, 11, -2, -9, -1, -6, -1,
141 -4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
142 1, -1, 2, -1, 3, -1, 4, -1, 6, -1,
143 9, -1, -31, 0, -23, 0, -18, 0, -14, 0,
144 -11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
145 -2, 0, -1, 0, 0, -31, 1, 0, 2, 0,
146 3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
147 14, 0, 18, 0, 23, 0, 31, 0, -9, 1,
148 -6, 1, -4, 1, -3, 1, -2, 1, -1, 1,
149 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
150 6, 1, 9, 1, -11, 2, -7, 2, -5, 2,
151 -3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
152 2, 2, 3, 2, 5, 2, 7, 2, 11, 2,
153 -8, 3, -6, 3, -4, 3, -2, 3, -1, 3,
154 0, 3, 1, 3, 2, 3, 3, 3, 4, 3,
155 6, 3, 8, 3, -13, 4, -10, 4, -5, 4,
156 -3, 4, -1, 4, 0, 4, 1, 4, 3, 4,
157 5, 4, 10, 4, 13, 4, -17, 5, -7, 5,
158 -4, 5, -2, 5, 0, 5, 2, 5, 4, 5,
159 7, 5, 17, 5, -22, 6, -9, 6, -6, 6,
160 -3, 6, -1, 6, 1, 6, 3, 6, 6, 6,
161 9, 6, 22, 6, -5, 7, -2, 7, 0, 7,
162 2, 7, 5, 7, -29, 8, -11, 8, -8, 8,
163 -3, 8, 3, 8, 8, 8, 11, 8, 29, 8,
164 -6, 9, -1, 9, 1, 9, 6, 9, -15, 10,
165 -4, 10, 4, 10, 15, 10, -8, 11, -2, 11,
166 0, 11, 2, 11, 8, 11, 19, 12, -19, 13,
167 -4, 13, 4, 13, 0, 14, -10, 15, 10, 15,
168 -5, 17, 5, 17, 25, 17, -25, 18, 0, 18,
169 -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
170 -17, 25, 18, 25, -8, 29, 8, 29, 0, 31,
171 0, 0, -6, -22, 6, -22, -13, -19, 12, -19,
172 0, -18, -5, -17, 5, -17, -10, -15, 10, -15,
173 0, -14, -4, -13, 4, -13, 19, -13, -19, -12,
174 -8, -11, -2, -11, 0, -11, 2, -11, 8, -11,
175 -15, -10, -4, -10, 4, -10, 15, -10, -6, -9,
176 -1, -9, 1, -9, 6, -9, -11, -8, -8, -8,
177 -3, -8, 0, -8, 3, -8, 8, -8, 11, -8,
178 -5, -7, -2, -7, 0, -7, 2, -7, 5, -7,
179 -22, -6, -9, -6, -6, -6, -3, -6, -1, -6,
180 1, -6, 3, -6, 6, -6, 9, -6, 22, -6,
181 -17, -5, -7, -5, -4, -5, -2, -5, -1, -5,
182 0, -5, 1, -5, 2, -5, 4, -5, 7, -5,
183 17, -5, -13, -4, -10, -4, -5, -4, -3, -4,
184 -2, -4, -1, -4, 0, -4, 1, -4, 2, -4,
185 3, -4, 5, -4, 10, -4, 13, -4, -8, -3,
186 -6, -3, -4, -3, -3, -3, -2, -3, -1, -3,
187 0, -3, 1, -3, 2, -3, 3, -3, 4, -3,
188 6, -3, 8, -3, -11, -2, -7, -2, -5, -2,
189 -4, -2, -3, -2, -2, -2, -1, -2, 0, -2,
190 1, -2, 2, -2, 3, -2, 4, -2, 5, -2,
191 7, -2, 11, -2, -9, -1, -6, -1, -5, -1,
192 -4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
193 1, -1, 2, -1, 3, -1, 4, -1, 5, -1,
194 6, -1, 9, -1, -23, 0, -18, 0, -14, 0,
195 -11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
196 -2, 0, -1, 0, 0, -23, 1, 0, 2, 0,
197 3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
198 14, 0, 18, 0, 23, 0, -9, 1, -6, 1,
199 -5, 1, -4, 1, -3, 1, -2, 1, -1, 1,
200 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
201 5, 1, 6, 1, 9, 1, -11, 2, -7, 2,
202 -5, 2, -4, 2, -3, 2, -2, 2, -1, 2,
203 0, 2, 1, 2, 2, 2, 3, 2, 4, 2,
204 5, 2, 7, 2, 11, 2, -8, 3, -6, 3,
205 -4, 3, -3, 3, -2, 3, -1, 3, 0, 3,
206 1, 3, 2, 3, 3, 3, 4, 3, 6, 3,
207 8, 3, -13, 4, -10, 4, -5, 4, -3, 4,
208 -2, 4, -1, 4, 0, 4, 1, 4, 2, 4,
209 3, 4, 5, 4, 10, 4, 13, 4, -17, 5,
210 -7, 5, -4, 5, -2, 5, -1, 5, 0, 5,
211 1, 5, 2, 5, 4, 5, 7, 5, 17, 5,
212 -22, 6, -9, 6, -6, 6, -3, 6, -1, 6,
213 1, 6, 3, 6, 6, 6, 9, 6, 22, 6,
214 -5, 7, -2, 7, 0, 7, 2, 7, 5, 7,
215 -11, 8, -8, 8, -3, 8, 0, 8, 3, 8,
216 8, 8, 11, 8, -6, 9, -1, 9, 1, 9,
217 6, 9, -15, 10, -4, 10, 4, 10, 15, 10,
218 -8, 11, -2, 11, 0, 11, 2, 11, 8, 11,
219 19, 12, -19, 13, -4, 13, 4, 13, 0, 14,
220 -10, 15, 10, 15, -5, 17, 5, 17, 0, 18,
221 -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
222 };
223
224 if (_tableLastPitch == pitch && _tableLastIndex == index)
225 return;
226
227 _tableLastPitch = pitch;
228 _tableLastIndex = index;
229 index *= 255;
230 assert(index + 254 < (int32)(sizeof(maketable_bytes) / 2));
231
232 for (int32 i = 0; i < 255; i++) {
233 int32 j = (i + index) * 2;
234 _offsetTable[i] = maketable_bytes[j + 1] * pitch + maketable_bytes[j];
235 }
236 }
237
238 #if defined(SCUMM_NEED_ALIGNMENT)
239
240 #define DECLARE_LITERAL_TEMP(v) \
241 byte v
242
243 #define READ_LITERAL_PIXEL(src, v) \
244 v = *src++
245
246 #define WRITE_4X1_LINE(dst, v) \
247 do { \
248 int j; \
249 for (j=0; j<4; j++) \
250 (dst)[j] = v; \
251 } while (0)
252
253 #define COPY_4X1_LINE(dst, src) \
254 do { \
255 int j; \
256 for (j=0; j<4; j++) \
257 (dst)[j] = (src)[j]; \
258 } while (0)
259
260 #else /* SCUMM_NEED_ALIGNMENT */
261
262 #define DECLARE_LITERAL_TEMP(v) \
263 uint32 v
264
265 #define READ_LITERAL_PIXEL(src, v) \
266 do { \
267 v = *src++; \
268 v += (v << 8) + (v << 16) + (v << 24); \
269 } while (0)
270
271 #define WRITE_4X1_LINE(dst, v) \
272 *(uint32 *)(dst) = v
273
274 #define COPY_4X1_LINE(dst, src) \
275 *(uint32 *)(dst) = *(const uint32 *)(src)
276
277 #endif /* SCUMM_NEED_ALIGNMENT */
278
279 /* Fill a 4x4 pixel block with a literal pixel value */
280
281 #define LITERAL_4X4(src, dst, pitch) \
282 do { \
283 int x; \
284 DECLARE_LITERAL_TEMP(t); \
285 READ_LITERAL_PIXEL(src, t); \
286 for (x=0; x<4; x++) { \
287 WRITE_4X1_LINE(dst + pitch * x, t); \
288 } \
289 dst += 4; \
290 } while (0)
291
292 /* Fill four 4x1 pixel blocks with literal pixel values */
293
294 #define LITERAL_4X1(src, dst, pitch) \
295 do { \
296 int x; \
297 DECLARE_LITERAL_TEMP(t); \
298 for (x=0; x<4; x++) { \
299 READ_LITERAL_PIXEL(src, t); \
300 WRITE_4X1_LINE(dst + pitch * x, t); \
301 } \
302 dst += 4; \
303 } while (0)
304
305 /* Fill sixteen 1x1 pixel blocks with literal pixel values */
306
307 #define LITERAL_1X1(src, dst, pitch) \
308 do { \
309 int x; \
310 for (x=0; x<4; x++) { \
311 COPY_4X1_LINE(dst + pitch * x, src); \
312 src += 4; \
313 } \
314 dst += 4; \
315 } while (0)
316
317 /* Copy a 4x4 pixel block from a different place in the framebuffer */
318
319 #define COPY_4X4(dst2, dst, pitch) \
320 do { \
321 int x; \
322 for (x=0; x<4; x++) { \
323 COPY_4X1_LINE(dst + pitch * x, dst2 + pitch * x); \
324 } \
325 dst += 4; \
326 } while (0)
327
proc1(byte * dst,const byte * src,int32 next_offs,int bw,int bh,int pitch,int16 * offset_table)328 void Codec37Decoder::proc1(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
329 uint8 code;
330 bool filling, skipCode;
331 int32 len;
332 int i, p;
333 uint32 pitches[16];
334
335 i = bw;
336 for (p = 0; p < 16; ++p) {
337 pitches[p] = (p >> 2) * pitch + (p & 0x3);
338 }
339 code = 0;
340 filling = false;
341 len = -1;
342 while (1) {
343 if (len < 0) {
344 filling = (*src & 1) == 1;
345 len = *src++ >> 1;
346 skipCode = false;
347 } else {
348 skipCode = true;
349 }
350 if (!filling || !skipCode) {
351 code = *src++;
352 if (code == 0xFF) {
353 --len;
354 for (p = 0; p < 0x10; ++p) {
355 if (len < 0) {
356 filling = (*src & 1) == 1;
357 len = *src++ >> 1;
358 if (filling) {
359 code = *src++;
360 }
361 }
362 if (filling) {
363 *(dst + pitches[p]) = code;
364 } else {
365 *(dst + pitches[p]) = *src++;
366 }
367 --len;
368 }
369 dst += 4;
370 --i;
371 if (i == 0) {
372 dst += pitch * 3;
373 --bh;
374 if (bh == 0) return;
375 i = bw;
376 }
377 continue;
378 }
379 }
380 byte *dst2 = dst + offset_table[code] + next_offs;
381 COPY_4X4(dst2, dst, pitch);
382 --i;
383 if (i == 0) {
384 dst += pitch * 3;
385 --bh;
386 if (bh == 0) return;
387 i = bw;
388 }
389 --len;
390 }
391 }
392
proc3WithFDFE(byte * dst,const byte * src,int32 next_offs,int bw,int bh,int pitch,int16 * offset_table)393 void Codec37Decoder::proc3WithFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
394 do {
395 int32 i = bw;
396 do {
397 int32 code = *src++;
398 if (code == 0xFD) {
399 LITERAL_4X4(src, dst, pitch);
400 } else if (code == 0xFE) {
401 LITERAL_4X1(src, dst, pitch);
402 } else if (code == 0xFF) {
403 LITERAL_1X1(src, dst, pitch);
404 } else {
405 byte *dst2 = dst + _offsetTable[code] + next_offs;
406 COPY_4X4(dst2, dst, pitch);
407 }
408 } while (--i);
409 dst += pitch * 3;
410 } while (--bh);
411 }
412
proc3WithoutFDFE(byte * dst,const byte * src,int32 next_offs,int bw,int bh,int pitch,int16 * offset_table)413 void Codec37Decoder::proc3WithoutFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
414 do {
415 int32 i = bw;
416 do {
417 int32 code = *src++;
418 if (code == 0xFF) {
419 LITERAL_1X1(src, dst, pitch);
420 } else {
421 byte *dst2 = dst + _offsetTable[code] + next_offs;
422 COPY_4X4(dst2, dst, pitch);
423 }
424 } while (--i);
425 dst += pitch * 3;
426 } while (--bh);
427 }
428
proc4WithFDFE(byte * dst,const byte * src,int32 next_offs,int bw,int bh,int pitch,int16 * offset_table)429 void Codec37Decoder::proc4WithFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
430 do {
431 int32 i = bw;
432 do {
433 int32 code = *src++;
434 if (code == 0xFD) {
435 LITERAL_4X4(src, dst, pitch);
436 } else if (code == 0xFE) {
437 LITERAL_4X1(src, dst, pitch);
438 } else if (code == 0xFF) {
439 LITERAL_1X1(src, dst, pitch);
440 } else if (code == 0x00) {
441 int32 length = *src++ + 1;
442 for (int32 l = 0; l < length; l++) {
443 byte *dst2 = dst + next_offs;
444 COPY_4X4(dst2, dst, pitch);
445 i--;
446 if (i == 0) {
447 dst += pitch * 3;
448 bh--;
449 i = bw;
450 }
451 }
452 if (bh == 0) {
453 return;
454 }
455 i++;
456 } else {
457 byte *dst2 = dst + _offsetTable[code] + next_offs;
458 COPY_4X4(dst2, dst, pitch);
459 }
460 } while (--i);
461 dst += pitch * 3;
462 } while (--bh);
463 }
464
proc4WithoutFDFE(byte * dst,const byte * src,int32 next_offs,int bw,int bh,int pitch,int16 * offset_table)465 void Codec37Decoder::proc4WithoutFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
466 do {
467 int32 i = bw;
468 do {
469 int32 code = *src++;
470 if (code == 0xFF) {
471 LITERAL_1X1(src, dst, pitch);
472 } else if (code == 0x00) {
473 int32 length = *src++ + 1;
474 for (int32 l = 0; l < length; l++) {
475 byte *dst2 = dst + next_offs;
476 COPY_4X4(dst2, dst, pitch);
477 i--;
478 if (i == 0) {
479 dst += pitch * 3;
480 bh--;
481 i = bw;
482 }
483 }
484 if (bh == 0) {
485 return;
486 }
487 i++;
488 } else {
489 byte *dst2 = dst + _offsetTable[code] + next_offs;
490 COPY_4X4(dst2, dst, pitch);
491 }
492 } while (--i);
493 dst += pitch * 3;
494 } while (--bh);
495 }
496
decode(byte * dst,const byte * src)497 void Codec37Decoder::decode(byte *dst, const byte *src) {
498 int32 bw = (_width + 3) / 4, bh = (_height + 3) / 4;
499 int32 pitch = bw * 4;
500
501 int16 seq_nb = READ_LE_UINT16(src + 2);
502 int32 decoded_size = READ_LE_UINT32(src + 4);
503 byte mask_flags = src[12];
504 maketable(pitch, src[1]);
505 int32 tmp;
506
507 switch (src[0]) {
508 case 0:
509 if ((_deltaBufs[_curtable] - _deltaBuf) > 0) {
510 memset(_deltaBuf, 0, _deltaBufs[_curtable] - _deltaBuf);
511 }
512 tmp = (_deltaBuf + _deltaSize) - _deltaBufs[_curtable] - decoded_size;
513 if (tmp > 0) {
514 memset(_deltaBufs[_curtable] + decoded_size, 0, tmp);
515 }
516 memcpy(_deltaBufs[_curtable], src + 16, decoded_size);
517 break;
518 case 1:
519 if ((seq_nb & 1) || !(mask_flags & 1)) {
520 _curtable ^= 1;
521 }
522 proc1(_deltaBufs[_curtable], src + 16, _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable],
523 bw, bh, pitch, _offsetTable);
524 break;
525 case 2:
526 bompDecodeLine(_deltaBufs[_curtable], src + 16, decoded_size);
527 if ((_deltaBufs[_curtable] - _deltaBuf) > 0) {
528 memset(_deltaBuf, 0, _deltaBufs[_curtable] - _deltaBuf);
529 }
530 tmp = (_deltaBuf + _deltaSize) - _deltaBufs[_curtable] - decoded_size;
531 if (tmp > 0) {
532 memset(_deltaBufs[_curtable] + decoded_size, 0, tmp);
533 }
534 break;
535 case 3:
536 if ((seq_nb & 1) || !(mask_flags & 1)) {
537 _curtable ^= 1;
538 }
539
540 if ((mask_flags & 4) != 0) {
541 proc3WithFDFE(_deltaBufs[_curtable], src + 16,
542 _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh,
543 pitch, _offsetTable);
544 } else {
545 proc3WithoutFDFE(_deltaBufs[_curtable], src + 16,
546 _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh,
547 pitch, _offsetTable);
548 }
549 break;
550 case 4:
551 if ((seq_nb & 1) || !(mask_flags & 1)) {
552 _curtable ^= 1;
553 }
554
555 if ((mask_flags & 4) != 0) {
556 proc4WithFDFE(_deltaBufs[_curtable], src + 16,
557 _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh,
558 pitch, _offsetTable);
559 } else {
560 proc4WithoutFDFE(_deltaBufs[_curtable], src + 16,
561 _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh,
562 pitch, _offsetTable);
563 }
564 break;
565 default:
566 break;
567 }
568 _prevSeqNb = seq_nb;
569
570 memcpy(dst, _deltaBufs[_curtable], _frameSize);
571 }
572
573 } // End of namespace Scumm
574