return 0;
}
+static void unpack_gray(TiffContext *s, AVFrame *p,
+ const uint8_t *src, int lnum, int width, int bpp)
+{
+ GetBitContext gb;
+ uint16_t *dst = (uint16_t *)(p->data[0] + lnum * p->linesize[0]);
+
+ init_get_bits8(&gb, src, width);
+
+ for (int i = 0; i < s->width; i++) {
+ dst[i] = get_bits(&gb, bpp);
+ }
+}
+
static void unpack_yuv(TiffContext *s, AVFrame *p,
const uint8_t *src, int lnum)
{
if (s->is_bayer) {
width = (s->bpp * s->width + 7) >> 3;
}
+ if (p->format == AV_PIX_FMT_GRAY12) {
+ av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, width);
+ if (s->yuv_line == NULL) {
+ av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
+ return AVERROR(ENOMEM);
+ }
+ dst = s->yuv_line;
+ stride = 0;
+ }
if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
#if CONFIG_ZLIB
if (is_yuv) {
unpack_yuv(s, p, dst, strip_start + line);
line += s->subsampling[1] - 1;
+ } else if (p->format == AV_PIX_FMT_GRAY12) {
+ unpack_gray(s, p, dst, strip_start + line, width, s->bpp);
}
dst += stride;
}
if (s->compr == TIFF_CCITT_RLE ||
s->compr == TIFF_G3 ||
s->compr == TIFF_G4) {
- if (is_yuv)
+ if (is_yuv || p->format == AV_PIX_FMT_GRAY12)
return AVERROR_INVALIDDATA;
return tiff_unpack_fax(s, dst, stride, src, size, width, lines);
if (is_yuv) {
unpack_yuv(s, p, dst, strip_start + line);
line += s->subsampling[1] - 1;
+ } else if (p->format == AV_PIX_FMT_GRAY12) {
+ unpack_gray(s, p, dst, strip_start + line, width, s->bpp);
}
dst += stride;
}
case 81:
s->avctx->pix_fmt = s->palette_is_set ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
break;
+ case 121:
+ s->avctx->pix_fmt = AV_PIX_FMT_GRAY12;
+ break;
case 10081:
switch (AV_RL32(s->pattern)) {
case 0x02010100:
s->avctx->pix_fmt = s->le ? AV_PIX_FMT_YA16LE : AV_PIX_FMT_YA16BE;
break;
case 324:
- s->avctx->pix_fmt = AV_PIX_FMT_RGBA;
+ s->avctx->pix_fmt = s->photometric == TIFF_PHOTOMETRIC_SEPARATED ? AV_PIX_FMT_RGB0 : AV_PIX_FMT_RGBA;
break;
case 483:
s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE;
case TIFF_PHOTOMETRIC_BLACK_IS_ZERO:
case TIFF_PHOTOMETRIC_RGB:
case TIFF_PHOTOMETRIC_PALETTE:
+ case TIFF_PHOTOMETRIC_SEPARATED:
case TIFF_PHOTOMETRIC_YCBCR:
case TIFF_PHOTOMETRIC_CFA:
s->photometric = value;
break;
case TIFF_PHOTOMETRIC_ALPHA_MASK:
- case TIFF_PHOTOMETRIC_SEPARATED:
case TIFF_PHOTOMETRIC_CIE_LAB:
case TIFF_PHOTOMETRIC_ICC_LAB:
case TIFF_PHOTOMETRIC_ITU_LAB:
dst += stride;
}
}
+
+ if (s->photometric == TIFF_PHOTOMETRIC_SEPARATED &&
+ s->avctx->pix_fmt == AV_PIX_FMT_RGB0) {
+ dst = p->data[plane];
+ for (i = 0; i < s->height; i++) {
+ for (j = 0; j < s->width; j++) {
+ int k = 255 - dst[4 * j + 3];
+ int r = (255 - dst[4 * j ]) * k;
+ int g = (255 - dst[4 * j + 1]) * k;
+ int b = (255 - dst[4 * j + 2]) * k;
+ dst[4 * j ] = r * 257 >> 16;
+ dst[4 * j + 1] = g * 257 >> 16;
+ dst[4 * j + 2] = b * 257 >> 16;
+ dst[4 * j + 3] = 255;
+ }
+ dst += p->linesize[plane];
+ }
+ }
}
if (s->planar && s->bppcount > 2) {
ff_lzw_decode_close(&s->lzw);
av_freep(&s->deinvert_buf);
s->deinvert_buf_size = 0;
+ av_freep(&s->yuv_line);
+ s->yuv_line_size = 0;
av_freep(&s->fax_buffer);
s->fax_buffer_size = 0;
return 0;