This version requires fewer code and is safer.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -646,7 +646,7 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, |
646 | 646 |
int magic; |
647 | 647 |
int got_header = 0; |
648 | 648 |
uint32_t chunk_size; |
649 |
- int chunk_type; |
|
649 |
+ int chunk_type, chunk_start; |
|
650 | 650 |
int i; |
651 | 651 |
int ret; |
652 | 652 |
|
... | ... |
@@ -672,8 +672,9 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, |
672 | 672 |
} |
673 | 673 |
|
674 | 674 |
while (bytestream2_get_bytes_left(&bc) > 5) { |
675 |
- chunk_size = bytestream2_get_le32(&bc) - 1; |
|
676 |
- chunk_type = bytestream2_get_byte(&bc); |
|
675 |
+ chunk_size = bytestream2_get_le32(&bc) - 1; |
|
676 |
+ chunk_type = bytestream2_get_byte(&bc); |
|
677 |
+ chunk_start = bytestream2_tell(&bc); |
|
677 | 678 |
if (chunk_size > bytestream2_get_bytes_left(&bc)) { |
678 | 679 |
av_log(avctx, AV_LOG_ERROR, "Invalid chunk size %d type %02X\n", |
679 | 680 |
chunk_size, chunk_type); |
... | ... |
@@ -722,8 +723,6 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, |
722 | 722 |
c->tiles_x = (c->width + c->tile_width - 1) / c->tile_width; |
723 | 723 |
c->tiles_y = (c->height + c->tile_height - 1) / c->tile_height; |
724 | 724 |
c->bpp = bytestream2_get_byte(&bc); |
725 |
- chunk_size -= 21; |
|
726 |
- bytestream2_skip(&bc, chunk_size); |
|
727 | 725 |
if (g2m_init_buffers(c)) { |
728 | 726 |
ret = AVERROR(ENOMEM); |
729 | 727 |
goto header_fail; |
... | ... |
@@ -734,7 +733,6 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, |
734 | 734 |
if (!c->tiles_x || !c->tiles_y) { |
735 | 735 |
av_log(avctx, AV_LOG_WARNING, |
736 | 736 |
"No display info - skipping tile\n"); |
737 |
- bytestream2_skip(&bc, bytestream2_get_bytes_left(&bc)); |
|
738 | 737 |
break; |
739 | 738 |
} |
740 | 739 |
if (chunk_size < 2) { |
... | ... |
@@ -750,7 +748,6 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, |
750 | 750 |
c->tile_x, c->tile_y, c->tiles_x, c->tiles_y); |
751 | 751 |
break; |
752 | 752 |
} |
753 |
- chunk_size -= 2; |
|
754 | 753 |
ret = 0; |
755 | 754 |
switch (c->compression) { |
756 | 755 |
case COMPR_EPIC_J_B: |
... | ... |
@@ -760,13 +757,12 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, |
760 | 760 |
case COMPR_KEMPF_J_B: |
761 | 761 |
ret = kempf_decode_tile(c, c->tile_x, c->tile_y, |
762 | 762 |
buf + bytestream2_tell(&bc), |
763 |
- chunk_size); |
|
763 |
+ chunk_size - 2); |
|
764 | 764 |
break; |
765 | 765 |
} |
766 | 766 |
if (ret && c->framebuf) |
767 | 767 |
av_log(avctx, AV_LOG_ERROR, "Error decoding tile %d,%d\n", |
768 | 768 |
c->tile_x, c->tile_y); |
769 |
- bytestream2_skip(&bc, chunk_size); |
|
770 | 769 |
break; |
771 | 770 |
case CURSOR_POS: |
772 | 771 |
if (chunk_size < 5) { |
... | ... |
@@ -776,7 +772,6 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, |
776 | 776 |
} |
777 | 777 |
c->cursor_x = bytestream2_get_be16(&bc); |
778 | 778 |
c->cursor_y = bytestream2_get_be16(&bc); |
779 |
- bytestream2_skip(&bc, chunk_size - 4); |
|
780 | 779 |
break; |
781 | 780 |
case CURSOR_SHAPE: |
782 | 781 |
if (chunk_size < 8) { |
... | ... |
@@ -787,17 +782,17 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, |
787 | 787 |
bytestream2_init(&tbc, buf + bytestream2_tell(&bc), |
788 | 788 |
chunk_size - 4); |
789 | 789 |
g2m_load_cursor(avctx, c, &tbc); |
790 |
- bytestream2_skip(&bc, chunk_size); |
|
791 | 790 |
break; |
792 | 791 |
case CHUNK_CC: |
793 | 792 |
case CHUNK_CD: |
794 |
- bytestream2_skip(&bc, chunk_size); |
|
795 | 793 |
break; |
796 | 794 |
default: |
797 | 795 |
av_log(avctx, AV_LOG_WARNING, "Skipping chunk type %02X\n", |
798 | 796 |
chunk_type); |
799 |
- bytestream2_skip(&bc, chunk_size); |
|
800 | 797 |
} |
798 |
+ |
|
799 |
+ /* navigate to next chunk */ |
|
800 |
+ bytestream2_skip(&bc, chunk_start + chunk_size - bytestream2_tell(&bc)); |
|
801 | 801 |
} |
802 | 802 |
if (got_header) |
803 | 803 |
c->got_header = 1; |