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;