Skip to content

Commit 5f72880

Browse files
authored
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 62be33f commit 5f72880

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
@@ -760,6 +760,59 @@ A sum of:
760760
A unique identifier for the image, as 16 ASCII hexadecimal digits
761761
representing a 128-bit number.
762762

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

764817

765818
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
OIIO_NAMESPACE_END

src/libOpenImageIO/exif.cpp

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

261261
switch (dir.tdir_type) {
262262
case TIFF_ASCII:
263+
case EXIF_TIFF_UTF8:
263264
OIIO::print(out, "'{}'", string_view(mydata, dir.tdir_count));
264265
break;
265266
case TIFF_RATIONAL: {
@@ -522,7 +523,18 @@ static const TagInfo exif_tag_table[] = {
522523
{ EXIF_LENSMAKE, "Exif:LensMake", TIFF_ASCII, 0 },
523524
{ EXIF_LENSMODEL, "Exif:LensModel", TIFF_ASCII, 0 },
524525
{ EXIF_LENSSERIALNUMBER, "Exif:LensSerialNumber", TIFF_ASCII, 0 },
525-
{ EXIF_GAMMA, "Exif:Gamma", TIFF_RATIONAL, 0 }
526+
{ EXIF_GAMMA, "Exif:Gamma", TIFF_RATIONAL, 0 },
527+
// Exif 3.0 additions follow
528+
{ EXIF_IMAGETITLE, "Exif:ImageTitle", TIFF_ASCII, 0 },
529+
{ EXIF_PHOTOGRAPHER, "Exif:Photographer", TIFF_ASCII, 0 },
530+
{ EXIF_IMAGEEDTOR, "Exif:ImageEdtor", TIFF_ASCII, 0 },
531+
{ EXIF_CAMERAFIRMWARE, "Exif:CameraFirmware", TIFF_ASCII, 0 },
532+
{ EXIF_RAWDEVELOPINGSOFTWARE, "Exif:RAWDevelopingSoftware", TIFF_ASCII, 0 },
533+
{ EXIF_IMAGEEDITINGSOFTWARE, "Exif:ImageEditingSoftware", TIFF_ASCII, 0 },
534+
{ EXIF_METADATAEDITINGSOFTWARE, "Exif:MetadataEditingSoftware", TIFF_ASCII, 0 },
535+
{ EXIF_COMPOSITEIMAGE, "Exif:CompositeImage", TIFF_SHORT, 1 },
536+
{ EXIF_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, "Exif:SourceImageNumberOfCompositeImage", TIFF_SHORT, 2 },
537+
{ EXIF_SOURCEIMAGEEXPOSURETIMESOFCOMPOSITEIMAGE, "Exif:SourceImageExposureTimesOfCompositeImage", TIFF_NOTYPE, 0 },
526538
// clang-format on
527539
};
528540

@@ -742,7 +754,7 @@ add_exif_item_to_spec(ImageSpec& spec, const char* name,
742754
spec.attribute(name, TypeDesc(TypeDesc::FLOAT, int(count)), f);
743755
return;
744756
}
745-
if (dirp->tdir_type == TIFF_ASCII) {
757+
if (dirp->tdir_type == TIFF_ASCII || dirp->tdir_type == EXIF_UTF8_TYPE) {
746758
size_t len = tiff_data_size(*dirp);
747759
cspan<uint8_t> dspan = pvt::dataspan<char>(*dirp, buf,
748760
offset_adjustment, len);
@@ -1393,6 +1405,8 @@ encode_exif(const ImageSpec& spec, std::vector<char>& blob,
13931405
// Add some required Exif tags that wouldn't be in the spec
13941406
append_tiff_dir_entry(exifdirs, blob, EXIF_EXIFVERSION, TIFF_UNDEFINED,
13951407
4, as_bytes("0230", 4), tiffstart, 0, endianreq);
1408+
// NOTE: We are still saying we write Exif 2.3 even though we support
1409+
// the additional 3.0 tags.
13961410
append_tiff_dir_entry(exifdirs, blob, EXIF_FLASHPIXVERSION,
13971411
TIFF_UNDEFINED, 4, as_bytes("0100", 4), tiffstart,
13981412
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
@@ -82,6 +82,7 @@ Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic
8282
Exif:ApertureValue: 2.52607 (f/2.4)
8383
Exif:BrightnessValue: 2.7506
8484
Exif:ColorSpace: 65535
85+
Exif:CompositeImage: 2
8586
Exif:DateTimeDigitized: "2023:09:28 09:44:03"
8687
Exif:DateTimeOriginal: "2023:09:28 09:44:03"
8788
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
@@ -82,6 +82,7 @@ Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic
8282
Exif:ApertureValue: 2.52607 (f/2.4)
8383
Exif:BrightnessValue: 2.7506
8484
Exif:ColorSpace: 65535
85+
Exif:CompositeImage: 2
8586
Exif:DateTimeDigitized: "2023:09:28 09:44:03"
8687
Exif:DateTimeOriginal: "2023:09:28 09:44:03"
8788
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
@@ -82,6 +82,7 @@ Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic
8282
Exif:ApertureValue: 2.52607 (f/2.4)
8383
Exif:BrightnessValue: 2.7506
8484
Exif:ColorSpace: 65535
85+
Exif:CompositeImage: 2
8586
Exif:DateTimeDigitized: "2023:09:28 09:44:03"
8687
Exif:DateTimeOriginal: "2023:09:28 09:44:03"
8788
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
@@ -82,6 +82,7 @@ Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic
8282
Exif:ApertureValue: 2.52607 (f/2.4)
8383
Exif:BrightnessValue: 2.7506
8484
Exif:ColorSpace: 65535
85+
Exif:CompositeImage: 2
8586
Exif:DateTimeDigitized: "2023:09:28 09:44:03"
8687
Exif:DateTimeOriginal: "2023:09:28 09:44:03"
8788
Exif:DigitalZoomRatio: 1.3057

0 commit comments

Comments
 (0)