Mercurial > libavcodec.hg
comparison tiff.c @ 4186:14fe1e8d337c libavcodec
8-bit images support for TIFF
author | kostya |
---|---|
date | Mon, 13 Nov 2006 05:32:10 +0000 |
parents | 7120f779d313 |
children | 46f12596304f |
comparison
equal
deleted
inserted
replaced
4185:7120f779d313 | 4186:14fe1e8d337c |
---|---|
35 TIFF_STRIP_OFFS = 0x111, | 35 TIFF_STRIP_OFFS = 0x111, |
36 TIFF_ROWSPERSTRIP = 0x116, | 36 TIFF_ROWSPERSTRIP = 0x116, |
37 TIFF_STRIP_SIZE, | 37 TIFF_STRIP_SIZE, |
38 TIFF_XPOS = 0x11E, | 38 TIFF_XPOS = 0x11E, |
39 TIFF_YPOS = 0x11F, | 39 TIFF_YPOS = 0x11F, |
40 TIFF_PREDICTOR = 0x13D | 40 TIFF_PREDICTOR = 0x13D, |
41 TIFF_PAL = 0x140 | |
41 }; | 42 }; |
42 | 43 |
43 enum TiffCompr{ | 44 enum TiffCompr{ |
44 TIFF_RAW = 1, | 45 TIFF_RAW = 1, |
45 TIFF_CCITT_RLE, | 46 TIFF_CCITT_RLE, |
67 | 68 |
68 int width, height; | 69 int width, height; |
69 unsigned int bpp; | 70 unsigned int bpp; |
70 int le; | 71 int le; |
71 int compr; | 72 int compr; |
73 int invert; | |
72 | 74 |
73 int strips, rps; | 75 int strips, rps; |
74 int sot; | 76 int sot; |
75 uint8_t* stripdata; | 77 uint8_t* stripdata; |
76 uint8_t* stripsizes; | 78 uint8_t* stripsizes; |
185 static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t *end_buf, AVFrame *pic) | 187 static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t *end_buf, AVFrame *pic) |
186 { | 188 { |
187 int tag, type, count, off, value = 0; | 189 int tag, type, count, off, value = 0; |
188 uint8_t *src, *dst; | 190 uint8_t *src, *dst; |
189 int i, j, ssize, soff, stride; | 191 int i, j, ssize, soff, stride; |
192 int *pal, *rp, *gp, *bp; | |
190 | 193 |
191 tag = tget_short(&buf, s->le); | 194 tag = tget_short(&buf, s->le); |
192 type = tget_short(&buf, s->le); | 195 type = tget_short(&buf, s->le); |
193 count = tget_long(&buf, s->le); | 196 count = tget_long(&buf, s->le); |
194 off = tget_long(&buf, s->le); | 197 off = tget_long(&buf, s->le); |
222 case TIFF_WIDTH: | 225 case TIFF_WIDTH: |
223 s->width = value; | 226 s->width = value; |
224 break; | 227 break; |
225 case TIFF_HEIGHT: | 228 case TIFF_HEIGHT: |
226 s->height = value; | 229 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; | 230 break; |
240 case TIFF_BPP: | 231 case TIFF_BPP: |
241 if(count == 1) s->bpp = value; | 232 if(count == 1) s->bpp = value; |
242 else{ | 233 else{ |
243 switch(type){ | 234 switch(type){ |
251 break; | 242 break; |
252 default: | 243 default: |
253 s->bpp = -1; | 244 s->bpp = -1; |
254 } | 245 } |
255 } | 246 } |
256 if(s->bpp != 24){ | 247 switch(s->bpp){ |
257 av_log(s->avctx, AV_LOG_ERROR, "Only RGB24 is supported\n"); | 248 case 8: |
258 return -1; | 249 s->avctx->pix_fmt = PIX_FMT_PAL8; |
250 break; | |
251 case 24: | |
252 s->avctx->pix_fmt = PIX_FMT_RGB24; | |
253 break; | |
254 default: | |
255 av_log(s->avctx, AV_LOG_ERROR, "Only RGB24 is supported (this bpp=%i)\n", s->bpp); | |
256 return -1; | |
257 } | |
258 if(s->width != s->avctx->width || s->height != s->avctx->height){ | |
259 if(avcodec_check_dimensions(s->avctx, s->width, s->height)) | |
260 return -1; | |
261 avcodec_set_dimensions(s->avctx, s->width, s->height); | |
262 } | |
263 if(s->picture.data[0]) | |
264 s->avctx->release_buffer(s->avctx, &s->picture); | |
265 if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){ | |
266 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
267 return -1; | |
268 } | |
269 if(s->bpp == 8){ | |
270 /* make default grayscale pal */ | |
271 pal = s->picture.data[1]; | |
272 for(i = 0; i < 256; i++) | |
273 pal[i] = i * 0x010101; | |
259 } | 274 } |
260 break; | 275 break; |
261 case TIFF_COMPR: | 276 case TIFF_COMPR: |
262 s->compr = value; | 277 s->compr = value; |
263 switch(s->compr){ | 278 switch(s->compr){ |
362 src[j] += src[j - soff]; | 377 src[j] += src[j - soff]; |
363 src += stride; | 378 src += stride; |
364 } | 379 } |
365 } | 380 } |
366 break; | 381 break; |
382 case TIFF_INVERT: | |
383 switch(value){ | |
384 case 0: | |
385 s->invert = 1; | |
386 break; | |
387 case 1: | |
388 s->invert = 0; | |
389 break; | |
390 } | |
391 break; | |
392 case TIFF_PAL: | |
393 if(s->avctx->pix_fmt != PIX_FMT_PAL8){ | |
394 av_log(s->avctx, AV_LOG_ERROR, "Palette met but this is not palettized format\n"); | |
395 return -1; | |
396 } | |
397 pal = s->picture.data[1]; | |
398 off = (type == TIFF_SHORT) ? 2 : 1; | |
399 rp = buf; | |
400 gp = buf + count / 3 * off; | |
401 bp = buf + count / 3 * off * 2; | |
402 off = (type == TIFF_SHORT) ? 8 : 0; | |
403 for(i = 0; i < count / 3; i++){ | |
404 j = (tget(&rp, type, s->le) >> off) << 16; | |
405 j |= (tget(&gp, type, s->le) >> off) << 8; | |
406 j |= tget(&bp, type, s->le) >> off; | |
407 pal[i] = j; | |
408 } | |
367 } | 409 } |
368 return 0; | 410 return 0; |
369 } | 411 } |
370 | 412 |
371 static int decode_frame(AVCodecContext *avctx, | 413 static int decode_frame(AVCodecContext *avctx, |
386 else{ | 428 else{ |
387 av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n"); | 429 av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n"); |
388 return -1; | 430 return -1; |
389 } | 431 } |
390 s->le = le; | 432 s->le = le; |
433 s->invert = 0; | |
391 // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number | 434 // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number |
392 // that further identifies the file as a TIFF file" | 435 // that further identifies the file as a TIFF file" |
393 if(tget_short(&buf, le) != 42){ | 436 if(tget_short(&buf, le) != 42){ |
394 av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n"); | 437 av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n"); |
395 return -1; | 438 return -1; |
406 if(tiff_decode_tag(s, orig_buf, buf, end_buf, p) < 0) | 449 if(tiff_decode_tag(s, orig_buf, buf, end_buf, p) < 0) |
407 return -1; | 450 return -1; |
408 buf += 12; | 451 buf += 12; |
409 } | 452 } |
410 | 453 |
454 if(s->invert){ | |
455 uint8_t *src; | |
456 int j; | |
457 | |
458 src = s->picture.data[0]; | |
459 for(j = 0; j < s->height; j++){ | |
460 for(i = 0; i < s->picture.linesize[0]; i++) | |
461 src[i] = 255 - src[i]; | |
462 src += s->picture.linesize[0]; | |
463 } | |
464 } | |
411 *picture= *(AVFrame*)&s->picture; | 465 *picture= *(AVFrame*)&s->picture; |
412 *data_size = sizeof(AVPicture); | 466 *data_size = sizeof(AVPicture); |
413 | 467 |
414 return buf_size; | 468 return buf_size; |
415 } | 469 } |