From e2570297c05b56a3cf8dd69ebb160c7aadf2197e Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Mon, 13 Nov 2006 05:32:10 +0000 Subject: [PATCH] 8-bit images support for TIFF Originally committed as revision 7005 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/tiff.c | 84 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index c2fa186feb..7d1ea80580 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -37,7 +37,8 @@ enum TiffTags{ TIFF_STRIP_SIZE, TIFF_XPOS = 0x11E, TIFF_YPOS = 0x11F, - TIFF_PREDICTOR = 0x13D + TIFF_PREDICTOR = 0x13D, + TIFF_PAL = 0x140 }; enum TiffCompr{ @@ -69,6 +70,7 @@ typedef struct TiffContext { unsigned int bpp; int le; int compr; + int invert; int strips, rps; int sot; @@ -187,6 +189,7 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t int tag, type, count, off, value = 0; uint8_t *src, *dst; int i, j, ssize, soff, stride; + int *pal, *rp, *gp, *bp; tag = tget_short(&buf, s->le); type = tget_short(&buf, s->le); @@ -224,18 +227,6 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t break; case TIFF_HEIGHT: s->height = value; - s->avctx->pix_fmt = PIX_FMT_RGB24; - if(s->width != s->avctx->width || s->height != s->avctx->height){ - if(avcodec_check_dimensions(s->avctx, s->width, s->height)) - 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; - } break; case TIFF_BPP: if(count == 1) s->bpp = value; @@ -253,10 +244,34 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t s->bpp = -1; } } - if(s->bpp != 24){ - av_log(s->avctx, AV_LOG_ERROR, "Only RGB24 is supported\n"); + switch(s->bpp){ + case 8: + s->avctx->pix_fmt = PIX_FMT_PAL8; + break; + case 24: + s->avctx->pix_fmt = PIX_FMT_RGB24; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "Only RGB24 is supported (this bpp=%i)\n", s->bpp); return -1; } + if(s->width != s->avctx->width || s->height != s->avctx->height){ + if(avcodec_check_dimensions(s->avctx, s->width, s->height)) + 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 = s->picture.data[1]; + for(i = 0; i < 256; i++) + pal[i] = i * 0x010101; + } break; case TIFF_COMPR: s->compr = value; @@ -364,6 +379,33 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t } } break; + case TIFF_INVERT: + switch(value){ + case 0: + s->invert = 1; + break; + case 1: + s->invert = 0; + break; + } + break; + case TIFF_PAL: + if(s->avctx->pix_fmt != PIX_FMT_PAL8){ + av_log(s->avctx, AV_LOG_ERROR, "Palette met but this is not palettized format\n"); + return -1; + } + pal = s->picture.data[1]; + off = (type == TIFF_SHORT) ? 2 : 1; + rp = buf; + gp = buf + count / 3 * off; + bp = buf + count / 3 * off * 2; + off = (type == TIFF_SHORT) ? 8 : 0; + for(i = 0; i < count / 3; i++){ + j = (tget(&rp, type, s->le) >> off) << 16; + j |= (tget(&gp, type, s->le) >> off) << 8; + j |= tget(&bp, type, s->le) >> off; + pal[i] = j; + } } return 0; } @@ -388,6 +430,7 @@ static int decode_frame(AVCodecContext *avctx, return -1; } s->le = le; + s->invert = 0; // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number // that further identifies the file as a TIFF file" if(tget_short(&buf, le) != 42){ @@ -408,6 +451,17 @@ static int decode_frame(AVCodecContext *avctx, buf += 12; } + if(s->invert){ + uint8_t *src; + int j; + + src = s->picture.data[0]; + for(j = 0; j < s->height; j++){ + for(i = 0; i < s->picture.linesize[0]; i++) + src[i] = 255 - src[i]; + src += s->picture.linesize[0]; + } + } *picture= *(AVFrame*)&s->picture; *data_size = sizeof(AVPicture);