]> git.sesse.net Git - ffmpeg/blob - libavcodec/tiff.c
f187cb2bcb1495e60f5f52528a4295c2bf2a32ec
[ffmpeg] / libavcodec / tiff.c
1 /*
2  * Copyright (c) 2006 Konstantin Shishkov
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file
23  * TIFF image decoder
24  * @author Konstantin Shishkov
25  */
26
27 #include "avcodec.h"
28 #if CONFIG_ZLIB
29 #include <zlib.h>
30 #endif
31 #include "lzw.h"
32 #include "tiff.h"
33 #include "faxcompr.h"
34 #include "libavutil/common.h"
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/imgutils.h"
37
38 typedef struct TiffContext {
39     AVCodecContext *avctx;
40     AVFrame picture;
41
42     int width, height;
43     unsigned int bpp, bppcount;
44     uint32_t palette[256];
45     int palette_is_set;
46     int le;
47     enum TiffCompr compr;
48     int invert;
49     int fax_opts;
50     int predictor;
51     int fill_order;
52
53     int strips, rps, sstype;
54     int sot;
55     const uint8_t* stripdata;
56     const uint8_t* stripsizes;
57     int stripsize, stripoff;
58     LZWState *lzw;
59 } TiffContext;
60
61 static int tget_short(const uint8_t **p, int le){
62     int v = le ? AV_RL16(*p) : AV_RB16(*p);
63     *p += 2;
64     return v;
65 }
66
67 static int tget_long(const uint8_t **p, int le){
68     int v = le ? AV_RL32(*p) : AV_RB32(*p);
69     *p += 4;
70     return v;
71 }
72
73 static int tget(const uint8_t **p, int type, int le){
74     switch(type){
75     case TIFF_BYTE : return *(*p)++;
76     case TIFF_SHORT: return tget_short(p, le);
77     case TIFF_LONG : return tget_long (p, le);
78     default        : return -1;
79     }
80 }
81
82 #if CONFIG_ZLIB
83 static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src, int size)
84 {
85     z_stream zstream;
86     int zret;
87
88     memset(&zstream, 0, sizeof(zstream));
89     zstream.next_in = src;
90     zstream.avail_in = size;
91     zstream.next_out = dst;
92     zstream.avail_out = *len;
93     zret = inflateInit(&zstream);
94     if (zret != Z_OK) {
95         av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
96         return zret;
97     }
98     zret = inflate(&zstream, Z_SYNC_FLUSH);
99     inflateEnd(&zstream);
100     *len = zstream.total_out;
101     return zret == Z_STREAM_END ? Z_OK : zret;
102 }
103 #endif
104
105 static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst,
106                                              int usePtr, const uint8_t *src,
107                                              uint8_t c, int width, int offset)
108 {
109     switch (bpp) {
110     case 2:
111         while (--width >= 0) {
112             dst[(width+offset)*4+3] = (usePtr ? src[width] : c) & 0x3;
113             dst[(width+offset)*4+2] = (usePtr ? src[width] : c) >> 2 & 0x3;
114             dst[(width+offset)*4+1] = (usePtr ? src[width] : c) >> 4 & 0x3;
115             dst[(width+offset)*4+0] = (usePtr ? src[width] : c) >> 6;
116         }
117         break;
118     case 4:
119         while (--width >= 0) {
120             dst[(width+offset)*2+1] = (usePtr ? src[width] : c) & 0xF;
121             dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4;
122         }
123         break;
124     default:
125         if (usePtr) {
126             memcpy(dst + offset, src, width);
127         } else {
128             memset(dst + offset, c, width);
129         }
130     }
131 }
132
133 static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uint8_t *src, int size, int lines){
134     int c, line, pixels, code;
135     const uint8_t *ssrc = src;
136     int width = ((s->width * s->bpp) + 7) >> 3;
137 #if CONFIG_ZLIB
138     uint8_t *zbuf; unsigned long outlen;
139
140     if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){
141         int ret;
142         outlen = width * lines;
143         zbuf = av_malloc(outlen);
144         ret = tiff_uncompress(zbuf, &outlen, src, size);
145         if(ret != Z_OK){
146             av_log(s->avctx, AV_LOG_ERROR, "Uncompressing failed (%lu of %lu) with error %d\n", outlen, (unsigned long)width * lines, ret);
147             av_free(zbuf);
148             return -1;
149         }
150         src = zbuf;
151         for(line = 0; line < lines; line++){
152             if(s->bpp == 4){
153                 horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
154             }else{
155                 memcpy(dst, src, width);
156             }
157             dst += stride;
158             src += width;
159         }
160         av_free(zbuf);
161         return 0;
162     }
163 #endif
164     if(s->compr == TIFF_LZW){
165         if(ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF) < 0){
166             av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
167             return -1;
168         }
169     }
170     if(s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3 || s->compr == TIFF_G4){
171         int i, ret = 0;
172         uint8_t *src2 = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
173
174         if(!src2 || (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE < (unsigned)size){
175             av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
176             return -1;
177         }
178         if(s->fax_opts & 2){
179             av_log(s->avctx, AV_LOG_ERROR, "Uncompressed fax mode is not supported (yet)\n");
180             av_free(src2);
181             return -1;
182         }
183         if(!s->fill_order){
184             memcpy(src2, src, size);
185         }else{
186             for(i = 0; i < size; i++)
187                 src2[i] = av_reverse[src[i]];
188         }
189         memset(src2+size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
190         switch(s->compr){
191         case TIFF_CCITT_RLE:
192         case TIFF_G3:
193         case TIFF_G4:
194             ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride, s->compr, s->fax_opts);
195             break;
196         }
197         av_free(src2);
198         return ret;
199     }
200     for(line = 0; line < lines; line++){
201         if(src - ssrc > size){
202             av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
203             return -1;
204         }
205         switch(s->compr){
206         case TIFF_RAW:
207             if (ssrc + size - src < width)
208                 return AVERROR_INVALIDDATA;
209             if (!s->fill_order) {
210                 horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
211             } else {
212                 int i;
213                 for (i = 0; i < width; i++)
214                     dst[i] = av_reverse[src[i]];
215             }
216             src += width;
217             break;
218         case TIFF_PACKBITS:
219             for(pixels = 0; pixels < width;){
220                 code = (int8_t)*src++;
221                 if(code >= 0){
222                     code++;
223                     if(pixels + code > width){
224                         av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n");
225                         return -1;
226                     }
227                     horizontal_fill(s->bpp, dst, 1, src, 0, code, pixels);
228                     src += code;
229                     pixels += code;
230                 }else if(code != -128){ // -127..-1
231                     code = (-code) + 1;
232                     if(pixels + code > width){
233                         av_log(s->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
234                         return -1;
235                     }
236                     c = *src++;
237                     horizontal_fill(s->bpp, dst, 0, NULL, c, code, pixels);
238                     pixels += code;
239                 }
240             }
241             break;
242         case TIFF_LZW:
243             pixels = ff_lzw_decode(s->lzw, dst, width);
244             if(pixels < width){
245                 av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n", pixels, width);
246                 return -1;
247             }
248             if(s->bpp == 4)
249                 horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
250             break;
251         }
252         dst += stride;
253     }
254     return 0;
255 }
256
257 static int init_image(TiffContext *s)
258 {
259     int i, ret;
260     uint32_t *pal;
261
262     switch (s->bpp * 10 + s->bppcount) {
263     case 11:
264         s->avctx->pix_fmt = PIX_FMT_MONOBLACK;
265         break;
266     case 21:
267     case 41:
268     case 81:
269         s->avctx->pix_fmt = PIX_FMT_PAL8;
270         break;
271     case 243:
272         s->avctx->pix_fmt = PIX_FMT_RGB24;
273         break;
274     case 161:
275         s->avctx->pix_fmt = PIX_FMT_GRAY16BE;
276         break;
277     case 324:
278         s->avctx->pix_fmt = PIX_FMT_RGBA;
279         break;
280     case 483:
281         s->avctx->pix_fmt = s->le ? PIX_FMT_RGB48LE : PIX_FMT_RGB48BE;
282         break;
283     default:
284         av_log(s->avctx, AV_LOG_ERROR,
285                "This format is not supported (bpp=%d, bppcount=%d)\n",
286                s->bpp, s->bppcount);
287         return AVERROR_INVALIDDATA;
288     }
289     if (s->width != s->avctx->width || s->height != s->avctx->height) {
290         if ((ret = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0)
291             return ret;
292         avcodec_set_dimensions(s->avctx, s->width, s->height);
293     }
294     if (s->picture.data[0])
295         s->avctx->release_buffer(s->avctx, &s->picture);
296     if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0) {
297         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
298         return ret;
299     }
300     if (s->avctx->pix_fmt == PIX_FMT_PAL8) {
301         if (s->palette_is_set) {
302             memcpy(s->picture.data[1], s->palette, sizeof(s->palette));
303         } else {
304             /* make default grayscale pal */
305             pal = (uint32_t *) s->picture.data[1];
306             for (i = 0; i < 1<<s->bpp; i++)
307                 pal[i] = 0xFF << 24 | i * 255 / ((1<<s->bpp) - 1) * 0x010101;
308         }
309     }
310     return 0;
311 }
312
313 static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf)
314 {
315     int tag, type, count, off, value = 0;
316     int i, j;
317     uint32_t *pal;
318     const uint8_t *rp, *gp, *bp;
319
320     if (end_buf - buf < 12)
321         return -1;
322     tag = tget_short(&buf, s->le);
323     type = tget_short(&buf, s->le);
324     count = tget_long(&buf, s->le);
325     off = tget_long(&buf, s->le);
326
327     if(count == 1){
328         switch(type){
329         case TIFF_BYTE:
330         case TIFF_SHORT:
331             buf -= 4;
332             value = tget(&buf, type, s->le);
333             buf = NULL;
334             break;
335         case TIFF_LONG:
336             value = off;
337             buf = NULL;
338             break;
339         case TIFF_STRING:
340             if(count <= 4){
341                 buf -= 4;
342                 break;
343             }
344         default:
345             value = -1;
346             buf = start + off;
347         }
348     }else if(type_sizes[type] * count <= 4){
349         buf -= 4;
350     }else{
351         buf = start + off;
352     }
353
354     if(buf && (buf < start || buf > end_buf)){
355         av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
356         return -1;
357     }
358
359     switch(tag){
360     case TIFF_WIDTH:
361         s->width = value;
362         break;
363     case TIFF_HEIGHT:
364         s->height = value;
365         break;
366     case TIFF_BPP:
367         s->bppcount = count;
368         if(count > 4){
369             av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count);
370             return -1;
371         }
372         if(count == 1) s->bpp = value;
373         else{
374             switch(type){
375             case TIFF_BYTE:
376                 s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF);
377                 break;
378             case TIFF_SHORT:
379             case TIFF_LONG:
380                 s->bpp = 0;
381                 for(i = 0; i < count && buf < end_buf; i++) s->bpp += tget(&buf, type, s->le);
382                 break;
383             default:
384                 s->bpp = -1;
385             }
386         }
387         break;
388     case TIFF_SAMPLES_PER_PIXEL:
389         if (count != 1) {
390             av_log(s->avctx, AV_LOG_ERROR,
391                    "Samples per pixel requires a single value, many provided\n");
392             return AVERROR_INVALIDDATA;
393         }
394         if (s->bppcount == 1)
395             s->bpp *= value;
396         s->bppcount = value;
397         break;
398     case TIFF_COMPR:
399         s->compr = value;
400         s->predictor = 0;
401         switch(s->compr){
402         case TIFF_RAW:
403         case TIFF_PACKBITS:
404         case TIFF_LZW:
405         case TIFF_CCITT_RLE:
406             break;
407         case TIFF_G3:
408         case TIFF_G4:
409             s->fax_opts = 0;
410             break;
411         case TIFF_DEFLATE:
412         case TIFF_ADOBE_DEFLATE:
413 #if CONFIG_ZLIB
414             break;
415 #else
416             av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");
417             return -1;
418 #endif
419         case TIFF_JPEG:
420         case TIFF_NEWJPEG:
421             av_log(s->avctx, AV_LOG_ERROR, "JPEG compression is not supported\n");
422             return -1;
423         default:
424             av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr);
425             return -1;
426         }
427         break;
428     case TIFF_ROWSPERSTRIP:
429         if(type == TIFF_LONG && value == -1)
430             value = s->avctx->height;
431         if(value < 1){
432             av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n");
433             return -1;
434         }
435         s->rps = value;
436         break;
437     case TIFF_STRIP_OFFS:
438         if(count == 1){
439             s->stripdata = NULL;
440             s->stripoff = value;
441         }else
442             s->stripdata = start + off;
443         s->strips = count;
444         if(s->strips == 1) s->rps = s->height;
445         s->sot = type;
446         if(s->stripdata > end_buf){
447             av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
448             return -1;
449         }
450         break;
451     case TIFF_STRIP_SIZE:
452         if(count == 1){
453             s->stripsizes = NULL;
454             s->stripsize = value;
455             s->strips = 1;
456         }else{
457             s->stripsizes = start + off;
458         }
459         s->strips = count;
460         s->sstype = type;
461         if(s->stripsizes > end_buf){
462             av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
463             return -1;
464         }
465         break;
466     case TIFF_PREDICTOR:
467         s->predictor = value;
468         break;
469     case TIFF_INVERT:
470         switch(value){
471         case 0:
472             s->invert = 1;
473             break;
474         case 1:
475             s->invert = 0;
476             break;
477         case 2:
478         case 3:
479             break;
480         default:
481             av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n", value);
482             return -1;
483         }
484         break;
485     case TIFF_FILL_ORDER:
486         if(value < 1 || value > 2){
487             av_log(s->avctx, AV_LOG_ERROR, "Unknown FillOrder value %d, trying default one\n", value);
488             value = 1;
489         }
490         s->fill_order = value - 1;
491         break;
492     case TIFF_PAL:
493         pal = (uint32_t *) s->palette;
494         off = type_sizes[type];
495         if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3)
496             return -1;
497         rp = buf;
498         gp = buf + count / 3 * off;
499         bp = buf + count / 3 * off * 2;
500         off = (type_sizes[type] - 1) << 3;
501         for(i = 0; i < count / 3; i++){
502             j = 0xff << 24;
503             j |= (tget(&rp, type, s->le) >> off) << 16;
504             j |= (tget(&gp, type, s->le) >> off) << 8;
505             j |= tget(&bp, type, s->le) >> off;
506             pal[i] = j;
507         }
508         s->palette_is_set = 1;
509         break;
510     case TIFF_PLANAR:
511         if(value == 2){
512             av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n");
513             return -1;
514         }
515         break;
516     case TIFF_T4OPTIONS:
517         if(s->compr == TIFF_G3)
518             s->fax_opts = value;
519         break;
520     case TIFF_T6OPTIONS:
521         if(s->compr == TIFF_G4)
522             s->fax_opts = value;
523         break;
524     default:
525         av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n", tag, tag);
526     }
527     return 0;
528 }
529
530 static int decode_frame(AVCodecContext *avctx,
531                         void *data, int *data_size,
532                         AVPacket *avpkt)
533 {
534     const uint8_t *buf = avpkt->data;
535     int buf_size = avpkt->size;
536     TiffContext * const s = avctx->priv_data;
537     AVFrame *picture = data;
538     AVFrame * const p= (AVFrame*)&s->picture;
539     const uint8_t *orig_buf = buf, *end_buf = buf + buf_size;
540     unsigned off;
541     int id, le, ret;
542     int i, j, entries;
543     int stride;
544     unsigned soff, ssize;
545     uint8_t *dst;
546
547     //parse image header
548     if (end_buf - buf < 8)
549         return AVERROR_INVALIDDATA;
550     id = AV_RL16(buf); buf += 2;
551     if(id == 0x4949) le = 1;
552     else if(id == 0x4D4D) le = 0;
553     else{
554         av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
555         return -1;
556     }
557     s->le = le;
558     s->invert = 0;
559     s->compr = TIFF_RAW;
560     s->fill_order = 0;
561     // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number
562     // that further identifies the file as a TIFF file"
563     if(tget_short(&buf, le) != 42){
564         av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n");
565         return -1;
566     }
567     /* parse image file directory */
568     off = tget_long(&buf, le);
569     if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) {
570         av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
571         return AVERROR_INVALIDDATA;
572     }
573     buf = orig_buf + off;
574     entries = tget_short(&buf, le);
575     for(i = 0; i < entries; i++){
576         if(tiff_decode_tag(s, orig_buf, buf, end_buf) < 0)
577             return -1;
578         buf += 12;
579     }
580     if(!s->stripdata && !s->stripoff){
581         av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
582         return -1;
583     }
584     /* now we have the data and may start decoding */
585     if ((ret = init_image(s)) < 0)
586         return ret;
587
588     if(s->strips == 1 && !s->stripsize){
589         av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
590         s->stripsize = buf_size - s->stripoff;
591     }
592     stride = p->linesize[0];
593     dst = p->data[0];
594     for(i = 0; i < s->height; i += s->rps){
595         if(s->stripsizes) {
596             if (s->stripsizes >= end_buf)
597                 return AVERROR_INVALIDDATA;
598             ssize = tget(&s->stripsizes, s->sstype, s->le);
599         } else
600             ssize = s->stripsize;
601
602         if(s->stripdata){
603             if (s->stripdata >= end_buf)
604                 return AVERROR_INVALIDDATA;
605             soff = tget(&s->stripdata, s->sot, s->le);
606         }else
607             soff = s->stripoff;
608
609         if (soff > buf_size || ssize > buf_size - soff) {
610             av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
611             return -1;
612         }
613         if(tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize, FFMIN(s->rps, s->height - i)) < 0)
614             break;
615         dst += s->rps * stride;
616     }
617     if(s->predictor == 2){
618         dst = p->data[0];
619         soff = s->bpp >> 3;
620         ssize = s->width * soff;
621         if (s->avctx->pix_fmt == PIX_FMT_RGB48LE) {
622             for (i = 0; i < s->height; i++) {
623                 for (j = soff; j < ssize; j += 2)
624                     AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff));
625                 dst += stride;
626             }
627         } else if (s->avctx->pix_fmt == PIX_FMT_RGB48BE) {
628             for (i = 0; i < s->height; i++) {
629                 for (j = soff; j < ssize; j += 2)
630                     AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff));
631                 dst += stride;
632             }
633         } else {
634             for(i = 0; i < s->height; i++) {
635                 for(j = soff; j < ssize; j++)
636                     dst[j] += dst[j - soff];
637                 dst += stride;
638             }
639         }
640     }
641
642     if(s->invert){
643         dst = s->picture.data[0];
644         for(i = 0; i < s->height; i++){
645             for(j = 0; j < s->picture.linesize[0]; j++)
646                 dst[j] = (s->avctx->pix_fmt == PIX_FMT_PAL8 ? (1<<s->bpp) - 1 : 255) - dst[j];
647             dst += s->picture.linesize[0];
648         }
649     }
650     *picture= *(AVFrame*)&s->picture;
651     *data_size = sizeof(AVPicture);
652
653     return buf_size;
654 }
655
656 static av_cold int tiff_init(AVCodecContext *avctx){
657     TiffContext *s = avctx->priv_data;
658
659     s->width = 0;
660     s->height = 0;
661     s->avctx = avctx;
662     avcodec_get_frame_defaults((AVFrame*)&s->picture);
663     avctx->coded_frame= (AVFrame*)&s->picture;
664     ff_lzw_decode_open(&s->lzw);
665     ff_ccitt_unpack_init();
666
667     return 0;
668 }
669
670 static av_cold int tiff_end(AVCodecContext *avctx)
671 {
672     TiffContext * const s = avctx->priv_data;
673
674     ff_lzw_decode_close(&s->lzw);
675     if(s->picture.data[0])
676         avctx->release_buffer(avctx, &s->picture);
677     return 0;
678 }
679
680 AVCodec ff_tiff_decoder = {
681     .name           = "tiff",
682     .type           = AVMEDIA_TYPE_VIDEO,
683     .id             = CODEC_ID_TIFF,
684     .priv_data_size = sizeof(TiffContext),
685     .init           = tiff_init,
686     .close          = tiff_end,
687     .decode         = decode_frame,
688     .capabilities   = CODEC_CAP_DR1,
689     .long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
690 };