Mercurial > libavcodec.hg
comparison tiff.c @ 8429:b3ecaba81501 libavcodec
Decode TIFF image only after all tags have been decoded
author | kostya |
---|---|
date | Mon, 22 Dec 2008 06:50:18 +0000 |
parents | 8bf9f50ed64f |
children | 902c43f89d92 |
comparison
equal
deleted
inserted
replaced
8428:8bf9f50ed64f | 8429:b3ecaba81501 |
---|---|
39 int width, height; | 39 int width, height; |
40 unsigned int bpp; | 40 unsigned int bpp; |
41 int le; | 41 int le; |
42 int compr; | 42 int compr; |
43 int invert; | 43 int invert; |
44 | 44 int predictor; |
45 int strips, rps; | 45 |
46 int strips, rps, sstype; | |
46 int sot; | 47 int sot; |
47 const uint8_t* stripdata; | 48 const uint8_t* stripdata; |
48 const uint8_t* stripsizes; | 49 const uint8_t* stripsizes; |
49 int stripsize, stripoff; | 50 int stripsize, stripoff; |
50 LZWState *lzw; | 51 LZWState *lzw; |
148 } | 149 } |
149 return 0; | 150 return 0; |
150 } | 151 } |
151 | 152 |
152 | 153 |
153 static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf, AVFrame *pic) | 154 static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf) |
154 { | 155 { |
155 int tag, type, count, off, value = 0; | 156 int tag, type, count, off, value = 0; |
156 const uint8_t *src; | 157 int i, j; |
157 uint8_t *dst; | |
158 int i, j, ssize, soff, stride; | |
159 uint32_t *pal; | 158 uint32_t *pal; |
160 const uint8_t *rp, *gp, *bp; | 159 const uint8_t *rp, *gp, *bp; |
161 | 160 |
162 tag = tget_short(&buf, s->le); | 161 tag = tget_short(&buf, s->le); |
163 type = tget_short(&buf, s->le); | 162 type = tget_short(&buf, s->le); |
259 pal[i] = i * 0x010101; | 258 pal[i] = i * 0x010101; |
260 } | 259 } |
261 break; | 260 break; |
262 case TIFF_COMPR: | 261 case TIFF_COMPR: |
263 s->compr = value; | 262 s->compr = value; |
263 s->predictor = 0; | |
264 switch(s->compr){ | 264 switch(s->compr){ |
265 case TIFF_RAW: | 265 case TIFF_RAW: |
266 case TIFF_PACKBITS: | 266 case TIFF_PACKBITS: |
267 case TIFF_LZW: | 267 case TIFF_LZW: |
268 break; | 268 break; |
322 s->strips = 1; | 322 s->strips = 1; |
323 }else{ | 323 }else{ |
324 s->stripsizes = start + off; | 324 s->stripsizes = start + off; |
325 } | 325 } |
326 s->strips = count; | 326 s->strips = count; |
327 s->sstype = type; | |
327 if(s->stripsizes > end_buf){ | 328 if(s->stripsizes > end_buf){ |
328 av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); | 329 av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); |
329 return -1; | 330 return -1; |
330 } | 331 } |
331 if(!pic->data[0]){ | |
332 av_log(s->avctx, AV_LOG_ERROR, "Picture initialization missing\n"); | |
333 return -1; | |
334 } | |
335 /* now we have the data and may start decoding */ | |
336 stride = pic->linesize[0]; | |
337 dst = pic->data[0]; | |
338 for(i = 0; i < s->height; i += s->rps){ | |
339 if(s->stripsizes) | |
340 ssize = tget(&s->stripsizes, type, s->le); | |
341 else | |
342 ssize = s->stripsize; | |
343 | |
344 if(s->stripdata){ | |
345 soff = tget(&s->stripdata, s->sot, s->le); | |
346 }else | |
347 soff = s->stripoff; | |
348 src = start + soff; | |
349 if(tiff_unpack_strip(s, dst, stride, src, ssize, FFMIN(s->rps, s->height - i)) < 0) | |
350 break; | |
351 dst += s->rps * stride; | |
352 } | |
353 break; | 332 break; |
354 case TIFF_PREDICTOR: | 333 case TIFF_PREDICTOR: |
355 if(!pic->data[0]){ | 334 s->predictor = value; |
356 av_log(s->avctx, AV_LOG_ERROR, "Picture initialization missing\n"); | |
357 return -1; | |
358 } | |
359 if(value == 2){ | |
360 dst = pic->data[0]; | |
361 stride = pic->linesize[0]; | |
362 soff = s->bpp >> 3; | |
363 ssize = s->width * soff; | |
364 for(i = 0; i < s->height; i++) { | |
365 for(j = soff; j < ssize; j++) | |
366 dst[j] += dst[j - soff]; | |
367 dst += stride; | |
368 } | |
369 } | |
370 break; | 335 break; |
371 case TIFF_INVERT: | 336 case TIFF_INVERT: |
372 switch(value){ | 337 switch(value){ |
373 case 0: | 338 case 0: |
374 s->invert = 1; | 339 s->invert = 1; |
419 TiffContext * const s = avctx->priv_data; | 384 TiffContext * const s = avctx->priv_data; |
420 AVFrame *picture = data; | 385 AVFrame *picture = data; |
421 AVFrame * const p= (AVFrame*)&s->picture; | 386 AVFrame * const p= (AVFrame*)&s->picture; |
422 const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; | 387 const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; |
423 int id, le, off; | 388 int id, le, off; |
424 int i, entries; | 389 int i, j, entries; |
390 int stride, soff, ssize; | |
391 uint8_t *dst; | |
425 | 392 |
426 //parse image header | 393 //parse image header |
427 id = AV_RL16(buf); buf += 2; | 394 id = AV_RL16(buf); buf += 2; |
428 if(id == 0x4949) le = 1; | 395 if(id == 0x4949) le = 1; |
429 else if(id == 0x4D4D) le = 0; | 396 else if(id == 0x4D4D) le = 0; |
447 return -1; | 414 return -1; |
448 } | 415 } |
449 buf = orig_buf + off; | 416 buf = orig_buf + off; |
450 entries = tget_short(&buf, le); | 417 entries = tget_short(&buf, le); |
451 for(i = 0; i < entries; i++){ | 418 for(i = 0; i < entries; i++){ |
452 if(tiff_decode_tag(s, orig_buf, buf, end_buf, p) < 0) | 419 if(tiff_decode_tag(s, orig_buf, buf, end_buf) < 0) |
453 return -1; | 420 return -1; |
454 buf += 12; | 421 buf += 12; |
422 } | |
423 if(!s->stripdata && !s->stripoff){ | |
424 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n"); | |
425 return -1; | |
426 } | |
427 /* now we have the data and may start decoding */ | |
428 if(!p->data[0]){ | |
429 av_log(s->avctx, AV_LOG_ERROR, "Picture initialization missing\n"); | |
430 return -1; | |
431 } | |
432 if(s->strips == 1 && !s->stripsize){ | |
433 av_log(avctx, AV_LOG_WARNING, "Image data size missing\n"); | |
434 s->stripsize = buf_size - s->stripoff; | |
435 } | |
436 stride = p->linesize[0]; | |
437 dst = p->data[0]; | |
438 for(i = 0; i < s->height; i += s->rps){ | |
439 if(s->stripsizes) | |
440 ssize = tget(&s->stripsizes, s->sstype, s->le); | |
441 else | |
442 ssize = s->stripsize; | |
443 | |
444 if(s->stripdata){ | |
445 soff = tget(&s->stripdata, s->sot, s->le); | |
446 }else | |
447 soff = s->stripoff; | |
448 if(tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize, FFMIN(s->rps, s->height - i)) < 0) | |
449 break; | |
450 dst += s->rps * stride; | |
451 } | |
452 if(s->predictor == 2){ | |
453 dst = p->data[0]; | |
454 soff = s->bpp >> 3; | |
455 ssize = s->width * soff; | |
456 for(i = 0; i < s->height; i++) { | |
457 for(j = soff; j < ssize; j++) | |
458 dst[j] += dst[j - soff]; | |
459 dst += stride; | |
460 } | |
455 } | 461 } |
456 | 462 |
457 if(s->invert){ | 463 if(s->invert){ |
458 uint8_t *src; | 464 uint8_t *src; |
459 int j; | 465 int j; |