| 537 | #endif |
| 538 | |
| 539 | static int xan_decode_frame(AVCodecContext *avctx, AVFrame *frame, |
| 540 | int *got_frame, AVPacket *avpkt) |
| 541 | { |
| 542 | const uint8_t *buf = avpkt->data; |
| 543 | int ret, buf_size = avpkt->size; |
| 544 | XanContext *s = avctx->priv_data; |
| 545 | GetByteContext ctx; |
| 546 | int tag = 0; |
| 547 | |
| 548 | bytestream2_init(&ctx, buf, buf_size); |
| 549 | while (bytestream2_get_bytes_left(&ctx) > 8 && tag != VGA__TAG) { |
| 550 | unsigned *tmpptr; |
| 551 | uint32_t new_pal; |
| 552 | int size; |
| 553 | int i; |
| 554 | tag = bytestream2_get_le32(&ctx); |
| 555 | size = bytestream2_get_be32(&ctx); |
| 556 | if (size < 0) { |
| 557 | av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size); |
| 558 | return AVERROR_INVALIDDATA; |
| 559 | } |
| 560 | size = FFMIN(size, bytestream2_get_bytes_left(&ctx)); |
| 561 | switch (tag) { |
| 562 | case PALT_TAG: |
| 563 | if (size < PALETTE_SIZE) |
| 564 | return AVERROR_INVALIDDATA; |
| 565 | if (s->palettes_count >= PALETTES_MAX) |
| 566 | return AVERROR_INVALIDDATA; |
| 567 | tmpptr = av_realloc_array(s->palettes, |
| 568 | s->palettes_count + 1, AVPALETTE_SIZE); |
| 569 | if (!tmpptr) |
| 570 | return AVERROR(ENOMEM); |
| 571 | s->palettes = tmpptr; |
| 572 | tmpptr += s->palettes_count * AVPALETTE_COUNT; |
| 573 | for (i = 0; i < PALETTE_COUNT; i++) { |
| 574 | #if RUNTIME_GAMMA |
| 575 | int r = gamma_corr(bytestream2_get_byteu(&ctx)); |
| 576 | int g = gamma_corr(bytestream2_get_byteu(&ctx)); |
| 577 | int b = gamma_corr(bytestream2_get_byteu(&ctx)); |
| 578 | #else |
| 579 | int r = gamma_lookup[bytestream2_get_byteu(&ctx)]; |
| 580 | int g = gamma_lookup[bytestream2_get_byteu(&ctx)]; |
| 581 | int b = gamma_lookup[bytestream2_get_byteu(&ctx)]; |
| 582 | #endif |
| 583 | *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b; |
| 584 | } |
| 585 | s->palettes_count++; |
| 586 | break; |
| 587 | case SHOT_TAG: |
| 588 | if (size < 4) |
| 589 | return AVERROR_INVALIDDATA; |
| 590 | new_pal = bytestream2_get_le32(&ctx); |
| 591 | if (new_pal < s->palettes_count) { |
| 592 | s->cur_palette = new_pal; |
| 593 | } else |
| 594 | av_log(avctx, AV_LOG_ERROR, "Invalid palette selected\n"); |
| 595 | break; |
| 596 | case VGA__TAG: |
nothing calls this directly
no test coverage detected