Originally committed as revision 16268 to svn://svn.ffmpeg.org/ffmpeg/trunk
Kostya Shishkov authored on 2008/12/22 15:50:18... | ... |
@@ -41,8 +41,9 @@ typedef struct TiffContext { |
41 | 41 |
int le; |
42 | 42 |
int compr; |
43 | 43 |
int invert; |
44 |
+ int predictor; |
|
44 | 45 |
|
45 |
- int strips, rps; |
|
46 |
+ int strips, rps, sstype; |
|
46 | 47 |
int sot; |
47 | 48 |
const uint8_t* stripdata; |
48 | 49 |
const uint8_t* stripsizes; |
... | ... |
@@ -150,12 +151,10 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin |
150 | 150 |
} |
151 | 151 |
|
152 | 152 |
|
153 |
-static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf, AVFrame *pic) |
|
153 |
+static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf) |
|
154 | 154 |
{ |
155 | 155 |
int tag, type, count, off, value = 0; |
156 |
- const uint8_t *src; |
|
157 |
- uint8_t *dst; |
|
158 |
- int i, j, ssize, soff, stride; |
|
156 |
+ int i, j; |
|
159 | 157 |
uint32_t *pal; |
160 | 158 |
const uint8_t *rp, *gp, *bp; |
161 | 159 |
|
... | ... |
@@ -261,6 +260,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * |
261 | 261 |
break; |
262 | 262 |
case TIFF_COMPR: |
263 | 263 |
s->compr = value; |
264 |
+ s->predictor = 0; |
|
264 | 265 |
switch(s->compr){ |
265 | 266 |
case TIFF_RAW: |
266 | 267 |
case TIFF_PACKBITS: |
... | ... |
@@ -324,49 +324,14 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * |
324 | 324 |
s->stripsizes = start + off; |
325 | 325 |
} |
326 | 326 |
s->strips = count; |
327 |
+ s->sstype = type; |
|
327 | 328 |
if(s->stripsizes > end_buf){ |
328 | 329 |
av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); |
329 | 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 | 332 |
break; |
354 | 333 |
case TIFF_PREDICTOR: |
355 |
- if(!pic->data[0]){ |
|
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 |
- } |
|
334 |
+ s->predictor = value; |
|
370 | 335 |
break; |
371 | 336 |
case TIFF_INVERT: |
372 | 337 |
switch(value){ |
... | ... |
@@ -421,7 +386,9 @@ static int decode_frame(AVCodecContext *avctx, |
421 | 421 |
AVFrame * const p= (AVFrame*)&s->picture; |
422 | 422 |
const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; |
423 | 423 |
int id, le, off; |
424 |
- int i, entries; |
|
424 |
+ int i, j, entries; |
|
425 |
+ int stride, soff, ssize; |
|
426 |
+ uint8_t *dst; |
|
425 | 427 |
|
426 | 428 |
//parse image header |
427 | 429 |
id = AV_RL16(buf); buf += 2; |
... | ... |
@@ -449,10 +416,49 @@ static int decode_frame(AVCodecContext *avctx, |
449 | 449 |
buf = orig_buf + off; |
450 | 450 |
entries = tget_short(&buf, le); |
451 | 451 |
for(i = 0; i < entries; i++){ |
452 |
- if(tiff_decode_tag(s, orig_buf, buf, end_buf, p) < 0) |
|
452 |
+ if(tiff_decode_tag(s, orig_buf, buf, end_buf) < 0) |
|
453 | 453 |
return -1; |
454 | 454 |
buf += 12; |
455 | 455 |
} |
456 |
+ if(!s->stripdata && !s->stripoff){ |
|
457 |
+ av_log(avctx, AV_LOG_ERROR, "Image data is missing\n"); |
|
458 |
+ return -1; |
|
459 |
+ } |
|
460 |
+ /* now we have the data and may start decoding */ |
|
461 |
+ if(!p->data[0]){ |
|
462 |
+ av_log(s->avctx, AV_LOG_ERROR, "Picture initialization missing\n"); |
|
463 |
+ return -1; |
|
464 |
+ } |
|
465 |
+ if(s->strips == 1 && !s->stripsize){ |
|
466 |
+ av_log(avctx, AV_LOG_WARNING, "Image data size missing\n"); |
|
467 |
+ s->stripsize = buf_size - s->stripoff; |
|
468 |
+ } |
|
469 |
+ stride = p->linesize[0]; |
|
470 |
+ dst = p->data[0]; |
|
471 |
+ for(i = 0; i < s->height; i += s->rps){ |
|
472 |
+ if(s->stripsizes) |
|
473 |
+ ssize = tget(&s->stripsizes, s->sstype, s->le); |
|
474 |
+ else |
|
475 |
+ ssize = s->stripsize; |
|
476 |
+ |
|
477 |
+ if(s->stripdata){ |
|
478 |
+ soff = tget(&s->stripdata, s->sot, s->le); |
|
479 |
+ }else |
|
480 |
+ soff = s->stripoff; |
|
481 |
+ if(tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize, FFMIN(s->rps, s->height - i)) < 0) |
|
482 |
+ break; |
|
483 |
+ dst += s->rps * stride; |
|
484 |
+ } |
|
485 |
+ if(s->predictor == 2){ |
|
486 |
+ dst = p->data[0]; |
|
487 |
+ soff = s->bpp >> 3; |
|
488 |
+ ssize = s->width * soff; |
|
489 |
+ for(i = 0; i < s->height; i++) { |
|
490 |
+ for(j = soff; j < ssize; j++) |
|
491 |
+ dst[j] += dst[j - soff]; |
|
492 |
+ dst += stride; |
|
493 |
+ } |
|
494 |
+ } |
|
456 | 495 |
|
457 | 496 |
if(s->invert){ |
458 | 497 |
uint8_t *src; |