diff options
Diffstat (limited to 'libavcodec/loco.c')
-rw-r--r-- | libavcodec/loco.c | 87 |
1 files changed, 37 insertions, 50 deletions
diff --git a/libavcodec/loco.c b/libavcodec/loco.c index b1ad41ae46..e21e693166 100644 --- a/libavcodec/loco.c +++ b/libavcodec/loco.c @@ -2,20 +2,20 @@ * LOCO codec * Copyright (c) 2005 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg 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. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -133,6 +133,9 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh int val; int i, j; + if(buf_size<=0) + return -1; + init_get_bits(&rc.gb, buf, buf_size*8); rc.save = 0; rc.run = 0; @@ -186,83 +189,65 @@ static int decode_frame(AVCodecContext *avctx, } p->key_frame = 1; +#define ADVANCE_BY_DECODED do { \ + if (decoded < 0 || decoded >= buf_size) goto buf_too_small; \ + buf += decoded; buf_size -= decoded; \ +} while(0) switch(l->mode) { case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY: decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, p->linesize[0], buf, buf_size, 1); - if (decoded >= buf_size) - goto buf_too_small; - buf += decoded; buf_size -= decoded; - + ADVANCE_BY_DECODED; decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height, p->linesize[1], buf, buf_size, 1); - if (decoded >= buf_size) - goto buf_too_small; - buf += decoded; buf_size -= decoded; - + ADVANCE_BY_DECODED; decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height, p->linesize[2], buf, buf_size, 1); break; case LOCO_CYV12: case LOCO_YV12: decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, p->linesize[0], buf, buf_size, 1); - if (decoded >= buf_size) - goto buf_too_small; - buf += decoded; buf_size -= decoded; - + ADVANCE_BY_DECODED; decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height / 2, p->linesize[2], buf, buf_size, 1); - if (decoded >= buf_size) - goto buf_too_small; - buf += decoded; buf_size -= decoded; - + ADVANCE_BY_DECODED; decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height / 2, p->linesize[1], buf, buf_size, 1); break; case LOCO_CRGB: case LOCO_RGB: decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, -p->linesize[0], buf, buf_size, 3); - if (decoded >= buf_size) - goto buf_too_small; - buf += decoded; buf_size -= decoded; - + ADVANCE_BY_DECODED; decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 1, avctx->width, avctx->height, -p->linesize[0], buf, buf_size, 3); - if (decoded >= buf_size) - goto buf_too_small; - buf += decoded; buf_size -= decoded; - + ADVANCE_BY_DECODED; decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height, -p->linesize[0], buf, buf_size, 3); break; + case LOCO_CRGBA: case LOCO_RGBA: - decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, - p->linesize[0], buf, buf_size, 4); - if (decoded >= buf_size) - goto buf_too_small; - buf += decoded; buf_size -= decoded; - - decoded = loco_decode_plane(l, p->data[0] + 1, avctx->width, avctx->height, - p->linesize[0], buf, buf_size, 4); - if (decoded >= buf_size) - goto buf_too_small; - buf += decoded; buf_size -= decoded; - - decoded = loco_decode_plane(l, p->data[0] + 2, avctx->width, avctx->height, - p->linesize[0], buf, buf_size, 4); - if (decoded >= buf_size) - goto buf_too_small; - buf += decoded; buf_size -= decoded; - - decoded = loco_decode_plane(l, p->data[0] + 3, avctx->width, avctx->height, - p->linesize[0], buf, buf_size, 4); + decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, + -p->linesize[0], buf, buf_size, 4); + ADVANCE_BY_DECODED; + decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 1, avctx->width, avctx->height, + -p->linesize[0], buf, buf_size, 4); + ADVANCE_BY_DECODED; + decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height, + -p->linesize[0], buf, buf_size, 4); + ADVANCE_BY_DECODED; + decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 3, avctx->width, avctx->height, + -p->linesize[0], buf, buf_size, 4); break; } + if (decoded < 0 || decoded > buf_size) + goto buf_too_small; + buf_size -= decoded; + *got_frame = 1; *(AVFrame*)data = l->pic; - return buf_size; + return avpkt->size - buf_size; buf_too_small: av_log(avctx, AV_LOG_ERROR, "Input data too small.\n"); return AVERROR(EINVAL); @@ -309,7 +294,7 @@ static av_cold int decode_init(AVCodecContext *avctx) break; case LOCO_CRGBA: case LOCO_RGBA: - avctx->pix_fmt = AV_PIX_FMT_RGB32; + avctx->pix_fmt = AV_PIX_FMT_BGRA; break; default: av_log(avctx, AV_LOG_INFO, "Unknown colorspace, index = %i\n", l->mode); @@ -318,6 +303,8 @@ static av_cold int decode_init(AVCodecContext *avctx) if (avctx->debug & FF_DEBUG_PICT_INFO) av_log(avctx, AV_LOG_INFO, "lossy:%i, version:%i, mode: %i\n", l->lossy, version, l->mode); + avcodec_get_frame_defaults(&l->pic); + return 0; } |