From eb78a2feae41f2c4cd91015a2f651d61d05a16f3 Mon Sep 17 00:00:00 2001 From: postscript-dev Date: Thu, 14 Oct 2021 18:03:26 +0100 Subject: [PATCH 1/9] Add NikonFl7 makernotes group source code This differs from other `NikonFl` groups as it uses `bigEndian` format. This is because `Exif.NikonFl7.ExternalFlashFirmware` is a short and was incorrectly output when using `invalidByteOrder` or `littleEndian`. The other groups use `invalidByteOrder` which may be wrong. Sadly all of Exiv2s --- test/data/exiv2-test.out | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/test/data/exiv2-test.out b/test/data/exiv2-test.out index 87513594..f7d02dfa 100644 --- a/test/data/exiv2-test.out +++ b/test/data/exiv2-test.out @@ -971,9 +971,9 @@ File 4/16: 20040329_224245.jpg 20040329_224245.jpg Exif.NikonFl1.ExternalFlashFirmware Short 1 n/a 20040329_224245.jpg Exif.NikonFl1.ExternalFlashFlags Byte 1 Fired 20040329_224245.jpg Exif.NikonFl1.0x0009 Byte 2 0 0 -20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 (0) -20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 (0) -20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 (0) +20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 n/a +20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 n/a +20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 n/a 20040329_224245.jpg Exif.NikonFl1.FlashGNDistance Byte 1 None 20040329_224245.jpg Exif.NikonFl1.FlashGroupAControlMode Byte 1 Off 20040329_224245.jpg Exif.NikonFl1.FlashGroupBControlMode Byte 1 Off @@ -2612,9 +2612,9 @@ Compare image data and extracted data ------------------------------------ < 20040329_224245.jpg Exif.NikonFl1.ExternalFlashFirmware Short 1 n/a < 20040329_224245.jpg Exif.NikonFl1.ExternalFlashFlags Byte 1 Fired < 20040329_224245.jpg Exif.NikonFl1.0x0009 Byte 2 0 0 -< 20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 (0) -< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 (0) -< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 (0) +< 20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 n/a +< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 n/a +< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 n/a < 20040329_224245.jpg Exif.NikonFl1.FlashGNDistance Byte 1 None < 20040329_224245.jpg Exif.NikonFl1.FlashGroupAControlMode Byte 1 Off < 20040329_224245.jpg Exif.NikonFl1.FlashGroupBControlMode Byte 1 Off @@ -4175,9 +4175,9 @@ Compare image data and extracted data ------------------------------------ > 20040329_224245.exv Exif.NikonFl1.ExternalFlashFirmware Short 1 n/a > 20040329_224245.exv Exif.NikonFl1.ExternalFlashFlags Byte 1 Fired > 20040329_224245.exv Exif.NikonFl1.0x0009 Byte 2 0 0 -> 20040329_224245.exv Exif.NikonFl1.FlashFocalLength Byte 1 (0) -> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashRate Byte 1 (0) -> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashCount Byte 1 (0) +> 20040329_224245.exv Exif.NikonFl1.FlashFocalLength Byte 1 n/a +> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashRate Byte 1 n/a +> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashCount Byte 1 n/a > 20040329_224245.exv Exif.NikonFl1.FlashGNDistance Byte 1 None > 20040329_224245.exv Exif.NikonFl1.FlashGroupAControlMode Byte 1 Off > 20040329_224245.exv Exif.NikonFl1.FlashGroupBControlMode Byte 1 Off @@ -5976,9 +5976,9 @@ Compare original and inserted image data --------------------------------- < 20040329_224245.jpg Exif.NikonFl1.ExternalFlashFirmware Short 1 n/a < 20040329_224245.jpg Exif.NikonFl1.ExternalFlashFlags Byte 1 Fired < 20040329_224245.jpg Exif.NikonFl1.0x0009 Byte 2 0 0 -< 20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 (0) -< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 (0) -< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 (0) +< 20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 n/a +< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 n/a +< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 n/a < 20040329_224245.jpg Exif.NikonFl1.FlashGNDistance Byte 1 None < 20040329_224245.jpg Exif.NikonFl1.FlashGroupAControlMode Byte 1 Off < 20040329_224245.jpg Exif.NikonFl1.FlashGroupBControlMode Byte 1 Off @@ -7539,9 +7539,9 @@ Compare original and inserted image data --------------------------------- > 20040329_224245.exv Exif.NikonFl1.ExternalFlashFirmware Short 1 n/a > 20040329_224245.exv Exif.NikonFl1.ExternalFlashFlags Byte 1 Fired > 20040329_224245.exv Exif.NikonFl1.0x0009 Byte 2 0 0 -> 20040329_224245.exv Exif.NikonFl1.FlashFocalLength Byte 1 (0) -> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashRate Byte 1 (0) -> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashCount Byte 1 (0) +> 20040329_224245.exv Exif.NikonFl1.FlashFocalLength Byte 1 n/a +> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashRate Byte 1 n/a +> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashCount Byte 1 n/a > 20040329_224245.exv Exif.NikonFl1.FlashGNDistance Byte 1 None > 20040329_224245.exv Exif.NikonFl1.FlashGroupAControlMode Byte 1 Off > 20040329_224245.exv Exif.NikonFl1.FlashGroupBControlMode Byte 1 Off From eb134d1946f6f713d70ab2473f98ce478e38a0a9 Mon Sep 17 00:00:00 2001 From: postscript-dev Date: Thu, 14 Oct 2021 18:09:21 +0100 Subject: [PATCH 2/9] Add testing for NikonFl7 makernotes group --- src/makernote_int.cpp | 2 + src/nikonmn_int.cpp | 284 ++++++++++++++++++++++- src/nikonmn_int.hpp | 18 ++ src/tags_int.cpp | 1 + src/tags_int.hpp | 17 +- src/tiffimage_int.cpp | 37 ++- test/data/exiv2-issue1941-1.exv | Bin 0 -> 11372 bytes tests/bugfixes/github/test_issue_1941.py | 58 +++++ 8 files changed, 405 insertions(+), 12 deletions(-) create mode 100644 test/data/exiv2-issue1941-1.exv create mode 100644 tests/bugfixes/github/test_issue_1941.py diff --git a/src/makernote_int.cpp b/src/makernote_int.cpp index 6d66cccc..939d0d4b 100644 --- a/src/makernote_int.cpp +++ b/src/makernote_int.cpp @@ -1139,6 +1139,8 @@ namespace Exiv2 { { 0x00a8, "0101", 0, 0, NA }, { 0x00a8, "0102", 0, 1, NA }, { 0x00a8, "0103", 0, 2, NA }, + { 0x00a8, "0107", 0, 3, NA }, + { 0x00a8, "0108", 0, 3, NA }, }; int nikonSelector(uint16_t tag, const byte* pData, uint32_t size, TiffComponent* const /*pRoot*/) diff --git a/src/nikonmn_int.cpp b/src/nikonmn_int.cpp index fd913bed..e0eab1c6 100644 --- a/src/nikonmn_int.cpp +++ b/src/nikonmn_int.cpp @@ -1050,7 +1050,6 @@ namespace Exiv2 { { 5, N_("GN (distance priority)") }, { 6, N_("Manual") }, { 7, N_("Repeating Flash") }, - { 7, N_("Repeating Flash") } // To silence compiler warning }; //! ExternalFlashFlags @@ -1135,6 +1134,32 @@ namespace Exiv2 { return tagInfoFl3_; } + // Nikon3 Flash Info 7 (0107 and 0108) Tag Info + constexpr TagInfo Nikon3MakerNote::tagInfoFl7_[] = { + { 0, "Version", N_("Version"), N_("Flash info version"), nikonFl7Id, makerTags, undefined, 4, printExifVersion}, + { 4, "FlashSource", N_("Flash source"), N_("The type of flash used (if any)"), nikonFl7Id, makerTags, unsignedByte, 1, EXV_PRINT_TAG(nikonFlashSource)}, + { 6, "ExternalFlashFirmware", N_("External Flash Firmware"), N_("External flash firmware version"), nikonFl7Id, makerTags, unsignedShort, 1, EXV_PRINT_TAG(nikonFlashFirmware)}, + { 8, "ExternalFlashData1", N_("External flash data"), N_("External flash data"), nikonFl7Id, makerTags, unsignedByte, 1, printExternalFlashData1}, + { 9, "ExternalFlashData2", N_("External flash ready state"), N_("External flash ready state"), nikonFl7Id, makerTags, unsignedByte, 1, printExternalFlashData2}, + { 10, "FlashCompensation", N_("Flash compensation"), N_("Flash compensation"), nikonFl7Id, makerTags, signedByte, 1, printFlashCompensation}, + { 12, "FlashFocalLength", N_("Flash focal length"), N_("Flash focal length"), nikonFl7Id, makerTags, unsignedByte, 1, printFlashFocalLength}, + { 13, "RepeatingFlashRate", N_("Repeating flash rate"), N_("Repeating flash rate"), nikonFl7Id, makerTags, unsignedByte, 1, printRepeatingFlashRate}, + { 14, "RepeatingFlashCount", N_("Repeating flash count"), N_("Repeating flash count"), nikonFl7Id, makerTags, unsignedByte, 1, printRepeatingFlashCount}, + { 15, "FlashGNDistance", N_("Flash GN Distance"), N_("Flash GN distance"), nikonFl7Id, makerTags, unsignedByte, 1, EXV_PRINT_TAG(nikonFlashGNDistance)}, + { 17, "FlashGroupAControlData", N_("Flash group A control data"), N_("Flash group A control data"), nikonFl7Id, makerTags, unsignedByte, 1, EXV_PRINT_TAG(nikonFlashControlMode)}, + { 18, "FlashGroupBCControlData", N_("Flash group B/C control data"), N_("Flash group B/C control data"), nikonFl7Id, makerTags, unsignedByte, 1, printFlashGroupBCControlData}, + { 40, "FlashGroupAData", N_("Flash group A data"), N_("Depending upon FlashGroupAControlData, either the FlashGroupACompensation value or the FlashGroupAOutput value"), nikonFl7Id, makerTags, unsignedByte, 1, printFlashGroupAData}, + { 41, "FlashGroupBData", N_("Flash group B data"), N_("Depending upon FlashGroupBCControlData, either the FlashGroupBCompensation value or the FlashGroupBOutput value"), nikonFl7Id, makerTags, unsignedByte, 1, printFlashGroupBData}, + { 42, "FlashGroupCData", N_("Flash group C data"), N_("Depending upon FlashGroupBCControlData, either the FlashGroupCCompensation value or the FlashGroupCOutput value"), nikonFl7Id, makerTags, unsignedByte, 1, printFlashGroupCData}, + // End of list marker + {0xffff, "(UnknownNikonFl7Tag)", "(UnknownNikonFl7Tag)", N_("Unknown Nikon Flash Info 7 Tag"), nikonFl7Id, makerTags, unsignedByte, 1, printValue}, + }; + + const TagInfo* Nikon3MakerNote::tagListFl7() + { + return tagInfoFl7_; + } + // Nikon3 Shot Info D80 Tag Info constexpr TagInfo Nikon3MakerNote::tagInfoSi1_[] = { { 0, "Version", N_("Version"), N_("Version"), nikonSi1Id, makerTags, unsignedByte, 4, printExifVersion}, @@ -2772,14 +2797,18 @@ fmountlens[] = { const ExifData*) { std::ios::fmtflags f( os.flags() ); - if (value.count() != 1 || value.typeId() != unsignedByte || value.toLong() == 0 || value.toLong() == 255) { + if (value.count() != 1 || value.typeId() != unsignedByte) { os << "(" << value << ")"; os.flags(f); return os; } + auto temp = value.toLong(); + if (temp == 0 || temp == 255) + return os << _("n/a"); + std::ostringstream oss; oss.copyfmt(os); - os << std::fixed << std::setprecision(1) << value.toLong() << " mm"; + os << std::fixed << std::setprecision(1) << temp << " mm"; os.copyfmt(oss); os.flags(f); return os; @@ -2790,12 +2819,16 @@ fmountlens[] = { const ExifData*) { std::ios::fmtflags f( os.flags() ); - if (value.count() != 1 || value.typeId() != unsignedByte || value.toLong() == 0 || value.toLong() == 255) { + if (value.count() != 1 || value.typeId() != unsignedByte) { return os << "(" << value << ")"; } + auto temp = value.toLong(); + if (temp == 0 || temp == 255) + return os << _("n/a"); + std::ostringstream oss; oss.copyfmt(os); - os << std::fixed << std::setprecision(2) << value.toLong() << " Hz"; + os << std::fixed << std::setprecision(2) << temp << " Hz"; os.copyfmt(oss); os.flags(f); return os; @@ -2806,12 +2839,249 @@ fmountlens[] = { const ExifData*) { std::ios::fmtflags f( os.flags() ); - if (value.count() != 1 || value.typeId() != unsignedByte || value.toLong() == 0 || value.toLong() == 255) { + if (value.count() != 1 || value.typeId() != unsignedByte) { return os << "(" << value << ")"; } + auto temp = value.toLong(); + if (temp == 0 || temp == 255) + return os << _("n/a"); + std::ostringstream oss; oss.copyfmt(os); - os << std::fixed << std::setprecision(2) << value.toLong(); + os << std::fixed << std::setprecision(2) << temp; + os.copyfmt(oss); + os.flags(f); + return os; + } + + std::ostream& Nikon3MakerNote::printExternalFlashData1(std::ostream& os, + const Value& value, + const ExifData*) + { + std::ios::fmtflags f( os.flags() ); + if (value.count() != 1 || value.typeId() != unsignedByte) { + os << "(" << value << ")"; + os.flags(f); + return os; + } + std::ostringstream oss; + oss.copyfmt(os); + os << (value.toLong() & 0x80 ? _("External flash zoom override") : _("No external flash zoom override")); + os << ", "; + os << (value.toLong() & 0x01 ? _("external flash attached") : _("external flash not attached")); + + os.copyfmt(oss); + os.flags(f); + return os; + } + + std::ostream& Nikon3MakerNote::printExternalFlashData2(std::ostream& os, + const Value& value, + const ExifData*) + { + std::ios::fmtflags f( os.flags() ); + if (value.count() != 1 || value.typeId() != unsignedByte) { + os << "(" << value << ")"; + os.flags(f); + return os; + } + + std::ostringstream oss; + oss.copyfmt(os); + long temp = value.toLong(); + + switch (temp & 0x07) { + case 0: + os << _("n/a"); + break; + case 1: + os << _("Ready"); + break; + case 6: + os << _("Not ready"); + break; + default: + os << "(" << temp << ")"; + break; + } + + os.copyfmt(oss); + os.flags(f); + return os; + } + + std::ostream& Nikon3MakerNote::printFlashCompensation(std::ostream& os, + const Value& value, + const ExifData*) + { + std::ios::fmtflags f( os.flags() ); + if (value.count() != 1 || value.typeId() != signedByte) { + os << "(" << value << ")"; + os.flags(f); + return os; + } + std::ostringstream oss; + oss.copyfmt(os); + float temp = ( value.toFloat()/float(-6.0) ); + temp *= 1.00001; // Avoid round-off errors + + if (temp == 0) + os << 0; + else if ( (int(temp)/temp) > 0.999 ) + os << int(temp); + else if ( (int(temp*2)/(temp*2)) > 0.999 ) + os << int(temp)*2 << "/2"; + else if ( (int(temp*3)/(temp*3)) > 0.999 ) + os << int(temp)*3 << "/3"; + else + os << std::setprecision(3) << temp; + + os.copyfmt(oss); + os.flags(f); + return os; + } + + std::ostream& Nikon3MakerNote::printFlashGroupBCControlData(std::ostream& os, + const Value& value, + const ExifData* data) + { + std::ios::fmtflags f( os.flags() ); + if (value.count() != 1 || value.typeId() != unsignedByte) { + os << "(" << value << ")"; + os.flags(f); + return os; + } + std::ostringstream oss; + oss.copyfmt(os); + long temp = value.toLong(); + + printTag(os, (temp & 0xf0), data); + os << ", "; + printTag(os, (temp & 0x0f), data); + + os.copyfmt(oss); + os.flags(f); + return os; + } + + std::ostream& Nikon3MakerNote::printFlashGroupAData(std::ostream& os, + const Value& value, + const ExifData* metadata) + { + std::ios::fmtflags f( os.flags() ); + if (value.count() != 1 || value.typeId() != unsignedByte) { + os << "(" << value << ")"; + os.flags(f); + return os; + } + + std::ostringstream oss; + oss.copyfmt(os); + double temp = value.toFloat()/double(-6.0); + + auto pos = metadata->findKey(ExifKey("Exif.NikonFl7.FlashGroupAControlData")); + if (pos == metadata->end() || pos-> count() != 1 || pos->typeId() != unsignedByte) { + os << "(" << value << ")"; + } + else { + if (pos->toLong() < 0x06) { + // FlashGroupACompensation value + if (temp == 0) + os << 0; + else + os << std::fixed << std::setprecision(1) << temp; + } + else { + // FlashGroupAOutput value + double flashGroupAOutput = std::exp2(temp); + if (flashGroupAOutput > 0.99) + os << _("Full"); + else + os << std::setprecision(2) << std::round(flashGroupAOutput*100) << "%"; + } + } + os.copyfmt(oss); + os.flags(f); + return os; + } + + std::ostream& Nikon3MakerNote::printFlashGroupBData(std::ostream& os, + const Value& value, + const ExifData* metadata) + { + std::ios::fmtflags f( os.flags() ); + if (value.count() != 1 || value.typeId() != unsignedByte) { + os << "(" << value << ")"; + os.flags(f); + return os; + } + + std::ostringstream oss; + oss.copyfmt(os); + double temp = value.toFloat()/double(-6.0); + + auto pos = metadata->findKey(ExifKey("Exif.NikonFl7.FlashGroupBCControlData")); + if (pos == metadata->end() || pos-> count() != 1 || pos->typeId() != unsignedByte) { + os << "(" << value << ")"; + } + else { + if (pos->toLong() < 0x06) { + // FlashGroupBCompensation value + if (temp == 0) + os << 0; + else + os << std::fixed << std::setprecision(1) << temp; + } + else { + // FlashGroupBOutput value + double flashGroupAOutput = std::exp2(temp); + if (flashGroupAOutput > 0.99) + os << _("Full"); + else + os << std::setprecision(2) << std::round(flashGroupAOutput*100) << "%"; + } + } + os.copyfmt(oss); + os.flags(f); + return os; + } + + std::ostream& Nikon3MakerNote::printFlashGroupCData(std::ostream& os, + const Value& value, + const ExifData* metadata) + { + std::ios::fmtflags f( os.flags() ); + if (value.count() != 1 || value.typeId() != unsignedByte) { + os << "(" << value << ")"; + os.flags(f); + return os; + } + + std::ostringstream oss; + oss.copyfmt(os); + double temp = value.toFloat()/double(-6.0); + + auto pos = metadata->findKey(ExifKey("Exif.NikonFl7.FlashGroupBCControlData")); + if (pos == metadata->end() || pos-> count() != 1 || pos->typeId() != unsignedByte) { + os << "(" << value << ")"; + } + else { + if (pos->toLong() < 0x06) { + // FlashGroupCCompensation value + if (temp == 0) + os << 0; + else + os << std::fixed << std::setprecision(1) << temp; + } + else { + // FlashGroupCOutput value + double flashGroupAOutput = std::exp2(temp); + if (flashGroupAOutput > 0.99) + os << _("Full"); + else + os << std::setprecision(2) << std::round(flashGroupAOutput*100) << "%"; + } + } os.copyfmt(oss); os.flags(f); return os; diff --git a/src/nikonmn_int.hpp b/src/nikonmn_int.hpp index 070d2cdb..37fba84c 100644 --- a/src/nikonmn_int.hpp +++ b/src/nikonmn_int.hpp @@ -130,6 +130,8 @@ namespace Exiv2 { static const TagInfo* tagListFl2(); //! Return read-only list of built-in Flash Info 3 tags static const TagInfo* tagListFl3(); + //! Return read-only list of built-in Flash Info 7 (0107 and 0108) tags + static const TagInfo* tagListFl7(); //! Return read-only list of built-in Shot Info D80 tags static const TagInfo* tagListSi1(); //! Return read-only list of built-in Shot Info D40 tags @@ -217,6 +219,20 @@ namespace Exiv2 { static std::ostream& printRepeatingFlashRate(std::ostream& os, const Value& value, const ExifData*); //! Print repeating flash count static std::ostream& printRepeatingFlashCount(std::ostream& os, const Value& value, const ExifData*); + //! Print external flash data 1 value + static std::ostream& printExternalFlashData1(std::ostream& os, const Value& value, const ExifData*); + //! Print external flash data 2 value + static std::ostream& printExternalFlashData2(std::ostream& os, const Value& value, const ExifData*); + //! Print flash compensation value + static std::ostream& printFlashCompensation(std::ostream& os, const Value& value, const ExifData*); + //! Print flash group B/C control data value + static std::ostream& printFlashGroupBCControlData(std::ostream& os, const Value& value, const ExifData* data); + //! Print flash group A data value + static std::ostream& printFlashGroupAData(std::ostream& os, const Value& value, const ExifData*); + //! Print flash group B data value + static std::ostream& printFlashGroupBData(std::ostream& os, const Value& value, const ExifData*); + //! Print flash group C data value + static std::ostream& printFlashGroupCData(std::ostream& os, const Value& value, const ExifData*); //! Print time zone static std::ostream& printTimeZone(std::ostream& os, const Value& value, const ExifData*); //! Print picture control value @@ -252,6 +268,8 @@ namespace Exiv2 { static const TagInfo tagInfoFl2_[]; //! Flash Info 3 tag information static const TagInfo tagInfoFl3_[]; + //! Flash Info 7 (0107 and 0108) tag information + static const TagInfo tagInfoFl7_[]; //! Shot Info D80 tag information static const TagInfo tagInfoSi1_[]; //! Shot Info D40 tag information diff --git a/src/tags_int.cpp b/src/tags_int.cpp index 6466ca19..7bf2fc13 100644 --- a/src/tags_int.cpp +++ b/src/tags_int.cpp @@ -115,6 +115,7 @@ namespace Exiv2 { { nikonFl1Id, "Makernote", "NikonFl1", Nikon3MakerNote::tagListFl1 }, { nikonFl2Id, "Makernote", "NikonFl2", Nikon3MakerNote::tagListFl2 }, { nikonFl3Id, "Makernote", "NikonFl3", Nikon3MakerNote::tagListFl3 }, + { nikonFl7Id, "Makernote", "NikonFl7", Nikon3MakerNote::tagListFl7 }, { nikonSi1Id, "Makernote", "NikonSiD80", Nikon3MakerNote::tagListSi1 }, { nikonSi2Id, "Makernote", "NikonSiD40", Nikon3MakerNote::tagListSi2 }, { nikonSi3Id, "Makernote", "NikonSiD300a", Nikon3MakerNote::tagListSi3 }, diff --git a/src/tags_int.hpp b/src/tags_int.hpp index da48f744..649c4c1c 100644 --- a/src/tags_int.hpp +++ b/src/tags_int.hpp @@ -125,6 +125,7 @@ namespace Exiv2 { nikonFl1Id, nikonFl2Id, nikonFl3Id, + nikonFl7Id, nikonSi1Id, nikonSi2Id, nikonSi3Id, @@ -266,9 +267,9 @@ namespace Exiv2 { by looking up a reference table. */ template - std::ostream& printTag(std::ostream& os, const Value& value, const ExifData*) + std::ostream& printTag(std::ostream& os, const long& value, const ExifData*) { - const TagDetails* td = find(array, value.toLong()); + const TagDetails* td = find(array, value); if (td) { os << exvGettext(td->label_); } @@ -278,7 +279,17 @@ namespace Exiv2 { return os; } -//! Shortcut for the printTag template which requires typing the array name only once. + /*! + @brief Generic pretty-print function to translate the first long value in Value, to a description + by looking up a reference table. + */ + template + std::ostream& printTag(std::ostream& os, const Value& value, const ExifData* data) + { + return printTag(os, value.toLong(), data); + } + + //! Shortcut for the printTag template which requires typing the array name only once. #define EXV_PRINT_TAG(array) printTag /*! diff --git a/src/tiffimage_int.cpp b/src/tiffimage_int.cpp index da740bc2..90100377 100644 --- a/src/tiffimage_int.cpp +++ b/src/tiffimage_int.cpp @@ -427,11 +427,42 @@ namespace Exiv2 { { 15, ttUnsignedByte, 1 }, // FlashGNDistance { 16, ttUnsignedByte, 1 }, // FlashColorFilter }; - //! Nikon Lens Data configurations and definitions + //! Nikon Flash Info 7 (0107 and 0108) binary array - configuration + constexpr ArrayCfg nikonFl7Cfg = { + nikonFl7Id, // Group for the elements + bigEndian, // Use byte order from parent + ttUndefined, // Type for array entry + notEncrypted, // Not encrypted + false, // No size element + true, // Write all tags + true, // Concatenate gaps + { 0, ttUnsignedByte, 1 } + }; + //! Nikon Flash Info 7 (0107 and 0108) binary array - definition + constexpr ArrayDef nikonFl7Def[] = { + { 0, ttUndefined, 4 }, // Version + { 4, ttUnsignedByte, 1 }, // FlashSource + { 6, ttUnsignedShort, 1 }, // ExternalFlashFirmware + { 8, ttUnsignedByte, 1 }, // ExternalFlashData1 + { 9, ttUnsignedByte, 1 }, // ExternalFlashData2 + { 10, ttSignedByte, 1 }, // FlashCompensation + { 12, ttUnsignedByte, 1 }, // FlashFocalLength + { 13, ttUnsignedByte, 1 }, // RepeatingFlashRate + { 14, ttUnsignedByte, 1 }, // RepeatingFlashCount + { 15, ttUnsignedByte, 1 }, // FlashGNDistance + { 17, ttUnsignedByte, 1 }, // FlashGroupAControlData + { 18, ttUnsignedByte, 1 }, // FlashGroupBCControlData + { 40, ttUnsignedByte, 1 }, // FlashGroupAData + { 41, ttUnsignedByte, 1 }, // FlashGroupBData + { 42, ttUnsignedByte, 1 } // FlashGroupCData + }; + + //! Nikon Flash Info Data configurations and definitions constexpr ArraySet nikonFlSet[] = { { nikonFl1Cfg, nikonFl1Def, EXV_COUNTOF(nikonFl1Def) }, { nikonFl2Cfg, nikonFl2Def, EXV_COUNTOF(nikonFl2Def) }, - { nikonFl3Cfg, nikonFl3Def, EXV_COUNTOF(nikonFl3Def) } + { nikonFl3Cfg, nikonFl3Def, EXV_COUNTOF(nikonFl3Def) }, + { nikonFl7Cfg, nikonFl7Def, EXV_COUNTOF(nikonFl7Def) } }; //! Nikon Shot Info binary array - configuration 1 (D80) @@ -1177,6 +1208,7 @@ namespace Exiv2 { { Tag::root, nikonFl1Id, nikon3Id, 0x00a8 }, { Tag::root, nikonFl2Id, nikon3Id, 0x00a8 }, { Tag::root, nikonFl3Id, nikon3Id, 0x00a8 }, + { Tag::root, nikonFl7Id, nikon3Id, 0x00a8 }, { Tag::root, panasonicId, exifId, 0x927c }, { Tag::root, pentaxId, exifId, 0x927c }, { Tag::root, pentaxDngId, ifd0Id, 0xc634 }, @@ -1577,6 +1609,7 @@ namespace Exiv2 { { Tag::all, nikonFl1Id, newTiffBinaryElement }, { Tag::all, nikonFl2Id, newTiffBinaryElement }, { Tag::all, nikonFl3Id, newTiffBinaryElement }, + { Tag::all, nikonFl7Id, newTiffBinaryElement }, // Nikon3 shot info { Tag::all, nikonSi1Id, newTiffBinaryElement }, diff --git a/test/data/exiv2-issue1941-1.exv b/test/data/exiv2-issue1941-1.exv new file mode 100644 index 0000000000000000000000000000000000000000..2416315fa599cad51bf0d6da61a350d7f6348017 GIT binary patch literal 11372 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 literal 0 HcmV?d00001 diff --git a/tests/bugfixes/github/test_issue_1941.py b/tests/bugfixes/github/test_issue_1941.py new file mode 100644 index 00000000..d951bdf0 --- /dev/null +++ b/tests/bugfixes/github/test_issue_1941.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- + +import system_tests +from system_tests import CaseMeta, CopyTmpFiles, path + +class TestNikonFl7GroupWithFlash(metaclass=CaseMeta): + + url = "https://github.com/Exiv2/exiv2/issues/1941" + + filename = system_tests.path("$data_path/exiv2-issue1941-1.exv") + commands = ["""$exiv2 --grep NikonFl7 $filename"""] + + stderr = [""] + retval = [0] + + stdout = ["""Exif.NikonFl7.Version Undefined 4 1.08 +Exif.NikonFl7.FlashSource Byte 1 External +Exif.NikonFl7.ExternalFlashFirmware Short 1 5.01 (SB-900) +Exif.NikonFl7.ExternalFlashData1 Byte 1 No external flash zoom override, external flash attached +Exif.NikonFl7.ExternalFlashData2 Byte 1 n/a +Exif.NikonFl7.FlashCompensation SByte 1 0 +Exif.NikonFl7.FlashFocalLength Byte 1 n/a +Exif.NikonFl7.RepeatingFlashRate Byte 1 n/a +Exif.NikonFl7.RepeatingFlashCount Byte 1 n/a +Exif.NikonFl7.FlashGNDistance Byte 1 None +Exif.NikonFl7.FlashGroupAControlData Byte 1 Manual +Exif.NikonFl7.FlashGroupBCControlData Byte 1 Off, Off +Exif.NikonFl7.FlashGroupAData Byte 1 4% +Exif.NikonFl7.FlashGroupBData Byte 1 0 +Exif.NikonFl7.FlashGroupCData Byte 1 0 +"""] + +class TestNikonFl7GroupWithoutFlash(metaclass=CaseMeta): + + url = "https://github.com/Exiv2/exiv2/issues/1941" + + filename = system_tests.path("$data_path/exiv2-bug1014_2.exv") + commands = ["""$exiv2 --grep NikonFl7 $filename"""] + + stderr = [""] + retval = [0] + + stdout = ["""Exif.NikonFl7.Version Undefined 4 1.07 +Exif.NikonFl7.FlashSource Byte 1 None +Exif.NikonFl7.ExternalFlashFirmware Short 1 n/a +Exif.NikonFl7.ExternalFlashData1 Byte 1 No external flash zoom override, external flash not attached +Exif.NikonFl7.ExternalFlashData2 Byte 1 n/a +Exif.NikonFl7.FlashCompensation SByte 1 0 +Exif.NikonFl7.FlashFocalLength Byte 1 n/a +Exif.NikonFl7.RepeatingFlashRate Byte 1 n/a +Exif.NikonFl7.RepeatingFlashCount Byte 1 n/a +Exif.NikonFl7.FlashGNDistance Byte 1 None +Exif.NikonFl7.FlashGroupAControlData Byte 1 Off +Exif.NikonFl7.FlashGroupBCControlData Byte 1 Off, Off +Exif.NikonFl7.FlashGroupAData Byte 1 0 +Exif.NikonFl7.FlashGroupBData Byte 1 0 +Exif.NikonFl7.FlashGroupCData Byte 1 0 +"""] From 8cd7dba847085aa9134ab248e455ea4235f1f035 Mon Sep 17 00:00:00 2001 From: postscript-dev Date: Thu, 14 Oct 2021 18:12:15 +0100 Subject: [PATCH 3/9] Add documentation for NikonFl7 makernotes group --- doc/templates/Makefile | 1 + doc/templates/tags-nikon.html.in | 5 +++++ exiv2.md | 26 +++++++++++++------------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/doc/templates/Makefile b/doc/templates/Makefile index 04dea6a2..4b2b2422 100644 --- a/doc/templates/Makefile +++ b/doc/templates/Makefile @@ -76,6 +76,7 @@ TABLES = Exif \ NikonFl1 \ NikonFl2 \ NikonFl3 \ + NikonFl7 \ NikonSiD80 \ NikonSiD40 \ NikonSiD300a \ diff --git a/doc/templates/tags-nikon.html.in b/doc/templates/tags-nikon.html.in index 9110c249..4f2ec5fd 100644 --- a/doc/templates/tags-nikon.html.in +++ b/doc/templates/tags-nikon.html.in @@ -91,6 +91,11 @@ __NikonFl2__ __NikonFl3__
+

Nikon Flash Info 7 Tags (for version 0107 and 0108)

+

Click on a column header to sort the table.

+__NikonFl7__ +
+

Nikon Shot Info D80 Tags

Click on a column header to sort the table.

__NikonSiD80__ diff --git a/exiv2.md b/exiv2.md index e46610d2..7243df44 100644 --- a/exiv2.md +++ b/exiv2.md @@ -793,19 +793,19 @@ Image CanonCf Nikon2 NikonPc OlympusFe9 SonyMisc3c Image2 CanonCs Nikon3 NikonPreview OlympusFi SonyMinolta Image3 CanonFi NikonAFT NikonSi01xx OlympusIp SonySInfo1 Iop CanonPa NikonAf NikonSi02xx OlympusRd -MakerNote CanonPi NikonAf NikonSiD300a OlympusRd2 Samsung2 -MpfInfo CanonPr NikonAf2 NikonSiD300b OlympusRi SamsungPictureWizard -Photo CanonSi NikonAf22 NikonSiD40 SamsungPreview -SubImage1 CanonTi NikonCb1 NikonSiD80 Sigma -SubImage2 NikonCb2 NikonVr -SubImage3 Casio NikonCb2a NikonWt Sony1 -SubImage4 Casio2 NikonCb2b Sony1Cs -SubImage5 NikonCb3 Olympus Sony1Cs2 -SubImage6 Minolta NikonCb4 Olympus2 Sony1MltCs7D -SubImage7 MinoltaCs5D NikonFi OlympusCs Sony1MltCsA100 -SubImage8 MinoltaCs7D NikonFl1 OlympusEq Sony1MltCsNew -SubImage9 MinoltaCsNew NikonFl2 OlympusFe1 Sony1MltCsOld -SubThumb1 MinoltaCsOld NikonFl3 OlympusFe2 Sony2 +MakerNote CanonPi NikonAf2 NikonSiD300a OlympusRd2 Samsung2 +MpfInfo CanonPr NikonAf22 NikonSiD300b OlympusRi SamsungPictureWizard +Photo CanonSi NikonCb1 NikonSiD40 SamsungPreview +SubImage1 CanonTi NikonCb2 NikonSiD80 Sigma +SubImage2 NikonCb2a NikonVr +SubImage3 Casio NikonCb2b NikonWt Sony1 +SubImage4 Casio2 NikonCb3 Sony1Cs +SubImage5 NikonCb4 Olympus Sony1Cs2 +SubImage6 Minolta NikonFi Olympus2 Sony1MltCs7D +SubImage7 MinoltaCs5D NikonFl1 OlympusCs Sony1MltCsA100 +SubImage8 MinoltaCs7D NikonFl2 OlympusEq Sony1MltCsNew +SubImage9 MinoltaCsNew NikonFl3 OlympusFe1 Sony1MltCsOld +SubThumb1 MinoltaCsOld NikonFl7 OlympusFe2 Sony2 Thumbnail NikonIi OlympusFe3 Sony2Cs Panasonic NikonLd1 OlympusFe4 Sony2Cs2 Pentax PanasonicRaw NikonLd2 OlympusFe5 Sony2010e From f0f3c7e8a23448cb2f9b5291e06460cda7ab79d3 Mon Sep 17 00:00:00 2001 From: postscript-dev Date: Fri, 15 Oct 2021 15:12:00 +0100 Subject: [PATCH 4/9] Fix compile issues for NikonFl7 makernotes group + Fix fuzzing CI errors of `exp2` and `round` not being in `std` by adding `#include ` + Fix Windows CI warning C4305 by explicitly defining value as a float --- src/nikonmn_int.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nikonmn_int.cpp b/src/nikonmn_int.cpp index e0eab1c6..f674ef36 100644 --- a/src/nikonmn_int.cpp +++ b/src/nikonmn_int.cpp @@ -38,6 +38,7 @@ #include #include #include //for log, pow, abs +#include // ***************************************************************************** // class member definitions @@ -2923,7 +2924,7 @@ fmountlens[] = { std::ostringstream oss; oss.copyfmt(os); float temp = ( value.toFloat()/float(-6.0) ); - temp *= 1.00001; // Avoid round-off errors + temp *= float(1.00001); // Avoid round-off errors if (temp == 0) os << 0; From f23d9656439b5092034d660b93c75a273ffcaabc Mon Sep 17 00:00:00 2001 From: postscript-dev Date: Sun, 17 Oct 2021 15:49:57 +0100 Subject: [PATCH 5/9] Add limits check: Exif.NikonFl7.FlashCompensation --- src/nikonmn_int.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/nikonmn_int.cpp b/src/nikonmn_int.cpp index f674ef36..2753b190 100644 --- a/src/nikonmn_int.cpp +++ b/src/nikonmn_int.cpp @@ -39,6 +39,7 @@ #include #include //for log, pow, abs #include +#include // ***************************************************************************** // class member definitions @@ -2928,11 +2929,13 @@ fmountlens[] = { if (temp == 0) os << 0; + else if ( std::numeric_limits::min() > temp && temp > std::numeric_limits::max() ) + os << "(" << value << ")"; else if ( (int(temp)/temp) > 0.999 ) os << int(temp); - else if ( (int(temp*2)/(temp*2)) > 0.999 ) + else if ( std::numeric_limits::min() <= (temp*2) && (temp*2) <= std::numeric_limits::max() && ((int(temp*2)/(temp*2)) > 0.999) ) os << int(temp)*2 << "/2"; - else if ( (int(temp*3)/(temp*3)) > 0.999 ) + else if ( std::numeric_limits::min() <= (temp*3) && (temp*3) <= std::numeric_limits::max() && ((int(temp*3)/(temp*3)) > 0.999) ) os << int(temp)*3 << "/3"; else os << std::setprecision(3) << temp; From 8ebf10f921dc8b09c594969ae583232d16f14171 Mon Sep 17 00:00:00 2001 From: postscript-dev Date: Sun, 17 Oct 2021 16:20:27 +0100 Subject: [PATCH 6/9] Fix condition in Exif.NikonFl7.FlashCompensation --- src/nikonmn_int.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nikonmn_int.cpp b/src/nikonmn_int.cpp index 2753b190..c886b474 100644 --- a/src/nikonmn_int.cpp +++ b/src/nikonmn_int.cpp @@ -2929,7 +2929,7 @@ fmountlens[] = { if (temp == 0) os << 0; - else if ( std::numeric_limits::min() > temp && temp > std::numeric_limits::max() ) + else if ( std::numeric_limits::min() > temp || temp > std::numeric_limits::max() ) os << "(" << value << ")"; else if ( (int(temp)/temp) > 0.999 ) os << int(temp); From b3ca98c1e705a163b538e058ff64408fa1d18d83 Mon Sep 17 00:00:00 2001 From: postscript-dev Date: Tue, 2 Nov 2021 15:47:30 +0000 Subject: [PATCH 7/9] Fix Exif.NikonFl7.FlashCompensation pretty print --- src/nikonmn_int.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nikonmn_int.cpp b/src/nikonmn_int.cpp index c886b474..a5989ab8 100644 --- a/src/nikonmn_int.cpp +++ b/src/nikonmn_int.cpp @@ -2929,14 +2929,14 @@ fmountlens[] = { if (temp == 0) os << 0; - else if ( std::numeric_limits::min() > temp || temp > std::numeric_limits::max() ) + else if (!std::isfinite(temp)) os << "(" << value << ")"; - else if ( (int(temp)/temp) > 0.999 ) - os << int(temp); - else if ( std::numeric_limits::min() <= (temp*2) && (temp*2) <= std::numeric_limits::max() && ((int(temp*2)/(temp*2)) > 0.999) ) - os << int(temp)*2 << "/2"; - else if ( std::numeric_limits::min() <= (temp*3) && (temp*3) <= std::numeric_limits::max() && ((int(temp*3)/(temp*3)) > 0.999) ) - os << int(temp)*3 << "/3"; + else if (std::abs(std::fmod(temp, 1)) < 0.001) + os << std::round(temp); + else if (std::abs(std::fmod(temp*2, 1)) < 0.001) + os << std::round(temp*2) << "/2"; + else if (std::abs(std::fmod(temp*3, 1)) < 0.001) + os << std::round(temp*3) << "/3"; else os << std::setprecision(3) << temp; From 277b1875f727f0796b8ee5c571edf09b203703c7 Mon Sep 17 00:00:00 2001 From: postscript-dev Date: Tue, 2 Nov 2021 15:56:17 +0000 Subject: [PATCH 8/9] Fix Exif.NikonFl7.FlashGroupBCControlData output --- src/nikonmn_int.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nikonmn_int.cpp b/src/nikonmn_int.cpp index a5989ab8..cf4f458f 100644 --- a/src/nikonmn_int.cpp +++ b/src/nikonmn_int.cpp @@ -2959,7 +2959,7 @@ fmountlens[] = { oss.copyfmt(os); long temp = value.toLong(); - printTag(os, (temp & 0xf0), data); + printTag(os, (temp >> 4), data); os << ", "; printTag(os, (temp & 0x0f), data); From 562b10f2c7c802797ae424d28578030bf92cdeb0 Mon Sep 17 00:00:00 2001 From: postscript-dev Date: Wed, 3 Nov 2021 17:39:05 +0000 Subject: [PATCH 9/9] Fix Exif.NikonFl7.FlashCompensation --- src/nikonmn_int.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/nikonmn_int.cpp b/src/nikonmn_int.cpp index cf4f458f..631b0139 100644 --- a/src/nikonmn_int.cpp +++ b/src/nikonmn_int.cpp @@ -2925,17 +2925,16 @@ fmountlens[] = { std::ostringstream oss; oss.copyfmt(os); float temp = ( value.toFloat()/float(-6.0) ); - temp *= float(1.00001); // Avoid round-off errors if (temp == 0) os << 0; else if (!std::isfinite(temp)) os << "(" << value << ")"; - else if (std::abs(std::fmod(temp, 1)) < 0.001) + else if (std::abs(std::remainderf(temp, 1)) < 0.001) os << std::round(temp); - else if (std::abs(std::fmod(temp*2, 1)) < 0.001) + else if (std::abs(std::remainderf(temp*2, 1)) < 0.001) os << std::round(temp*2) << "/2"; - else if (std::abs(std::fmod(temp*3, 1)) < 0.001) + else if (std::abs(std::remainderf(temp*3, 1)) < 0.001) os << std::round(temp*3) << "/3"; else os << std::setprecision(3) << temp;