diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-03-09 01:22:31 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-03-09 01:22:31 +0100 |
commit | a8cedbebf163ad376abc4703b3156c44d0858404 (patch) | |
tree | 7198ad7a96b58d3ea53b2208601b707da2db3c00 /libavcodec/pngdec.c | |
parent | a4524930d9299dbb8fafe165105d83bf7b6d3b89 (diff) | |
parent | ea1d64ab1066145ba919b79a2080f3091d562217 (diff) | |
download | ffmpeg-a8cedbebf163ad376abc4703b3156c44d0858404.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
ttadec: unbreak playback of matroska files
vorbisdec: avoid invalid memory access
Fix uninitialized reads on malformed ogg files.
huffyuv: add padding to classic (v1) huffman tables.
png: convert to bytestream2 API.
dca: include libavutil/mathematics.h for possibly missing M_SQRT1_2
avs: fix infinite loop on end-of-stream.
tiffdec: Prevent illegal memory access caused by recycled pointers.
rtpenc: Fix the AVRational used for av_rescale_q_rnd
wma: fix off-by-one in array bounds check.
Conflicts:
libavcodec/huffyuv.c
libavcodec/pngdec.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/pngdec.c')
-rw-r--r-- | libavcodec/pngdec.c | 72 |
1 files changed, 32 insertions, 40 deletions
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 55df8b0a57..398c48b419 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -38,9 +38,7 @@ typedef struct PNGDecContext { PNGDSPContext dsp; - const uint8_t *bytestream; - const uint8_t *bytestream_start; - const uint8_t *bytestream_end; + GetByteContext gb; AVFrame picture1, picture2; AVFrame *current_picture, *last_picture; @@ -360,12 +358,9 @@ static void png_handle_row(PNGDecContext *s) static int png_decode_idat(PNGDecContext *s, int length) { int ret; - s->zstream.avail_in = length; - s->zstream.next_in = s->bytestream; - s->bytestream += length; - - if(s->bytestream > s->bytestream_end) - return -1; + s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb)); + s->zstream.next_in = s->gb.buffer; + bytestream2_skip(&s->gb, length); /* decode one line if possible */ while (s->zstream.avail_in > 0) { @@ -401,17 +396,15 @@ static int decode_frame(AVCodecContext *avctx, avctx->coded_frame= s->current_picture; p = s->current_picture; - s->bytestream_start= - s->bytestream= buf; - s->bytestream_end= buf + buf_size; - /* check signature */ - if (memcmp(s->bytestream, ff_pngsig, 8) != 0 && - memcmp(s->bytestream, ff_mngsig, 8) != 0) { + if (buf_size < 8 || + memcmp(buf, ff_pngsig, 8) != 0 && + memcmp(buf, ff_mngsig, 8) != 0) { av_log(avctx, AV_LOG_ERROR, "Missing png signature\n"); return -1; } - s->bytestream+= 8; + + bytestream2_init(&s->gb, buf + 8, buf_size - 8); s->y= s->state=0; // memset(s, 0, sizeof(PNGDecContext)); @@ -423,14 +416,13 @@ static int decode_frame(AVCodecContext *avctx, if (ret != Z_OK) return -1; for(;;) { - int tag32; - if (s->bytestream >= s->bytestream_end) + if (bytestream2_get_bytes_left(&s->gb) <= 0) goto fail; - length = bytestream_get_be32(&s->bytestream); - if (length > 0x7fffffff || length > s->bytestream_end - s->bytestream) + + length = bytestream2_get_be32(&s->gb); + if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) goto fail; - tag32 = bytestream_get_be32(&s->bytestream); - tag = av_bswap32(tag32); + tag = bytestream2_get_le32(&s->gb); if (avctx->debug & FF_DEBUG_STARTCODE) av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n", (tag & 0xff), @@ -441,18 +433,18 @@ static int decode_frame(AVCodecContext *avctx, case MKTAG('I', 'H', 'D', 'R'): if (length != 13) goto fail; - s->width = bytestream_get_be32(&s->bytestream); - s->height = bytestream_get_be32(&s->bytestream); + s->width = bytestream2_get_be32(&s->gb); + s->height = bytestream2_get_be32(&s->gb); if(av_image_check_size(s->width, s->height, 0, avctx)){ s->width= s->height= 0; goto fail; } - s->bit_depth = *s->bytestream++; - s->color_type = *s->bytestream++; - s->compression_type = *s->bytestream++; - s->filter_type = *s->bytestream++; - s->interlace_type = *s->bytestream++; - s->bytestream += 4; /* crc */ + s->bit_depth = bytestream2_get_byte(&s->gb); + s->color_type = bytestream2_get_byte(&s->gb); + s->compression_type = bytestream2_get_byte(&s->gb); + s->filter_type = bytestream2_get_byte(&s->gb); + s->interlace_type = bytestream2_get_byte(&s->gb); + bytestream2_skip(&s->gb, 4); /* crc */ s->state |= PNG_IHDR; if (avctx->debug & FF_DEBUG_PICT_INFO) av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n", @@ -555,7 +547,7 @@ static int decode_frame(AVCodecContext *avctx, s->state |= PNG_IDAT; if (png_decode_idat(s, length) < 0) goto fail; - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ break; case MKTAG('P', 'L', 'T', 'E'): { @@ -566,16 +558,16 @@ static int decode_frame(AVCodecContext *avctx, /* read the palette */ n = length / 3; for(i=0;i<n;i++) { - r = *s->bytestream++; - g = *s->bytestream++; - b = *s->bytestream++; + r = bytestream2_get_byte(&s->gb); + g = bytestream2_get_byte(&s->gb); + b = bytestream2_get_byte(&s->gb); s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b; } for(;i<256;i++) { s->palette[i] = (0xff << 24); } s->state |= PNG_PLTE; - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ } break; case MKTAG('t', 'R', 'N', 'S'): @@ -588,21 +580,21 @@ static int decode_frame(AVCodecContext *avctx, !(s->state & PNG_PLTE)) goto skip_tag; for(i=0;i<length;i++) { - v = *s->bytestream++; + v = bytestream2_get_byte(&s->gb); s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24); } - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ } break; case MKTAG('I', 'E', 'N', 'D'): if (!(s->state & PNG_ALLIMAGE)) goto fail; - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ goto exit_loop; default: /* skip tag */ skip_tag: - s->bytestream += length + 4; + bytestream2_skip(&s->gb, length + 4); break; } } @@ -686,7 +678,7 @@ static int decode_frame(AVCodecContext *avctx, *picture= *s->current_picture; *data_size = sizeof(AVFrame); - ret = s->bytestream - s->bytestream_start; + ret = bytestream2_tell(&s->gb); the_end: inflateEnd(&s->zstream); av_free(crow_buf_base); |