From patchwork Thu Oct 3 18:42:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Skakov Pavel X-Patchwork-Id: 15496 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 5914D4486C4 for ; Thu, 3 Oct 2019 21:50:47 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 32A81687F6B; Thu, 3 Oct 2019 21:50:47 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f178.google.com (mail-lj1-f178.google.com [209.85.208.178]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0409F6804E8 for ; Thu, 3 Oct 2019 21:50:40 +0300 (EEST) Received: by mail-lj1-f178.google.com with SMTP id q64so3890739ljb.12 for ; Thu, 03 Oct 2019 11:50:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:message-id:date:user-agent:mime-version :content-language; bh=URlFayL4972qtZqBW7VXjXq3XxsRYEAyXY3xLw/LZMM=; b=Ob1iCWkx+4QpgWsGzhxYbUnGk4a3I8hBA/KMH7cytrFKgxNOV56RB7aTjng9P0REsa stBC0ABgDcWLIwyncvRrw2NYjMYLmbzsdz+9ieSFF45+j5Ee9u6Mk9cOKHzKYBd68u9j sLYTqRPr98lsn3gOAWXKci9Nt4zD/nEh7sHDYmkeDz9yNvK2R1tV6KJDTHpzmJrGJofH fn+qbOFwH+q4q2nEMdIf/gITT9sj5l18XGCrCUclmHkTD+7o9Egk8mUsp1xortvo74hC od4shIq+M7ovhRCEO0pBajL2MZxUOjxnNGperGsm5ZvMKS0dsyhkaIW0JTv5zB0Q3KDg t9fA== 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:message-id:date:user-agent :mime-version:content-language; bh=URlFayL4972qtZqBW7VXjXq3XxsRYEAyXY3xLw/LZMM=; b=Szkek4L1HV7gCMRzEj5gZ0UzM1HOIAVyYlLsXtn6XImK6GhopibiJmarLUUxCZOBoK BJiGitIdmW5XQ41Zfeioy9Ou6ZwhjL1KxwfSHlzOna9bw4esK+QGchUBy2TYXFlIVRI0 3Q8EKGuoX+YpZo6B5yvcSEsIvzY3zCG8V7YstNEOvFz9FvQygdhVPq63HH/U740GJNlN GMlcTX8fj3+aHw6lpFPUk4TBsvyQhK9c18cxph47OOJ81Lnn+sn2o8/JgNrW50oZuDsR WAfP+bZzND/gSHy39vYvtGig1Sbeq4XMy6NA8tX7cHoBJk/Rl9FgHgGv8w8ftsmBNcGb wg0g== X-Gm-Message-State: APjAAAVh+xZjOgsUODO+GfLRHNjpWLtoyV740MRCMMC9OyMfAX+Y1n+a ZJfyvM0UnZWh/VCt5QgI175lmVht X-Google-Smtp-Source: APXvYqwkcND7QBbH5dI/4NXwUGmDdJdCx4Zac5nSRo62/W/jABOjftMh1rJEOZiIg5RpPGAitL4d3w== X-Received: by 2002:a2e:9d16:: with SMTP id t22mr6218211lji.207.1570128175178; Thu, 03 Oct 2019 11:42:55 -0700 (PDT) Received: from [10.1.0.176] ([5.18.235.135]) by smtp.gmail.com with ESMTPSA id e19sm700190lja.8.2019.10.03.11.42.53 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 03 Oct 2019 11:42:54 -0700 (PDT) From: Skakov Pavel To: FFmpeg development discussions and patches Message-ID: Date: Thu, 3 Oct 2019 21:42:49 +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 Content-Language: en-US Subject: [FFmpeg-devel] [PATCH] 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. Example for PC range YUV, compare to ImageMagick decoding: https://samples.ffmpeg.org/image-samples/dscf0013.tif From 5e24edbf73f3a897fd203e36963e9cf5db5e688d Mon Sep 17 00:00:00 2001 From: Pavel Skakov Date: Thu, 3 Oct 2019 21:28:10 +0300 Subject: [PATCH] avcodec/tiff: add limited support for ReferenceBlackWhite and YCbCrCoefficients tags Signed-off-by: Pavel Skakov --- libavcodec/tiff.c | 74 ++++++++++++++++++++++++++++++++++++++++-- tests/ref/fate/exif-image-tiff | 2 +- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 8b39ca1ebc..90215fce09 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -1441,12 +1441,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 +1523,72 @@ 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 { + // LibTIFF handles rational values by converting them to/from floats, so we do the same in tests for equality + float coef[3]; + for (i = 0; i < 3; i++) { + unsigned num = ff_tget(&s->gb, TIFF_LONG, s->le); + unsigned den = ff_tget(&s->gb, TIFF_LONG, s->le); + if (!den) { + av_log(s->avctx, AV_LOG_ERROR, "YCbCrCoefficients divisor is zero\n"); + return AVERROR_INVALIDDATA; + } + coef[i] = (float)num/den; + } + if (coef[0] == 0.2125f && coef[1] == 0.7154f && coef[2] == 0.0721f) + s->avctx->colorspace = AVCOL_SPC_BT709; + else if (coef[0] != 0.299f || coef[1] != 0.587f || coef[2] != 0.114f) { + av_log(s->avctx, AV_LOG_WARNING, "Unrecognized YCbCrCoefficients values: %.4f %.4f %.4f\n", coef[0], coef[1], coef[2]); + 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; + unsigned mul = 1 << (bpp - 8); + float max_val = (1 << bpp) - 1; + float coef[6]; + for (i = 0; i < 6; i++) { + unsigned num = ff_tget(&s->gb, TIFF_LONG, s->le); + unsigned den = ff_tget(&s->gb, TIFF_LONG, s->le); + if (!den) { + av_log(s->avctx, AV_LOG_ERROR, "ReferenceBlackWhite divisor is zero\n"); + return AVERROR_INVALIDDATA; + } + coef[i] = (float)num/den; + } + if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) { + if (!coef[0] && coef[1] == max_val && coef[2] == (max_val + 1)/2 && coef[3] == max_val && coef[4] == coef[2] && coef[5] == coef[3]) + s->avctx->color_range = AVCOL_RANGE_JPEG; + // NOTE: TIFF 6.0 specification has an example where it mistakenly shows TV range coef[0] as 15 + else if (coef[0] == 16*mul && coef[1] == 235*mul && coef[2] == 128*mul && coef[3] == 240*mul && coef[4] == coef[2] && coef[5] == coef[3]) + 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", coef[0], coef[1], coef[2], coef[3], coef[4], coef[5]); + s->avctx->color_range = AVCOL_RANGE_UNSPECIFIED; + } + } else { + if (!coef[0] && coef[1] == max_val && !coef[2] && coef[3] == max_val && !coef[4] && coef[5] == max_val) + s->avctx->color_range = AVCOL_RANGE_JPEG; + else if (coef[0] == 16*mul && coef[1] == 235*mul && coef[2] == coef[0] && coef[3] == coef[1] && coef[2] == coef[0] && coef[3] == coef[1]) + 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", coef[0], coef[1], coef[2], coef[3], coef[4], coef[5]); + 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