X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Ftiff.c;h=4a12a2bb1e941c938884546d3962d45d2e77a75b;hb=d29ee34ce31668703913f9e9c5dc3b8df969addd;hp=199fbad70b6b3166d82d84c2299901e19eac0618;hpb=fead30d4440bc7b75006ae60f2742c63a05168b3;p=ffmpeg diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 199fbad70b6..4a12a2bb1e9 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -17,56 +17,20 @@ * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + */ + +/** + * TIFF image decoder + * @file tiff.c + * @author Konstantin Shishkov */ #include "avcodec.h" #ifdef CONFIG_ZLIB #include #endif #include "lzw.h" +#include "tiff.h" -/* abridged list of TIFF tags */ -enum TiffTags{ - TIFF_WIDTH = 0x100, - TIFF_HEIGHT, - TIFF_BPP, - TIFF_COMPR, - TIFF_INVERT = 0x106, - TIFF_STRIP_OFFS = 0x111, - TIFF_ROWSPERSTRIP = 0x116, - TIFF_STRIP_SIZE, - TIFF_PLANAR = 0x11C, - TIFF_XPOS = 0x11E, - TIFF_YPOS = 0x11F, - TIFF_PREDICTOR = 0x13D, - TIFF_PAL = 0x140 -}; - -enum TiffCompr{ - TIFF_RAW = 1, - TIFF_CCITT_RLE, - TIFF_G3, - TIFF_G4, - TIFF_LZW, - TIFF_JPEG, - TIFF_NEWJPEG, - TIFF_ADOBE_DEFLATE, - TIFF_PACKBITS = 0x8005, - TIFF_DEFLATE = 0x80B2 -}; - -enum TiffTypes{ - TIFF_BYTE = 1, - TIFF_STRING, - TIFF_SHORT, - TIFF_LONG, - TIFF_LONGLONG -}; - -/** sizes of various TIFF field types */ -static const int type_sizes[6] = { - 0, 1, 100, 2, 4, 8 -}; typedef struct TiffContext { AVCodecContext *avctx; @@ -80,25 +44,25 @@ typedef struct TiffContext { int strips, rps; int sot; - uint8_t* stripdata; - uint8_t* stripsizes; + const uint8_t* stripdata; + const uint8_t* stripsizes; int stripsize, stripoff; LZWState *lzw; } TiffContext; -static int tget_short(uint8_t **p, int le){ +static int tget_short(const uint8_t **p, int le){ int v = le ? AV_RL16(*p) : AV_RB16(*p); *p += 2; return v; } -static int tget_long(uint8_t **p, int le){ +static int tget_long(const uint8_t **p, int le){ int v = le ? AV_RL32(*p) : AV_RB32(*p); *p += 4; return v; } -static int tget(uint8_t **p, int type, int le){ +static int tget(const uint8_t **p, int type, int le){ switch(type){ case TIFF_BYTE : return *(*p)++; case TIFF_SHORT: return tget_short(p, le); @@ -107,9 +71,9 @@ static int tget(uint8_t **p, int type, int le){ } } -static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, uint8_t *src, int size, int lines){ +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; - uint8_t *ssrc = src; + const uint8_t *ssrc = src; int width = s->width * (s->bpp / 8); #ifdef CONFIG_ZLIB uint8_t *zbuf; unsigned long outlen; @@ -186,12 +150,14 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, uint8_t * } -static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t *end_buf, AVFrame *pic) +static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf, AVFrame *pic) { int tag, type, count, off, value = 0; - uint8_t *src, *dst; + const uint8_t *src; + uint8_t *dst; int i, j, ssize, soff, stride; - int *pal, *rp, *gp, *bp; + uint32_t *pal; + const uint8_t *rp, *gp, *bp; tag = tget_short(&buf, s->le); type = tget_short(&buf, s->le); @@ -280,7 +246,7 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t } if(s->bpp == 8){ /* make default grayscale pal */ - pal = s->picture.data[1]; + pal = (uint32_t *) s->picture.data[1]; for(i = 0; i < 256; i++) pal[i] = i * 0x010101; } @@ -332,6 +298,7 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t }else s->stripdata = start + off; s->strips = count; + if(s->strips == 1) s->rps = s->height; s->sot = type; if(s->stripdata > end_buf){ av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); @@ -380,14 +347,14 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t return -1; } if(value == 2){ - src = pic->data[0]; + dst = pic->data[0]; stride = pic->linesize[0]; soff = s->bpp >> 3; ssize = s->width * soff; for(i = 0; i < s->height; i++) { for(j = soff; j < ssize; j++) - src[j] += src[j - soff]; - src += stride; + dst[j] += dst[j - soff]; + dst += stride; } } break; @@ -412,7 +379,7 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t av_log(s->avctx, AV_LOG_ERROR, "Palette met but this is not palettized format\n"); return -1; } - pal = s->picture.data[1]; + pal = (uint32_t *) s->picture.data[1]; off = type_sizes[type]; rp = buf; gp = buf + count / 3 * off; @@ -437,12 +404,12 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { TiffContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p= (AVFrame*)&s->picture; - uint8_t *orig_buf = buf, *end_buf = buf + buf_size; + const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; int id, le, off; int i, entries; @@ -456,6 +423,7 @@ static int decode_frame(AVCodecContext *avctx, } s->le = le; s->invert = 0; + s->compr = TIFF_RAW; // 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){ @@ -493,7 +461,7 @@ static int decode_frame(AVCodecContext *avctx, return buf_size; } -static int tiff_init(AVCodecContext *avctx){ +static av_cold int tiff_init(AVCodecContext *avctx){ TiffContext *s = avctx->priv_data; s->width = 0; @@ -507,7 +475,7 @@ static int tiff_init(AVCodecContext *avctx){ return 0; } -static int tiff_end(AVCodecContext *avctx) +static av_cold int tiff_end(AVCodecContext *avctx) { TiffContext * const s = avctx->priv_data;