[FFmpeg-devel] [PATCH] avcodec/tiff: Add support for recognizing DNG files
velocityra at gmail.com
velocityra at gmail.com
Sun Mar 17 23:29:34 EET 2019
From: Nick Renieris <velocityra at gmail.com>
Prints "DNG images are not supported" if it finds a TIFF image with
the 'DNGVersion' tag. In DNG images with the .tiff extension it,
solves the issue where the TIFF thumbnail in IFD 0 was incorrectly
parsed (related confusion: [1]). Adds an option (-dng_thumbnail)
for dumping TIFF thumbnails, should the user want to. Also prints
the DNG version of the file on the debug channel.
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
---
[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 | 29 ++++++++++++++++++++++++++++-
libavcodec/tiff.h | 18 +++++++++++++-----
libavformat/img2.c | 1 +
3 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 112f5b52f4..341c280736 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -54,7 +54,9 @@ typedef struct TiffContext {
AVCodecContext *avctx;
GetByteContext gb;
+ /** options */
int get_subimage;
+ int get_dng_thumbnail;
int width, height;
unsigned int bpp, bppcount;
@@ -70,6 +72,7 @@ typedef struct TiffContext {
int fill_order;
uint32_t res[4];
+ int dng_mode; /** denotes that this is a DNG image */
int is_bayer;
uint8_t pattern[4];
unsigned white_level;
@@ -1077,7 +1080,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:
@@ -1322,6 +1325,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,
@@ -1375,6 +1392,7 @@ again:
s->fill_order = 0;
s->white_level = 0;
s->is_bayer = 0;
+ s->dng_mode = 0;
free_geotags(s);
// Reset these offsets so we can tell if they were set this frame
@@ -1389,6 +1407,14 @@ again:
return ret;
}
+ if (s->dng_mode) {
+ av_log(avctx, AV_LOG_ERROR, "DNG images are not supported\n");
+ av_log(avctx, AV_LOG_INFO, "Consider using -dng_thumbnail for decoding the embedded thumbail instead\n");
+
+ if (!s->get_dng_thumbnail)
+ return AVERROR_PATCHWELCOME;
+ }
+
if (s->sub_ifd && s->get_subimage) {
off = s->sub_ifd;
if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
@@ -1607,6 +1633,7 @@ static av_cold int tiff_end(AVCodecContext *avctx)
#define OFFSET(x) offsetof(TiffContext, x)
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 },
+ { "dng_thumbnail", "decode embedded thumbnail for DNG images, if available", OFFSET(get_dng_thumbnail), 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.17.1.windows.2
More information about the ffmpeg-devel
mailing list