diff options
author | James Almer <jamrial@gmail.com> | 2014-08-22 23:39:57 -0300 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-08-24 01:21:39 +0200 |
commit | b140b51ebbc277fa558accc33f3e99da2b9657b3 (patch) | |
tree | ea1db181210e86040569f0e62ef576c3e1b8c304 | |
parent | 2e3c1699aea7bb5a72d18903f4b8d3d33964c14d (diff) | |
download | ffmpeg-b140b51ebbc277fa558accc33f3e99da2b9657b3.tar.gz |
lavc/tiff: add support for LZMA compression
Derived from deflate code.
Requires liblzma.
Signed-off-by: James Almer <jamrial@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | Changelog | 1 | ||||
-rwxr-xr-x | configure | 5 | ||||
-rw-r--r-- | libavcodec/tiff.c | 85 |
3 files changed, 88 insertions, 3 deletions
@@ -7,6 +7,7 @@ version <next>: - large optimizations in dctdnoiz to make it usable - request icecast metadata by default - support for using metadata in stream specifiers in fftools +- LZMA compression support in TIFF decoder version 2.3: @@ -254,6 +254,7 @@ External library support: native MPEG-4/Xvid encoder exists [no] --enable-libzmq enable message passing via libzmq [no] --enable-libzvbi enable teletext support via libzvbi [no] + --disable-lzma disable lzma [autodetect] --enable-decklink enable Blackmagick DeckLink output [no] --enable-openal enable OpenAL 1.1 capture support [no] --enable-opencl enable OpenCL code @@ -1381,6 +1382,7 @@ EXTERNAL_LIBRARY_LIST=" libxvid libzmq libzvbi + lzma openal opencl opengl @@ -2188,7 +2190,7 @@ svq3_decoder_suggest="zlib" tak_decoder_select="audiodsp" theora_decoder_select="vp3_decoder" thp_decoder_select="mjpeg_decoder" -tiff_decoder_suggest="zlib" +tiff_decoder_suggest="zlib lzma" tiff_encoder_suggest="zlib" truehd_decoder_select="mlp_parser" truemotion2_decoder_select="bswapdsp" @@ -4759,6 +4761,7 @@ fi disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib +disabled lzma || check_lib2 lzma.h lzma_version_number -llzma || disable lzma check_lib math.h sin -lm && LIBM="-lm" disabled crystalhd || check_lib libcrystalhd/libcrystalhd_if.h DtsCrystalHDVersion -lcrystalhd || disable crystalhd diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 2bb7c906c4..613ad3d9e0 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -28,6 +28,9 @@ #if CONFIG_ZLIB #include <zlib.h> #endif +#if CONFIG_LZMA +#include <lzma.h> +#endif #include "libavutil/attributes.h" #include "libavutil/avstring.h" @@ -378,6 +381,70 @@ static int tiff_unpack_zlib(TiffContext *s, AVFrame *p, uint8_t *dst, int stride } #endif +#if CONFIG_LZMA +static int tiff_uncompress_lzma(uint8_t *dst, uint64_t *len, const uint8_t *src, + int size) +{ + lzma_stream stream = LZMA_STREAM_INIT; + lzma_ret ret; + + stream.next_in = (uint8_t *)src; + stream.avail_in = size; + stream.next_out = dst; + stream.avail_out = *len; + ret = lzma_stream_decoder(&stream, UINT64_MAX, 0); + if (ret != LZMA_OK) { + av_log(NULL, AV_LOG_ERROR, "LZMA init error: %d\n", ret); + return ret; + } + ret = lzma_code(&stream, LZMA_RUN); + lzma_end(&stream); + *len = stream.total_out; + return ret == LZMA_STREAM_END ? LZMA_OK : ret; +} + +static int tiff_unpack_lzma(TiffContext *s, AVFrame *p, uint8_t *dst, int stride, + const uint8_t *src, int size, int width, int lines, + int strip_start, int is_yuv) +{ + uint64_t outlen = width * lines; + int ret, line; + uint8_t *buf = av_malloc(outlen); + if (!buf) + return AVERROR(ENOMEM); + if (s->fill_order) { + if ((ret = deinvert_buffer(s, src, size)) < 0) { + av_free(buf); + return ret; + } + src = s->deinvert_buf; + } + ret = tiff_uncompress_lzma(buf, &outlen, src, size); + if (ret != LZMA_OK) { + av_log(s->avctx, AV_LOG_ERROR, + "Uncompressing failed (%"PRIu64" of %"PRIu64") with error %d\n", outlen, + (uint64_t)width * lines, ret); + av_free(buf); + return AVERROR_UNKNOWN; + } + src = buf; + for (line = 0; line < lines; line++) { + if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) { + horizontal_fill(s->bpp, dst, 1, src, 0, width, 0); + } else { + memcpy(dst, src, width); + } + if (is_yuv) { + unpack_yuv(s, p, dst, strip_start + line); + line += s->subsampling[1] - 1; + } + dst += stride; + src += width; + } + av_free(buf); + return 0; +} +#endif static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride, const uint8_t *src, int size, int width, int lines) @@ -457,6 +524,16 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid return AVERROR(ENOSYS); #endif } + if (s->compr == TIFF_LZMA) { +#if CONFIG_LZMA + return tiff_unpack_lzma(s, p, dst, stride, src, size, width, lines, + strip_start, is_yuv); +#else + av_log(s->avctx, AV_LOG_ERROR, + "LZMA support not enabled\n"); + return AVERROR(ENOSYS); +#endif + } if (s->compr == TIFF_LZW) { if (s->fill_order) { if ((ret = deinvert_buffer(s, src, size)) < 0) @@ -783,8 +860,12 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) avpriv_report_missing_feature(s->avctx, "JPEG compression"); return AVERROR_PATCHWELCOME; case TIFF_LZMA: - avpriv_report_missing_feature(s->avctx, "LZMA compression"); - return AVERROR_PATCHWELCOME; +#if CONFIG_LZMA + break; +#else + av_log(s->avctx, AV_LOG_ERROR, "LZMA not compiled in\n"); + return AVERROR(ENOSYS); +#endif default: av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr); |