FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/argo.c
Date: 2021-09-22 05:58:22
Exec Total Coverage
Lines: 0 468 0.0%
Branches: 0 280 0.0%

Line Branch Exec Source
1 /*
2 * Argonaut Games Video decoder
3 * Copyright (c) 2020 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
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "libavutil/imgutils.h"
27 #include "libavutil/internal.h"
28 #include "libavutil/intreadwrite.h"
29
30 #include "avcodec.h"
31 #include "bytestream.h"
32 #include "internal.h"
33
34 typedef struct ArgoContext {
35 GetByteContext gb;
36
37 int bpp;
38 int key;
39 int mv0[128][2];
40 int mv1[16][2];
41 uint32_t pal[256];
42 AVFrame *frame;
43 } ArgoContext;
44
45 static int decode_pal8(AVCodecContext *avctx, uint32_t *pal)
46 {
47 ArgoContext *s = avctx->priv_data;
48 GetByteContext *gb = &s->gb;
49 int start, count;
50
51 start = bytestream2_get_le16(gb);
52 count = bytestream2_get_le16(gb);
53
54 if (start + count > 256)
55 return AVERROR_INVALIDDATA;
56
57 if (bytestream2_get_bytes_left(gb) < 3 * count)
58 return AVERROR_INVALIDDATA;
59
60 for (int i = 0; i < count; i++)
61 pal[start + i] = (0xFFU << 24) | bytestream2_get_be24u(gb);
62
63 return 0;
64 }
65
66 static int decode_avcf(AVCodecContext *avctx, AVFrame *frame)
67 {
68 ArgoContext *s = avctx->priv_data;
69 GetByteContext *gb = &s->gb;
70 const int l = frame->linesize[0];
71 const uint8_t *map = gb->buffer;
72 uint8_t *dst = frame->data[0];
73
74 if (bytestream2_get_bytes_left(gb) < 1024 + (frame->width / 2) * (frame->height / 2))
75 return AVERROR_INVALIDDATA;
76
77 bytestream2_skipu(gb, 1024);
78 for (int y = 0; y < frame->height; y += 2) {
79 for (int x = 0; x < frame->width; x += 2) {
80 int index = bytestream2_get_byteu(gb);
81 const uint8_t *block = map + index * 4;
82
83 dst[x+0] = block[0];
84 dst[x+1] = block[1];
85 dst[x+l] = block[2];
86 dst[x+l+1] = block[3];
87 }
88
89 dst += frame->linesize[0] * 2;
90 }
91
92 return 0;
93 }
94
95 static int decode_alcd(AVCodecContext *avctx, AVFrame *frame)
96 {
97 ArgoContext *s = avctx->priv_data;
98 GetByteContext *gb = &s->gb;
99 GetByteContext sb;
100 const int l = frame->linesize[0];
101 const uint8_t *map = gb->buffer;
102 uint8_t *dst = frame->data[0];
103 uint8_t codes = 0;
104 int count = 0;
105
106 if (bytestream2_get_bytes_left(gb) < 1024 + (((frame->width / 2) * (frame->height / 2) + 7) >> 3))
107 return AVERROR_INVALIDDATA;
108
109 bytestream2_skipu(gb, 1024);
110 sb = *gb;
111 bytestream2_skipu(gb, ((frame->width / 2) * (frame->height / 2) + 7) >> 3);
112
113 for (int y = 0; y < frame->height; y += 2) {
114 for (int x = 0; x < frame->width; x += 2) {
115 const uint8_t *block;
116 int index;
117
118 if (count == 0) {
119 codes = bytestream2_get_byteu(&sb);
120 count = 8;
121 }
122
123 if (codes & 0x80) {
124 index = bytestream2_get_byte(gb);
125 block = map + index * 4;
126
127 dst[x+0] = block[0];
128 dst[x+1] = block[1];
129 dst[x+l] = block[2];
130 dst[x+l+1] = block[3];
131 }
132
133 codes <<= 1;
134 count--;
135 }
136
137 dst += frame->linesize[0] * 2;
138 }
139
140 return 0;
141 }
142
143 static int decode_mad1(AVCodecContext *avctx, AVFrame *frame)
144 {
145 ArgoContext *s = avctx->priv_data;
146 GetByteContext *gb = &s->gb;
147 const int w = frame->width;
148 const int h = frame->height;
149 const int l = frame->linesize[0];
150
151 while (bytestream2_get_bytes_left(gb) > 0) {
152 int size, type, pos, dy;
153 uint8_t *dst;
154
155 type = bytestream2_get_byte(gb);
156 if (type == 0xFF)
157 break;
158
159 switch (type) {
160 case 8:
161 dst = frame->data[0];
162 for (int y = 0; y < h; y += 8) {
163 for (int x = 0; x < w; x += 8) {
164 int fill = bytestream2_get_byte(gb);
165 uint8_t *ddst = dst + x;
166
167 for (int by = 0; by < 8; by++) {
168 memset(ddst, fill, 8);
169 ddst += l;
170 }
171 }
172
173 dst += 8 * l;
174 }
175 break;
176 case 7:
177 while (bytestream2_get_bytes_left(gb) > 0) {
178 int bsize = bytestream2_get_byte(gb);
179 uint8_t *src;
180 int count;
181
182 if (!bsize)
183 break;
184
185 count = bytestream2_get_be16(gb);
186 while (count > 0) {
187 int mvx, mvy, a, b, c, mx, my;
188 int bsize_w, bsize_h;
189
190 bsize_w = bsize_h = bsize;
191 if (bytestream2_get_bytes_left(gb) < 4)
192 return AVERROR_INVALIDDATA;
193 mvx = bytestream2_get_byte(gb) * bsize;
194 mvy = bytestream2_get_byte(gb) * bsize;
195 a = bytestream2_get_byte(gb);
196 b = bytestream2_get_byte(gb);
197 c = ((a & 0x3F) << 8) + b;
198 mx = mvx + (c & 0x7F) - 64;
199 my = mvy + (c >> 7) - 64;
200
201 if (mvy < 0 || mvy >= h)
202 return AVERROR_INVALIDDATA;
203
204 if (mvx < 0 || mvx >= w)
205 return AVERROR_INVALIDDATA;
206
207 if (my < 0 || my >= h)
208 return AVERROR_INVALIDDATA;
209
210 if (mx < 0 || mx >= w)
211 return AVERROR_INVALIDDATA;
212
213 dst = frame->data[0] + mvx + l * mvy;
214 src = frame->data[0] + mx + l * my;
215
216 bsize_w = FFMIN3(bsize_w, w - mvx, w - mx);
217 bsize_h = FFMIN3(bsize_h, h - mvy, h - my);
218
219 if (mvy >= my && (mvy != my || mvx >= mx)) {
220 src += (bsize_h - 1) * l;
221 dst += (bsize_h - 1) * l;
222 for (int by = 0; by < bsize_h; by++) {
223 memmove(dst, src, bsize_w);
224 src -= l;
225 dst -= l;
226 }
227 } else {
228 for (int by = 0; by < bsize_h; by++) {
229 memmove(dst, src, bsize_w);
230 src += l;
231 dst += l;
232 }
233 }
234
235 count--;
236 }
237 }
238 break;
239 case 6:
240 dst = frame->data[0];
241 if (bytestream2_get_bytes_left(gb) < w * h)
242 return AVERROR_INVALIDDATA;
243 for (int y = 0; y < h; y++) {
244 bytestream2_get_bufferu(gb, dst, w);
245 dst += l;
246 }
247 break;
248 case 5:
249 dst = frame->data[0];
250 for (int y = 0; y < h; y += 2) {
251 for (int x = 0; x < w; x += 2) {
252 int fill = bytestream2_get_byte(gb);
253 uint8_t *ddst = dst + x;
254
255 fill = (fill << 8) | fill;
256 for (int by = 0; by < 2; by++) {
257 AV_WN16(ddst, fill);
258
259 ddst += l;
260 }
261 }
262
263 dst += 2 * l;
264 }
265 break;
266 case 3:
267 size = bytestream2_get_le16(gb);
268 if (size > 0) {
269 int x = bytestream2_get_byte(gb) * 4;
270 int y = bytestream2_get_byte(gb) * 4;
271 int count = bytestream2_get_byte(gb);
272 int fill = bytestream2_get_byte(gb);
273
274 av_log(avctx, AV_LOG_DEBUG, "%d %d %d %d\n", x, y, count, fill);
275 for (int i = 0; i < count; i++)
276 ;
277 return AVERROR_PATCHWELCOME;
278 }
279 break;
280 case 2:
281 dst = frame->data[0];
282 pos = 0;
283 dy = 0;
284 while (bytestream2_get_bytes_left(gb) > 0) {
285 int count = bytestream2_get_byteu(gb);
286 int skip = count & 0x3F;
287
288 count = count >> 6;
289 if (skip == 0x3F) {
290 pos += 0x3E;
291 while (pos >= w) {
292 pos -= w;
293 dst += l;
294 dy++;
295 if (dy >= h)
296 return 0;
297 }
298 } else {
299 pos += skip;
300 while (pos >= w) {
301 pos -= w;
302 dst += l;
303 dy++;
304 if (dy >= h)
305 return 0;
306 }
307 while (count >= 0) {
308 int bits = bytestream2_get_byte(gb);
309
310 for (int i = 0; i < 4; i++) {
311 switch (bits & 3) {
312 case 0:
313 break;
314 case 1:
315 if (dy < 1 && !pos)
316 return AVERROR_INVALIDDATA;
317 else
318 dst[pos] = pos ? dst[pos - 1] : dst[-l + w - 1];
319 break;
320 case 2:
321 if (dy < 1)
322 return AVERROR_INVALIDDATA;
323 dst[pos] = dst[pos - l];
324 break;
325 case 3:
326 dst[pos] = bytestream2_get_byte(gb);
327 break;
328 }
329
330 pos++;
331 if (pos >= w) {
332 pos -= w;
333 dst += l;
334 dy++;
335 if (dy >= h)
336 return 0;
337 }
338 bits >>= 2;
339 }
340 count--;
341 }
342 }
343 }
344 break;
345 default:
346 return AVERROR_INVALIDDATA;
347 }
348 }
349
350 return 0;
351 }
352
353 static int decode_mad1_24(AVCodecContext *avctx, AVFrame *frame)
354 {
355 ArgoContext *s = avctx->priv_data;
356 GetByteContext *gb = &s->gb;
357 const int w = frame->width;
358 const int h = frame->height;
359 const int l = frame->linesize[0] / 4;
360
361 while (bytestream2_get_bytes_left(gb) > 0) {
362 int osize, type, pos, dy, di, bcode, value, v14;
363 const uint8_t *bits;
364 uint32_t *dst;
365
366 type = bytestream2_get_byte(gb);
367 if (type == 0xFF)
368 return 0;
369
370 switch (type) {
371 case 8:
372 dst = (uint32_t *)frame->data[0];
373 for (int y = 0; y + 12 <= h; y += 12) {
374 for (int x = 0; x + 12 <= w; x += 12) {
375 int fill = bytestream2_get_be24(gb);
376 uint32_t *dstp = dst + x;
377
378 for (int by = 0; by < 12; by++) {
379 for (int bx = 0; bx < 12; bx++)
380 dstp[bx] = fill;
381
382 dstp += l;
383 }
384 }
385
386 dst += 12 * l;
387 }
388 break;
389 case 7:
390 while (bytestream2_get_bytes_left(gb) > 0) {
391 int bsize = bytestream2_get_byte(gb);
392 uint32_t *src;
393 int count;
394
395 if (!bsize)
396 break;
397
398 count = bytestream2_get_be16(gb);
399 while (count > 0) {
400 int mvx, mvy, a, b, c, mx, my;
401 int bsize_w, bsize_h;
402
403 bsize_w = bsize_h = bsize;
404 if (bytestream2_get_bytes_left(gb) < 4)
405 return AVERROR_INVALIDDATA;
406 mvx = bytestream2_get_byte(gb) * bsize;
407 mvy = bytestream2_get_byte(gb) * bsize;
408 a = bytestream2_get_byte(gb);
409 b = bytestream2_get_byte(gb);
410 c = ((a & 0x3F) << 8) + b;
411 mx = mvx + (c & 0x7F) - 64;
412 my = mvy + (c >> 7) - 64;
413
414 if (mvy < 0 || mvy >= h)
415 return AVERROR_INVALIDDATA;
416
417 if (mvx < 0 || mvx >= w)
418 return AVERROR_INVALIDDATA;
419
420 if (my < 0 || my >= h)
421 return AVERROR_INVALIDDATA;
422
423 if (mx < 0 || mx >= w)
424 return AVERROR_INVALIDDATA;
425
426 dst = (uint32_t *)frame->data[0] + mvx + l * mvy;
427 src = (uint32_t *)frame->data[0] + mx + l * my;
428
429 bsize_w = FFMIN3(bsize_w, w - mvx, w - mx);
430 bsize_h = FFMIN3(bsize_h, h - mvy, h - my);
431
432 if (mvy >= my && (mvy != my || mvx >= mx)) {
433 src += (bsize_h - 1) * l;
434 dst += (bsize_h - 1) * l;
435 for (int by = 0; by < bsize_h; by++) {
436 memmove(dst, src, bsize_w * 4);
437 src -= l;
438 dst -= l;
439 }
440 } else {
441 for (int by = 0; by < bsize_h; by++) {
442 memmove(dst, src, bsize_w * 4);
443 src += l;
444 dst += l;
445 }
446 }
447
448 count--;
449 }
450 }
451 break;
452 case 12:
453 osize = ((h + 3) / 4) * ((w + 3) / 4) + 7;
454 bits = gb->buffer;
455 di = 0;
456 bcode = v14 = 0;
457 if (bytestream2_get_bytes_left(gb) < osize >> 3)
458 return AVERROR_INVALIDDATA;
459 bytestream2_skip(gb, osize >> 3);
460 for (int x = 0; x < w; x += 4) {
461 for (int y = 0; y < h; y += 4) {
462 int astate = 0;
463
464 if (bits[di >> 3] & (1 << (di & 7))) {
465 int codes = bytestream2_get_byte(gb);
466
467 for (int count = 0; count < 4; count++) {
468 uint32_t *src = (uint32_t *)frame->data[0];
469 size_t src_size = l * (h - 1) + (w - 1);
470 int nv, v, code = codes & 3;
471
472 pos = x;
473 dy = y + count;
474 dst = (uint32_t *)frame->data[0] + pos + dy * l;
475 if (code & 1)
476 bcode = bytestream2_get_byte(gb);
477 if (code == 3) {
478 for (int j = 0; j < 4; j++) {
479 switch (bcode & 3) {
480 case 0:
481 break;
482 case 1:
483 if (dy < 1 && !pos)
484 return AVERROR_INVALIDDATA;
485 dst[0] = dst[-1];
486 break;
487 case 2:
488 if (dy < 1)
489 return AVERROR_INVALIDDATA;
490 dst[0] = dst[-l];
491 break;
492 case 3:
493 if (astate) {
494 nv = value >> 4;
495 } else {
496 value = bytestream2_get_byte(gb);
497 nv = value & 0xF;
498 }
499 astate ^= 1;
500 dst[0] = src[av_clip(l * (dy + s->mv1[nv][1]) + pos +
501 s->mv1[nv][0], 0, src_size)];
502 break;
503 }
504
505 bcode >>= 2;
506 dst++;
507 pos++;
508 }
509 } else if (code) {
510 if (code == 1)
511 v14 = bcode;
512 else
513 bcode = v14;
514 for (int j = 0; j < 4; j++) {
515 switch (bcode & 3) {
516 case 0:
517 break;
518 case 1:
519 if (dy < 1 && !pos)
520 return AVERROR_INVALIDDATA;
521 dst[0] = dst[-1];
522 break;
523 case 2:
524 if (dy < 1)
525 return AVERROR_INVALIDDATA;
526 dst[0] = dst[-l];
527 break;
528 case 3:
529 v = bytestream2_get_byte(gb);
530 if (v < 128) {
531 dst[0] = src[av_clip(l * (dy + s->mv0[v][1]) + pos +
532 s->mv0[v][0], 0, src_size)];
533 } else {
534 dst[0] = ((v & 0x7F) << 17) | bytestream2_get_be16(gb);
535 }
536 break;
537 }
538
539 bcode >>= 2;
540 dst++;
541 pos++;
542 }
543 }
544
545 codes >>= 2;
546 }
547 }
548
549 di++;
550 }
551 }
552 break;
553 default:
554 return AVERROR_INVALIDDATA;
555 }
556 }
557
558 return AVERROR_INVALIDDATA;
559 }
560
561 static int decode_rle(AVCodecContext *avctx, AVFrame *frame)
562 {
563 ArgoContext *s = avctx->priv_data;
564 GetByteContext *gb = &s->gb;
565 const int w = frame->width;
566 const int h = frame->height;
567 const int l = frame->linesize[0];
568 uint8_t *dst = frame->data[0];
569 int pos = 0, y = 0;
570
571 while (bytestream2_get_bytes_left(gb) > 0) {
572 int count = bytestream2_get_byte(gb);
573 int pixel = bytestream2_get_byte(gb);
574
575 if (!count) {
576 pos += pixel;
577 while (pos >= w) {
578 pos -= w;
579 y++;
580 if (y >= h)
581 return 0;
582 }
583 } else {
584 while (count > 0) {
585 dst[pos + y * l] = pixel;
586 count--;
587 pos++;
588 if (pos >= w) {
589 pos = 0;
590 y++;
591 if (y >= h)
592 return 0;
593 }
594 }
595 }
596 }
597
598 return 0;
599 }
600
601 static int decode_frame(AVCodecContext *avctx, void *data,
602 int *got_frame, AVPacket *avpkt)
603 {
604 ArgoContext *s = avctx->priv_data;
605 GetByteContext *gb = &s->gb;
606 AVFrame *frame = s->frame;
607 uint32_t chunk;
608 int ret;
609
610 bytestream2_init(gb, avpkt->data, avpkt->size);
611
612 if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
613 return ret;
614
615 chunk = bytestream2_get_be32(gb);
616 switch (chunk) {
617 case MKBETAG('P', 'A', 'L', '8'):
618 for (int y = 0; y < frame->height; y++)
619 memset(frame->data[0] + y * frame->linesize[0], 0, frame->width * s->bpp);
620 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
621 memset(frame->data[1], 0, AVPALETTE_SIZE);
622 return decode_pal8(avctx, s->pal);
623 case MKBETAG('M', 'A', 'D', '1'):
624 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
625 ret = decode_mad1(avctx, frame);
626 else
627 ret = decode_mad1_24(avctx, frame);
628 break;
629 case MKBETAG('A', 'V', 'C', 'F'):
630 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
631 s->key = 1;
632 ret = decode_avcf(avctx, frame);
633 break;
634 }
635 case MKBETAG('A', 'L', 'C', 'D'):
636 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
637 s->key = 0;
638 ret = decode_alcd(avctx, frame);
639 break;
640 }
641 case MKBETAG('R', 'L', 'E', 'F'):
642 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
643 s->key = 1;
644 ret = decode_rle(avctx, frame);
645 break;
646 }
647 case MKBETAG('R', 'L', 'E', 'D'):
648 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
649 s->key = 0;
650 ret = decode_rle(avctx, frame);
651 break;
652 }
653 default:
654 av_log(avctx, AV_LOG_DEBUG, "unknown chunk 0x%X\n", chunk);
655 break;
656 }
657
658 if (ret < 0)
659 return ret;
660
661 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
662 memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
663
664 if ((ret = av_frame_ref(data, s->frame)) < 0)
665 return ret;
666
667 frame->pict_type = s->key ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
668 frame->key_frame = s->key;
669 *got_frame = 1;
670
671 return avpkt->size;
672 }
673
674 static av_cold int decode_init(AVCodecContext *avctx)
675 {
676 ArgoContext *s = avctx->priv_data;
677
678 switch (avctx->bits_per_coded_sample) {
679 case 8: s->bpp = 1;
680 avctx->pix_fmt = AV_PIX_FMT_PAL8; break;
681 case 24: s->bpp = 4;
682 avctx->pix_fmt = AV_PIX_FMT_BGR0; break;
683 default: avpriv_request_sample(s, "depth == %u", avctx->bits_per_coded_sample);
684 return AVERROR_PATCHWELCOME;
685 }
686
687 if (avctx->width % 2 || avctx->height % 2) {
688 avpriv_request_sample(s, "Odd dimensions\n");
689 return AVERROR_PATCHWELCOME;
690 }
691
692 s->frame = av_frame_alloc();
693 if (!s->frame)
694 return AVERROR(ENOMEM);
695
696 for (int n = 0, i = -4; i < 4; i++) {
697 for (int j = -14; j < 2; j++) {
698 s->mv0[n][0] = j;
699 s->mv0[n++][1] = i;
700 }
701 }
702
703 for (int n = 0, i = -5; i <= 1; i += 2) {
704 int j = -5;
705
706 while (j <= 1) {
707 s->mv1[n][0] = j;
708 s->mv1[n++][1] = i;
709 j += 2;
710 }
711 }
712
713 return 0;
714 }
715
716 static void decode_flush(AVCodecContext *avctx)
717 {
718 ArgoContext *s = avctx->priv_data;
719
720 av_frame_unref(s->frame);
721 }
722
723 static av_cold int decode_close(AVCodecContext *avctx)
724 {
725 ArgoContext *s = avctx->priv_data;
726
727 av_frame_free(&s->frame);
728
729 return 0;
730 }
731
732 const AVCodec ff_argo_decoder = {
733 .name = "argo",
734 .long_name = NULL_IF_CONFIG_SMALL("Argonaut Games Video"),
735 .type = AVMEDIA_TYPE_VIDEO,
736 .id = AV_CODEC_ID_ARGO,
737 .priv_data_size = sizeof(ArgoContext),
738 .init = decode_init,
739 .decode = decode_frame,
740 .flush = decode_flush,
741 .close = decode_close,
742 .capabilities = AV_CODEC_CAP_DR1,
743 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
744 };
745