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 "codec_internal.h" 33#include "internal.h" 34 35typedef 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 46static 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] = (0xFFU << 24) | bytestream2_get_be24u(gb); 63 64 return 0; 65} 66 67static 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 96static 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 144static 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 354static 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 562static 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 602static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, 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 if (avpkt->size < 4) 612 return AVERROR_INVALIDDATA; 613 614 bytestream2_init(gb, avpkt->data, avpkt->size); 615 616 if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0) 617 return ret; 618 619 chunk = bytestream2_get_be32(gb); 620 switch (chunk) { 621 case MKBETAG('P', 'A', 'L', '8'): 622 for (int y = 0; y < frame->height; y++) 623 memset(frame->data[0] + y * frame->linesize[0], 0, frame->width * s->bpp); 624 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) 625 memset(frame->data[1], 0, AVPALETTE_SIZE); 626 return decode_pal8(avctx, s->pal); 627 case MKBETAG('M', 'A', 'D', '1'): 628 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) 629 ret = decode_mad1(avctx, frame); 630 else 631 ret = decode_mad1_24(avctx, frame); 632 break; 633 case MKBETAG('A', 'V', 'C', 'F'): 634 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { 635 s->key = 1; 636 ret = decode_avcf(avctx, frame); 637 break; 638 } 639 case MKBETAG('A', 'L', 'C', 'D'): 640 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { 641 s->key = 0; 642 ret = decode_alcd(avctx, frame); 643 break; 644 } 645 case MKBETAG('R', 'L', 'E', 'F'): 646 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { 647 s->key = 1; 648 ret = decode_rle(avctx, frame); 649 break; 650 } 651 case MKBETAG('R', 'L', 'E', 'D'): 652 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { 653 s->key = 0; 654 ret = decode_rle(avctx, frame); 655 break; 656 } 657 default: 658 av_log(avctx, AV_LOG_DEBUG, "unknown chunk 0x%X\n", chunk); 659 break; 660 } 661 662 if (ret < 0) 663 return ret; 664 665 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) 666 memcpy(frame->data[1], s->pal, AVPALETTE_SIZE); 667 668 if ((ret = av_frame_ref(rframe, s->frame)) < 0) 669 return ret; 670 671 frame->pict_type = s->key ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; 672 frame->key_frame = s->key; 673 *got_frame = 1; 674 675 return avpkt->size; 676} 677 678static 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 720static void decode_flush(AVCodecContext *avctx) 721{ 722 ArgoContext *s = avctx->priv_data; 723 724 av_frame_unref(s->frame); 725} 726 727static 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 736const FFCodec ff_argo_decoder = { 737 .p.name = "argo", 738 .p.long_name = NULL_IF_CONFIG_SMALL("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_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 748}; 749