aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/tiff.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2018-12-14 17:32:25 +0100
committerPaul B Mahol <onemda@gmail.com>2018-12-16 22:06:08 +0100
commitde5e71fb1b2caa1d3925fa39d4242dc620f4dd8e (patch)
treeaffd7020631ce7a0450e1f07d115cc61aa6921ed /libavcodec/tiff.c
parent092cb17983b2660b4e050a05c739060f8e03d27a (diff)
downloadffmpeg-de5e71fb1b2caa1d3925fa39d4242dc620f4dd8e.tar.gz
avcodec/tiff: add support for 12bit grayscale images
Fixes #4688.
Diffstat (limited to 'libavcodec/tiff.c')
-rw-r--r--libavcodec/tiff.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index f71885d156..570b3cbd01 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -310,6 +310,19 @@ static int deinvert_buffer(TiffContext *s, const uint8_t *src, int size)
return 0;
}
+static void unpack_gray(TiffContext *s, AVFrame *p,
+ const uint8_t *src, int lnum, int width, int bpp)
+{
+ GetBitContext gb;
+ uint16_t *dst = (uint16_t *)(p->data[0] + lnum * p->linesize[0]);
+
+ init_get_bits8(&gb, src, width);
+
+ for (int i = 0; i < s->width; i++) {
+ dst[i] = get_bits(&gb, bpp);
+ }
+}
+
static void unpack_yuv(TiffContext *s, AVFrame *p,
const uint8_t *src, int lnum)
{
@@ -540,6 +553,15 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid
if (s->is_bayer) {
width = (s->bpp * s->width + 7) >> 3;
}
+ if (p->format == AV_PIX_FMT_GRAY12) {
+ av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, width);
+ if (s->yuv_line == NULL) {
+ av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
+ return AVERROR(ENOMEM);
+ }
+ dst = s->yuv_line;
+ stride = 0;
+ }
if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
#if CONFIG_ZLIB
@@ -587,6 +609,8 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid
if (is_yuv) {
unpack_yuv(s, p, dst, strip_start + line);
line += s->subsampling[1] - 1;
+ } else if (p->format == AV_PIX_FMT_GRAY12) {
+ unpack_gray(s, p, dst, strip_start + line, width, s->bpp);
}
dst += stride;
}
@@ -670,6 +694,8 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid
if (is_yuv) {
unpack_yuv(s, p, dst, strip_start + line);
line += s->subsampling[1] - 1;
+ } else if (p->format == AV_PIX_FMT_GRAY12) {
+ unpack_gray(s, p, dst, strip_start + line, width, s->bpp);
}
dst += stride;
}
@@ -705,6 +731,9 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
case 81:
s->avctx->pix_fmt = s->palette_is_set ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
break;
+ case 121:
+ s->avctx->pix_fmt = AV_PIX_FMT_GRAY12;
+ break;
case 10081:
switch (AV_RL32(s->pattern)) {
case 0x02010100: