aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeo Izen <leo.izen@gmail.com>2025-04-09 13:07:49 -0400
committerLeo Izen <leo.izen@gmail.com>2025-08-19 11:26:48 -0400
commit1e816ebefee0ef479fa76bd2a1fb9ec5d5e807df (patch)
treefa83e2fc129c9e94504b92cac2792fa901d054b7
parent93a8091015978c44462626409af71789080bbef4 (diff)
downloadffmpeg-1e816ebefee0ef479fa76bd2a1fb9ec5d5e807df.tar.gz
avcodec/tiff: decode TIFF non-image-data tags into EXIF metadata struct
This commit will cause TIFF files to store their tags in the EXIF struct so tags such as orientation can be transfered to other formats (such as PNG) in a way that doesn't corrupt the IFD. Signed-off-by: Leo Izen <leo.izen@gmail.com>
-rw-r--r--libavcodec/tiff.c14
-rw-r--r--tests/ref/fate/exif-image-tiff24
2 files changed, 37 insertions, 1 deletions
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index b468598fbb..d15bc497ec 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -47,6 +47,7 @@
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"
+#include "exif_internal.h"
#include "faxcompr.h"
#include "lzw.h"
#include "tiff.h"
@@ -124,6 +125,8 @@ typedef struct TiffContext {
int geotag_count;
TiffGeoTag *geotags;
+
+ AVExifMetadata exif_meta;
} TiffContext;
static const float d65_white[3] = { 0.950456f, 1.f, 1.088754f };
@@ -1937,6 +1940,12 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
int is_dng;
int has_tile_bits, has_strip_bits;
+ av_exif_free(&s->exif_meta);
+ /* this will not parse the image data */
+ ret = av_exif_parse_buffer(avctx, avpkt->data, avpkt->size, &s->exif_meta, AV_EXIF_TIFF_HEADER);
+ if (ret < 0)
+ av_log(avctx, AV_LOG_ERROR, "could not parse EXIF data: %s\n", av_err2str(ret));
+
bytestream2_init(&s->gb, avpkt->data, avpkt->size);
// parse image header
@@ -2402,6 +2411,10 @@ again:
}
}
+ ret = ff_exif_attach_ifd(avctx, p, &s->exif_meta);
+ if (ret < 0)
+ av_log(avctx, AV_LOG_ERROR, "error attaching EXIF ifd: %s\n", av_err2str(ret));
+
*got_frame = 1;
return avpkt->size;
@@ -2450,6 +2463,7 @@ static av_cold int tiff_end(AVCodecContext *avctx)
TiffContext *const s = avctx->priv_data;
free_geotags(s);
+ av_exif_free(&s->exif_meta);
ff_lzw_decode_close(&s->lzw);
av_freep(&s->deinvert_buf);
diff --git a/tests/ref/fate/exif-image-tiff b/tests/ref/fate/exif-image-tiff
index 0e604d4271..81737cb983 100644
--- a/tests/ref/fate/exif-image-tiff
+++ b/tests/ref/fate/exif-image-tiff
@@ -32,5 +32,27 @@ color_transfer=unknown
chroma_location=unspecified
TAG:document_name=image_small.tiff
TAG:page_number= 0 / 1
-TAG:software=ImageMagick 6.5.8-0 2010-02-09 Q16 http://www.imagemagick.org
+TAG:0x0129= 0, 1
+TAG:ImageWidth= 200
+TAG:ImageLength= 112
+TAG:BitsPerSample= 8, 8, 8
+TAG:Compression= 1
+TAG:PhotometricInterpretation= 2
+TAG:0x010A= 1
+TAG:0x010D=image_small.tiff
+TAG:StripOffsets= 8, 7808, 15608, 23408, 31208, 39008, 46808, 54608
+ 62408
+TAG:Orientation= 1
+TAG:SamplesPerPixel= 3
+TAG:RowsPerStrip= 13
+TAG:StripByteCounts= 7800, 7800, 7800, 7800, 7800, 7800, 7800, 7800
+ 4800
+TAG:XResolution=1188833536:16777216
+TAG:YResolution=1188833536:16777216
+TAG:PlanarConfiguration= 1
+TAG:ResolutionUnit= 3
+TAG:Software=ImageMagick 6.5.8-0 2010-02-09 Q16 http://www.imagemagick.org
+[SIDE_DATA]
+side_data_type=EXIF metadata
+[/SIDE_DATA]
[/FRAME]