X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fpngdec.c;h=927248f2e3464eb74c97ce81b6ef15868b2048de;hb=1146bb3babca3973e88005d267cd06210d6ac075;hp=fa7f7cc0a62a01028ee6ca8a6d816c850fbad89c;hpb=e64f0bf2d2b1347ec9461f0e82852a62e8c6ffbe;p=ffmpeg diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index fa7f7cc0a62..927248f2e34 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -18,7 +18,11 @@ * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "libavutil/avstring.h" #include "libavutil/imgutils.h" +#include "libavutil/stereo3d.h" + #include "avcodec.h" #include "bytestream.h" #include "internal.h" @@ -414,10 +418,23 @@ static int decode_frame(AVCodecContext *avctx, int ret; /* check signature */ - if (buf_size < 8 || - memcmp(buf, ff_pngsig, 8) != 0 && - memcmp(buf, ff_mngsig, 8) != 0) - return -1; + if (buf_size < 8) { + av_log(avctx, AV_LOG_ERROR, "Not enough data %d\n", + buf_size); + return AVERROR_INVALIDDATA; + } + if (memcmp(buf, ff_pngsig, 8) != 0 && + memcmp(buf, ff_mngsig, 8) != 0) { + char signature[5 * 8 + 1] = { 0 }; + int i; + for (i = 0; i < 8; i++) { + av_strlcatf(signature + i * 5, sizeof(signature) - i * 5, + " 0x%02x", buf[i]); + } + av_log(avctx, AV_LOG_ERROR, "Invalid PNG signature %s\n", + signature); + return AVERROR_INVALIDDATA; + } bytestream2_init(&s->gb, buf + 8, buf_size - 8); s->y = s->state = 0; @@ -436,7 +453,7 @@ static int decode_frame(AVCodecContext *avctx, if (length > 0x7fffffff) goto fail; tag = bytestream2_get_le32(&s->gb); - av_dlog(avctx, "png: tag=%c%c%c%c length=%u\n", + ff_dlog(avctx, "png: tag=%c%c%c%c length=%"PRIu32"\n", (tag & 0xff), ((tag >> 8) & 0xff), ((tag >> 16) & 0xff), @@ -458,7 +475,7 @@ static int decode_frame(AVCodecContext *avctx, s->interlace_type = bytestream2_get_byte(&s->gb); bytestream2_skip(&s->gb, 4); /* crc */ s->state |= PNG_IHDR; - av_dlog(avctx, "width=%d height=%d depth=%d color_type=%d " + ff_dlog(avctx, "width=%d height=%d depth=%d color_type=%d " "compression_type=%d filter_type=%d interlace_type=%d\n", s->width, s->height, s->bit_depth, s->color_type, s->compression_type, s->filter_type, s->interlace_type); @@ -525,7 +542,7 @@ static int decode_frame(AVCodecContext *avctx, s->width); s->crow_size = s->pass_row_size + 1; } - av_dlog(avctx, "row_size=%d crow_size =%d\n", + ff_dlog(avctx, "row_size=%d crow_size =%d\n", s->row_size, s->crow_size); s->image_buf = p->data[0]; s->image_linesize = p->linesize[0]; @@ -593,6 +610,22 @@ static int decode_frame(AVCodecContext *avctx, bytestream2_skip(&s->gb, 4); /* crc */ } break; + case MKTAG('s', 'T', 'E', 'R'): { + int mode = bytestream2_get_byte(&s->gb); + AVStereo3D *stereo3d = av_stereo3d_create_side_data(p); + if (!stereo3d) + goto the_end; + + if (mode == 0 || mode == 1) { + stereo3d->type = AV_STEREO3D_SIDEBYSIDE; + stereo3d->flags = mode ? 0 : AV_STEREO3D_FLAG_INVERT; + } else { + av_log(avctx, AV_LOG_WARNING, + "Unknown value in sTER chunk (%d)\n", mode); + } + bytestream2_skip(&s->gb, 4); /* crc */ + break; + } case MKTAG('I', 'E', 'N', 'D'): if (!(s->state & PNG_ALLIMAGE)) goto fail; @@ -606,7 +639,7 @@ skip_tag: } } exit_loop: - /* handle p-frames only if a predecessor frame is available */ + /* handle P-frames only if a predecessor frame is available */ if (s->prev->data[0]) { if (!(avpkt->flags & AV_PKT_FLAG_KEY)) { int i, j; @@ -645,6 +678,8 @@ static av_cold int png_dec_init(AVCodecContext *avctx) { PNGDecContext *s = avctx->priv_data; + avctx->color_range = AVCOL_RANGE_JPEG; + s->prev = av_frame_alloc(); if (!s->prev) return AVERROR(ENOMEM); @@ -672,5 +707,6 @@ AVCodec ff_png_decoder = { .init = png_dec_init, .close = png_dec_end, .decode = decode_frame, - .capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, + .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, };