1 /*
2 * Chronomaster DFA Video Decoder
3 * Copyright (c) 2011 Konstantin Shishkov
4 * based on work by Vladimir "VAG" Gneushev
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <inttypes.h>
24
29
33
38
40 {
42
44
47
49
53
54 return 0;
55 }
56
58 {
60
63 return 0;
64 }
65
67 {
70 int mask = 0x10000, bitbuf = 0;
71 int v, count;
72 unsigned segments;
74
75 segments = bytestream2_get_le32(gb);
76 offset = bytestream2_get_le32(gb);
78 return 0; // skip frame
82 while (segments--) {
85 if (
mask == 0x10000) {
86 bitbuf = bytestream2_get_le16u(gb);
88 }
92 v = bytestream2_get_le16(gb);
93 offset = (v & 0x1FFF) << 1;
94 count = ((v >> 13) + 2) << 1;
99 } else {
100 *
frame++ = bytestream2_get_byte(gb);
101 *
frame++ = bytestream2_get_byte(gb);
102 }
104 }
105
106 return 0;
107 }
108
110 {
113 int mask = 0x10000, bitbuf = 0;
114 int v,
offset, count, segments;
115
116 segments = bytestream2_get_le16(gb);
117 while (segments--) {
120 if (
mask == 0x10000) {
121 bitbuf = bytestream2_get_le16u(gb);
123 }
127 v = bytestream2_get_le16(gb);
128 offset = (v & 0x1FFF) << 1;
129 count = ((v >> 13) + 2) << 1;
134 }
else if (bitbuf & (
mask << 1)) {
135 frame += bytestream2_get_le16(gb);
136 } else {
137 *
frame++ = bytestream2_get_byte(gb);
138 *
frame++ = bytestream2_get_byte(gb);
139 }
141 }
142
143 return 0;
144 }
145
147 {
150 int mask = 0x10000, bitbuf = 0;
151 int i, v,
offset, count, segments;
152
155 segments = bytestream2_get_le16(gb);
156 while (segments--) {
159 if (
mask == 0x10000) {
160 bitbuf = bytestream2_get_le16u(gb);
162 }
163
165 v = bytestream2_get_le16(gb);
166 offset = (v & 0x1FFF) << 2;
167 count = ((v >> 13) + 2) << 1;
170 for (
i = 0;
i < count;
i++) {
173
175 }
176 }
else if (bitbuf & (
mask << 1)) {
177 v = bytestream2_get_le16(gb)*2;
181 } else {
190 }
192 }
193
194 return 0;
195 }
196
198 {
199 uint8_t *line_ptr;
200 int count, lines, segments;
201
202 count = bytestream2_get_le16(gb);
206 lines = bytestream2_get_le16(gb);
207 if (count + lines >
height)
209
210 while (lines--) {
215 segments = bytestream2_get_byteu(gb);
216 while (segments--) {
217 if (
frame - line_ptr <= bytestream2_peek_byte(gb))
219 line_ptr += bytestream2_get_byte(gb);
220 count = (int8_t)bytestream2_get_byte(gb);
221 if (count >= 0) {
222 if (
frame - line_ptr < count)
226 } else {
227 count = -count;
228 if (
frame - line_ptr < count)
230 memset(line_ptr, bytestream2_get_byte(gb), count);
231 }
232 line_ptr += count;
233 }
234 }
235
236 return 0;
237 }
238
240 {
242 uint8_t *line_ptr;
243 int count,
i, v, lines, segments;
244 int y = 0;
245
246 lines = bytestream2_get_le16(gb);
249
250 while (lines--) {
253 segments = bytestream2_get_le16u(gb);
254 while ((segments & 0xC000) == 0xC000) {
255 unsigned skip_lines = -(int16_t)segments;
260 y += skip_lines;
261 segments = bytestream2_get_le16(gb);
262 }
263
266 if (segments & 0x8000) {
268 segments = bytestream2_get_le16(gb);
269 }
274 y++;
275 while (segments--) {
276 if (
frame - line_ptr <= bytestream2_peek_byte(gb))
278 line_ptr += bytestream2_get_byte(gb);
279 count = (int8_t)bytestream2_get_byte(gb);
280 if (count >= 0) {
281 if (
frame - line_ptr < count * 2)
285 line_ptr += count * 2;
286 } else {
287 count = -count;
288 if (
frame - line_ptr < count * 2)
290 v = bytestream2_get_le16(gb);
291 for (
i = 0;
i < count;
i++)
292 bytestream_put_le16(&line_ptr, v);
293 }
294 }
295 }
296
297 return 0;
298 }
299
301 {
303 uint32_t segments = bytestream2_get_le32(gb);
305
306 while (segments--) {
309 copy = bytestream2_get_byteu(gb) * 2;
310 skip = bytestream2_get_byteu(gb) * 2;
317 }
318
319 return 0;
320 }
321
323 {
325 return 0;
326 }
327
328
330
334 };
335
337 "COPY", "TSW1", "BDLT", "WDLT", "TDLT", "DSW1", "BLCK", "DDS1"
338 };
339
342 {
345 const uint8_t *buf = avpkt->
data;
346 uint32_t chunk_type, chunk_size;
351
354
360 chunk_size = bytestream2_get_le32(&gb);
361 chunk_type = bytestream2_get_le32(&gb);
362 if (!chunk_type)
363 break;
364 if (chunk_type == 1) {
365 pal_elems =
FFMIN(chunk_size / 3, 256);
366 for (
i = 0;
i < pal_elems;
i++) {
367 s->pal[
i] = bytestream2_get_be24(&gb) << 2;
368 s->pal[
i] |= 0xFF
U << 24 | (
s->pal[
i] >> 6) & 0x30303;
369 }
370 #if FF_API_PALETTE_HAS_CHANGED
372 frame->palette_has_changed = 1;
374 #endif
375 } else if (chunk_type <= 9) {
380 }
381 } else {
383 "Ignoring unknown chunk type %"PRIu32"\n",
384 chunk_type);
385 }
386 buf += chunk_size;
387 }
388
393 int j;
394 const uint8_t *buf1 = buf + (
i&3)*(avctx->
width/4) + (
i/4)*avctx->
width;
396 for(j = 0; j < avctx->
width/4; j++) {
401 }
402 j *= 4;
403 for(; j < avctx->
width; j++) {
405 }
407 }
408 } else
411
412 memcpy(
frame->data[1],
s->pal,
sizeof(
s->pal));
413
414 *got_frame = 1;
415
417 }
418
420 {
422
424
425 return 0;
426 }
427
438 };