1 /*
2 * Feeble Files/ScummVM DXA decoder
3 * Copyright (c) 2007 Konstantin Shishkov
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg 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 GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * DXA Video decoder
25 */
26
33
34 #include <zlib.h>
35
36 /*
37 * Decoder context
38 */
41
43 #define DECOMP_BUF_PADDING 16
47
48 static const uint8_t
shift1[6] = { 0, 8, 8, 8, 4, 4 };
49 static const uint8_t
shift2[6] = { 0, 0, 8, 4, 0, 4 };
50
53 {
55 uint8_t *src_end =
src + srcsize;
57 int type, x, y, d, d2;
59
62
67
68 for(j = 0; j < avctx->
height; j += 4){
69 for(
i = 0;
i < avctx->
width;
i += 4){
70 if (
data > src_end ||
mv > src_end || msk > src_end)
76 case 4: // motion compensation
77 x = (*mv) >> 4; if(x & 8) x = 8 - x;
78 y = (*
mv++) & 0xF;
if(y & 8) y = 8 - y;
79 if (i < -x || avctx->
width -
i - 4 < x ||
80 j < -y || avctx->
height - j - 4 < y) {
83 }
85 case 0: // skip
86 case 5: // skip in method 12
87 for(y = 0; y < 4; y++){
91 }
92 break;
93 case 1: // masked change
94 case 10: // masked change with only half of pixels changed
95 case 11: // cases 10-15 are for method 12 only
96 case 12:
97 case 13:
98 case 14:
99 case 15:
102 msk += 2;
103 }else{
106 msk++;
107 }
108 for(y = 0; y < 4; y++){
109 for(x = 0; x < 4; x++){
112 }
115 }
116 break;
117 case 2: // fill block
118 for(y = 0; y < 4; y++){
121 }
123 break;
124 case 3: // raw block
125 for(y = 0; y < 4; y++){
129 }
130 break;
131 case 8: // subblocks - method 13 only
133 for(k = 0; k < 4; k++){
134 d = ((k & 1) << 1) + ((k & 2) *
stride);
135 d2 = ((k & 1) << 1) + ((k & 2) *
stride);
138 case 0x80: // motion compensation
139 x = (*mv) >> 4; if(x & 8) x = 8 - x;
140 y = (*
mv++) & 0xF;
if(y & 8) y = 8 - y;
141 if (
i + 2*(k & 1) < -x || avctx->
width -
i - 2*(k & 1) - 2 < x ||
142 j + (k & 2) < -y || avctx->
height - j - (k & 2) - 2 < y) {
145 }
147 case 0x00: // skip
148 tmp[d + 0 ] = tmp2[0];
149 tmp[d + 1 ] = tmp2[1];
152 break;
153 case 0x40: // fill
159 break;
160 case 0xC0: // raw
165 break;
166 }
168 }
169 break;
170 case 32: // vector quantization - 2 colors
172 msk += 2;
173 for(y = 0; y < 4; y++){
174 for(x = 0; x < 4; x++){
177 }
180 }
182 break;
183 case 33: // vector quantization - 3 or 4 colors
184 case 34:
186 msk += 4;
187 for(y = 0; y < 4; y++){
188 for(x = 0; x < 4; x++){
191 }
194 }
196 break;
197 default:
200 }
201 }
204 }
205 return 0;
206 }
207
210 {
212 uint8_t *outptr, *srcptr, *tmpptr;
213 unsigned long dsize;
214 int i, j, compr,
ret;
217
219
220 /* make the palette available on the way out */
221 if (bytestream2_peek_le32(&gb) ==
MKTAG(
'C',
'M',
'A',
'P')) {
223 for(
i = 0;
i < 256;
i++){
224 c->pal[
i] = 0xFF
U << 24 | bytestream2_get_be24(&gb);
225 }
226 }
227
231
232 outptr =
frame->data[0];
233 srcptr =
c->decomp_buf;
234 tmpptr =
c->prev->data[0];
236
237 if (bytestream2_get_le32(&gb) ==
MKTAG(
'N',
'U',
'L',
'L'))
238 compr = -1;
239 else
240 compr = bytestream2_get_byte(&gb);
241
243 if (compr != 4 && compr != -1) {
249 }
251 }
252
255
256 switch(compr){
257 case -1:
260 if (
c->prev->data[0])
262 else{ // Should happen only when first frame is 'NULL'
266 }
267 break;
268 case 2:
269 case 4:
272 for (j = 0; j < avctx->
height; j++) {
273 memcpy(outptr, srcptr, avctx->
width);
275 srcptr += avctx->
width;
276 }
277 break;
278 case 3:
279 case 5:
280 if (!tmpptr) {
284 }
287 for (j = 0; j < avctx->
height; j++) {
288 if(tmpptr){
290 outptr[
i] = srcptr[
i] ^ tmpptr[
i];
292 }else
293 memcpy(outptr, srcptr, avctx->
width);
295 srcptr += avctx->
width;
296 }
297 break;
298 case 12: // ScummVM coding
299 case 13:
302 if (!
c->prev->data[0]) {
305 }
307 break;
308 default:
311 }
312
315
316 *got_frame = 1;
317
318 /* always report that the buffer was completely consumed */
320 }
321
323 {
325
329 }
330
334
336
339 if (!
c->decomp_buf) {
342 }
343
344 return 0;
345 }
346
348 {
350
353
354 return 0;
355 }
356
368 };