1 /*
2 * Packed Animation File video decoder
3 * Copyright (c) 2012 Paul B Mahol
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
23
28
29
31 { 0, 0, 0, 0, 0, 0, 0, 0 },
32 { 2, 0, 0, 0, 0, 0, 0, 0 },
33 { 5, 7, 0, 0, 0, 0, 0, 0 },
34 { 5, 0, 0, 0, 0, 0, 0, 0 },
35 { 6, 0, 0, 0, 0, 0, 0, 0 },
36 { 5, 7, 5, 7, 0, 0, 0, 0 },
37 { 5, 7, 5, 0, 0, 0, 0, 0 },
38 { 5, 7, 6, 0, 0, 0, 0, 0 },
39 { 5, 5, 0, 0, 0, 0, 0, 0 },
40 { 3, 0, 0, 0, 0, 0, 0, 0 },
41 { 6, 6, 0, 0, 0, 0, 0, 0 },
42 { 2, 4, 0, 0, 0, 0, 0, 0 },
43 { 2, 4, 5, 7, 0, 0, 0, 0 },
44 { 2, 4, 5, 0, 0, 0, 0, 0 },
45 { 2, 4, 6, 0, 0, 0, 0, 0 },
46 { 2, 4, 5, 7, 5, 7, 0, 0 },
47 };
48
52
55
60
63
65 {
67 int i;
68
70
71 for (i = 0; i < 4; i++)
73
74 return 0;
75 }
76
78 {
80 int i;
81
84
87 "width %d and height %d must be multiplie of 4.\n",
90 }
91
93
97
100 for (i = 0; i < 4; i++) {
105 }
106 }
107
108 return 0;
109 }
110
112 {
113 int i;
114
115 for (i = 0; i < 4; i++) {
118 }
119 }
120
122 {
123 int i;
124
125 for (i = 0; i < 4; i++) {
126 if (mask & (1 << 7 - i))
128 if (mask & (1 << 3 - i))
129 dst[width + i] =
color;
130 }
131 }
132
134 {
135 int i;
136
137 for (i = 0; i < 4; i++) {
138 if (mask & (1 << 7 - i))
139 dst[i] = src[i];
140 if (mask & (1 << 3 - i))
141 dst[width + i] = src[width + i];
142 }
143 }
144
148 {
149 int val = bytestream2_get_be16(&c->
gb);
150 int page = val >> 14;
151 int x = (val & 0x7F);
152 int y = ((val >> 7) & 0x7F);
153
154 *p = c->
frame[page] + x * 2 + y * 2 * c->
width;
156 }
157
159 {
160 uint32_t opcode_size,
offset;
164
165 i = bytestream2_get_byte(&c->
gb);
166 if (i) {
167 if (code & 0x10) {
169
171 if (align)
173 }
174 do {
176 val = bytestream2_get_be16(&c->
gb);
177 page = val >> 14;
178 x = (val & 0x7F) * 2;
179 y = ((val >> 7) & 0x7F) * 2;
182 offset = (x & 0x7F) * 2;
183 j = bytestream2_get_le16(&c->
gb) +
offset;
184 do {
185 offset++;
186 if (dst + 3 * c->
width + 4 > dend)
189 if ((offset & 0x3F) == 0)
191 dst += 4;
192 } while (offset < j);
193 } while (--i);
194 }
195
198 do {
200 if ((src + 3 * c->
width + 4 > send) ||
201 (dst + 3 * c->
width + 4 > dend))
204 i++;
205 if ((i & 0x3F) == 0)
207 dst += 4;
208 } while (i < c->video_size / 16);
209
210 opcode_size = bytestream2_get_le16(&c->
gb);
212
215
218
220
221 for (i = 0; i < c->
height; i += 4, dst += c->
width * 3)
222 for (j = 0; j < c->
width; j += 4, dst += 4) {
223 int opcode, k = 0;
224 if (op > opcode_size)
226 if (j & 4) {
227 opcode = opcodes[
op] & 15;
228 op++;
229 } else {
230 opcode = opcodes[
op] >> 4;
231 }
232
234 offset = c->
width * 2;
236
237 switch (code) {
238 case 2:
239 offset = 0;
240 case 3:
241 color = bytestream2_get_byte(&c->
gb);
242 case 4:
243 mask = bytestream2_get_byte(&c->
gb);
245 break;
246 case 5:
247 offset = 0;
248 case 6:
250 case 7:
251 if (src + offset + c->
width + 4 > send)
253 mask = bytestream2_get_byte(&c->
gb);
255 break;
256 }
257 }
258 }
259
260 return 0;
261 }
262
265 {
269
272
274
275 code = bytestream2_get_byte(&c->
gb);
276 if (code & 0x20) { // frame is keyframe
277 for (i = 0; i < 4; i++)
279
284 } else {
287 }
288
289 if (code & 0x40) { // palette update
292
293 index = bytestream2_get_byte(&c->
gb);
294 count = bytestream2_get_byte(&c->
gb) + 1;
295
296 if (index +
count > 256)
300
302 for (i = 0; i <
count; i++) {
304
305 r = bytestream2_get_byteu(&c->
gb);
306 r = r << 2 | r >> 4;
307 g = bytestream2_get_byteu(&c->
gb);
308 g = g << 2 | g >> 4;
309 b = bytestream2_get_byteu(&c->
gb);
310 b = b << 2 | b >> 4;
311 *out++ = (0xFF
U << 24) | (r << 16) | (g << 8) | b;
312 }
314 }
315
316 switch (code & 0x0F) {
317 case 0:
318 /* Block-based motion compensation using 4x4 blocks with either
319 * horizontal or vertical vectors; might incorporate VQ as well. */
322 break;
323 case 1:
324 /* Uncompressed data. This mode specifies that (width * height) bytes
325 * should be copied directly from the encoded buffer into the output. */
327 // possibly chunk length data
332 break;
333 case 2:
334 /* Copy reference frame: Consume the next byte in the stream as the
335 * reference frame (which should be 0, 1, 2, or 3, and should not be
336 * the same as the current frame number). */
337 frame = bytestream2_get_byte(&c->
gb);
338 if (frame > 3)
342 break;
343 case 4:
344 /* Run length encoding.*/
347
349
350 while (dst < end) {
351 int8_t code;
353
356
357 code = bytestream2_get_byteu(&c->
gb);
358 count =
FFABS(code) + 1;
359
360 if (dst + count > end)
362 if (code < 0)
363 memset(dst, bytestream2_get_byteu(&c->
gb), count);
364 else
367 }
368 break;
369 default:
372 }
373
377
380 return ret;
381
382 *got_frame = 1;
383
385 }
386
397 };