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