Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2013/05/10 04:39:32... | ... |
@@ -52,6 +52,7 @@ typedef struct TiffContext { |
52 | 52 |
int le; |
53 | 53 |
enum TiffCompr compr; |
54 | 54 |
int invert; |
55 |
+ int planar; |
|
55 | 56 |
int fax_opts; |
56 | 57 |
int predictor; |
57 | 58 |
int fill_order; |
... | ... |
@@ -431,6 +432,9 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride, |
431 | 431 |
const uint8_t *ssrc = src; |
432 | 432 |
int width = ((s->width * s->bpp) + 7) >> 3; |
433 | 433 |
|
434 |
+ if (s->planar) |
|
435 |
+ width /= s->bppcount; |
|
436 |
+ |
|
434 | 437 |
if (size <= 0) |
435 | 438 |
return AVERROR_INVALIDDATA; |
436 | 439 |
|
... | ... |
@@ -617,22 +621,24 @@ static int init_image(TiffContext *s, AVFrame *frame) |
617 | 617 |
s->avctx->pix_fmt = AV_PIX_FMT_PAL8; |
618 | 618 |
break; |
619 | 619 |
case 243: |
620 |
- s->avctx->pix_fmt = AV_PIX_FMT_RGB24; |
|
620 |
+ s->avctx->pix_fmt = s->planar ? AV_PIX_FMT_GBRP : AV_PIX_FMT_RGB24; |
|
621 | 621 |
break; |
622 | 622 |
case 161: |
623 | 623 |
s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GRAY16LE : AV_PIX_FMT_GRAY16BE; |
624 | 624 |
break; |
625 | 625 |
case 162: |
626 |
- s->avctx->pix_fmt = AV_PIX_FMT_GRAY8A; |
|
626 |
+ s->avctx->pix_fmt = s>planar ? AV_PIX_FMT_NONE : AV_PIX_FMT_GRAY8A; |
|
627 | 627 |
break; |
628 | 628 |
case 324: |
629 |
- s->avctx->pix_fmt = AV_PIX_FMT_RGBA; |
|
629 |
+ s->avctx->pix_fmt = s->planar ? AV_PIX_FMT_GBRAP : AV_PIX_FMT_RGBA; |
|
630 | 630 |
break; |
631 | 631 |
case 483: |
632 |
- s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE; |
|
632 |
+ s->avctx->pix_fmt = s->planar ? (s->le ? AV_PIX_FMT_GBRP16LE : AV_PIX_FMT_GBRP16BE) : |
|
633 |
+ (s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE); |
|
633 | 634 |
break; |
634 | 635 |
case 644: |
635 |
- s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE; |
|
636 |
+ s->avctx->pix_fmt = s->planar ? (s->le ? AV_PIX_FMT_GBRAP16LE : AV_PIX_FMT_GBRAP16BE) : |
|
637 |
+ (s->le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE); |
|
636 | 638 |
break; |
637 | 639 |
default: |
638 | 640 |
av_log(s->avctx, AV_LOG_ERROR, |
... | ... |
@@ -884,10 +890,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) |
884 | 884 |
s->palette_is_set = 1; |
885 | 885 |
break; |
886 | 886 |
case TIFF_PLANAR: |
887 |
- if (value == 2) { |
|
888 |
- av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n"); |
|
889 |
- return AVERROR_PATCHWELCOME; |
|
890 |
- } |
|
887 |
+ s->planar = value == 2; |
|
891 | 888 |
break; |
892 | 889 |
case TIFF_T4OPTIONS: |
893 | 890 |
if (s->compr == TIFF_G3) |
... | ... |
@@ -1042,7 +1045,7 @@ static int decode_frame(AVCodecContext *avctx, |
1042 | 1042 |
TiffContext *const s = avctx->priv_data; |
1043 | 1043 |
AVFrame *const p = data; |
1044 | 1044 |
unsigned off; |
1045 |
- int id, le, ret; |
|
1045 |
+ int id, le, ret, plane, planes; |
|
1046 | 1046 |
int i, j, entries; |
1047 | 1047 |
int stride; |
1048 | 1048 |
unsigned soff, ssize; |
... | ... |
@@ -1125,8 +1128,6 @@ static int decode_frame(AVCodecContext *avctx, |
1125 | 1125 |
av_log(avctx, AV_LOG_WARNING, "Image data size missing\n"); |
1126 | 1126 |
s->stripsize = avpkt->size - s->stripoff; |
1127 | 1127 |
} |
1128 |
- stride = p->linesize[0]; |
|
1129 |
- dst = p->data[0]; |
|
1130 | 1128 |
|
1131 | 1129 |
if (s->stripsizesoff) { |
1132 | 1130 |
if (s->stripsizesoff >= (unsigned)avpkt->size) |
... | ... |
@@ -1144,6 +1145,10 @@ static int decode_frame(AVCodecContext *avctx, |
1144 | 1144 |
return AVERROR_INVALIDDATA; |
1145 | 1145 |
} |
1146 | 1146 |
|
1147 |
+ planes = s->planar ? s->bppcount : 1; |
|
1148 |
+ for (plane = 0; plane < planes; plane++) { |
|
1149 |
+ stride = p->linesize[plane]; |
|
1150 |
+ dst = p->data[plane]; |
|
1147 | 1151 |
for (i = 0; i < s->height; i += s->rps) { |
1148 | 1152 |
if (s->stripsizesoff) |
1149 | 1153 |
ssize = tget(&stripsizes, s->sstype, s->le); |
... | ... |
@@ -1165,7 +1170,7 @@ static int decode_frame(AVCodecContext *avctx, |
1165 | 1165 |
dst += s->rps * stride; |
1166 | 1166 |
} |
1167 | 1167 |
if (s->predictor == 2) { |
1168 |
- dst = p->data[0]; |
|
1168 |
+ dst = p->data[plane]; |
|
1169 | 1169 |
soff = s->bpp >> 3; |
1170 | 1170 |
ssize = s->width * soff; |
1171 | 1171 |
if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48LE || |
... | ... |
@@ -1192,13 +1197,22 @@ static int decode_frame(AVCodecContext *avctx, |
1192 | 1192 |
} |
1193 | 1193 |
|
1194 | 1194 |
if (s->invert) { |
1195 |
- dst = p->data[0]; |
|
1195 |
+ dst = p->data[plane]; |
|
1196 | 1196 |
for (i = 0; i < s->height; i++) { |
1197 |
- for (j = 0; j < p->linesize[0]; j++) |
|
1197 |
+ for (j = 0; j < p->linesize[plane]; j++) |
|
1198 | 1198 |
dst[j] = (s->avctx->pix_fmt == AV_PIX_FMT_PAL8 ? (1<<s->bpp) - 1 : 255) - dst[j]; |
1199 |
- dst += p->linesize[0]; |
|
1199 |
+ dst += p->linesize[plane]; |
|
1200 | 1200 |
} |
1201 | 1201 |
} |
1202 |
+ } |
|
1203 |
+ |
|
1204 |
+ if (s->planar && s->bpp_count > 2) { |
|
1205 |
+ FFSWAP(uint8_t*, p->data[0], p->data[2]); |
|
1206 |
+ FFSWAP(int, p->linesize[0], p->linesize[2]); |
|
1207 |
+ FFSWAP(uint8_t*, p->data[0], p->data[1]); |
|
1208 |
+ FFSWAP(int, p->linesize[0], p->linesize[1]); |
|
1209 |
+ } |
|
1210 |
+ |
|
1202 | 1211 |
*got_frame = 1; |
1203 | 1212 |
|
1204 | 1213 |
return avpkt->size; |