diff --git a/src/convert.cpp b/src/convert.cpp index fa5fa73969..9d9dbfbcef 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -19,6 +19,7 @@ // + standard includes #include +#include #include #if defined WIN32 && !defined __CYGWIN__ @@ -1538,10 +1539,15 @@ struct ConvFctList { ConvFct convFct_; }; -const ConvFctList convFctList[] = { - {"UTF-8", "UCS-2BE", utf8ToUcs2be}, {"UTF-8", "UCS-2LE", utf8ToUcs2le}, {"UCS-2BE", "UTF-8", ucs2beToUtf8}, - {"UCS-2BE", "UCS-2LE", ucs2beToUcs2le}, {"UCS-2LE", "UTF-8", ucs2leToUtf8}, {"UCS-2LE", "UCS-2BE", ucs2leToUcs2be}, - {"ISO-8859-1", "UTF-8", iso88591ToUtf8}, {"ASCII", "UTF-8", asciiToUtf8} +constexpr auto convFctList = std::array{ + ConvFctList{"UTF-8", "UCS-2BE", utf8ToUcs2be}, + ConvFctList{"UTF-8", "UCS-2LE", utf8ToUcs2le}, + ConvFctList{"UCS-2BE", "UTF-8", ucs2beToUtf8}, + ConvFctList{"UCS-2BE", "UCS-2LE", ucs2beToUcs2le}, + ConvFctList{"UCS-2LE", "UTF-8", ucs2leToUtf8}, + ConvFctList{"UCS-2LE", "UCS-2BE", ucs2leToUcs2be}, + ConvFctList{"ISO-8859-1", "UTF-8", iso88591ToUtf8}, + ConvFctList{"ASCII", "UTF-8", asciiToUtf8} // Update the convertStringCharset() documentation if you add more here! }; diff --git a/src/datasets.cpp b/src/datasets.cpp index c1c94f5251..4b6335350c 100644 --- a/src/datasets.cpp +++ b/src/datasets.cpp @@ -11,6 +11,7 @@ #include "i18n.h" // NLS support. #include "types.hpp" +#include #include #include #include @@ -19,11 +20,11 @@ // class member definitions namespace Exiv2 { -constexpr const char* familyName_{"Iptc"}; -constexpr RecordInfo recordInfo_[] = { - {IptcDataSets::invalidRecord, "(invalid)", N_("(invalid)")}, - {IptcDataSets::envelope, "Envelope", N_("IIM envelope record")}, - {IptcDataSets::application2, "Application2", N_("IIM application record 2")}, +constexpr auto familyName_ = "Iptc"; +constexpr auto recordInfo_ = std::array{ + RecordInfo{IptcDataSets::invalidRecord, "(invalid)", N_("(invalid)")}, + RecordInfo{IptcDataSets::envelope, "Envelope", N_("IIM envelope record")}, + RecordInfo{IptcDataSets::application2, "Application2", N_("IIM application record 2")}, }; constexpr DataSet envelopeRecord[] = { diff --git a/src/epsimage.cpp b/src/epsimage.cpp index 9832f0b8c6..b1421a07bf 100644 --- a/src/epsimage.cpp +++ b/src/epsimage.cpp @@ -66,20 +66,17 @@ constexpr std::string_view xmpHeaders[] = { }; // list of all valid XMP trailers -struct XmpTrailer { - std::string_view trailer; - bool readOnly; -}; +using XmpTrailer = std::pair; -constexpr XmpTrailer xmpTrailers[] = { +constexpr auto xmpTrailers = std::array{ // We do not enforce the trailing "?>" here, because the XMP specification // permits additional attributes after end="...". - {" size) continue; diff --git a/src/exif.cpp b/src/exif.cpp index 6d9d280bf6..77e194ff2b 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -496,10 +496,7 @@ ByteOrder ExifParser::decode(ExifData& exifData, const byte* pData, size_t size) //! @cond IGNORE enum Ptt { pttLen, pttTag, pttIfd }; -struct PreviewTags { - Ptt ptt_; - const char* key_; -}; +using PreviewTags = std::pair; //! @endcond WriteMethod ExifParser::encode(Blob& blob, const byte* pData, size_t size, ByteOrder byteOrder, @@ -545,12 +542,13 @@ WriteMethod ExifParser::encode(Blob& blob, const byte* pData, size_t size, ByteO } // Delete IFDs which do not occur in JPEGs - static const IfdId filteredIfds[] = {subImage1Id, subImage2Id, subImage3Id, subImage4Id, subImage5Id, - subImage6Id, subImage7Id, subImage8Id, subImage9Id, subThumb1Id, - panaRawId, ifd2Id, ifd3Id}; + static constexpr auto filteredIfds = std::array{ + subImage1Id, subImage2Id, subImage3Id, subImage4Id, subImage5Id, subImage6Id, subImage7Id, + subImage8Id, subImage9Id, subThumb1Id, panaRawId, ifd2Id, ifd3Id, + }; for (auto&& filteredIfd : filteredIfds) { #ifdef EXIV2_DEBUG_MESSAGES - std::cerr << "Warning: Exif IFD " << filteredIfds << " not encoded\n"; + std::cerr << "Warning: Exif IFD " << filteredIfd << " not encoded\n"; #endif eraseIfd(ed, filteredIfd); } @@ -575,41 +573,41 @@ WriteMethod ExifParser::encode(Blob& blob, const byte* pData, size_t size, ByteO // Todo: Enhance preview classes to be able to write and delete previews and use that instead. // Table must be sorted by preview, the first tag in each group is the size static constexpr auto filteredPvTags = std::array{ - PreviewTags{pttLen, "Exif.Minolta.ThumbnailLength"}, - PreviewTags{pttTag, "Exif.Minolta.ThumbnailOffset"}, - PreviewTags{pttLen, "Exif.Minolta.Thumbnail"}, - PreviewTags{pttLen, "Exif.NikonPreview.JPEGInterchangeFormatLength"}, - PreviewTags{pttIfd, "NikonPreview"}, - PreviewTags{pttLen, "Exif.Olympus.ThumbnailLength"}, - PreviewTags{pttTag, "Exif.Olympus.ThumbnailOffset"}, - PreviewTags{pttLen, "Exif.Olympus.ThumbnailImage"}, - PreviewTags{pttLen, "Exif.Olympus.Thumbnail"}, - PreviewTags{pttLen, "Exif.Olympus2.ThumbnailLength"}, - PreviewTags{pttTag, "Exif.Olympus2.ThumbnailOffset"}, - PreviewTags{pttLen, "Exif.Olympus2.ThumbnailImage"}, - PreviewTags{pttLen, "Exif.Olympus2.Thumbnail"}, - PreviewTags{pttLen, "Exif.OlympusCs.PreviewImageLength"}, - PreviewTags{pttTag, "Exif.OlympusCs.PreviewImageStart"}, - PreviewTags{pttTag, "Exif.OlympusCs.PreviewImageValid"}, - PreviewTags{pttLen, "Exif.Pentax.PreviewLength"}, - PreviewTags{pttTag, "Exif.Pentax.PreviewOffset"}, - PreviewTags{pttTag, "Exif.Pentax.PreviewResolution"}, - PreviewTags{pttLen, "Exif.PentaxDng.PreviewLength"}, - PreviewTags{pttTag, "Exif.PentaxDng.PreviewOffset"}, - PreviewTags{pttTag, "Exif.PentaxDng.PreviewResolution"}, - PreviewTags{pttLen, "Exif.SamsungPreview.JPEGInterchangeFormatLength"}, - PreviewTags{pttIfd, "SamsungPreview"}, - PreviewTags{pttLen, "Exif.Thumbnail.StripByteCounts"}, - PreviewTags{pttIfd, "Thumbnail"}, - PreviewTags{pttLen, "Exif.Thumbnail.JPEGInterchangeFormatLength"}, - PreviewTags{pttIfd, "Thumbnail"}, + PreviewTags(pttLen, "Exif.Minolta.ThumbnailLength"), + PreviewTags(pttTag, "Exif.Minolta.ThumbnailOffset"), + PreviewTags(pttLen, "Exif.Minolta.Thumbnail"), + PreviewTags(pttLen, "Exif.NikonPreview.JPEGInterchangeFormatLength"), + PreviewTags(pttIfd, "NikonPreview"), + PreviewTags(pttLen, "Exif.Olympus.ThumbnailLength"), + PreviewTags(pttTag, "Exif.Olympus.ThumbnailOffset"), + PreviewTags(pttLen, "Exif.Olympus.ThumbnailImage"), + PreviewTags(pttLen, "Exif.Olympus.Thumbnail"), + PreviewTags(pttLen, "Exif.Olympus2.ThumbnailLength"), + PreviewTags(pttTag, "Exif.Olympus2.ThumbnailOffset"), + PreviewTags(pttLen, "Exif.Olympus2.ThumbnailImage"), + PreviewTags(pttLen, "Exif.Olympus2.Thumbnail"), + PreviewTags(pttLen, "Exif.OlympusCs.PreviewImageLength"), + PreviewTags(pttTag, "Exif.OlympusCs.PreviewImageStart"), + PreviewTags(pttTag, "Exif.OlympusCs.PreviewImageValid"), + PreviewTags(pttLen, "Exif.Pentax.PreviewLength"), + PreviewTags(pttTag, "Exif.Pentax.PreviewOffset"), + PreviewTags(pttTag, "Exif.Pentax.PreviewResolution"), + PreviewTags(pttLen, "Exif.PentaxDng.PreviewLength"), + PreviewTags(pttTag, "Exif.PentaxDng.PreviewOffset"), + PreviewTags(pttTag, "Exif.PentaxDng.PreviewResolution"), + PreviewTags(pttLen, "Exif.SamsungPreview.JPEGInterchangeFormatLength"), + PreviewTags(pttIfd, "SamsungPreview"), + PreviewTags(pttLen, "Exif.Thumbnail.StripByteCounts"), + PreviewTags(pttIfd, "Thumbnail"), + PreviewTags(pttLen, "Exif.Thumbnail.JPEGInterchangeFormatLength"), + PreviewTags(pttIfd, "Thumbnail"), }; bool delTags = false; - for (auto&& filteredPvTag : filteredPvTags) { - switch (filteredPvTag.ptt_) { + for (auto&& [ptt, key] : filteredPvTags) { + switch (ptt) { case pttLen: { delTags = false; - auto pos = ed.findKey(ExifKey(filteredPvTag.key_)); + auto pos = ed.findKey(ExifKey(key)); if (pos != ed.end() && sumToLong(*pos) > 32768) { delTags = true; #ifndef SUPPRESS_WARNINGS @@ -621,7 +619,7 @@ WriteMethod ExifParser::encode(Blob& blob, const byte* pData, size_t size, ByteO } case pttTag: { if (delTags) { - auto pos = ed.findKey(ExifKey(filteredPvTag.key_)); + auto pos = ed.findKey(ExifKey(key)); if (pos != ed.end()) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Exif tag " << pos->key() << " not encoded\n"; @@ -634,9 +632,9 @@ WriteMethod ExifParser::encode(Blob& blob, const byte* pData, size_t size, ByteO case pttIfd: if (delTags) { #ifndef SUPPRESS_WARNINGS - EXV_WARNING << "Exif IFD " << filteredPvTag.key_ << " not encoded\n"; + EXV_WARNING << "Exif IFD " << key << " not encoded\n"; #endif - eraseIfd(ed, Internal::groupId(filteredPvTag.key_)); + eraseIfd(ed, Internal::groupId(key)); } break; } diff --git a/src/olympusmn_int.cpp b/src/olympusmn_int.cpp index b8a2a89601..f39a2bb544 100644 --- a/src/olympusmn_int.cpp +++ b/src/olympusmn_int.cpp @@ -10,6 +10,8 @@ #include "tags_int.hpp" #include "value.hpp" +#include + // ***************************************************************************** // class member definitions namespace Exiv2::Internal { @@ -1344,20 +1346,17 @@ std::ostream& OlympusMakerNote::printEq0x0301(std::ostream& os, const Value& val //! OlympusCs FocusMode, tag 0x0301 // (1 or 2 values) std::ostream& OlympusMakerNote::printCs0x0301(std::ostream& os, const Value& value, const ExifData*) { - static struct { - uint16_t val; - const char* label; - } focusModes0[] = { - {0, N_("Single AF")}, {1, N_("Sequential shooting AF")}, - {2, N_("Continuous AF")}, {3, N_("Multi AF")}, - {4, N_("Face detect")}, {10, N_("MF")}, + using mode0 = std::pair; + static constexpr auto focusModes0 = std::array{ + mode0(0, N_("Single AF")), mode0(1, N_("Sequential shooting AF")), + mode0(2, N_("Continuous AF")), mode0(3, N_("Multi AF")), + mode0(4, N_("Face detect")), mode0(10, N_("MF")), }; - static struct { - uint16_t val; - const char* label; - } focusModes1[] = { - {0x0001, N_("S-AF")}, {0x0004, N_("C-AF")}, {0x0010, N_("MF")}, - {0x0020, N_("Face detect")}, {0x0040, N_("Imager AF")}, {0x0100, N_("AF sensor")}, + + using mode1 = std::pair; + static constexpr auto focusModes1 = std::array{ + mode1(0x0001, N_("S-AF")), mode1(0x0004, N_("C-AF")), mode1(0x0010, N_("MF")), + mode1(0x0020, N_("Face detect")), mode1(0x0040, N_("Imager AF")), mode1(0x0100, N_("AF sensor")), }; if (value.count() < 1 || value.typeId() != unsignedShort) { @@ -1370,19 +1369,19 @@ std::ostream& OlympusMakerNote::printCs0x0301(std::ostream& os, const Value& val std::string p; // Used to enable ',' separation v = static_cast(value.toInt64(1)); - for (auto&& mode : focusModes1) { - if ((v & mode.val) != 0) { + for (auto&& [val, label] : focusModes1) { + if ((v & val) != 0) { if (!p.empty()) { os << ", "; } - p = mode.label; + p = label; os << p; } } } else { - for (auto&& mode : focusModes0) { - if (mode.val == v) { - os << mode.label; + for (auto&& [val, label] : focusModes0) { + if (val == v) { + os << label; break; } } @@ -1500,41 +1499,38 @@ std::ostream& OlympusMakerNote::print0x0305(std::ostream& os, const Value& value // Olympus FocusInfo tag 0x0308 AFPoint std::ostream& OlympusMakerNote::print0x0308(std::ostream& os, const Value& value, const ExifData* metadata) { - static struct { - uint16_t val; - const char* label; - } afPoints[] = { - {0, N_("Left (or n/a)")}, {1, N_("Center (horizontal)")}, {2, N_("Right")}, {3, N_("Center (vertical)")}, - {255, N_("None")}, + using point = std::pair; + static constexpr auto afPoints = std::array{ + point(0, N_("Left (or n/a)")), point(1, N_("Center (horizontal)")), + point(2, N_("Right")), point(3, N_("Center (vertical)")), + point(255, N_("None")), }; - static struct { - byte val; - const char* label; - } afPointsE3[] = { - {0x00, N_("None")}, - {0x01, N_("Top-left (horizontal)")}, - {0x02, N_("Top-center (horizontal)")}, - {0x03, N_("Top-right (horizontal)")}, - {0x04, N_("Left (horizontal)")}, - {0x05, N_("Mid-left (horizontal)")}, - {0x06, N_("Center (horizontal)")}, - {0x07, N_("Mid-right (horizontal)")}, - {0x08, N_("Right (horizontal)")}, - {0x09, N_("Bottom-left (horizontal)")}, - {0x0a, N_("Bottom-center (horizontal)")}, - {0x0b, N_("Bottom-right (horizontal)")}, - {0x0c, N_("Top-left (vertical)")}, - {0x0d, N_("Top-center (vertical)")}, - {0x0e, N_("Top-right (vertical)")}, - {0x0f, N_("Left (vertical)")}, - {0x10, N_("Mid-left (vertical)")}, - {0x11, N_("Center (vertical)")}, - {0x12, N_("Mid-right (vertical)")}, - {0x13, N_("Right (vertical)")}, - {0x14, N_("Bottom-left (vertical)")}, - {0x15, N_("Bottom-center (vertical)")}, - {0x16, N_("Bottom-right (vertical)")}, + using pointE3 = std::pair; + static constexpr auto afPointsE3 = std::array{ + pointE3(0x00, N_("None")), + pointE3(0x01, N_("Top-left (horizontal)")), + pointE3(0x02, N_("Top-center (horizontal)")), + pointE3(0x03, N_("Top-right (horizontal)")), + pointE3(0x04, N_("Left (horizontal)")), + pointE3(0x05, N_("Mid-left (horizontal)")), + pointE3(0x06, N_("Center (horizontal)")), + pointE3(0x07, N_("Mid-right (horizontal)")), + pointE3(0x08, N_("Right (horizontal)")), + pointE3(0x09, N_("Bottom-left (horizontal)")), + pointE3(0x0a, N_("Bottom-center (horizontal)")), + pointE3(0x0b, N_("Bottom-right (horizontal)")), + pointE3(0x0c, N_("Top-left (vertical)")), + pointE3(0x0d, N_("Top-center (vertical)")), + pointE3(0x0e, N_("Top-right (vertical)")), + pointE3(0x0f, N_("Left (vertical)")), + pointE3(0x10, N_("Mid-left (vertical)")), + pointE3(0x11, N_("Center (vertical)")), + pointE3(0x12, N_("Mid-right (vertical)")), + pointE3(0x13, N_("Right (vertical)")), + pointE3(0x14, N_("Bottom-left (vertical)")), + pointE3(0x15, N_("Bottom-center (vertical)")), + pointE3(0x16, N_("Bottom-right (vertical)")), }; if (value.count() != 1 || value.typeId() != unsignedShort) { @@ -1556,16 +1552,16 @@ std::ostream& OlympusMakerNote::print0x0308(std::ostream& os, const Value& value auto v = static_cast(value.toInt64(0)); if (!E3_E30model) { - for (auto&& point : afPoints) { - if (point.val == v) { - return os << point.label; + for (auto&& [val, label] : afPoints) { + if (val == v) { + return os << label; } } } else { // E-3 and E-30 - for (auto&& point : afPointsE3) { - if (point.val == (v & 0x1f)) { - os << point.label; + for (auto&& [val, label] : afPointsE3) { + if (val == (v & 0x1f)) { + os << label; os << ", "; if ((v & 0xe0) == 0) return os << N_("Single Target"); diff --git a/src/orfimage.cpp b/src/orfimage.cpp index d9002ffea3..6e5e08095a 100644 --- a/src/orfimage.cpp +++ b/src/orfimage.cpp @@ -13,6 +13,7 @@ #include "tiffimage.hpp" #include "tiffimage_int.hpp" +#include #include // ***************************************************************************** @@ -124,10 +125,12 @@ WriteMethod OrfParser::encode(BasicIo& io, const byte* pData, size_t size, ByteO ExifData ed = exifData; // Delete IFDs which do not occur in TIFF images - static const IfdId filteredIfds[] = {panaRawId}; + static constexpr auto filteredIfds = { + panaRawId, + }; for (auto&& filteredIfd : filteredIfds) { #ifdef EXIV2_DEBUG_MESSAGES - std::cerr << "Warning: Exif IFD " << filteredIfds << " not encoded\n"; + std::cerr << "Warning: Exif IFD " << filteredIfd << " not encoded\n"; #endif ed.erase(std::remove_if(ed.begin(), ed.end(), FindExifdatum(filteredIfd)), ed.end()); }