On date Monday 2011-05-09 22:27:44 +0200, Stefano Sabatini encoded: > Also add support for bits per component storage. > > Fix decoding of file 11.tiff, trac issue number #167. > > Based on a patch by Kostya Shiskov <[email protected]>.
Updated, CC-ed to libav-devel.
>From f264eeb4d74f399f04b6a70536a5e9131bfd5283 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini <[email protected]> Date: Mon, 9 May 2011 12:51:24 +0200 Subject: [PATCH] tiff: add support to TIFF_SAMPLES_PER_PIXEL case in tiff_decode_tag() Also add support for bits per component storage. Fix decoding of file 11.tiff, trac issue number #167. Based on a patch by Kostya Shishkov <[email protected]>. --- libavcodec/tiff.c | 138 ++++++++++++++++++++++++++++------------------------- 1 files changed, 73 insertions(+), 65 deletions(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index f252913..9a94e86 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -38,7 +38,7 @@ typedef struct TiffContext { AVFrame picture; int width, height; - unsigned int bpp; + unsigned int bpp[4], bppcount, totalbpp; int le; enum TiffCompr compr; int invert; @@ -101,7 +101,7 @@ static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src, static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uint8_t *src, int size, int lines){ int c, line, pixels, code; const uint8_t *ssrc = src; - int width = s->width * s->bpp >> 3; + int width = s->width * s->totalbpp >> 3; #if CONFIG_ZLIB uint8_t *zbuf; unsigned long outlen; @@ -208,6 +208,58 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin return 0; } +static int init_image(TiffContext *s) +{ + int i, ret; + uint32_t *pal; + + /* compute total bpp */ + s->totalbpp = 0; + for (i = 0; i < s->bppcount; i++) + s->totalbpp += s->bpp[i] ? s->bpp[i] : s->bpp[0]; + + switch (s->totalbpp*10 + s->bppcount) { + case 11: + s->avctx->pix_fmt = PIX_FMT_MONOBLACK; + break; + case 81: + s->avctx->pix_fmt = PIX_FMT_PAL8; + break; + case 243: + s->avctx->pix_fmt = PIX_FMT_RGB24; + break; + case 161: + s->avctx->pix_fmt = PIX_FMT_GRAY16BE; + break; + case 324: + s->avctx->pix_fmt = PIX_FMT_RGBA; + break; + case 483: + s->avctx->pix_fmt = s->le ? PIX_FMT_RGB48LE : PIX_FMT_RGB48BE; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, bppcount=%d)\n", s->totalbpp, s->bppcount); + return AVERROR_INVALIDDATA; + } + if (s->width != s->avctx->width || s->height != s->avctx->height) { + if ((ret = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0) + return ret; + avcodec_set_dimensions(s->avctx, s->width, s->height); + } + if (s->picture.data[0]) + s->avctx->release_buffer(s->avctx, &s->picture); + if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0) { + av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + if (s->totalbpp == 8 && s->picture.data[1]){ + /* make default grayscale pal */ + pal = (uint32_t *) s->picture.data[1]; + for (i = 0; i < 256; i++) + pal[i] = i * 0x010101; + } + return 0; +} static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf) { @@ -261,65 +313,33 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * s->height = value; break; case TIFF_BPP: + s->bppcount = count; if(count > 4){ - av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count); + av_log(s->avctx, AV_LOG_ERROR, "More than 4 pixel components are not supported, %d specified\n", count); return -1; } - if(count == 1) s->bpp = value; + if (count == 1) s->bpp[0] = value; else{ switch(type){ case TIFF_BYTE: - s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF); + s->bpp[0] = off & 0xFF; + s->bpp[1] = (off >> 8) & 0xFF; + s->bpp[2] = (off >> 16) & 0xFF; + s->bpp[3] = (off >> 24) & 0xFF; break; case TIFF_SHORT: case TIFF_LONG: - s->bpp = 0; - for(i = 0; i < count; i++) s->bpp += tget(&buf, type, s->le); + for (i = 0; i < count; i++) s->bpp[i] = tget(&buf, type, s->le); break; - default: - s->bpp = -1; } } - switch(s->bpp*10 + count){ - case 11: - s->avctx->pix_fmt = PIX_FMT_MONOBLACK; - break; - case 81: - s->avctx->pix_fmt = PIX_FMT_PAL8; - break; - case 243: - s->avctx->pix_fmt = PIX_FMT_RGB24; - break; - case 161: - s->avctx->pix_fmt = PIX_FMT_GRAY16BE; - break; - case 324: - s->avctx->pix_fmt = PIX_FMT_RGBA; - break; - case 483: - s->avctx->pix_fmt = s->le ? PIX_FMT_RGB48LE : PIX_FMT_RGB48BE; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count); - return -1; - } - if(s->width != s->avctx->width || s->height != s->avctx->height){ - if(av_image_check_size(s->width, s->height, 0, s->avctx)) - return -1; - avcodec_set_dimensions(s->avctx, s->width, s->height); - } - if(s->picture.data[0]) - s->avctx->release_buffer(s->avctx, &s->picture); - if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - if(s->bpp == 8){ - /* make default grayscale pal */ - pal = (uint32_t *) s->picture.data[1]; - for(i = 0; i < 256; i++) - pal[i] = i * 0x010101; + break; + case TIFF_SAMPLES_PER_PIXEL: + if (count != 1) { + av_log(s->avctx, AV_LOG_ERROR, "Samples per pixel is not a single value\n"); + return AVERROR_INVALIDDATA; } + s->bppcount = value; break; case TIFF_COMPR: s->compr = value; @@ -462,7 +482,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture = data; AVFrame * const p= (AVFrame*)&s->picture; const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; - int id, le, off; + int id, le, off, ret; int i, j, entries; int stride, soff, ssize; uint8_t *dst; @@ -503,21 +523,9 @@ static int decode_frame(AVCodecContext *avctx, return -1; } /* now we have the data and may start decoding */ - if(!p->data[0]){ - s->bpp = 1; - avctx->pix_fmt = PIX_FMT_MONOBLACK; - if(s->width != s->avctx->width || s->height != s->avctx->height){ - if(av_image_check_size(s->width, s->height, 0, s->avctx)) - return -1; - avcodec_set_dimensions(s->avctx, s->width, s->height); - } - if(s->picture.data[0]) - s->avctx->release_buffer(s->avctx, &s->picture); - if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - } + if ((ret = init_image(s)) < 0) + return ret; + if(s->strips == 1 && !s->stripsize){ av_log(avctx, AV_LOG_WARNING, "Image data size missing\n"); s->stripsize = buf_size - s->stripoff; @@ -549,7 +557,7 @@ static int decode_frame(AVCodecContext *avctx, } if(s->predictor == 2){ dst = p->data[0]; - soff = s->bpp >> 3; + soff = s->totalbpp >> 3; ssize = s->width * soff; for(i = 0; i < s->height; i++) { for(j = soff; j < ssize; j++) -- 1.7.2.3
_______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
