diff options
Diffstat (limited to 'libavcodec/zmbv.c')
-rw-r--r-- | libavcodec/zmbv.c | 123 |
1 files changed, 45 insertions, 78 deletions
diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c index d17f37a59f..21a9e35c39 100644 --- a/libavcodec/zmbv.c +++ b/libavcodec/zmbv.c @@ -2,20 +2,20 @@ * Zip Motion Blocks Video (ZMBV) decoder * Copyright (c) 2006 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 */ @@ -28,6 +28,7 @@ #include <stdlib.h> #include "libavutil/common.h" +#include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "internal.h" @@ -64,6 +65,7 @@ typedef struct ZmbvContext { int fmt; int comp; int flags; + int stride; int bw, bh, bx, by; int decomp_len; z_stream zstream; @@ -143,7 +145,7 @@ static int zmbv_decode_xor_8(ZmbvContext *c) prev += c->width * c->bh; } if (src - c->decomp_buf != c->decomp_len) - av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", + av_log(c->avctx, AV_LOG_ERROR, "Used %"PTRDIFF_SPECIFIER" of %i bytes\n", src-c->decomp_buf, c->decomp_len); return 0; } @@ -217,7 +219,7 @@ static int zmbv_decode_xor_16(ZmbvContext *c) prev += c->width * c->bh; } if (src - c->decomp_buf != c->decomp_len) - av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", + av_log(c->avctx, AV_LOG_ERROR, "Used %"PTRDIFF_SPECIFIER" of %i bytes\n", src-c->decomp_buf, c->decomp_len); return 0; } @@ -375,7 +377,7 @@ static int zmbv_decode_xor_32(ZmbvContext *c) prev += c->width * c->bh; } if (src - c->decomp_buf != c->decomp_len) - av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", + av_log(c->avctx, AV_LOG_ERROR, "Used %"PTRDIFF_SPECIFIER" of %i bytes\n", src-c->decomp_buf, c->decomp_len); return 0; } @@ -406,17 +408,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac int zret = Z_OK; // Zlib return code int len = buf_size; int hi_ver, lo_ver, ret; - uint8_t *tmp; - - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return ret; - } /* parse header */ c->flags = buf[0]; buf++; len--; if (c->flags & ZMBV_KEYFRAME) { + void *decode_intra = NULL; + c->decode_intra= NULL; hi_ver = buf[0]; lo_ver = buf[1]; c->comp = buf[2]; @@ -447,29 +445,39 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac switch (c->fmt) { case ZMBV_FMT_8BPP: c->bpp = 8; - c->decode_intra = zmbv_decode_intra; + decode_intra = zmbv_decode_intra; c->decode_xor = zmbv_decode_xor_8; + avctx->pix_fmt = AV_PIX_FMT_PAL8; + c->stride = c->width; break; case ZMBV_FMT_15BPP: case ZMBV_FMT_16BPP: c->bpp = 16; - c->decode_intra = zmbv_decode_intra; + decode_intra = zmbv_decode_intra; c->decode_xor = zmbv_decode_xor_16; + if (c->fmt == ZMBV_FMT_15BPP) + avctx->pix_fmt = AV_PIX_FMT_RGB555LE; + else + avctx->pix_fmt = AV_PIX_FMT_RGB565LE; + c->stride = c->width * 2; break; #ifdef ZMBV_ENABLE_24BPP case ZMBV_FMT_24BPP: c->bpp = 24; - c->decode_intra = zmbv_decode_intra; + decode_intra = zmbv_decode_intra; c->decode_xor = zmbv_decode_xor_24; + avctx->pix_fmt = AV_PIX_FMT_RGB24; + c->stride = c->width * 3; break; #endif //ZMBV_ENABLE_24BPP case ZMBV_FMT_32BPP: c->bpp = 32; - c->decode_intra = zmbv_decode_intra; + decode_intra = zmbv_decode_intra; c->decode_xor = zmbv_decode_xor_32; + avctx->pix_fmt = AV_PIX_FMT_BGR0; + c->stride = c->width * 4; break; default: - c->decode_intra = NULL; c->decode_xor = NULL; avpriv_request_sample(avctx, "Format %i", c->fmt); return AVERROR_PATCHWELCOME; @@ -481,16 +489,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac return AVERROR_UNKNOWN; } - tmp = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8)); - if (!tmp) - return AVERROR(ENOMEM); - c->cur = tmp; - tmp = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8)); - if (!tmp) + c->cur = av_realloc_f(c->cur, avctx->width * avctx->height, (c->bpp / 8)); + c->prev = av_realloc_f(c->prev, avctx->width * avctx->height, (c->bpp / 8)); + c->bx = (c->width + c->bw - 1) / c->bw; + c->by = (c->height+ c->bh - 1) / c->bh; + if (!c->cur || !c->prev) return AVERROR(ENOMEM); - c->prev = tmp; - c->bx = (c->width + c->bw - 1) / c->bw; - c->by = (c->height + c->bh - 1) / c->bh; + memset(c->cur, 0, avctx->width * avctx->height * (c->bpp / 8)); + memset(c->prev, 0, avctx->width * avctx->height * (c->bpp / 8)); + c->decode_intra= decode_intra; } if (c->decode_intra == NULL) { @@ -498,6 +505,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac return AVERROR_INVALIDDATA; } + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + if (c->comp == 0) { //Uncompressed data if (c->decomp_size < len) { av_log(avctx, AV_LOG_ERROR, "Buffer too small\n"); @@ -506,7 +516,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac memcpy(c->decomp_buf, buf, len); } else { // ZLIB-compressed data c->zstream.total_in = c->zstream.total_out = 0; - c->zstream.next_in = buf; + c->zstream.next_in = (uint8_t*)buf; c->zstream.avail_in = len; c->zstream.next_out = c->decomp_buf; c->zstream.avail_out = c->decomp_size; @@ -531,64 +541,22 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac /* update frames */ { uint8_t *out, *src; - int i, j; + int j; out = frame->data[0]; src = c->cur; switch (c->fmt) { case ZMBV_FMT_8BPP: - for (j = 0; j < c->height; j++) { - for (i = 0; i < c->width; i++) { - out[i * 3 + 0] = c->pal[(*src) * 3 + 0]; - out[i * 3 + 1] = c->pal[(*src) * 3 + 1]; - out[i * 3 + 2] = c->pal[(*src) * 3 + 2]; - src++; - } - out += frame->linesize[0]; - } - break; + for (j = 0; j < 256; j++) + AV_WN32(&frame->data[1][j * 4], 0xFFU << 24 | AV_RB24(&c->pal[j * 3])); case ZMBV_FMT_15BPP: - for (j = 0; j < c->height; j++) { - for (i = 0; i < c->width; i++) { - uint16_t tmp = AV_RL16(src); - src += 2; - out[i * 3 + 0] = (tmp & 0x7C00) >> 7; - out[i * 3 + 1] = (tmp & 0x03E0) >> 2; - out[i * 3 + 2] = (tmp & 0x001F) << 3; - } - out += frame->linesize[0]; - } - break; case ZMBV_FMT_16BPP: - for (j = 0; j < c->height; j++) { - for (i = 0; i < c->width; i++) { - uint16_t tmp = AV_RL16(src); - src += 2; - out[i * 3 + 0] = (tmp & 0xF800) >> 8; - out[i * 3 + 1] = (tmp & 0x07E0) >> 3; - out[i * 3 + 2] = (tmp & 0x001F) << 3; - } - out += frame->linesize[0]; - } - break; #ifdef ZMBV_ENABLE_24BPP case ZMBV_FMT_24BPP: - for (j = 0; j < c->height; j++) { - memcpy(out, src, c->width * 3); - src += c->width * 3; - out += frame->linesize[0]; - } - break; -#endif //ZMBV_ENABLE_24BPP +#endif case ZMBV_FMT_32BPP: - for (j = 0; j < c->height; j++) { - for (i = 0; i < c->width; i++) { - uint32_t tmp = AV_RL32(src); - src += 4; - AV_WB24(out+(i*3), tmp); - } - out += frame->linesize[0]; - } + av_image_copy_plane(out, frame->linesize[0], src, c->stride, + c->stride, c->height); break; default: av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt); @@ -616,12 +584,11 @@ static av_cold int decode_init(AVCodecContext *avctx) // Needed if zlib unused or init aborted before inflateInit memset(&c->zstream, 0, sizeof(z_stream)); - avctx->pix_fmt = AV_PIX_FMT_RGB24; c->decomp_size = (avctx->width + 255) * 4 * (avctx->height + 64); /* Allocate decompression buffer */ if (c->decomp_size) { - if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) { + if ((c->decomp_buf = av_mallocz(c->decomp_size)) == NULL) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); return AVERROR(ENOMEM); |