From patchwork Fri Oct 4 18:29:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Skakov Pavel X-Patchwork-Id: 15503 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 A813044A143 for ; Fri, 4 Oct 2019 21:29:16 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 86B086805D8; Fri, 4 Oct 2019 21:29:16 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f42.google.com (mail-ed1-f42.google.com [209.85.208.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4DE076805D8 for ; Fri, 4 Oct 2019 21:29:10 +0300 (EEST) Received: by mail-ed1-f42.google.com with SMTP id h33so6813584edh.12 for ; Fri, 04 Oct 2019 11:29:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:references:message-id:date:user-agent:mime-version :in-reply-to:content-language; bh=3zxYtG+0HL2bpUd2pkoT8wX37xKq9CRwQSUs53OLYqM=; b=jiJA6r5CtmbDLdpcuG9wiiet4IzR+a3EIB3L8q4uw/XlL4vEhICIbCy53H9bOBU9sp TM/NekDF7ZLIWuA1BhFz2+g9d/vA0k9Tpd+eklUatpJi2OtEuiGvtfgo/piYQRu0hX09 JtacNcmgjJtVl5WrmNDpSejgeXQj91dRtDsZ8Odp3Tpkr0+HPpp+eY14qdGytKAsX4Pk HPeCv6CwLrCCOvsScNokXSNScfbi+Srees5hmVFcdv79RCxxW6Fy1SkJS9lRyq0+I2st dWCvYzmwg/t0F1phBwcGRuCEG6/us0/cUFqkAhNCrHih8oPCYlDuE1brDTh8QnNfNalN cSnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:subject:to:references:message-id:date :user-agent:mime-version:in-reply-to:content-language; bh=3zxYtG+0HL2bpUd2pkoT8wX37xKq9CRwQSUs53OLYqM=; b=U9Skh2CdYlWRO4XDvAQhHSVUXS80PVmPKV1pk0H42FHrJ5233ozadPFD0Gj8lUr6mI KO7pFLxyYgVGVnqKjll+A2R4IvO3VyC3BG2Fl/lG0wqprKX0DLrka4dy1oVJnQbzbR77 ZnHZ+IIHodiXCHaq1F40bUtfTzoeVnWatzojMa13QnCqrIvzBzYb0t+EFaD7cmLVFJKE 7jPE3VqMIfBfm3e8arn3cspfT1aLXEOc2j7bPAXdOD5ZGVSn//nbsh2EUJrbbWRDyr2y BZ09u1l0EaklYyU8D7c6y+ql2QaH2ezO7/GDa0Nbz+nYMIiu4k3m4WtJt+fc3ibb59Ei 9pPQ== X-Gm-Message-State: APjAAAVuf5RZCqRNOzL+/TZwVBnK95cNrWv5FUrClZE00ddVZeiZty2H pHQcq0fzwl72CZhh3Hru2z98npsv X-Google-Smtp-Source: APXvYqw18fAq9JTtyd2olLFAnjM4ivhw5MIhunrv8s/6x8d4E4kWmS711SHH4tEqwPzBhG4030N7/Q== X-Received: by 2002:a50:eb93:: with SMTP id y19mr16714240edr.94.1570213749624; Fri, 04 Oct 2019 11:29:09 -0700 (PDT) Received: from [10.1.0.176] ([5.18.233.189]) by smtp.gmail.com with ESMTPSA id s24sm1261515edx.5.2019.10.04.11.29.08 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 Oct 2019 11:29:08 -0700 (PDT) From: Skakov Pavel To: FFmpeg development discussions and patches References: Message-ID: <9c8a962b-e36f-2ab9-8608-6c98f45288ba@gmail.com> Date: Fri, 4 Oct 2019 21:29:02 +0300 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US Subject: [FFmpeg-devel] [PATCH v2] avcodec/tiff: add limited support for ReferenceBlackWhite and YCbCrCoefficients tags 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" >> Add support for properly handling PC/TV ranges and Rec601/Rec709 color spaces. > Can't this be implemented without using floats? AVRationals are not a good idea as those values are unsigned and often use full unsigned range. Here is slightly different approach: range check for fractional rationals and exact check for integer expected values. Warning text is probably better left with floats as they provide the most meaningful values for end user. From 14c712eb2a7c3b92f83c6edd0115d6eefccac476 Mon Sep 17 00:00:00 2001 From: Pavel Skakov Date: Fri, 4 Oct 2019 21:12:19 +0300 Subject: [PATCH] avcodec/tiff: add limited support for ReferenceBlackWhite and YCbCrCoefficients tags Signed-off-by: Pavel Skakov --- libavcodec/tiff.c | 73 ++++++++++++++++++++++++++++++++++++++++-- tests/ref/fate/exif-image-tiff | 2 +- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 8b39ca1ebc..069792b4c3 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -1216,6 +1216,13 @@ static void set_sar(TiffContext *s, unsigned tag, unsigned num, unsigned den) } } +static int r_near(unsigned n1, unsigned d1, unsigned n2, unsigned d2) +{ + uint64_t v1 = (uint64_t)n1*d2; + uint64_t v2 = (uint64_t)n2*d1; + return v2 - d1 < v1 && v1 < v2 + d1; +} + static int tiff_decode_tag(TiffContext *s, AVFrame *frame) { unsigned tag, type, count, off, value = 0, value2 = 1; // value2 is a denominator so init. to 1 @@ -1441,12 +1448,16 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) break; case TIFF_PHOTOMETRIC: switch (value) { + case TIFF_PHOTOMETRIC_YCBCR: + s->avctx->colorspace = AVCOL_SPC_BT470BG; + // fallthrough + case TIFF_PHOTOMETRIC_RGB: + s->avctx->color_range = AVCOL_RANGE_JPEG; + // fallthrough case TIFF_PHOTOMETRIC_WHITE_IS_ZERO: 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: case TIFF_PHOTOMETRIC_LINEAR_RAW: // Used by DNG images s->photometric = value; @@ -1519,6 +1530,64 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) } } break; + case TIFF_YCBCR_COEFFICIENTS: + if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) + if (count != 3 || type != TIFF_RATIONAL) { + av_log(s->avctx, AV_LOG_ERROR, "YCbCrCoefficients are invalid\n"); + return AVERROR_INVALIDDATA; + } else { + unsigned c[6]; + for (i = 0; i < 6; i++) + c[i] = ff_tget(&s->gb, TIFF_LONG, s->le); + if (r_near(c[0], c[1], 2125, 10000) && r_near(c[2], c[3], 7154, 10000) && r_near(c[4], c[5], 721, 10000)) + s->avctx->colorspace = AVCOL_SPC_BT709; + else if (!r_near(c[0], c[1], 299, 1000) || !r_near(c[2], c[3], 587, 1000) || !r_near(c[4], c[5], 114, 1000)) { + av_log(s->avctx, AV_LOG_WARNING, "Unrecognized YCbCrCoefficients values: %.4f %.4f %.4f\n", (float)c[0]/c[1], (float)c[2]/c[3], (float)c[4]/c[5]); + s->avctx->colorspace = AVCOL_SPC_UNSPECIFIED; + } + } + break; + case TIFF_REFERENCE_BW: + if (s->photometric == TIFF_PHOTOMETRIC_YCBCR || s->photometric == TIFF_PHOTOMETRIC_RGB) + if (count != 6 || type != TIFF_RATIONAL) { + av_log(s->avctx, AV_LOG_ERROR, "ReferenceBlackWhite is invalid\n"); + return AVERROR_INVALIDDATA; + } else { + unsigned bpp = s->bpp/s->bppcount; + uint64_t mul = 1 << (bpp - 8); + uint64_t max_val = (1 << bpp) - 1; + uint64_t mid_val = 1 << (bpp - 1); + unsigned c[12]; + for (i = 0; i < 12; i++) + c[i] = ff_tget(&s->gb, TIFF_LONG, s->le); + if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) { + if (!c[0] && c[2] == max_val*c[3] && c[4] == mid_val*c[5] && c[6] == max_val*c[7] && c[8] == mid_val*c[9] && c[10] == max_val*c[11]) + s->avctx->color_range = AVCOL_RANGE_JPEG; + // NOTE: TIFF 6.0 specification has an example where it mistakenly shows TV range c[0] as 15 + else if (c[0] == 16*mul*c[1] && c[ 2] == 235*mul*c[3] && + c[4] == 128*mul*c[5] && c[ 6] == 240*mul*c[7] && + c[8] == 128*mul*c[9] && c[10] == 240*mul*c[11]) + s->avctx->color_range = AVCOL_RANGE_MPEG; + else { + av_log(s->avctx, AV_LOG_WARNING, "Unrecognized ReferenceBlackWhite values: [%g;%g] [%g;%g] [%g;%g]\n", + (float)c[0]/c[1], (float)c[2]/c[3], (float)c[4]/c[5], (float)c[6]/c[7], (float)c[8]/c[9], (float)c[10]/c[11]); + s->avctx->color_range = AVCOL_RANGE_UNSPECIFIED; + } + } else { + if (!c[0] && c[2] == max_val*c[3] && !c[4] && c[6] == max_val*c[7] && !c[8] && c[10] == max_val*c[11]) + s->avctx->color_range = AVCOL_RANGE_JPEG; + else if (c[0] == 16*mul*c[1] && c[ 2] == 235*mul*c[3] && + c[4] == 16*mul*c[5] && c[ 6] == 235*mul*c[7] && + c[8] == 16*mul*c[9] && c[10] == 235*mul*c[11]) + s->avctx->color_range = AVCOL_RANGE_MPEG; + else { + av_log(s->avctx, AV_LOG_WARNING, "Unrecognized ReferenceBlackWhite values: [%g;%g] [%g;%g] [%g;%g]\n", + (float)c[0]/c[1], (float)c[2]/c[3], (float)c[4]/c[5], (float)c[6]/c[7], (float)c[8]/c[9], (float)c[10]/c[11]); + s->avctx->color_range = AVCOL_RANGE_UNSPECIFIED; + } + } + } + break; case TIFF_T4OPTIONS: if (s->compr == TIFF_G3) s->fax_opts = value; diff --git a/tests/ref/fate/exif-image-tiff b/tests/ref/fate/exif-image-tiff index 51580601e1..ebf2f38d6e 100644 --- a/tests/ref/fate/exif-image-tiff +++ b/tests/ref/fate/exif-image-tiff @@ -22,7 +22,7 @@ display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 -color_range=unknown +color_range=pc color_space=unknown color_primaries=unknown color_transfer=unknown -- 2.13.2.windows.1