annotate tiff.c @ 4166:eced83504436 libavcodec

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