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