From 15776ca18298a1214a19c2cbf456b0545f5ba60e Mon Sep 17 00:00:00 2001 From: Nick Renieris Date: Thu, 29 Aug 2019 16:10:53 +0300 Subject: lavc/tiff: Default-initialize WhiteLevel DNG tag value Initialized to `(2 ^ BitsPerSample) - 1` as per the DNG Specification. Also make sure that `BlackLevel < WhiteLevel`. This fixes decoding for "X7 CinemaDNG" samples here: - https://www.dji.com/gr/zenmuse-x7/info#downloads Signed-off-by: Nick Renieris --- libavcodec/tiff.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 411bf4dd40..ccd5678c23 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -1776,6 +1776,7 @@ static int decode_frame(AVCodecContext *avctx, GetByteContext stripsizes; GetByteContext stripdata; int retry_for_subifd, retry_for_page; + int is_dng; bytestream2_init(&s->gb, avpkt->data, avpkt->size); @@ -1853,6 +1854,10 @@ again: goto again; } + /* At this point we've decided on which (Sub)IFD to process */ + + is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG); + for (i = 0; igeotag_count; i++) { const char *keyname = get_geokey_name(s->geotags[i].key); if (!keyname) { @@ -1870,10 +1875,22 @@ again: } } + if (is_dng) { + if (s->white_level == 0) + s->white_level = (1 << s->bpp) - 1; /* Default value as per the spec */ + + if (s->white_level <= s->black_level) { + av_log(avctx, AV_LOG_ERROR, "BlackLevel (%"PRId32") must be less than WhiteLevel (%"PRId32")\n", + s->black_level, s->white_level); + return AVERROR_INVALIDDATA; + } + } + if (!s->is_tiled && !s->strippos && !s->stripoff) { av_log(avctx, AV_LOG_ERROR, "Image data is missing\n"); return AVERROR_INVALIDDATA; } + /* now we have the data and may start decoding */ if ((ret = init_image(s, &frame)) < 0) return ret; @@ -1905,7 +1922,7 @@ again: /* Handle DNG images with JPEG-compressed tiles */ - if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG) && s->is_tiled) { + if (is_dng && s->is_tiled) { if (!s->is_jpeg) { avpriv_report_missing_feature(avctx, "DNG uncompressed tiled images"); return AVERROR_PATCHWELCOME; @@ -2063,8 +2080,7 @@ again: FFSWAP(int, p->linesize[0], p->linesize[1]); } - if (s->is_bayer && s->white_level && s->bpp == 16 && - !(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG)) { + if (s->is_bayer && s->white_level && s->bpp == 16 && !is_dng) { uint16_t *dst = (uint16_t *)p->data[0]; for (i = 0; i < s->height; i++) { for (j = 0; j < s->width; j++) -- cgit v1.2.3