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