[FFmpeg-devel] [PATCH] avcodec/tiff: Add support for recognizing DNG files
Paul B Mahol
onemda at gmail.com
Tue May 28 23:13:59 EEST 2019
On 5/28/19, velocityra at gmail.com <velocityra at gmail.com> wrote:
> From: Nick Renieris <velocityra at gmail.com>
>
> In DNG images with the .tiff extension, it solves the issue where the
> TIFF thumbnail in IFD 0 was incorrectly parsed (related confusion: [1]).
> Embedded thumbnails for DNG images can still be decoded with the added
> "-dng_thumb" option.
>
> Additionally:
> - Renamed TIFF_WHITE_LEVEL to DNG_WHITE_LEVEL since it is specified
> in the DNG spec.
> - Added/changed some comments to be more precise in differentiating
> between TIFF, TIFF/EP and DNG values.
>
> Related to ticket: https://trac.ffmpeg.org/ticket/4364
>
This patch breaks decoding DNGs which are already supported.
> ---
>
> [1]:
> https://superuser.com/questions/546879/creating-video-from-dng-images-with-ffmpeg
>
> Signed-off-by: Nick Renieris <velocityra at gmail.com>
> ---
> libavcodec/tiff.c | 36 +++++++++++++++++++++++++++++++++++-
> libavcodec/tiff.h | 18 +++++++++++++-----
> libavformat/img2.c | 1 +
> 3 files changed, 49 insertions(+), 6 deletions(-)
>
> diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
> index 79e6242549..9575fe92ce 100644
> --- a/libavcodec/tiff.c
> +++ b/libavcodec/tiff.c
> @@ -56,6 +56,7 @@ typedef struct TiffContext {
>
> int get_subimage;
> uint16_t get_page;
> + int get_dng_thumb;
>
> int width, height;
> unsigned int bpp, bppcount;
> @@ -70,7 +71,9 @@ typedef struct TiffContext {
> int predictor;
> int fill_order;
> uint32_t res[4];
> + int is_thumbnail;
>
> + int dng_mode; /** denotes that this is a DNG image */
> int is_bayer;
> uint8_t pattern[4];
> unsigned white_level;
> @@ -948,6 +951,8 @@ static int tiff_decode_tag(TiffContext *s, AVFrame
> *frame)
> }
>
> switch (tag) {
> + case TIFF_SUBFILE:
> + s->is_thumbnail = (value != 0);
> case TIFF_WIDTH:
> s->width = value;
> break;
> @@ -1088,7 +1093,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame
> *frame)
> case TIFF_SUB_IFDS:
> s->sub_ifd = value;
> break;
> - case TIFF_WHITE_LEVEL:
> + case DNG_WHITE_LEVEL:
> s->white_level = value;
> break;
> case TIFF_CFA_PATTERN_DIM:
> @@ -1339,6 +1344,20 @@ static int tiff_decode_tag(TiffContext *s, AVFrame
> *frame)
> case TIFF_SOFTWARE_NAME:
> ADD_METADATA(count, "software", NULL);
> break;
> + case DNG_VERSION:
> + if (count == 4) {
> + unsigned int ver[4];
> + ver[0] = ff_tget(&s->gb, type, s->le);
> + ver[1] = ff_tget(&s->gb, type, s->le);
> + ver[2] = ff_tget(&s->gb, type, s->le);
> + ver[3] = ff_tget(&s->gb, type, s->le);
> +
> + av_log(s->avctx, AV_LOG_DEBUG, "DNG file, version
> %u.%u.%u.%u\n",
> + ver[0], ver[1], ver[2], ver[3]);
> +
> + s->dng_mode = 1;
> + }
> + break;
> default:
> if (s->avctx->err_recognition & AV_EF_EXPLODE) {
> av_log(s->avctx, AV_LOG_ERROR,
> @@ -1387,6 +1406,7 @@ static int decode_frame(AVCodecContext *avctx,
> s->le = le;
> // TIFF_BPP is not a required tag and defaults to 1
> again:
> + s->is_thumbnail = 0;
> s->bppcount = s->bpp = 1;
> s->photometric = TIFF_PHOTOMETRIC_NONE;
> s->compr = TIFF_RAW;
> @@ -1394,6 +1414,7 @@ again:
> s->white_level = 0;
> s->is_bayer = 0;
> s->cur_page = 0;
> + s->dng_mode = 0;
> free_geotags(s);
>
> // Reset these offsets so we can tell if they were set this frame
> @@ -1408,6 +1429,18 @@ again:
> return ret;
> }
>
> + if (s->dng_mode) {
> + if (!s->get_dng_thumb) {
> + av_log(avctx, AV_LOG_ERROR, "DNG images are not supported\n");
> + av_log(avctx, AV_LOG_INFO, "You can use -dng_thumb to decode an
> embedded TIFF thumbnail (if any) instead\n");
> + return AVERROR_INVALIDDATA;
> + }
> + if (!s->is_thumbnail) {
> + av_log(avctx, AV_LOG_INFO, "No embedded thumbnail present\n");
> + return AVERROR_EOF;
> + }
> + }
> +
> /** whether we should look for this IFD's SubIFD */
> retry_for_subifd = s->sub_ifd && s->get_subimage;
> /** whether we should look for this multi-page IFD's next page */
> @@ -1671,6 +1704,7 @@ static av_cold int tiff_end(AVCodecContext *avctx)
> static const AVOption tiff_options[] = {
> { "subimage", "decode subimage instead if available",
> OFFSET(get_subimage), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1,
> AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM },
> { "page", "page number of multi-page image to decode (starting from
> 1)", OFFSET(get_page), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX,
> AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM },
> + { "dng_thumb", "decode TIFF thumbnail of DNG image",
> OFFSET(get_dng_thumb), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1,
> AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM },
> { NULL },
> };
>
> diff --git a/libavcodec/tiff.h b/libavcodec/tiff.h
> index 4b08650108..3cede299f6 100644
> --- a/libavcodec/tiff.h
> +++ b/libavcodec/tiff.h
> @@ -20,7 +20,7 @@
>
> /**
> * @file
> - * TIFF tables
> + * TIFF constants & data structures
> *
> * For more information about the TIFF format, check the official docs at:
> * http://partners.adobe.com/public/developer/tiff/index.html
> @@ -33,7 +33,7 @@
> #include <stdint.h>
> #include "tiff_common.h"
>
> -/** abridged list of TIFF tags */
> +/** abridged list of TIFF and TIFF/EP tags */
> enum TiffTags {
> TIFF_SUBFILE = 0xfe,
> TIFF_WIDTH = 0x100,
> @@ -85,10 +85,17 @@ enum TiffTags {
> TIFF_GEO_KEY_DIRECTORY = 0x87AF,
> TIFF_GEO_DOUBLE_PARAMS = 0x87B0,
> TIFF_GEO_ASCII_PARAMS = 0x87B1,
> - TIFF_WHITE_LEVEL = 0xC61D,
> };
>
> -/** list of TIFF compression types */
> +/** abridged list of DNG tags */
> +enum DngTags
> +{
> + DNG_VERSION = 0xC612,
> + DNG_BACKWARD_VERSION = 0xC613,
> + DNG_WHITE_LEVEL = 0xC61D,
> +};
> +
> +/** list of TIFF, TIFF/EP and DNG compression types */
> enum TiffCompr {
> TIFF_RAW = 1,
> TIFF_CCITT_RLE,
> @@ -151,6 +158,7 @@ enum TiffGeoTagKey {
> TIFF_VERTICAL_UNITS_GEOKEY = 4099
> };
>
> +/** list of TIFF, TIFF/AP and DNG PhotometricInterpretation
> (TIFF_PHOTOMETRIC) values */
> enum TiffPhotometric {
> TIFF_PHOTOMETRIC_NONE = -1,
> TIFF_PHOTOMETRIC_WHITE_IS_ZERO, /* mono or grayscale, 0 is white
> */
> @@ -163,7 +171,7 @@ enum TiffPhotometric {
> TIFF_PHOTOMETRIC_CIE_LAB = 8, /* 1976 CIE L*a*b* */
> TIFF_PHOTOMETRIC_ICC_LAB, /* ICC L*a*b* */
> TIFF_PHOTOMETRIC_ITU_LAB, /* ITU L*a*b* */
> - TIFF_PHOTOMETRIC_CFA = 32803, /* Color Filter Array (DNG) */
> + TIFF_PHOTOMETRIC_CFA = 32803, /* Color Filter Array (TIFF/AP and
> DNG) */
> TIFF_PHOTOMETRIC_LOG_L = 32844, /* CIE Log2(L) */
> TIFF_PHOTOMETRIC_LOG_LUV, /* CIE Log L*u*v* */
> TIFF_PHOTOMETRIC_LINEAR_RAW = 34892, /* Linear Raw (DNG) */
> diff --git a/libavformat/img2.c b/libavformat/img2.c
> index 8432cc0955..16bc9d2abd 100644
> --- a/libavformat/img2.c
> +++ b/libavformat/img2.c
> @@ -51,6 +51,7 @@ const IdStrMap ff_img_tags[] = {
> { AV_CODEC_ID_TARGA, "tga" },
> { AV_CODEC_ID_TIFF, "tiff" },
> { AV_CODEC_ID_TIFF, "tif" },
> + { AV_CODEC_ID_TIFF, "dng" },
> { AV_CODEC_ID_SGI, "sgi" },
> { AV_CODEC_ID_PTX, "ptx" },
> { AV_CODEC_ID_PCX, "pcx" },
> --
> 2.21.0.windows.1
>
>
More information about the ffmpeg-devel
mailing list