X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Flcldec.c;h=b66a3ce65b63ed701cfe17e47ed99e7fa01ab67f;hb=cdfe94c5ab1df40c6c724df5d4cafe2539c5571a;hp=4a5a2eb7997a4edc2205e0ebeb1fda296c0a9fb1;hpb=2fddb91e9496eb0e3caf99342123ef4cce801c14;p=ffmpeg diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 4a5a2eb7997..b66a3ce65b6 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -2,25 +2,25 @@ * LCL (LossLess Codec Library) Codec * Copyright (c) 2002-2004 Roberto Togni * - * 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 libavcodec/lcldec.c + * @file * LCL (LossLess Codec Library) Video Codec * Decoder for MSZH and ZLIB codecs * Experimental encoder for ZLIB RGB24 @@ -42,8 +42,9 @@ #include #include "avcodec.h" -#include "get_bits.h" +#include "bytestream.h" #include "lcl.h" +#include "libavutil/lzo.h" #if CONFIG_ZLIB_DECODER #include @@ -71,43 +72,44 @@ typedef struct LclDecContext { } LclDecContext; -static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) +/** + * @param srcptr compressed source buffer, must be padded with at least 5 extra bytes + * @param destptr must be padded sufficiently for av_memcpy_backptr + */ +static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) { unsigned char *destptr_bak = destptr; unsigned char *destptr_end = destptr + destsize; - unsigned char mask = 0; - unsigned char maskbit = 0; - unsigned int ofs, cnt; + const unsigned char *srcptr_end = srcptr + srclen; + unsigned mask = *srcptr++; + unsigned maskbit = 0x80; - while (srclen > 0 && destptr < destptr_end) { - if (maskbit == 0) { - mask = *srcptr++; - maskbit = 8; - srclen--; - continue; - } - if ((mask & (1 << (--maskbit))) == 0) { - if (destptr + 4 > destptr_end) - break; + while (srcptr < srcptr_end && destptr < destptr_end) { + if (!(mask & maskbit)) { memcpy(destptr, srcptr, 4); - srclen -= 4; destptr += 4; srcptr += 4; } else { - ofs = *srcptr++; - cnt = *srcptr++; - ofs += cnt * 256; - cnt = ((cnt >> 3) & 0x1f) + 1; + unsigned ofs = bytestream_get_le16(&srcptr); + unsigned cnt = (ofs >> 11) + 1; ofs &= 0x7ff; - srclen -= 2; + ofs = FFMIN(ofs, destptr - destptr_bak); cnt *= 4; - if (destptr + cnt > destptr_end) { - cnt = destptr_end - destptr; - } - for (; cnt > 0; cnt--) { - *destptr = *(destptr - ofs); - destptr++; + cnt = FFMIN(cnt, destptr_end - destptr); + av_memcpy_backptr(destptr, ofs, cnt); + destptr += cnt; + } + maskbit >>= 1; + if (!maskbit) { + mask = *srcptr++; + while (!mask) { + if (destptr_end - destptr < 32 || srcptr_end - srcptr < 32) break; + memcpy(destptr, srcptr, 32); + destptr += 32; + srcptr += 32; + mask = *srcptr++; } + maskbit = 0x80; } } @@ -115,12 +117,13 @@ static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned cha } +#if CONFIG_ZLIB_DECODER /** - * \brief decompress a zlib-compressed data block into decomp_buf - * \param src compressed input buffer - * \param src_len data length in input buffer - * \param offset offset in decomp_buf - * \param expected expected decompressed length + * @brief decompress a zlib-compressed data block into decomp_buf + * @param src compressed input buffer + * @param src_len data length in input buffer + * @param offset offset in decomp_buf + * @param expected expected decompressed length */ static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected) { @@ -146,6 +149,7 @@ static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, i } return c->zstream.total_out; } +#endif /* @@ -446,25 +450,14 @@ static av_cold int decode_init(AVCodecContext *avctx) { LclDecContext * const c = avctx->priv_data; unsigned int basesize = avctx->width * avctx->height; - unsigned int max_basesize = FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4); + unsigned int max_basesize = FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) + AV_LZO_OUTPUT_PADDING; unsigned int max_decomp_size; - c->pic.data[0] = NULL; - -#if CONFIG_ZLIB_DECODER - // Needed if zlib unused or init aborted before inflateInit - memset(&c->zstream, 0, sizeof(z_stream)); -#endif - if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); return 1; } - if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { - return 1; - } - /* Check codec type */ if ((avctx->codec_id == CODEC_ID_MSZH && avctx->extradata[7] != CODEC_MSZH) || (avctx->codec_id == CODEC_ID_ZLIB && avctx->extradata[7] != CODEC_ZLIB)) { @@ -515,7 +508,7 @@ static av_cold int decode_init(AVCodecContext *avctx) } /* Detect compression method */ - c->compression = avctx->extradata[5]; + c->compression = (int8_t)avctx->extradata[5]; switch (avctx->codec_id) { case CODEC_ID_MSZH: switch (c->compression) { @@ -586,6 +579,7 @@ static av_cold int decode_init(AVCodecContext *avctx) zret = inflateInit(&c->zstream); if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); + av_freep(&c->decomp_buf); return 1; } } @@ -603,41 +597,41 @@ static av_cold int decode_end(AVCodecContext *avctx) { LclDecContext * const c = avctx->priv_data; + av_freep(&c->decomp_buf); if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); #if CONFIG_ZLIB_DECODER - inflateEnd(&c->zstream); + if (avctx->codec_id == CODEC_ID_ZLIB) + inflateEnd(&c->zstream); #endif return 0; } #if CONFIG_MSZH_DECODER -AVCodec mszh_decoder = { - "mszh", - CODEC_TYPE_VIDEO, - CODEC_ID_MSZH, - sizeof(LclDecContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, +AVCodec ff_mszh_decoder = { + .name = "mszh", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MSZH, + .priv_data_size = sizeof(LclDecContext), + .init = decode_init, + .close = decode_end, + .decode = decode_frame, + .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"), }; #endif #if CONFIG_ZLIB_DECODER -AVCodec zlib_decoder = { - "zlib", - CODEC_TYPE_VIDEO, - CODEC_ID_ZLIB, - sizeof(LclDecContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, +AVCodec ff_zlib_decoder = { + .name = "zlib", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_ZLIB, + .priv_data_size = sizeof(LclDecContext), + .init = decode_init, + .close = decode_end, + .decode = decode_frame, + .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), }; #endif