X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fsunrast.c;h=a10f44964817947d1558f5e8324c8723be7accb3;hb=dbb37e77117466edfc146f9f0df4c70bef6239d6;hp=8a78f1aab4e6ac0b8141a5d270d129a401742ebb;hpb=7a00bbad2100367481240e62876b941b5c4befdc;p=ffmpeg diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c index 8a78f1aab4e..a10f4496481 100644 --- a/libavcodec/sunrast.c +++ b/libavcodec/sunrast.c @@ -2,32 +2,28 @@ * Sun Rasterfile (.sun/.ras/im{1,8,24}/.sunras) image decoder * Copyright (c) 2007, 2008 Ivo van Poorten * - * 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 */ +#include "libavutil/common.h" #include "libavutil/intreadwrite.h" +#include "libavutil/imgutils.h" #include "avcodec.h" - -#define RT_OLD 0 -#define RT_STANDARD 1 -#define RT_BYTE_ENCODED 2 -#define RT_FORMAT_RGB 3 -#define RT_FORMAT_TIFF 4 -#define RT_FORMAT_IFF 5 +#include "sunrast.h" typedef struct SUNRASTContext { AVFrame picture; @@ -37,96 +33,105 @@ static av_cold int sunrast_init(AVCodecContext *avctx) { SUNRASTContext *s = avctx->priv_data; avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; + avctx->coded_frame = &s->picture; return 0; } static int sunrast_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; SUNRASTContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = &s->picture; + AVFrame *picture = data; + AVFrame * const p = &s->picture; unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen; uint8_t *ptr; const uint8_t *bufstart = buf; + int ret; + + if (avpkt->size < 32) + return AVERROR_INVALIDDATA; - if (AV_RB32(buf) != 0x59a66a95) { + if (AV_RB32(buf) != RAS_MAGIC) { av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n"); - return -1; + return AVERROR_INVALIDDATA; } - w = AV_RB32(buf+4); - h = AV_RB32(buf+8); - depth = AV_RB32(buf+12); - type = AV_RB32(buf+20); - maptype = AV_RB32(buf+24); - maplength = AV_RB32(buf+28); - - if (type > RT_BYTE_ENCODED && type <= RT_FORMAT_IFF) { - av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n"); - return -1; + w = AV_RB32(buf + 4); + h = AV_RB32(buf + 8); + depth = AV_RB32(buf + 12); + type = AV_RB32(buf + 20); + maptype = AV_RB32(buf + 24); + maplength = AV_RB32(buf + 28); + buf += 32; + + if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF || type == RT_EXPERIMENTAL) { + av_log_ask_for_sample(avctx, "unsupported (compression) type\n"); + return AVERROR_PATCHWELCOME; } if (type > RT_FORMAT_IFF) { av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); - return -1; + return AVERROR_INVALIDDATA; + } + if (av_image_check_size(w, h, 0, avctx)) { + av_log(avctx, AV_LOG_ERROR, "invalid image size\n"); + return AVERROR_INVALIDDATA; } - if (maptype & ~1) { + if (maptype == RMT_RAW) { + av_log_ask_for_sample(avctx, "unsupported colormap type\n"); + return AVERROR_PATCHWELCOME; + } + if (maptype > RMT_RAW) { av_log(avctx, AV_LOG_ERROR, "invalid colormap type\n"); - return -1; + return AVERROR_INVALIDDATA; } - buf += 32; switch (depth) { case 1: - avctx->pix_fmt = PIX_FMT_MONOWHITE; + avctx->pix_fmt = AV_PIX_FMT_MONOWHITE; break; case 8: - avctx->pix_fmt = PIX_FMT_PAL8; + avctx->pix_fmt = maplength ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8; break; case 24: - avctx->pix_fmt = PIX_FMT_BGR24; + avctx->pix_fmt = (type == RT_FORMAT_RGB) ? AV_PIX_FMT_RGB24 : AV_PIX_FMT_BGR24; break; default: av_log(avctx, AV_LOG_ERROR, "invalid depth\n"); - return -1; + return AVERROR_INVALIDDATA; } if (p->data[0]) avctx->release_buffer(avctx, p); - if (avcodec_check_dimensions(avctx, w, h)) - return -1; if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); - if (avctx->get_buffer(avctx, p) < 0) { + if ((ret = avctx->get_buffer(avctx, p)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } - p->pict_type = FF_I_TYPE; + p->pict_type = AV_PICTURE_TYPE_I; + + if (buf_end - buf < maplength) + return AVERROR_INVALIDDATA; if (depth != 8 && maplength) { av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n"); - } else if (depth == 8) { + } else if (maplength) { unsigned int len = maplength / 3; - if (!maplength) { - av_log(avctx, AV_LOG_ERROR, "colormap expected\n"); - return -1; - } if (maplength % 3 || maplength > 768) { av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n"); - return -1; + return AVERROR_INVALIDDATA; } ptr = p->data[1]; - for (x=0; x> 3; - alen = len + (len&1); + alen = len + (len & 1); if (type == RT_BYTE_ENCODED) { int value, run; - uint8_t *end = ptr + h*stride; + uint8_t *end = ptr + h * stride; x = 0; - while (ptr != end) { + while (ptr != end && buf < buf_end) { run = 1; - if ((value = *buf++) == 0x80) { + if (buf_end - buf < 1) + return AVERROR_INVALIDDATA; + + if ((value = *buf++) == RLE_TRIGGER) { run = *buf++ + 1; if (run != 1) value = *buf++; @@ -162,14 +170,16 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, } } } else { - for (y=0; ypicture; + *picture = s->picture; *data_size = sizeof(AVFrame); return buf - bufstart; @@ -184,16 +194,14 @@ static av_cold int sunrast_end(AVCodecContext *avctx) { return 0; } -AVCodec sunrast_decoder = { - "sunrast", - CODEC_TYPE_VIDEO, - CODEC_ID_SUNRAST, - sizeof(SUNRASTContext), - sunrast_init, - NULL, - sunrast_end, - sunrast_decode_frame, - 0, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"), +AVCodec ff_sunrast_decoder = { + .name = "sunrast", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_SUNRAST, + .priv_data_size = sizeof(SUNRASTContext), + .init = sunrast_init, + .close = sunrast_end, + .decode = sunrast_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"), };