X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Flcldec.c;h=d4fe65ccebb4d5bfc9abc4c5150e6cdf1e400e58;hb=8d872e8ac9d17dd004af60787cd69eac69ef8891;hp=5225ff0552572bc3dcc263e07a8e9f819a8dd039;hpb=e4f141ad60afbd721e494975677fbfd8e0ebcb22;p=ffmpeg diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 5225ff05525..d4fe65ccebb 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -73,7 +73,7 @@ typedef struct LclDecContext { /** - * \param srcptr compressed source buffer, must be padded with at least 4 extra bytes + * \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) @@ -81,31 +81,36 @@ static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsign unsigned char *destptr_bak = destptr; unsigned char *destptr_end = destptr + destsize; const unsigned char *srcptr_end = srcptr + srclen; - unsigned char mask = 0; - unsigned char maskbit = 0; - unsigned int ofs, cnt; + unsigned mask = *srcptr++; + unsigned maskbit = 0x80; while (srcptr < srcptr_end && destptr < destptr_end) { - if (maskbit == 0) { - mask = *srcptr++; - maskbit = 8; - continue; - } - if ((mask & (1 << (--maskbit))) == 0) { - if (destptr_end - destptr < 4) - break; + if (!(mask & maskbit)) { memcpy(destptr, srcptr, 4); destptr += 4; srcptr += 4; } else { - ofs = bytestream_get_le16(&srcptr); - cnt = (ofs >> 11) + 1; + unsigned ofs = bytestream_get_le16(&srcptr); + unsigned cnt = (ofs >> 11) + 1; ofs &= 0x7ff; + ofs = FFMIN(ofs, destptr - destptr_bak); cnt *= 4; 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; + } } return destptr - destptr_bak; @@ -119,6 +124,7 @@ static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsign * \param offset offset in decomp_buf * \param expected expected decompressed length */ +#if CONFIG_ZLIB_DECODER static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected) { LclDecContext *c = avctx->priv_data; @@ -143,6 +149,7 @@ static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, i } return c->zstream.total_out; } +#endif /* @@ -446,22 +453,11 @@ static av_cold int decode_init(AVCodecContext *avctx) 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)) { @@ -512,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) { @@ -583,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; } } @@ -600,10 +597,12 @@ 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;