X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmjpegbdec.c;h=4ad17ab3ce3010d05e99a0af6ddae972cf889c75;hb=2df73eefb4f7c954d2bb80afa823bb7d4f8e5006;hp=7056bd2b28ea04847b3d86344352f115354c83d6;hpb=81752d0c2bf56827d91b676113aab1ee4f5b69de;p=ffmpeg diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index 7056bd2b28e..4ad17ab3ce3 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -2,25 +2,25 @@ * Apple MJPEG-B decoder * Copyright (c) 2002 Alex Beregszaszi * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file mjpegbdec.c + * @file * Apple MJPEG-B decoder. */ @@ -28,13 +28,23 @@ #include "mjpeg.h" #include "mjpegdec.h" +static uint32_t read_offs(AVCodecContext *avctx, GetBitContext *gb, uint32_t size, const char *err_msg){ + uint32_t offs= get_bits_long(gb, 32); + if(offs >= size){ + av_log(avctx, AV_LOG_WARNING, err_msg, offs, size); + return 0; + } + return offs; +} static int mjpegb_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + AVPacket *avpkt) { + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; MJpegDecodeContext *s = avctx->priv_data; - uint8_t *buf_end, *buf_ptr; + const uint8_t *buf_end, *buf_ptr; AVFrame *picture = data; GetBitContext hgb; /* for the header */ uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs; @@ -62,19 +72,21 @@ read_header: field_size = get_bits_long(&hgb, 32); /* field size */ av_log(avctx, AV_LOG_DEBUG, "field size: 0x%x\n", field_size); skip_bits(&hgb, 32); /* padded field size */ - second_field_offs = get_bits_long(&hgb, 32); + second_field_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "second_field_offs is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "second field offs: 0x%x\n", second_field_offs); - dqt_offs = get_bits_long(&hgb, 32); + dqt_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dqt is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%x\n", dqt_offs); if (dqt_offs) { init_get_bits(&s->gb, buf_ptr+dqt_offs, (buf_end - (buf_ptr+dqt_offs))*8); s->start_code = DQT; - ff_mjpeg_decode_dqt(s); + if (ff_mjpeg_decode_dqt(s) < 0 && + (avctx->err_recognition & AV_EF_EXPLODE)) + return AVERROR_INVALIDDATA; } - dht_offs = get_bits_long(&hgb, 32); + dht_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dht is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%x\n", dht_offs); if (dht_offs) { @@ -83,7 +95,7 @@ read_header: ff_mjpeg_decode_dht(s); } - sof_offs = get_bits_long(&hgb, 32); + sof_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%x\n", sof_offs); if (sof_offs) { @@ -93,9 +105,9 @@ read_header: return -1; } - sos_offs = get_bits_long(&hgb, 32); + sos_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sos is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "sos offs: 0x%x\n", sos_offs); - sod_offs = get_bits_long(&hgb, 32); + sod_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs); if (sos_offs) { @@ -103,13 +115,15 @@ read_header: init_get_bits(&s->gb, buf_ptr+sos_offs, field_size*8); s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); s->start_code = SOS; - ff_mjpeg_decode_sos(s); + if (ff_mjpeg_decode_sos(s, NULL, NULL) < 0 && + (avctx->err_recognition & AV_EF_EXPLODE)) + return AVERROR_INVALIDDATA; } if (s->interlaced) { s->bottom_field ^= 1; /* if not bottom field, do not output image yet */ - if (s->bottom_field && second_field_offs) + if (s->bottom_field != s->interlace_polarity && second_field_offs) { buf_ptr = buf + second_field_offs; second_field_offs = 0; @@ -119,11 +133,11 @@ read_header: //XXX FIXME factorize, this looks very similar to the EOI code - *picture= s->picture; + *picture= *s->picture_ptr; *data_size = sizeof(AVFrame); if(!s->lossless){ - picture->quality= FFMAX(FFMAX(s->qscale[0], s->qscale[1]), s->qscale[2]); + picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]); picture->qstride= 0; picture->qscale_table= s->qscale_table; memset(picture->qscale_table, picture->quality, (s->width+15)/16); @@ -135,15 +149,15 @@ read_header: return buf_ptr - buf; } -AVCodec mjpegb_decoder = { - "mjpegb", - CODEC_TYPE_VIDEO, - CODEC_ID_MJPEGB, - sizeof(MJpegDecodeContext), - ff_mjpeg_decode_init, - NULL, - ff_mjpeg_decode_end, - mjpegb_decode_frame, - CODEC_CAP_DR1, - NULL +AVCodec ff_mjpegb_decoder = { + .name = "mjpegb", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MJPEGB, + .priv_data_size = sizeof(MJpegDecodeContext), + .init = ff_mjpeg_decode_init, + .close = ff_mjpeg_decode_end, + .decode = mjpegb_decode_frame, + .capabilities = CODEC_CAP_DR1, + .max_lowres = 3, + .long_name = NULL_IF_CONFIG_SMALL("Apple MJPEG-B"), };