libavcodec/tiff.c
Go to the documentation of this file.
00001 /*
00002  * TIFF image decoder
00003  * Copyright (c) 2006 Konstantin Shishkov
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * Libav is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00028 #include "avcodec.h"
00029 #include "bytestream.h"
00030 #if CONFIG_ZLIB
00031 #include <zlib.h>
00032 #endif
00033 #include "lzw.h"
00034 #include "tiff.h"
00035 #include "faxcompr.h"
00036 #include "libavutil/common.h"
00037 #include "libavutil/intreadwrite.h"
00038 #include "libavutil/imgutils.h"
00039 
00040 typedef struct TiffContext {
00041     AVCodecContext *avctx;
00042     AVFrame picture;
00043     GetByteContext gb;
00044 
00045     int width, height;
00046     unsigned int bpp, bppcount;
00047     uint32_t palette[256];
00048     int palette_is_set;
00049     int le;
00050     enum TiffCompr compr;
00051     int invert;
00052     int fax_opts;
00053     int predictor;
00054     int fill_order;
00055 
00056     int strips, rps, sstype;
00057     int sot;
00058     int stripsizesoff, stripsize, stripoff, strippos;
00059     LZWState *lzw;
00060 } TiffContext;
00061 
00062 static unsigned tget_short(GetByteContext *gb, int le)
00063 {
00064     return le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
00065 }
00066 
00067 static unsigned tget_long(GetByteContext *gb, int le)
00068 {
00069     return le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb);
00070 }
00071 
00072 static unsigned tget(GetByteContext *gb, int type, int le)
00073 {
00074     switch(type){
00075     case TIFF_BYTE:  return bytestream2_get_byte(gb);
00076     case TIFF_SHORT: return tget_short(gb, le);
00077     case TIFF_LONG:  return tget_long(gb, le);
00078     default:         return UINT_MAX;
00079     }
00080 }
00081 
00082 #if CONFIG_ZLIB
00083 static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src, int size)
00084 {
00085     z_stream zstream;
00086     int zret;
00087 
00088     memset(&zstream, 0, sizeof(zstream));
00089     zstream.next_in = src;
00090     zstream.avail_in = size;
00091     zstream.next_out = dst;
00092     zstream.avail_out = *len;
00093     zret = inflateInit(&zstream);
00094     if (zret != Z_OK) {
00095         av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
00096         return zret;
00097     }
00098     zret = inflate(&zstream, Z_SYNC_FLUSH);
00099     inflateEnd(&zstream);
00100     *len = zstream.total_out;
00101     return zret == Z_STREAM_END ? Z_OK : zret;
00102 }
00103 #endif
00104 
00105 static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uint8_t *src, int size, int lines){
00106     PutByteContext pb;
00107     int c, line, pixels, code;
00108     int width = ((s->width * s->bpp) + 7) >> 3;
00109 #if CONFIG_ZLIB
00110     uint8_t *zbuf; unsigned long outlen;
00111 
00112     if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){
00113         int ret;
00114         outlen = width * lines;
00115         zbuf = av_malloc(outlen);
00116         ret = tiff_uncompress(zbuf, &outlen, src, size);
00117         if(ret != Z_OK){
00118             av_log(s->avctx, AV_LOG_ERROR, "Uncompressing failed (%lu of %lu) with error %d\n", outlen, (unsigned long)width * lines, ret);
00119             av_free(zbuf);
00120             return -1;
00121         }
00122         src = zbuf;
00123         for(line = 0; line < lines; line++){
00124             memcpy(dst, src, width);
00125             dst += stride;
00126             src += width;
00127         }
00128         av_free(zbuf);
00129         return 0;
00130     }
00131 #endif
00132     if(s->compr == TIFF_LZW){
00133         if(ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF) < 0){
00134             av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
00135             return -1;
00136         }
00137         for (line = 0; line < lines; line++) {
00138             pixels = ff_lzw_decode(s->lzw, dst, width);
00139             if (pixels < width) {
00140                 av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n",
00141                        pixels, width);
00142                 return AVERROR_INVALIDDATA;
00143             }
00144             dst += stride;
00145         }
00146         return 0;
00147     }
00148     if(s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3 || s->compr == TIFF_G4){
00149         int i, ret = 0;
00150         uint8_t *src2 = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
00151 
00152         if(!src2 || (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE < (unsigned)size){
00153             av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
00154             return -1;
00155         }
00156         if(s->fax_opts & 2){
00157             av_log(s->avctx, AV_LOG_ERROR, "Uncompressed fax mode is not supported (yet)\n");
00158             av_free(src2);
00159             return -1;
00160         }
00161         if(!s->fill_order){
00162             memcpy(src2, src, size);
00163         }else{
00164             for(i = 0; i < size; i++)
00165                 src2[i] = av_reverse[src[i]];
00166         }
00167         memset(src2+size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
00168         switch(s->compr){
00169         case TIFF_CCITT_RLE:
00170         case TIFF_G3:
00171         case TIFF_G4:
00172             ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride, s->compr, s->fax_opts);
00173             break;
00174         }
00175         av_free(src2);
00176         return ret;
00177     }
00178 
00179     bytestream2_init(&s->gb, src, size);
00180     bytestream2_init_writer(&pb, dst, stride * lines);
00181 
00182     for(line = 0; line < lines; line++){
00183         if (bytestream2_get_bytes_left(&s->gb) == 0 || bytestream2_get_eof(&pb))
00184             break;
00185         bytestream2_seek_p(&pb, stride * line, SEEK_SET);
00186         switch(s->compr){
00187         case TIFF_RAW:
00188             if (!s->fill_order) {
00189                 bytestream2_copy_buffer(&pb, &s->gb, width);
00190             } else {
00191                 int i;
00192                 for (i = 0; i < width; i++)
00193                     bytestream2_put_byte(&pb, av_reverse[bytestream2_get_byte(&s->gb)]);
00194             }
00195             break;
00196         case TIFF_PACKBITS:
00197             for(pixels = 0; pixels < width;){
00198                 code = (int8_t)bytestream2_get_byte(&s->gb);
00199                 if(code >= 0){
00200                     code++;
00201                     bytestream2_copy_buffer(&pb, &s->gb, code);
00202                     pixels += code;
00203                 }else if(code != -128){ // -127..-1
00204                     code = (-code) + 1;
00205                     c    = bytestream2_get_byte(&s->gb);
00206                     bytestream2_set_buffer(&pb, c, code);
00207                     pixels += code;
00208                 }
00209             }
00210             break;
00211         }
00212     }
00213     return 0;
00214 }
00215 
00216 static int init_image(TiffContext *s)
00217 {
00218     int i, ret;
00219     uint32_t *pal;
00220 
00221     // make sure there is no aliasing in the following switch
00222     if (s->bpp >= 100 || s->bppcount >= 10) {
00223         av_log(s->avctx, AV_LOG_ERROR,
00224                "Unsupported image parameters: bpp=%d, bppcount=%d\n",
00225                s->bpp, s->bppcount);
00226         return AVERROR_INVALIDDATA;
00227     }
00228 
00229     switch (s->bpp * 10 + s->bppcount) {
00230     case 11:
00231         s->avctx->pix_fmt = PIX_FMT_MONOBLACK;
00232         break;
00233     case 81:
00234         s->avctx->pix_fmt = PIX_FMT_PAL8;
00235         break;
00236     case 243:
00237         s->avctx->pix_fmt = PIX_FMT_RGB24;
00238         break;
00239     case 161:
00240         s->avctx->pix_fmt = PIX_FMT_GRAY16BE;
00241         break;
00242     case 324:
00243         s->avctx->pix_fmt = PIX_FMT_RGBA;
00244         break;
00245     case 483:
00246         s->avctx->pix_fmt = s->le ? PIX_FMT_RGB48LE : PIX_FMT_RGB48BE;
00247         break;
00248     default:
00249         av_log(s->avctx, AV_LOG_ERROR,
00250                "This format is not supported (bpp=%d, bppcount=%d)\n",
00251                s->bpp, s->bppcount);
00252         return AVERROR_INVALIDDATA;
00253     }
00254     if (s->width != s->avctx->width || s->height != s->avctx->height) {
00255         if ((ret = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0)
00256             return ret;
00257         avcodec_set_dimensions(s->avctx, s->width, s->height);
00258     }
00259     if (s->picture.data[0])
00260         s->avctx->release_buffer(s->avctx, &s->picture);
00261     if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0) {
00262         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00263         return ret;
00264     }
00265     if (s->avctx->pix_fmt == PIX_FMT_PAL8) {
00266         if (s->palette_is_set) {
00267             memcpy(s->picture.data[1], s->palette, sizeof(s->palette));
00268         } else {
00269             /* make default grayscale pal */
00270             pal = (uint32_t *) s->picture.data[1];
00271             for (i = 0; i < 256; i++)
00272                 pal[i] = i * 0x010101;
00273         }
00274     }
00275     return 0;
00276 }
00277 
00278 static int tiff_decode_tag(TiffContext *s)
00279 {
00280     unsigned tag, type, count, off, value = 0;
00281     int i, start;
00282     uint32_t *pal;
00283 
00284     if (bytestream2_get_bytes_left(&s->gb) < 12)
00285         return -1;
00286     tag   = tget_short(&s->gb, s->le);
00287     type  = tget_short(&s->gb, s->le);
00288     count = tget_long(&s->gb, s->le);
00289     off   = tget_long(&s->gb, s->le);
00290     start = bytestream2_tell(&s->gb);
00291 
00292     if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) {
00293         av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n", type);
00294         return 0;
00295     }
00296 
00297     if(count == 1){
00298         switch(type){
00299         case TIFF_BYTE:
00300         case TIFF_SHORT:
00301             bytestream2_seek(&s->gb, -4, SEEK_CUR);
00302             value = tget(&s->gb, type, s->le);
00303             break;
00304         case TIFF_LONG:
00305             value = off;
00306             break;
00307         case TIFF_STRING:
00308             if(count <= 4){
00309                 bytestream2_seek(&s->gb, -4, SEEK_CUR);
00310                 break;
00311             }
00312         default:
00313             value = UINT_MAX;
00314             bytestream2_seek(&s->gb, off, SEEK_SET);
00315         }
00316     } else {
00317         if (count <= 4 && type_sizes[type] * count <= 4)
00318             bytestream2_seek(&s->gb, -4, SEEK_CUR);
00319         else
00320             bytestream2_seek(&s->gb, off, SEEK_SET);
00321     }
00322 
00323     switch(tag){
00324     case TIFF_WIDTH:
00325         s->width = value;
00326         break;
00327     case TIFF_HEIGHT:
00328         s->height = value;
00329         break;
00330     case TIFF_BPP:
00331         s->bppcount = count;
00332         if(count > 4){
00333             av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count);
00334             return -1;
00335         }
00336         if(count == 1) s->bpp = value;
00337         else{
00338             switch(type){
00339             case TIFF_BYTE:
00340                 s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF);
00341                 break;
00342             case TIFF_SHORT:
00343             case TIFF_LONG:
00344                 s->bpp = 0;
00345                 for (i = 0; i < count; i++)
00346                     s->bpp += tget(&s->gb, type, s->le);
00347                 break;
00348             default:
00349                 s->bpp = -1;
00350             }
00351         }
00352         break;
00353     case TIFF_SAMPLES_PER_PIXEL:
00354         if (count != 1) {
00355             av_log(s->avctx, AV_LOG_ERROR,
00356                    "Samples per pixel requires a single value, many provided\n");
00357             return AVERROR_INVALIDDATA;
00358         }
00359         if (s->bppcount == 1)
00360             s->bpp *= value;
00361         s->bppcount = value;
00362         break;
00363     case TIFF_COMPR:
00364         s->compr = value;
00365         s->predictor = 0;
00366         switch(s->compr){
00367         case TIFF_RAW:
00368         case TIFF_PACKBITS:
00369         case TIFF_LZW:
00370         case TIFF_CCITT_RLE:
00371             break;
00372         case TIFF_G3:
00373         case TIFF_G4:
00374             s->fax_opts = 0;
00375             break;
00376         case TIFF_DEFLATE:
00377         case TIFF_ADOBE_DEFLATE:
00378 #if CONFIG_ZLIB
00379             break;
00380 #else
00381             av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");
00382             return -1;
00383 #endif
00384         case TIFF_JPEG:
00385         case TIFF_NEWJPEG:
00386             av_log(s->avctx, AV_LOG_ERROR, "JPEG compression is not supported\n");
00387             return -1;
00388         default:
00389             av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr);
00390             return -1;
00391         }
00392         break;
00393     case TIFF_ROWSPERSTRIP:
00394         if (type == TIFF_LONG && value == UINT_MAX)
00395             value = s->avctx->height;
00396         if(value < 1){
00397             av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n");
00398             return -1;
00399         }
00400         s->rps = value;
00401         break;
00402     case TIFF_STRIP_OFFS:
00403         if(count == 1){
00404             s->strippos = 0;
00405             s->stripoff = value;
00406         }else
00407             s->strippos = off;
00408         s->strips = count;
00409         if(s->strips == 1) s->rps = s->height;
00410         s->sot = type;
00411         break;
00412     case TIFF_STRIP_SIZE:
00413         if(count == 1){
00414             s->stripsizesoff = 0;
00415             s->stripsize     = value;
00416             s->strips        = 1;
00417         }else{
00418             s->stripsizesoff = off;
00419         }
00420         s->strips = count;
00421         s->sstype = type;
00422         break;
00423     case TIFF_PREDICTOR:
00424         s->predictor = value;
00425         break;
00426     case TIFF_INVERT:
00427         switch(value){
00428         case 0:
00429             s->invert = 1;
00430             break;
00431         case 1:
00432             s->invert = 0;
00433             break;
00434         case 2:
00435         case 3:
00436             break;
00437         default:
00438             av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n", value);
00439             return -1;
00440         }
00441         break;
00442     case TIFF_FILL_ORDER:
00443         if(value < 1 || value > 2){
00444             av_log(s->avctx, AV_LOG_ERROR, "Unknown FillOrder value %d, trying default one\n", value);
00445             value = 1;
00446         }
00447         s->fill_order = value - 1;
00448         break;
00449     case TIFF_PAL: {
00450         GetByteContext pal_gb[3];
00451         pal = (uint32_t *) s->palette;
00452         off = type_sizes[type];
00453         if (count / 3 > 256 ||
00454             bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3)
00455             return -1;
00456         pal_gb[0] = pal_gb[1] = pal_gb[2] = s->gb;
00457         bytestream2_skip(&pal_gb[1], count / 3 * off);
00458         bytestream2_skip(&pal_gb[2], count / 3 * off * 2);
00459         off = (type_sizes[type] - 1) << 3;
00460         for(i = 0; i < count / 3; i++){
00461             uint32_t p = 0xFF000000;
00462             p |= (tget(&pal_gb[0], type, s->le) >> off) << 16;
00463             p |= (tget(&pal_gb[1], type, s->le) >> off) << 8;
00464             p |=  tget(&pal_gb[2], type, s->le) >> off;
00465             pal[i] = p;
00466         }
00467         s->palette_is_set = 1;
00468         break;
00469     }
00470     case TIFF_PLANAR:
00471         if(value == 2){
00472             av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n");
00473             return -1;
00474         }
00475         break;
00476     case TIFF_T4OPTIONS:
00477         if(s->compr == TIFF_G3)
00478             s->fax_opts = value;
00479         break;
00480     case TIFF_T6OPTIONS:
00481         if(s->compr == TIFF_G4)
00482             s->fax_opts = value;
00483         break;
00484     default:
00485         av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n", tag, tag);
00486     }
00487     bytestream2_seek(&s->gb, start, SEEK_SET);
00488     return 0;
00489 }
00490 
00491 static int decode_frame(AVCodecContext *avctx,
00492                         void *data, int *data_size,
00493                         AVPacket *avpkt)
00494 {
00495     TiffContext * const s = avctx->priv_data;
00496     AVFrame *picture = data;
00497     AVFrame * const p= (AVFrame*)&s->picture;
00498     unsigned off;
00499     int id, le, ret;
00500     int i, j, entries;
00501     int stride;
00502     unsigned soff, ssize;
00503     uint8_t *dst;
00504     GetByteContext stripsizes;
00505     GetByteContext stripdata;
00506 
00507     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
00508 
00509     //parse image header
00510     if (avpkt->size < 8)
00511         return AVERROR_INVALIDDATA;
00512     id = bytestream2_get_le16(&s->gb);
00513     if(id == 0x4949) le = 1;
00514     else if(id == 0x4D4D) le = 0;
00515     else{
00516         av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
00517         return -1;
00518     }
00519     s->le = le;
00520     s->invert = 0;
00521     s->compr = TIFF_RAW;
00522     s->fill_order = 0;
00523     // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number
00524     // that further identifies the file as a TIFF file"
00525     if (tget_short(&s->gb, le) != 42) {
00526         av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n");
00527         return -1;
00528     }
00529     // Reset these offsets so we can tell if they were set this frame
00530     s->stripsizesoff = s->strippos = 0;
00531     /* parse image file directory */
00532     off = tget_long(&s->gb, le);
00533     if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
00534         av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
00535         return AVERROR_INVALIDDATA;
00536     }
00537     bytestream2_seek(&s->gb, off, SEEK_SET);
00538     entries = tget_short(&s->gb, le);
00539     for(i = 0; i < entries; i++){
00540         if (tiff_decode_tag(s) < 0)
00541             return -1;
00542     }
00543     if (!s->strippos && !s->stripoff) {
00544         av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
00545         return -1;
00546     }
00547     /* now we have the data and may start decoding */
00548     if ((ret = init_image(s)) < 0)
00549         return ret;
00550 
00551     if(s->strips == 1 && !s->stripsize){
00552         av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
00553         s->stripsize = avpkt->size - s->stripoff;
00554     }
00555     stride = p->linesize[0];
00556     dst = p->data[0];
00557 
00558     if (s->stripsizesoff) {
00559         if (s->stripsizesoff >= avpkt->size)
00560             return AVERROR_INVALIDDATA;
00561         bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
00562                          avpkt->size - s->stripsizesoff);
00563     }
00564     if (s->strippos) {
00565         if (s->strippos >= avpkt->size)
00566             return AVERROR_INVALIDDATA;
00567         bytestream2_init(&stripdata, avpkt->data + s->strippos,
00568                          avpkt->size - s->strippos);
00569     }
00570 
00571     for(i = 0; i < s->height; i += s->rps){
00572         if (s->stripsizesoff)
00573             ssize = tget(&stripsizes, s->sstype, le);
00574         else
00575             ssize = s->stripsize;
00576 
00577         if (s->strippos)
00578             soff = tget(&stripdata, s->sot, le);
00579         else
00580             soff = s->stripoff;
00581 
00582         if (soff > avpkt->size || ssize > avpkt->size - soff) {
00583             av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
00584             return -1;
00585         }
00586         if (tiff_unpack_strip(s, dst, stride, avpkt->data + soff, ssize,
00587                               FFMIN(s->rps, s->height - i)) < 0)
00588             break;
00589         dst += s->rps * stride;
00590     }
00591     if(s->predictor == 2){
00592         dst = p->data[0];
00593         soff = s->bpp >> 3;
00594         ssize = s->width * soff;
00595         for(i = 0; i < s->height; i++) {
00596             for(j = soff; j < ssize; j++)
00597                 dst[j] += dst[j - soff];
00598             dst += stride;
00599         }
00600     }
00601 
00602     if(s->invert){
00603         uint8_t *src;
00604         int j;
00605 
00606         src = s->picture.data[0];
00607         for(j = 0; j < s->height; j++){
00608             for(i = 0; i < s->picture.linesize[0]; i++)
00609                 src[i] = 255 - src[i];
00610             src += s->picture.linesize[0];
00611         }
00612     }
00613     *picture= *(AVFrame*)&s->picture;
00614     *data_size = sizeof(AVPicture);
00615 
00616     return avpkt->size;
00617 }
00618 
00619 static av_cold int tiff_init(AVCodecContext *avctx){
00620     TiffContext *s = avctx->priv_data;
00621 
00622     s->width = 0;
00623     s->height = 0;
00624     s->avctx = avctx;
00625     avcodec_get_frame_defaults((AVFrame*)&s->picture);
00626     avctx->coded_frame= (AVFrame*)&s->picture;
00627     ff_lzw_decode_open(&s->lzw);
00628     ff_ccitt_unpack_init();
00629 
00630     return 0;
00631 }
00632 
00633 static av_cold int tiff_end(AVCodecContext *avctx)
00634 {
00635     TiffContext * const s = avctx->priv_data;
00636 
00637     ff_lzw_decode_close(&s->lzw);
00638     if(s->picture.data[0])
00639         avctx->release_buffer(avctx, &s->picture);
00640     return 0;
00641 }
00642 
00643 AVCodec ff_tiff_decoder = {
00644     .name           = "tiff",
00645     .type           = AVMEDIA_TYPE_VIDEO,
00646     .id             = CODEC_ID_TIFF,
00647     .priv_data_size = sizeof(TiffContext),
00648     .init           = tiff_init,
00649     .close          = tiff_end,
00650     .decode         = decode_frame,
00651     .capabilities   = CODEC_CAP_DR1,
00652     .long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
00653 };