]> git.sesse.net Git - ffmpeg/blob - libavcodec/tiff.c
simplify escape decoding
[ffmpeg] / libavcodec / tiff.c
1 /*
2  * TIFF image decoder
3  * Copyright (c) 2006 Konstantin Shishkov
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  */
22 #include "avcodec.h"
23 #ifdef CONFIG_ZLIB
24 #include <zlib.h>
25 #endif
26
27 /* abridged list of TIFF tags */
28 enum TiffTags{
29     TIFF_WIDTH = 0x100,
30     TIFF_HEIGHT,
31     TIFF_BPP,
32     TIFF_COMPR,
33     TIFF_INVERT = 0x106,
34     TIFF_STRIP_OFFS = 0x111,
35     TIFF_ROWSPERSTRIP = 0x116,
36     TIFF_STRIP_SIZE,
37     TIFF_XPOS = 0x11E,
38     TIFF_YPOS = 0x11F,
39     TIFF_PREDICTOR = 0x13D
40 };
41
42 enum TiffCompr{
43     TIFF_RAW = 1,
44     TIFF_CCITT_RLE,
45     TIFF_G3,
46     TIFF_G4,
47     TIFF_LZW,
48     TIFF_JPEG,
49     TIFF_NEWJPEG,
50     TIFF_ADOBE_DEFLATE,
51     TIFF_PACKBITS = 0x8005,
52     TIFF_DEFLATE = 0x80B2
53 };
54
55 enum TiffTypes{
56     TIFF_BYTE = 1,
57     TIFF_STRING,
58     TIFF_SHORT,
59     TIFF_LONG,
60     TIFF_LONGLONG
61 };
62
63 typedef struct TiffContext {
64     AVCodecContext *avctx;
65     AVFrame picture;
66
67     int width, height;
68     unsigned int bpp;
69     int le;
70     int compr;
71
72     int strips, rps;
73     int sot;
74     uint8_t* stripdata;
75     uint8_t* stripsizes;
76     int stripsize, stripoff;
77 } TiffContext;
78
79 static int tget_short(uint8_t **p, int le){
80     int v = le ? LE_16(*p) : BE_16(*p);
81     *p += 2;
82     return v;
83 }
84
85 static int tget_long(uint8_t **p, int le){
86     int v = le ? LE_32(*p) : BE_32(*p);
87     *p += 4;
88     return v;
89 }
90
91 static int tget(uint8_t **p, int type, int le){
92     switch(type){
93     case TIFF_BYTE : return *(*p)++;
94     case TIFF_SHORT: return tget_short(p, le);
95     case TIFF_LONG : return tget_long (p, le);
96     default        : return -1;
97     }
98 }
99
100 static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, uint8_t *src, int size, int lines){
101     int c, line, pixels, code;
102     uint8_t *ssrc = src;
103     int width = s->width * (s->bpp / 8);
104 #ifdef CONFIG_ZLIB
105     uint8_t *zbuf; unsigned long outlen;
106
107     if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){
108         outlen = width * lines;
109         if(lines != s->height){
110             av_log(s->avctx, AV_LOG_ERROR, "This decoder won't decode ZLib-packed TIFF with %i lines per strip\n", lines);
111             return -1;
112         }
113         zbuf = av_malloc(outlen);
114         if(uncompress(zbuf, &outlen, src, size) != Z_OK){
115             av_log(s->avctx, AV_LOG_ERROR, "Uncompressing failed (%lu of %lu)\n", outlen, (unsigned long)width * lines);
116             av_free(zbuf);
117             return -1;
118         }
119         src = zbuf;
120         for(line = 0; line < lines; line++){
121             memcpy(dst, src, width);
122             dst += stride;
123             src += width;
124         }
125         av_free(zbuf);
126         return 0;
127     }
128 #endif
129     for(line = 0; line < lines; line++){
130         if(src - ssrc > size){
131             av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
132             return -1;
133         }
134         switch(s->compr){
135         case TIFF_RAW:
136             memcpy(dst, src, s->width * (s->bpp / 8));
137             src += s->width * (s->bpp / 8);
138             break;
139         case TIFF_PACKBITS:
140             for(pixels = 0; pixels < width;){
141                 code = (int8_t)*src++;
142                 if(code >= 0){
143                     code++;
144                     if(pixels + code > width){
145                         av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n");
146                         return -1;
147                     }
148                     memcpy(dst + pixels, src, code);
149                     src += code;
150                     pixels += code;
151                 }else if(code != -128){ // -127..-1
152                     code = (-code) + 1;
153                     if(pixels + code > width){
154                         av_log(s->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
155                         return -1;
156                     }
157                     c = *src++;
158                     memset(dst + pixels, c, code);
159                     pixels += code;
160                 }
161             }
162             break;
163         }
164         dst += stride;
165     }
166     return 0;
167 }
168
169
170 static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t *end_buf, AVFrame *pic)
171 {
172     int tag, type, count, off, value = 0;
173     uint8_t *src, *dst;
174     int i, j, ssize, soff, stride;
175
176     tag = tget_short(&buf, s->le);
177     type = tget_short(&buf, s->le);
178     count = tget_long(&buf, s->le);
179     off = tget_long(&buf, s->le);
180
181     if(count == 1){
182         switch(type){
183         case TIFF_BYTE:
184         case TIFF_SHORT:
185             buf -= 4;
186             value = tget(&buf, type, s->le);
187             buf = NULL;
188             break;
189         case TIFF_LONG:
190             value = off;
191             buf = NULL;
192             break;
193         default:
194             value = -1;
195             buf = start + off;
196         }
197     }else{
198         buf = start + off;
199     }
200
201     if(buf && (buf < start || buf > end_buf)){
202         av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
203         return -1;
204     }
205
206     switch(tag){
207     case TIFF_WIDTH:
208         s->width = value;
209         break;
210     case TIFF_HEIGHT:
211         s->height = value;
212         s->avctx->pix_fmt = PIX_FMT_RGB24;
213         if(s->width != s->avctx->width || s->height != s->avctx->height){
214             if(avcodec_check_dimensions(s->avctx, s->width, s->height))
215                 return -1;
216             avcodec_set_dimensions(s->avctx, s->width, s->height);
217         }
218         if(s->picture.data[0])
219             s->avctx->release_buffer(s->avctx, &s->picture);
220         if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){
221             av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
222             return -1;
223         }
224         break;
225     case TIFF_BPP:
226         if(count == 1) s->bpp = value;
227         else{
228             switch(type){
229             case TIFF_BYTE:
230                 s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + ((off >> 16) & 0xFF);
231                 break;
232             case TIFF_SHORT:
233             case TIFF_LONG:
234                 s->bpp = tget(&buf, type, s->le) + tget(&buf, type, s->le) + tget(&buf, type, s->le);
235                 break;
236             default:
237                 s->bpp = -1;
238             }
239         }
240         if(s->bpp != 24){
241             av_log(s->avctx, AV_LOG_ERROR, "Only RGB24 is supported\n");
242             return -1;
243         }
244         break;
245     case TIFF_COMPR:
246         s->compr = value;
247         switch(s->compr){
248         case TIFF_RAW:
249         case TIFF_PACKBITS:
250             break;
251         case TIFF_DEFLATE:
252         case TIFF_ADOBE_DEFLATE:
253 #ifdef CONFIG_ZLIB
254             break;
255 #else
256             av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");
257             return -1;
258 #endif
259         case TIFF_LZW:
260             av_log(s->avctx, AV_LOG_ERROR, "LZW: not implemented yet\n");
261             return -1;
262         case TIFF_G3:
263             av_log(s->avctx, AV_LOG_ERROR, "CCITT G3 compression is not supported\n");
264             return -1;
265         case TIFF_G4:
266             av_log(s->avctx, AV_LOG_ERROR, "CCITT G4 compression is not supported\n");
267             return -1;
268         case TIFF_CCITT_RLE:
269             av_log(s->avctx, AV_LOG_ERROR, "CCITT RLE compression is not supported\n");
270             return -1;
271         default:
272             av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr);
273             return -1;
274         }
275         break;
276     case TIFF_ROWSPERSTRIP:
277         if(value < 1 || value > s->height){
278             av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n");
279             return -1;
280         }
281         s->rps = value;
282         break;
283     case TIFF_STRIP_OFFS:
284         if(count == 1){
285             s->stripdata = NULL;
286             s->stripoff = value;
287         }else
288             s->stripdata = start + off;
289         s->strips = count;
290         s->sot = type;
291         if(s->stripdata > end_buf){
292             av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
293             return -1;
294         }
295         break;
296     case TIFF_STRIP_SIZE:
297         if(count == 1){
298             s->stripsizes = NULL;
299             s->stripsize = value;
300             s->strips = 1;
301         }else{
302             s->stripsizes = start + off;
303         }
304         s->strips = count;
305         if(s->stripsizes > end_buf){
306             av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");
307             return -1;
308         }
309         if(!pic->data[0]){
310             av_log(s->avctx, AV_LOG_ERROR, "Picture initialization missing\n");
311             return -1;
312         }
313         /* now we have the data and may start decoding */
314         stride = pic->linesize[0];
315         dst = pic->data[0];
316         for(i = 0; i < s->height; i += s->rps){
317             if(s->stripsizes)
318                 ssize = tget(&s->stripsizes, type, s->le);
319             else
320                 ssize = s->stripsize;
321
322             if(s->stripdata){
323                 soff = tget(&s->stripdata, s->sot, s->le);
324             }else
325                 soff = s->stripoff;
326             src = start + soff;
327             if(tiff_unpack_strip(s, dst, stride, src, ssize, FFMIN(s->rps, s->height - i)) < 0)
328                 break;
329             dst += s->rps * stride;
330         }
331         break;
332     case TIFF_PREDICTOR:
333         if(!pic->data[0]){
334             av_log(s->avctx, AV_LOG_ERROR, "Picture initialization missing\n");
335             return -1;
336         }
337         if(value == 2){
338             src = pic->data[0] + pic->linesize[0];
339             stride = pic->linesize[0];
340             soff = s->bpp >> 3;
341             ssize = s->width * soff;
342             for(i = 0; i < s->height; i++) {
343                 for(j = soff; j < ssize; j++)
344                     src[j] += src[j - soff];
345                 src += stride;
346             }
347         }
348         break;
349     }
350     return 0;
351 }
352
353 static int decode_frame(AVCodecContext *avctx,
354                         void *data, int *data_size,
355                         uint8_t *buf, int buf_size)
356 {
357     TiffContext * const s = avctx->priv_data;
358     AVFrame *picture = data;
359     AVFrame * const p= (AVFrame*)&s->picture;
360     uint8_t *orig_buf = buf, *end_buf = buf + buf_size;
361     int id, le, off;
362     int i, entries;
363
364     //parse image header
365     id = LE_16(buf); buf += 2;
366     if(id == 0x4949) le = 1;
367     else if(id == 0x4D4D) le = 0;
368     else{
369         av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
370         return -1;
371     }
372     s->le = le;
373     // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number
374     // that further identifies the file as a TIFF file"
375     if(tget_short(&buf, le) != 42){
376         av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n");
377         return -1;
378     }
379     /* parse image file directory */
380     off = tget_long(&buf, le);
381     if(orig_buf + off + 14 >= end_buf){
382         av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
383         return -1;
384     }
385     buf = orig_buf + off;
386     entries = tget_short(&buf, le);
387     for(i = 0; i < entries; i++){
388         if(tiff_decode_tag(s, orig_buf, buf, end_buf, p) < 0)
389             return -1;
390         buf += 12;
391     }
392
393     *picture= *(AVFrame*)&s->picture;
394     *data_size = sizeof(AVPicture);
395
396     return buf_size;
397 }
398
399 static int tiff_init(AVCodecContext *avctx){
400     TiffContext *s = avctx->priv_data;
401
402     s->width = 0;
403     s->height = 0;
404     s->avctx = avctx;
405     avcodec_get_frame_defaults((AVFrame*)&s->picture);
406     avctx->coded_frame= (AVFrame*)&s->picture;
407     s->picture.data[0] = NULL;
408
409     return 0;
410 }
411
412 static int tiff_end(AVCodecContext *avctx)
413 {
414     TiffContext * const s = avctx->priv_data;
415
416     if(s->picture.data[0])
417         avctx->release_buffer(avctx, &s->picture);
418     return 0;
419 }
420
421 AVCodec tiff_decoder = {
422     "tiff",
423     CODEC_TYPE_VIDEO,
424     CODEC_ID_TIFF,
425     sizeof(TiffContext),
426     tiff_init,
427     NULL,
428     tiff_end,
429     decode_frame,
430     0,
431     NULL
432 };