Skip to content

Commit 02c5768

Browse files
committed
fix(exif): Support EXIF 3.0 tags (#4961)
We were supporting Exif 2.3, but in 2024, Exif 3.0 was published and it adds some more tags for us to recognize. The only part I am not sure about here is that the ExifVersion we output is still marked as 2.3, not 3.0, because I'm worried that if we mark it as 3.0, older software reading the images will reject it. Let's see what happens. If downstream apps care, maybe we can bump to 3.0, or even bump to 3.0 only if any of the 3.0 tags are used (that is more involved). Fixes #4960 --------- Signed-off-by: Larry Gritz <[email protected]>
1 parent 8c8bbda commit 02c5768

File tree

12 files changed

+99
-3
lines changed

12 files changed

+99
-3
lines changed

src/doc/stdmetadata.rst

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,59 @@ A sum of:
759759
A unique identifier for the image, as 16 ASCII hexadecimal digits
760760
representing a 128-bit number.
761761

762+
.. option:: "Exif:ImageTitle" : string
763+
764+
Title of the image.
765+
766+
.. option:: "Exif:Photographer" : string
767+
768+
The name of the photographer. This may be different from the "Artist"
769+
field.
770+
771+
.. option:: "Exif:ImageEdtor" : string
772+
773+
The name of the main person who edited the image.
774+
775+
.. option:: "Exif:CameraFirmware" : string
776+
777+
The name and version of the firmware of the camera that captured the image.
778+
779+
.. option:: "Exif:RAWDevelopingSoftware" : string
780+
781+
The name and version of the software that developed the RAW image.
782+
783+
.. option:: "Exif:ImageEditingSoftware" : string
784+
785+
The name and version of any image editing software that was used to
786+
process or edit the image.
787+
788+
.. option:: "Exif:MetadataEditingSoftware" : string
789+
790+
The name and version of any image editing software that was used to
791+
edit the image metadata but not the pixels.
792+
793+
.. option:: "Exif:CompositeImage" : int
794+
795+
Indicates whether the recorded image is a composite image (generated
796+
from capturing multiple, tentatively recorded, source images).
797+
798+
=== ==============================================================
799+
0 unknown
800+
1 non-composite image
801+
2 general composite image
802+
3 composite image captured when shooting
803+
=== ==============================================================
804+
805+
.. option:: "Exif:SourceImageNumberOfCompositeImage" : ushort[2]
806+
807+
If a composite image, the first value is the number of source images
808+
captured (at least 2) and the second value is the number of those
809+
source images ultimately used in the comopsite image.
810+
811+
.. option:: "Exif:SourceImageExposureTimesOfCompositeImage"
812+
813+
This is currently unsupported by OpenImageIO.
814+
762815

763816

764817
GPS Exif metadata

src/include/OpenImageIO/tiffutils.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ struct TIFFDirEntry {
4545

4646
OIIO_NAMESPACE_BEGIN
4747

48+
// Exif spec extends TIFFDataType beyond what TIFF or litiff define in
49+
// TIFFDataType.
50+
enum TIFFDataType_Exif3_Extensions {
51+
EXIF_UTF8_TYPE = 129
52+
};
53+
54+
55+
4856
// Define EXIF constants
4957
enum TIFFTAG {
5058
EXIF_EXPOSURETIME = 33434,
@@ -128,6 +136,17 @@ enum TIFFTAG {
128136
EXIF_LENSMODEL = 42036,
129137
EXIF_LENSSERIALNUMBER = 42037,
130138
EXIF_GAMMA = 42240,
139+
// Exif 3.0 additions follow
140+
EXIF_IMAGETITLE = 42038,
141+
EXIF_PHOTOGRAPHER = 42039,
142+
EXIF_IMAGEEDTOR = 42040,
143+
EXIF_CAMERAFIRMWARE = 42041,
144+
EXIF_RAWDEVELOPINGSOFTWARE = 42042,
145+
EXIF_IMAGEEDITINGSOFTWARE = 42043,
146+
EXIF_METADATAEDITINGSOFTWARE = 42044,
147+
EXIF_COMPOSITEIMAGE = 42080,
148+
EXIF_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE = 42081,
149+
EXIF_SOURCEIMAGEEXPOSURETIMESOFCOMPOSITEIMAGE = 42082,
131150
};
132151

133152

src/libOpenImageIO/exif.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ print_dir_entry(std::ostream& out, const TagMap& tagmap,
254254

255255
switch (dir.tdir_type) {
256256
case TIFF_ASCII:
257+
case EXIF_TIFF_UTF8:
257258
OIIO::print(out, "'{}'", string_view(mydata, dir.tdir_count));
258259
break;
259260
case TIFF_RATIONAL: {
@@ -516,7 +517,18 @@ static const TagInfo exif_tag_table[] = {
516517
{ EXIF_LENSMAKE, "Exif:LensMake", TIFF_ASCII, 0 },
517518
{ EXIF_LENSMODEL, "Exif:LensModel", TIFF_ASCII, 0 },
518519
{ EXIF_LENSSERIALNUMBER, "Exif:LensSerialNumber", TIFF_ASCII, 0 },
519-
{ EXIF_GAMMA, "Exif:Gamma", TIFF_RATIONAL, 0 }
520+
{ EXIF_GAMMA, "Exif:Gamma", TIFF_RATIONAL, 0 },
521+
// Exif 3.0 additions follow
522+
{ EXIF_IMAGETITLE, "Exif:ImageTitle", TIFF_ASCII, 0 },
523+
{ EXIF_PHOTOGRAPHER, "Exif:Photographer", TIFF_ASCII, 0 },
524+
{ EXIF_IMAGEEDTOR, "Exif:ImageEdtor", TIFF_ASCII, 0 },
525+
{ EXIF_CAMERAFIRMWARE, "Exif:CameraFirmware", TIFF_ASCII, 0 },
526+
{ EXIF_RAWDEVELOPINGSOFTWARE, "Exif:RAWDevelopingSoftware", TIFF_ASCII, 0 },
527+
{ EXIF_IMAGEEDITINGSOFTWARE, "Exif:ImageEditingSoftware", TIFF_ASCII, 0 },
528+
{ EXIF_METADATAEDITINGSOFTWARE, "Exif:MetadataEditingSoftware", TIFF_ASCII, 0 },
529+
{ EXIF_COMPOSITEIMAGE, "Exif:CompositeImage", TIFF_SHORT, 1 },
530+
{ EXIF_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, "Exif:SourceImageNumberOfCompositeImage", TIFF_SHORT, 2 },
531+
{ EXIF_SOURCEIMAGEEXPOSURETIMESOFCOMPOSITEIMAGE, "Exif:SourceImageExposureTimesOfCompositeImage", TIFF_NOTYPE, 0 },
520532
// clang-format on
521533
};
522534

@@ -729,7 +741,7 @@ add_exif_item_to_spec(ImageSpec& spec, const char* name,
729741
spec.attribute(name, TypeDesc(TypeDesc::FLOAT, int(count)), f);
730742
return;
731743
}
732-
if (dirp->tdir_type == TIFF_ASCII) {
744+
if (dirp->tdir_type == TIFF_ASCII || dirp->tdir_type == EXIF_UTF8_TYPE) {
733745
size_t len = tiff_data_size(*dirp);
734746
cspan<uint8_t> dspan = pvt::dataspan<char>(*dirp, buf,
735747
offset_adjustment, len);
@@ -1376,6 +1388,8 @@ encode_exif(const ImageSpec& spec, std::vector<char>& blob,
13761388
// Add some required Exif tags that wouldn't be in the spec
13771389
append_tiff_dir_entry(exifdirs, blob, EXIF_EXIFVERSION, TIFF_UNDEFINED,
13781390
4, as_bytes("0230", 4), tiffstart, 0, endianreq);
1391+
// NOTE: We are still saying we write Exif 2.3 even though we support
1392+
// the additional 3.0 tags.
13791393
append_tiff_dir_entry(exifdirs, blob, EXIF_FLASHPIXVERSION,
13801394
TIFF_UNDEFINED, 4, as_bytes("0100", 4), tiffstart,
13811395
0, endianreq);

src/libOpenImageIO/exif.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#define DEBUG_EXIF_UNHANDLED 0
2323

2424

25+
// Exif Documentation:
26+
// - https://archive.org/details/exif-specs-3.0-dc-008-translation-2023-e
27+
2528

2629
OIIO_NAMESPACE_BEGIN
2730
namespace pvt {

src/libOpenImageIO/xmp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ add_attrib(ImageSpec& spec, string_view xmlname, string_view xmlvalue,
317317
&& count == 1) {
318318
oiiotype = TypeDesc::FLOAT;
319319
special = Rational;
320-
} else if (tifftype == TIFF_ASCII)
320+
} else if (tifftype == TIFF_ASCII || tifftype == EXIF_UTF8_TYPE)
321321
oiiotype = TypeDesc::STRING;
322322
else if (tifftype == TIFF_BYTE && count == 1)
323323
oiiotype = TypeDesc::INT;

testsuite/heif/ref/out-libheif1.12-orient.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic
5656
Exif:ApertureValue: 2.52607 (f/2.4)
5757
Exif:BrightnessValue: 2.7506
5858
Exif:ColorSpace: 65535
59+
Exif:CompositeImage: 2
5960
Exif:DateTimeDigitized: "2023:09:28 09:44:03"
6061
Exif:DateTimeOriginal: "2023:09:28 09:44:03"
6162
Exif:DigitalZoomRatio: 1.3057

testsuite/heif/ref/out-libheif1.4.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic
6161
Exif:ApertureValue: 2.52607 (f/2.4)
6262
Exif:BrightnessValue: 2.7506
6363
Exif:ColorSpace: 65535
64+
Exif:CompositeImage: 2
6465
Exif:DateTimeDigitized: "2023:09:28 09:44:03"
6566
Exif:DateTimeOriginal: "2023:09:28 09:44:03"
6667
Exif:DigitalZoomRatio: 1.3057

testsuite/heif/ref/out-libheif1.5.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic
6161
Exif:ApertureValue: 2.52607 (f/2.4)
6262
Exif:BrightnessValue: 2.7506
6363
Exif:ColorSpace: 65535
64+
Exif:CompositeImage: 2
6465
Exif:DateTimeDigitized: "2023:09:28 09:44:03"
6566
Exif:DateTimeOriginal: "2023:09:28 09:44:03"
6667
Exif:DigitalZoomRatio: 1.3057

testsuite/heif/ref/out-libheif1.9-alt2.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic
5656
Exif:ApertureValue: 2.52607 (f/2.4)
5757
Exif:BrightnessValue: 2.7506
5858
Exif:ColorSpace: 65535
59+
Exif:CompositeImage: 2
5960
Exif:DateTimeDigitized: "2023:09:28 09:44:03"
6061
Exif:DateTimeOriginal: "2023:09:28 09:44:03"
6162
Exif:DigitalZoomRatio: 1.3057

testsuite/heif/ref/out-libheif1.9-with-av1-alt2.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic
6161
Exif:ApertureValue: 2.52607 (f/2.4)
6262
Exif:BrightnessValue: 2.7506
6363
Exif:ColorSpace: 65535
64+
Exif:CompositeImage: 2
6465
Exif:DateTimeDigitized: "2023:09:28 09:44:03"
6566
Exif:DateTimeOriginal: "2023:09:28 09:44:03"
6667
Exif:DigitalZoomRatio: 1.3057

0 commit comments

Comments
 (0)