From patchwork Wed Oct 31 14:25:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 10868 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 76A6444C9DB for ; Wed, 31 Oct 2018 16:25:45 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id DB7EF68A870; Wed, 31 Oct 2018 16:25:16 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f65.google.com (mail-ed1-f65.google.com [209.85.208.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2B71F68A84C for ; Wed, 31 Oct 2018 16:25:10 +0200 (EET) Received: by mail-ed1-f65.google.com with SMTP id z12-v6so8004326edp.7 for ; Wed, 31 Oct 2018 07:25:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=anQBm7uMw+VfGIDYNt7/532h5gonj0f3Wzeg0UF5Mu8=; b=ikMb+mirLIZDi8VJH0oClT5EE8JQ/NEDBS5yp5aRr7OgRsjhhRXGxP3OvbIH1AZDnU KeVtv0IA1IBJ/Eblq0/zdtBnONh9SyEzUgFBnuOeb2epFmmvx6FDv9hzbSXC8jefqYD8 jd4IvfVhCr39nyFj+UAHg8DjdDjxAOei+LY+vka9+6fFg0/IHbIs7OSL14z4vNrvQaHf NVJOHACLFPWMXWjDgMmEv9lzC7zaUuNsv/vnFSmRRtzx5JihQK0Q2IUt2OEYLfYlPLIx vi+07IzBI7aCY45hMlxWNCXLTFSdsbn4lff8H49+X2KIfw8LiqQU7J4XlzsDhgre0Fqo /hsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=anQBm7uMw+VfGIDYNt7/532h5gonj0f3Wzeg0UF5Mu8=; b=AZlRXb75HEA88q/0FZ/BhTUAwPRyMahQ/lPHF03b5qW/L5Zv01JV7cR0aGQCTaG970 M33qQ+viSggWk4cggnImH6OBNbLkE4X3z05mAjXXM44Yn9FjvTCu6VcnBu8QbLRVEDOa 7DiqBuHrE1ypKNt9I9skVvqqwtk1/+CpJ40NWNaQoQzl+4A8QeVIX8WWTm5anmmt7Xhu hka7O3WXtfa6qNbqucvMuBb28ydR425liNVp5uD8ptSRm3JVgNz2PaEq77rjKdoPK+o5 Fj0O8AV4fu6dPbvQpIZXHvsQa1Rru/Lqu7hVk1zU0Nh5NP93P3QniH5RccKwjUARjC3I c8FA== X-Gm-Message-State: AGRZ1gKaS6BCzppkSPs20SLHh9X1WiZ/8U0cFARMhU+4PMU+lElBlrqj 0Ew9KbBjG7v0gupisSg4LeJwb71Q2WE= X-Google-Smtp-Source: AJdET5dXaekiUDjRYHLkTLYT2F9zVdU7K+g/XOTY/QNK4+ZSGHTJGf+8o/5JulqxvekxjgdwJ4NMqg== X-Received: by 2002:aa7:d804:: with SMTP id v4-v6mr2268299edq.255.1540995941154; Wed, 31 Oct 2018 07:25:41 -0700 (PDT) Received: from localhost.localdomain ([94.250.174.60]) by smtp.gmail.com with ESMTPSA id i17-v6sm3583222edq.75.2018.10.31.07.25.39 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Oct 2018 07:25:40 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Wed, 31 Oct 2018 15:25:27 +0100 Message-Id: <20181031142528.25850-1-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH 1/2] avcodec/tiff: add initial bayer support X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Paul B Mahol --- libavcodec/tiff.c | 58 +++++++++++++++++++++++++++++++++++++++-------- libavcodec/tiff.h | 1 + 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index b537ec06a5..d42550b4cf 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -46,6 +46,7 @@ #include "tiff.h" #include "tiff_data.h" #include "thread.h" +#include "get_bits.h" typedef struct TiffContext { AVCodecContext *avctx; @@ -65,6 +66,9 @@ typedef struct TiffContext { int fill_order; uint32_t res[4]; + int is_bayer; + uint8_t pattern[4]; + int strips, rps, sstype; int sot; int stripsizesoff, stripsize, stripoff, strippos; @@ -236,7 +240,8 @@ static int add_metadata(int count, int type, }; } -static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst, +static void av_always_inline horizontal_fill(TiffContext *s, + unsigned int bpp, uint8_t* dst, int usePtr, const uint8_t *src, uint8_t c, int width, int offset) { @@ -267,6 +272,15 @@ static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst, dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4; } break; + case 12: { + uint16_t *dst16 = (uint16_t *)dst; + GetBitContext gb; + init_get_bits8(&gb, src, width); + for (int i = 0; i < s->width; i++) { + dst16[i] = get_bits(&gb, 12) << 4;; + } + } + break; default: if (usePtr) { memcpy(dst + offset, src, width); @@ -368,7 +382,7 @@ static int tiff_unpack_zlib(TiffContext *s, AVFrame *p, uint8_t *dst, int stride src = zbuf; for (line = 0; line < lines; line++) { if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) { - horizontal_fill(s->bpp, dst, 1, src, 0, width, 0); + horizontal_fill(s, s->bpp, dst, 1, src, 0, width, 0); } else { memcpy(dst, src, width); } @@ -433,7 +447,7 @@ static int tiff_unpack_lzma(TiffContext *s, AVFrame *p, uint8_t *dst, int stride src = buf; for (line = 0; line < lines; line++) { if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) { - horizontal_fill(s->bpp, dst, 1, src, 0, width, 0); + horizontal_fill(s, s->bpp, dst, 1, src, 0, width, 0); } else { memcpy(dst, src, width); } @@ -476,7 +490,7 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride, s->compr, s->fax_opts); if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) for (line = 0; line < lines; line++) { - horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0); + horizontal_fill(s, s->bpp, dst, 1, dst, 0, width, 0); dst += stride; } return ret; @@ -516,6 +530,9 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid av_assert0(width <= bytes_per_row); av_assert0(s->bpp == 24); } + if (s->is_bayer) { + width = (s->bpp * s->width + 7) >> 3; + } if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) { #if CONFIG_ZLIB @@ -559,7 +576,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid return AVERROR_INVALIDDATA; } if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) - horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0); + horizontal_fill(s, s->bpp, dst, 1, dst, 0, width, 0); if (is_yuv) { unpack_yuv(s, p, dst, strip_start + line); line += s->subsampling[1] - 1; @@ -595,7 +612,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid return AVERROR_INVALIDDATA; if (!s->fill_order) { - horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8), + horizontal_fill(s, s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8 || s->is_bayer), dst, 1, src, 0, width, 0); } else { int i; @@ -619,7 +636,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid "Copy went out of bounds\n"); return AVERROR_INVALIDDATA; } - horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8), + horizontal_fill(s, s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8), dst, 1, src, 0, code, pixels); src += code; pixels += code; @@ -631,7 +648,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid return AVERROR_INVALIDDATA; } c = *src++; - horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8), + horizontal_fill(s, s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8), dst, 0, NULL, c, code, pixels); pixels += code; } @@ -665,7 +682,7 @@ static int init_image(TiffContext *s, ThreadFrame *frame) return AVERROR_INVALIDDATA; } - switch (s->planar * 1000 + s->bpp * 10 + s->bppcount) { + switch (s->planar * 1000 + s->bpp * 10 + s->bppcount + s->is_bayer * 10000) { case 11: if (!s->palette_is_set) { s->avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; @@ -681,6 +698,20 @@ static int init_image(TiffContext *s, ThreadFrame *frame) case 81: s->avctx->pix_fmt = s->palette_is_set ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8; break; + case 10121: + switch (s->pattern[0] | s->pattern[1] << 8 | s->pattern[2] << 16 | s->pattern[3] << 24) { + case 0x02010100: + s->avctx->pix_fmt = s->le ? AV_PIX_FMT_BAYER_RGGB16LE : AV_PIX_FMT_BAYER_RGGB16BE; + break; + case 0x00010102: + s->avctx->pix_fmt = s->le ? AV_PIX_FMT_BAYER_BGGR16LE : AV_PIX_FMT_BAYER_BGGR16BE; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "Unsupported Bayer pattern: 0x%X\n", + s->pattern[0] | s->pattern[1] << 8 | s->pattern[2] << 16 | s->pattern[3] << 24); + return AVERROR_PATCHWELCOME; + } + break; case 243: if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) { if (s->subsampling[0] == 1 && s->subsampling[1] == 1) { @@ -961,6 +992,13 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) case TIFF_PREDICTOR: s->predictor = value; break; + case TIFF_CFA_PATTERN: + s->is_bayer = 1; + s->pattern[0] = ff_tget(&s->gb, type, s->le); + s->pattern[1] = ff_tget(&s->gb, type, s->le); + s->pattern[2] = ff_tget(&s->gb, type, s->le); + s->pattern[3] = ff_tget(&s->gb, type, s->le); + break; case TIFF_PHOTOMETRIC: switch (value) { case TIFF_PHOTOMETRIC_WHITE_IS_ZERO: @@ -968,6 +1006,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) case TIFF_PHOTOMETRIC_RGB: case TIFF_PHOTOMETRIC_PALETTE: case TIFF_PHOTOMETRIC_YCBCR: + case TIFF_PHOTOMETRIC_CFA: s->photometric = value; break; case TIFF_PHOTOMETRIC_ALPHA_MASK: @@ -975,7 +1014,6 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) case TIFF_PHOTOMETRIC_CIE_LAB: case TIFF_PHOTOMETRIC_ICC_LAB: case TIFF_PHOTOMETRIC_ITU_LAB: - case TIFF_PHOTOMETRIC_CFA: case TIFF_PHOTOMETRIC_LOG_L: case TIFF_PHOTOMETRIC_LOG_LUV: case TIFF_PHOTOMETRIC_LINEAR_RAW: diff --git a/libavcodec/tiff.h b/libavcodec/tiff.h index 3f692afa00..ae6622cb0c 100644 --- a/libavcodec/tiff.h +++ b/libavcodec/tiff.h @@ -75,6 +75,7 @@ enum TiffTags { TIFF_YCBCR_SUBSAMPLING = 0x212, TIFF_YCBCR_POSITIONING = 0x213, TIFF_REFERENCE_BW = 0x214, + TIFF_CFA_PATTERN = 0x828E, TIFF_COPYRIGHT = 0x8298, TIFF_MODEL_TIEPOINT = 0x8482, TIFF_MODEL_PIXEL_SCALE = 0x830E,