diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7af4cb97..a33b8f5b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,7 @@ SET( LIBEXIV2_PRIVATE_HDR canonmn_int.hpp rw2image_int.hpp sigmamn_int.hpp sonymn_int.hpp + tags_int.hpp tiffcomposite_int.hpp tifffwd_int.hpp tiffimage_int.hpp diff --git a/src/canonmn.cpp b/src/canonmn.cpp index 8cc2479f..52ac191c 100644 --- a/src/canonmn.cpp +++ b/src/canonmn.cpp @@ -33,6 +33,7 @@ EXIV2_RCSID("@(#) $Id$") // included header files #include "types.hpp" #include "canonmn_int.hpp" +#include "tags_int.hpp" #include "value.hpp" #include "exif.hpp" #include "i18n.h" // NLS support. diff --git a/src/crwimage.cpp b/src/crwimage.cpp index 813140c7..0ee13742 100644 --- a/src/crwimage.cpp +++ b/src/crwimage.cpp @@ -47,6 +47,7 @@ EXIV2_RCSID("@(#) $Id$") #include "futils.hpp" #include "value.hpp" #include "tags.hpp" +#include "tags_int.hpp" #include "canonmn_int.hpp" #include "i18n.h" // NLS support. diff --git a/src/fujimn.cpp b/src/fujimn.cpp index ab96bfef..80de14ae 100644 --- a/src/fujimn.cpp +++ b/src/fujimn.cpp @@ -35,6 +35,7 @@ EXIV2_RCSID("@(#) $Id$") // included header files #include "types.hpp" #include "fujimn_int.hpp" +#include "tags_int.hpp" #include "value.hpp" #include "i18n.h" // NLS support. diff --git a/src/minoltamn.cpp b/src/minoltamn.cpp index 753dc1e0..e0ef1186 100644 --- a/src/minoltamn.cpp +++ b/src/minoltamn.cpp @@ -34,6 +34,7 @@ EXIV2_RCSID("@(#) $Id$") // ***************************************************************************** // included header files #include "minoltamn_int.hpp" +#include "tags_int.hpp" #include "value.hpp" #include "i18n.h" // NLS support. diff --git a/src/nikonmn.cpp b/src/nikonmn.cpp index 7e0200aa..662a199a 100644 --- a/src/nikonmn.cpp +++ b/src/nikonmn.cpp @@ -40,7 +40,7 @@ EXIV2_RCSID("@(#) $Id$") #include "nikonmn_int.hpp" #include "value.hpp" #include "image.hpp" -#include "tags.hpp" +#include "tags_int.hpp" #include "error.hpp" #include "i18n.h" // NLS support. diff --git a/src/olympusmn.cpp b/src/olympusmn.cpp index e2f28a6a..b8d0d258 100644 --- a/src/olympusmn.cpp +++ b/src/olympusmn.cpp @@ -39,7 +39,7 @@ EXIV2_RCSID("@(#) $Id$") #include "olympusmn_int.hpp" #include "value.hpp" #include "image.hpp" -#include "tags.hpp" +#include "tags_int.hpp" #include "i18n.h" // NLS support. // + standard includes diff --git a/src/panasonicmn.cpp b/src/panasonicmn.cpp index 45b90ea6..a48c5919 100644 --- a/src/panasonicmn.cpp +++ b/src/panasonicmn.cpp @@ -34,6 +34,7 @@ EXIV2_RCSID("@(#) $Id$") // included header files #include "types.hpp" #include "panasonicmn_int.hpp" +#include "tags_int.hpp" #include "value.hpp" #include "i18n.h" // NLS support. diff --git a/src/pentaxmn_int.hpp b/src/pentaxmn_int.hpp index 75199f65..651f72d4 100644 --- a/src/pentaxmn_int.hpp +++ b/src/pentaxmn_int.hpp @@ -35,6 +35,7 @@ // ***************************************************************************** // included header files #include "tags.hpp" +#include "tags_int.hpp" #include "types.hpp" // + standard includes diff --git a/src/properties.cpp b/src/properties.cpp index 852263ba..0355e22c 100644 --- a/src/properties.cpp +++ b/src/properties.cpp @@ -32,7 +32,7 @@ EXIV2_RCSID("@(#) $Id$") // ***************************************************************************** // included header files #include "properties.hpp" -#include "tags.hpp" +#include "tags_int.hpp" #include "error.hpp" #include "types.hpp" #include "value.hpp" @@ -67,6 +67,8 @@ namespace { // class member definitions namespace Exiv2 { + using namespace Internal; + //! @cond IGNORE extern const XmpPropertyInfo xmpDcInfo[]; extern const XmpPropertyInfo xmpDigikamInfo[]; diff --git a/src/sigmamn.cpp b/src/sigmamn.cpp index dfdce665..34761834 100644 --- a/src/sigmamn.cpp +++ b/src/sigmamn.cpp @@ -35,6 +35,7 @@ EXIV2_RCSID("@(#) $Id$") // included header files #include "types.hpp" #include "sigmamn_int.hpp" +#include "tags_int.hpp" #include "value.hpp" #include "i18n.h" // NLS support. diff --git a/src/sonymn.cpp b/src/sonymn.cpp index 3a591f2a..4afa3258 100644 --- a/src/sonymn.cpp +++ b/src/sonymn.cpp @@ -33,6 +33,7 @@ EXIV2_RCSID("@(#) $Id$") #include "types.hpp" #include "minoltamn_int.hpp" #include "sonymn_int.hpp" +#include "tags_int.hpp" #include "value.hpp" #include "i18n.h" // NLS support. diff --git a/src/tags.cpp b/src/tags.cpp index c0b2922c..fd85dd36 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -34,6 +34,7 @@ EXIV2_RCSID("@(#) $Id$") // included header files #include "types.hpp" #include "tags.hpp" +#include "tags_int.hpp" #include "error.hpp" #include "futils.hpp" #include "value.hpp" @@ -76,9 +77,7 @@ namespace { // ***************************************************************************** // class member definitions namespace Exiv2 { - - // Todo: Remove: temporary fix used during migration of makernote classes to namespace Internal - using namespace Internal; + namespace Internal { bool TagVocabulary::operator==(const std::string& key) const { @@ -86,161 +85,6 @@ namespace Exiv2 { return 0 == strcmp(voc_, key.c_str() + key.size() - strlen(voc_)); } - //! @cond IGNORE - IfdInfo::Item::Item(const std::string& item) - { - i_ = item; - } - //! @endcond - - bool IfdInfo::operator==(IfdId ifdId) const - { - return ifdId_ == ifdId; - } - - bool IfdInfo::operator==(const Item& item) const - { - return 0 == strcmp(item.i_.c_str(), item_); - } - - // Important: IFD item must be unique! - const IfdInfo ExifTags::ifdInfo_[] = { - { ifdIdNotSet, "(Unknown IFD)", "(Unknown item)", 0 }, - { ifd0Id, "IFD0", "Image", ExifTags::ifdTagList }, - { exifIfdId, "Exif", "Photo", ExifTags::exifTagList }, // just to avoid 'Exif.Exif.*' keys - { gpsIfdId, "GPSInfo", "GPSInfo", ExifTags::gpsTagList }, - { iopIfdId, "Iop", "Iop", ExifTags::iopTagList }, - { ifd1Id, "IFD1", "Thumbnail", ExifTags::ifdTagList }, - { ifd2Id, "IFD2", "Image2", ExifTags::ifdTagList }, - { ifd3Id, "IFD3", "Image3", ExifTags::ifdTagList }, - { subImage1Id, "SubImage1", "SubImage1", ExifTags::ifdTagList }, - { subImage2Id, "SubImage2", "SubImage2", ExifTags::ifdTagList }, - { subImage3Id, "SubImage3", "SubImage3", ExifTags::ifdTagList }, - { subImage4Id, "SubImage4", "SubImage4", ExifTags::ifdTagList }, - { subImage5Id, "SubImage5", "SubImage5", ExifTags::ifdTagList }, - { subImage6Id, "SubImage6", "SubImage6", ExifTags::ifdTagList }, - { subImage7Id, "SubImage7", "SubImage7", ExifTags::ifdTagList }, - { subImage8Id, "SubImage8", "SubImage8", ExifTags::ifdTagList }, - { subImage9Id, "SubImage9", "SubImage9", ExifTags::ifdTagList }, - { mnIfdId, "Makernote", "MakerNote", ExifTags::mnTagList }, - { canonIfdId, "Makernote", "Canon", CanonMakerNote::tagList }, - { canonCsIfdId, "Makernote", "CanonCs", CanonMakerNote::tagListCs }, - { canonSiIfdId, "Makernote", "CanonSi", CanonMakerNote::tagListSi }, - { canonCfIfdId, "Makernote", "CanonCf", CanonMakerNote::tagListCf }, - { canonPiIfdId, "Makernote", "CanonPi", CanonMakerNote::tagListPi }, - { canonFiIfdId, "Makernote", "CanonFi", CanonMakerNote::tagListFi }, - { canonPaIfdId, "Makernote", "CanonPa", CanonMakerNote::tagListPa }, - { fujiIfdId, "Makernote", "Fujifilm", FujiMakerNote::tagList }, - { minoltaIfdId, "Makernote", "Minolta", MinoltaMakerNote::tagList }, - { minoltaCs5DIfdId, "Makernote", "MinoltaCs5D", MinoltaMakerNote::tagListCs5D }, - { minoltaCs7DIfdId, "Makernote", "MinoltaCs7D", MinoltaMakerNote::tagListCs7D }, - { minoltaCsOldIfdId, "Makernote", "MinoltaCsOld", MinoltaMakerNote::tagListCsStd }, - { minoltaCsNewIfdId, "Makernote", "MinoltaCsNew", MinoltaMakerNote::tagListCsStd }, - { nikon1IfdId, "Makernote", "Nikon1", Nikon1MakerNote::tagList }, - { nikon2IfdId, "Makernote", "Nikon2", Nikon2MakerNote::tagList }, - { nikon3IfdId, "Makernote", "Nikon3", Nikon3MakerNote::tagList }, - { nikonPvIfdId, "Makernote", "NikonPreview", ExifTags::ifdTagList }, - { nikonVrIfdId, "Makernote", "NikonVr", Nikon3MakerNote::tagListVr }, - { nikonPcIfdId, "Makernote", "NikonPc", Nikon3MakerNote::tagListPc }, - { nikonWtIfdId, "Makernote", "NikonWt", Nikon3MakerNote::tagListWt }, - { nikonIiIfdId, "Makernote", "NikonIi", Nikon3MakerNote::tagListIi }, - { nikonAfIfdId, "Makernote", "NikonAf", Nikon3MakerNote::tagListAf }, - { nikonAf2IfdId, "Makernote", "NikonAf2", Nikon3MakerNote::tagListAf2 }, - { nikonFiIfdId, "Makernote", "NikonFi", Nikon3MakerNote::tagListFi }, - { nikonMeIfdId, "Makernote", "NikonMe", Nikon3MakerNote::tagListMe }, - { nikonFl1IfdId, "Makernote", "NikonFl1", Nikon3MakerNote::tagListFl1 }, - { nikonFl2IfdId, "Makernote", "NikonFl2", Nikon3MakerNote::tagListFl2 }, - { nikonFl3IfdId, "Makernote", "NikonFl3", Nikon3MakerNote::tagListFl3 }, - { nikonSi1IfdId, "Makernote", "NikonSiD80", Nikon3MakerNote::tagListSi1 }, - { nikonSi2IfdId, "Makernote", "NikonSiD40", Nikon3MakerNote::tagListSi2 }, - { nikonSi3IfdId, "Makernote", "NikonSiD300a", Nikon3MakerNote::tagListSi3 }, - { nikonSi4IfdId, "Makernote", "NikonSiD300b", Nikon3MakerNote::tagListSi4 }, - { nikonSi5IfdId, "Makernote", "NikonSi02xx", Nikon3MakerNote::tagListSi5 }, - { nikonSi6IfdId, "Makernote", "NikonSi01xx", Nikon3MakerNote::tagListSi5 }, - { nikonCb1IfdId, "Makernote", "NikonCb1", Nikon3MakerNote::tagListCb1 }, - { nikonCb2IfdId, "Makernote", "NikonCb2", Nikon3MakerNote::tagListCb2 }, - { nikonCb2aIfdId, "Makernote", "NikonCb2a", Nikon3MakerNote::tagListCb2a }, - { nikonCb2bIfdId, "Makernote", "NikonCb2b", Nikon3MakerNote::tagListCb2b }, - { nikonCb3IfdId, "Makernote", "NikonCb3", Nikon3MakerNote::tagListCb3 }, - { nikonCb4IfdId, "Makernote", "NikonCb4", Nikon3MakerNote::tagListCb4 }, - { nikonLd1IfdId, "Makernote", "NikonLd1", Nikon3MakerNote::tagListLd1 }, - { nikonLd2IfdId, "Makernote", "NikonLd2", Nikon3MakerNote::tagListLd2 }, - { nikonLd3IfdId, "Makernote", "NikonLd3", Nikon3MakerNote::tagListLd3 }, - { olympusIfdId, "Makernote", "Olympus", OlympusMakerNote::tagList }, - { olympus2IfdId, "Makernote", "Olympus2", OlympusMakerNote::tagList }, - { olympusCsIfdId, "Makernote", "OlympusCs", OlympusMakerNote::tagListCs }, - { olympusEqIfdId, "Makernote", "OlympusEq", OlympusMakerNote::tagListEq }, - { olympusRdIfdId, "Makernote", "OlympusRd", OlympusMakerNote::tagListRd }, - { olympusRd2IfdId, "Makernote", "OlympusRd2", OlympusMakerNote::tagListRd2 }, - { olympusIpIfdId, "Makernote", "OlympusIp", OlympusMakerNote::tagListIp }, - { olympusFiIfdId, "Makernote", "OlympusFi", OlympusMakerNote::tagListFi }, - { olympusFe1IfdId, "Makernote", "OlympusFe1", OlympusMakerNote::tagListFe }, - { olympusFe2IfdId, "Makernote", "OlympusFe2", OlympusMakerNote::tagListFe }, - { olympusFe3IfdId, "Makernote", "OlympusFe3", OlympusMakerNote::tagListFe }, - { olympusFe4IfdId, "Makernote", "OlympusFe4", OlympusMakerNote::tagListFe }, - { olympusFe5IfdId, "Makernote", "OlympusFe5", OlympusMakerNote::tagListFe }, - { olympusFe6IfdId, "Makernote", "OlympusFe6", OlympusMakerNote::tagListFe }, - { olympusFe7IfdId, "Makernote", "OlympusFe7", OlympusMakerNote::tagListFe }, - { olympusFe8IfdId, "Makernote", "OlympusFe8", OlympusMakerNote::tagListFe }, - { olympusFe9IfdId, "Makernote", "OlympusFe9", OlympusMakerNote::tagListFe }, - { olympusRiIfdId, "Makernote", "OlympusRi", OlympusMakerNote::tagListRi }, - { panasonicIfdId, "Makernote", "Panasonic", PanasonicMakerNote::tagList }, - { panaRawIfdId, "PanaRaw", "PanasonicRaw", PanasonicMakerNote::tagListRaw }, - { pentaxIfdId, "Makernote", "Pentax", PentaxMakerNote::tagList }, - { sigmaIfdId, "Makernote", "Sigma", SigmaMakerNote::tagList }, - { sony1IfdId, "Makernote", "Sony1", SonyMakerNote::tagList }, - { sony2IfdId, "Makernote", "Sony2", SonyMakerNote::tagList }, - { sonyMltIfdId, "Makernote", "SonyMinolta", MinoltaMakerNote::tagList }, - { sony1CsIfdId, "Makernote", "Sony1Cs", SonyMakerNote::tagListCs }, - { sony1Cs2IfdId, "Makernote", "Sony1Cs2", SonyMakerNote::tagListCs2 }, - { sony1MltCs7DIfdId, "Makernote", "Sony1MltCs7D", MinoltaMakerNote::tagListCs7D }, - { sony1MltCsOldIfdId,"Makernote", "Sony1MltCsOld",MinoltaMakerNote::tagListCsStd }, - { sony1MltCsNewIfdId,"Makernote", "Sony1MltCsNew",MinoltaMakerNote::tagListCsStd }, - { sony1MltCsA100IfdId,"Makernote","Sony1MltCsA100",MinoltaMakerNote::tagListCsA100}, - { sony2CsIfdId, "Makernote", "Sony2Cs", SonyMakerNote::tagListCs }, - { sony2Cs2IfdId, "Makernote", "Sony2Cs2", SonyMakerNote::tagListCs2 }, - { lastIfdId, "(Last IFD info)", "(Last IFD item)", 0 } - }; - - const SectionInfo ExifTags::sectionInfo_[] = { - { sectionIdNotSet, "(UnknownSection)", N_("Unknown section") }, - { imgStruct, "ImageStructure", N_("Image data structure") }, - { recOffset, "RecordingOffset", N_("Recording offset") }, - { imgCharacter, "ImageCharacteristics", N_("Image data characteristics") }, - { otherTags, "OtherTags", N_("Other data") }, - { exifFormat, "ExifFormat", N_("Exif data structure") }, - { exifVersion, "ExifVersion", N_("Exif version") }, - { imgConfig, "ImageConfig", N_("Image configuration") }, - { userInfo, "UserInfo", N_("User information") }, - { relatedFile, "RelatedFile", N_("Related file") }, - { dateTime, "DateTime", N_("Date and time") }, - { captureCond, "CaptureConditions", N_("Picture taking conditions") }, - { gpsTags, "GPS", N_("GPS information") }, - { iopTags, "Interoperability", N_("Interoperability information") }, - { makerTags, "Makernote", N_("Vendor specific information") }, - { dngTags, "DngTags", N_("Adobe DNG tags") }, - { panaRaw, "PanasonicRaw", N_("Panasonic RAW tags") }, - { tiffEp, "TIFF/EP", N_("TIFF/EP tags") }, - { tiffPm6, "TIFF&PM6", N_("TIFF PageMaker 6.0 tags") }, - { adobeOpi, "AdobeOPI", N_("Adobe OPI tags") }, - { lastSectionId, "(LastSection)", N_("Last section") } - }; - - TagInfo::TagInfo( - uint16_t tag, - const char* name, - const char* title, - const char* desc, - IfdId ifdId, - SectionId sectionId, - TypeId typeId, - PrintFct printFct - ) - : tag_(tag), name_(name), title_(title), desc_(desc), ifdId_(ifdId), - sectionId_(sectionId), typeId_(typeId), printFct_(printFct) - { - } - //! NewSubfileType, TIFF tag 0x00fe - this is actually a bitmask extern const TagDetails exifNewSubfileType[] = { { 0, N_("Primary image") }, @@ -1230,11 +1074,6 @@ namespace Exiv2 { ifdIdNotSet, sectionIdNotSet, invalidTypeId, printValue) }; - const TagInfo* ExifTags::ifdTagList() - { - return ifdTagInfo; - } - //! ExposureProgram, tag 0x8822 extern const TagDetails exifExposureProgram[] = { { 0, N_("Not defined") }, @@ -1639,11 +1478,6 @@ namespace Exiv2 { ifdIdNotSet, sectionIdNotSet, invalidTypeId, printValue) }; - const TagInfo* ExifTags::exifTagList() - { - return exifTagInfo; - } - //! GPS latitude reference, tag 0x0001; also GPSDestLatitudeRef, tag 0x0013 extern const TagDetails exifGPSLatitudeRef[] = { { 78, N_("North") }, @@ -1857,11 +1691,6 @@ namespace Exiv2 { ifdIdNotSet, sectionIdNotSet, invalidTypeId, printValue) }; - const TagInfo* ExifTags::gpsTagList() - { - return gpsTagInfo; - } - // Exif Interoperability IFD Tags static const TagInfo iopTagInfo[] = { TagInfo(0x0001, "InteroperabilityIndex", N_("Interoperability Index"), @@ -1889,11 +1718,6 @@ namespace Exiv2 { ifdIdNotSet, sectionIdNotSet, invalidTypeId, printValue) }; - const TagInfo* ExifTags::iopTagList() - { - return iopTagInfo; - } - // Synthesized Exiv2 Makernote info Tags (read-only) static const TagInfo mnTagInfo[] = { TagInfo(0x0001, "Offset", N_("Offset"), @@ -1908,412 +1732,11 @@ namespace Exiv2 { ifdIdNotSet, sectionIdNotSet, invalidTypeId, printValue) }; - const TagInfo* ExifTags::mnTagList() - { - return mnTagInfo; - } - // Unknown Tag static const TagInfo unknownTag(0xffff, "Unknown tag", N_("Unknown tag"), N_("Unknown tag"), ifdIdNotSet, sectionIdNotSet, asciiString, printValue); - const TagInfo* ExifTags::tagList(const std::string& group) - { - const IfdInfo* ii = find(ifdInfo_, IfdInfo::Item(group)); - if (ii == 0 || ii->tagList_ == 0) return 0; - return ii->tagList_(); - } // ExifTags::tagList - - const TagInfo* ExifTags::tagList(IfdId ifdId) - { - const IfdInfo* ii = find(ifdInfo_, ifdId); - if (ii == 0 || ii->tagList_ == 0) return 0; - return ii->tagList_(); - } // ExifTags::tagList - - const TagInfo* ExifTags::tagInfo(uint16_t tag, IfdId ifdId) - { - const TagInfo* ti = tagList(ifdId); - if (ti == 0) return 0; - for (int idx = 0; ti[idx].tag_ != 0xffff; ++idx) { - if (ti[idx].tag_ == tag) return &ti[idx]; - } - return 0; - } // ExifTags::tagInfo - - const TagInfo* ExifTags::tagInfo(const std::string& tagName, IfdId ifdId) - { - const TagInfo* ti = tagList(ifdId); - if (ti == 0) return 0; - const char* tn = tagName.c_str(); - if (tn == 0) return 0; - for (int idx = 0; ti[idx].tag_ != 0xffff; ++idx) { - if (0 == strcmp(ti[idx].name_, tn)) { - return &ti[idx]; - } - } - return 0; - } // ExifTags::tagInfo - - bool ExifTags::isMakerIfd(IfdId ifdId) - { - bool rc = false; - const IfdInfo* ii = find(ifdInfo_, ifdId); - if (ii != 0 && 0 == strcmp(ii->name_, "Makernote")) { - rc = true; - } - return rc; - } // ExifTags::isMakerIfd - - bool ExifTags::isExifIfd(IfdId ifdId) - { - bool rc; - switch (ifdId) { - case ifd0Id: - case exifIfdId: - case gpsIfdId: - case iopIfdId: - case ifd1Id: - case ifd2Id: - case ifd3Id: - case subImage1Id: - case subImage2Id: - case subImage3Id: - case subImage4Id: - case subImage5Id: - case subImage6Id: - case subImage7Id: - case subImage8Id: - case subImage9Id: - case panaRawIfdId: rc = true; break; - default: rc = false; break; - } - return rc; - } // ExifTags::isExifIfd - - std::string ExifTags::tagName(uint16_t tag, IfdId ifdId) - { - const TagInfo* ti = tagInfo(tag, ifdId); - if (ti != 0) return ti->name_; - std::ostringstream os; - os << "0x" << std::setw(4) << std::setfill('0') << std::right - << std::hex << tag; - return os.str(); - } // ExifTags::tagName - - const char* ExifTags::tagTitle(uint16_t tag, IfdId ifdId) - { - return tagLabel(tag, ifdId); - } // ExifTags::tagTitle - - const char* ExifTags::tagLabel(uint16_t tag, IfdId ifdId) - { - const TagInfo* ti = tagInfo(tag, ifdId); - if (ti == 0) return ""; - return _(ti->title_); - } // ExifTags::tagLabel - - const char* ExifTags::tagDesc(uint16_t tag, IfdId ifdId) - { - const TagInfo* ti = tagInfo(tag, ifdId); - if (ti == 0) return ""; - return _(ti->desc_); - } // ExifTags::tagDesc - - TypeId ExifTags::tagType(uint16_t tag, IfdId ifdId) - { - const TagInfo* ti = tagInfo(tag, ifdId); - if (ti == 0) return unknownTag.typeId_; - return ti->typeId_; - } // ExifTags::tagType - - uint16_t ExifTags::tag(const std::string& tagName, IfdId ifdId) - { - const TagInfo* ti = tagInfo(tagName, ifdId); - if (ti != 0) return ti->tag_; - if (!isHex(tagName, 4, "0x")) throw Error(7, tagName, ifdId); - std::istringstream is(tagName); - uint16_t tag; - is >> std::hex >> tag; - return tag; - } // ExifTags::tag - - IfdId ExifTags::ifdIdByIfdItem(const std::string& ifdItem) - { - IfdId ifdId = ifdIdNotSet; - const IfdInfo* ii = find(ifdInfo_, IfdInfo::Item(ifdItem)); - if (ii != 0) ifdId = ii->ifdId_; - return ifdId; - } - - const char* ExifTags::sectionName(uint16_t tag, IfdId ifdId) - { - const TagInfo* ti = tagInfo(tag, ifdId); - if (ti == 0) return sectionInfo_[unknownTag.sectionId_].name_; - return sectionInfo_[ti->sectionId_].name_; - } // ExifTags::sectionName - - const char* ExifTags::sectionDesc(uint16_t tag, IfdId ifdId) - { - const TagInfo* ti = tagInfo(tag, ifdId); - if (ti == 0) return _(sectionInfo_[unknownTag.sectionId_].desc_); - return _(sectionInfo_[ti->sectionId_].desc_); - } // ExifTags::sectionDesc - - const char* ExifTags::ifdName(IfdId ifdId) - { - const IfdInfo* ii = find(ifdInfo_, ifdId); - if (ii == 0) return ifdInfo_[0].name_; - return ii->name_; - } // ExifTags::ifdName - - const char* ExifTags::ifdItem(IfdId ifdId) - { - const IfdInfo* ii = find(ifdInfo_, ifdId); - if (ii == 0) return ifdInfo_[0].item_; - return ii->item_; - } // ExifTags::ifdItem - - const char* ExifTags::sectionName(SectionId sectionId) - { - return sectionInfo_[sectionId].name_; - } // ExifTags::sectionName - - SectionId ExifTags::sectionId(const std::string& sectionName) - { - int i; - for (i = int(lastSectionId) - 1; i > 0; --i) { - if (sectionInfo_[i].name_ == sectionName) break; - } - return SectionId(i); - } // ExifTags::sectionId - - std::ostream& ExifTags::printTag(std::ostream& os, - uint16_t tag, - IfdId ifdId, - const Value& value, - const ExifData* pExifData) - { - if (value.count() == 0) return os; - PrintFct fct = printValue; - const TagInfo* ti = tagInfo(tag, ifdId); - if (ti != 0) fct = ti->printFct_; - return fct(os, value, pExifData); - } // ExifTags::printTag - - void ExifTags::taglist(std::ostream& os) - { - for (int i=0; ifdTagInfo[i].tag_ != 0xffff; ++i) { - os << ifdTagInfo[i] << "\n"; - } - for (int i=0; exifTagInfo[i].tag_ != 0xffff; ++i) { - os << exifTagInfo[i] << "\n"; - } - for (int i=0; iopTagInfo[i].tag_ != 0xffff; ++i) { - os << iopTagInfo[i] << "\n"; - } - for (int i=0; gpsTagInfo[i].tag_ != 0xffff; ++i) { - os << gpsTagInfo[i] << "\n"; - } - } // ExifTags::taglist - - void ExifTags::taglist(std::ostream& os, IfdId ifdId) - { - const TagInfo* ti = tagList(ifdId); - if (ti != 0) { - for (int k = 0; ti[k].tag_ != 0xffff; ++k) { - os << ti[k] << "\n"; - } - } - } // ExifTags::taglist - - const char* ExifKey::familyName_ = "Exif"; - - ExifKey::ExifKey(const std::string& key) - : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""), - idx_(0), key_(key) - { - decomposeKey(); - } - - ExifKey::ExifKey(uint16_t tag, const std::string& ifdItem) - : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""), - idx_(0), key_("") - { - IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); - if (!ExifTags::isExifIfd(ifdId) && !ExifTags::isMakerIfd(ifdId)) { - throw Error(23, ifdId); - } - tag_ = tag; - ifdId_ = ifdId; - ifdItem_ = ifdItem; - makeKey(); - } - - ExifKey::ExifKey(const ExifKey& rhs) - : Key(rhs), tag_(rhs.tag_), ifdId_(rhs.ifdId_), ifdItem_(rhs.ifdItem_), - idx_(rhs.idx_), key_(rhs.key_) - { - } - - ExifKey::~ExifKey() - { - } - - ExifKey& ExifKey::operator=(const ExifKey& rhs) - { - if (this == &rhs) return *this; - Key::operator=(rhs); - tag_ = rhs.tag_; - ifdId_ = rhs.ifdId_; - ifdItem_ = rhs.ifdItem_; - idx_ = rhs.idx_; - key_ = rhs.key_; - return *this; - } - - void ExifKey::setIdx(int idx) - { - idx_ = idx; - } - - std::string ExifKey::key() const - { - return key_; - } - - const char* ExifKey::familyName() const - { - return familyName_; - } - - std::string ExifKey::groupName() const - { - return ifdItem(); - } - - std::string ExifKey::tagName() const - { - return ExifTags::tagName(tag_, ifdId_); - } - - std::string ExifKey::tagLabel() const - { - return ExifTags::tagLabel(tag_, ifdId_); - } - - uint16_t ExifKey::tag() const - { - return tag_; - } - - ExifKey::AutoPtr ExifKey::clone() const - { - return AutoPtr(clone_()); - } - - ExifKey* ExifKey::clone_() const - { - return new ExifKey(*this); - } - - std::string ExifKey::sectionName() const - { - return ExifTags::sectionName(tag(), ifdId()); - } - - void ExifKey::decomposeKey() - { - // Get the family name, IFD name and tag name parts of the key - std::string::size_type pos1 = key_.find('.'); - if (pos1 == std::string::npos) throw Error(6, key_); - std::string familyName = key_.substr(0, pos1); - if (0 != strcmp(familyName.c_str(), familyName_)) { - throw Error(6, key_); - } - std::string::size_type pos0 = pos1 + 1; - pos1 = key_.find('.', pos0); - if (pos1 == std::string::npos) throw Error(6, key_); - std::string ifdItem = key_.substr(pos0, pos1 - pos0); - if (ifdItem == "") throw Error(6, key_); - std::string tagName = key_.substr(pos1 + 1); - if (tagName == "") throw Error(6, key_); - - // Find IfdId - IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); - if (ifdId == ifdIdNotSet) throw Error(6, key_); - if (!ExifTags::isExifIfd(ifdId) && !ExifTags::isMakerIfd(ifdId)) { - throw Error(6, key_); - } - // Convert tag - uint16_t tag = ExifTags::tag(tagName, ifdId); - - // Translate hex tag name (0xabcd) to a real tag name if there is one - tagName = ExifTags::tagName(tag, ifdId); - - tag_ = tag; - ifdId_ = ifdId; - ifdItem_ = ifdItem; - key_ = familyName + "." + ifdItem + "." + tagName; - } - - void ExifKey::makeKey() - { - key_ = std::string(familyName_) - + "." + ifdItem_ - + "." + ExifTags::tagName(tag_, ifdId_); - } - - // ************************************************************************* - // free functions - - std::ostream& operator<<(std::ostream& os, const TagInfo& ti) - { - ExifKey exifKey(ti.tag_, ExifTags::ifdItem(ti.ifdId_)); - return os << ExifTags::tagName(ti.tag_, ti.ifdId_) << ",\t" - << std::dec << ti.tag_ << ",\t" - << "0x" << std::setw(4) << std::setfill('0') - << std::right << std::hex << ti.tag_ << ",\t" - << ExifTags::ifdName(ti.ifdId_) << ",\t" - << exifKey.key() << ",\t" - << TypeInfo::typeName( - ExifTags::tagType(ti.tag_, ti.ifdId_)) << ",\t" - << ExifTags::tagDesc(ti.tag_, ti.ifdId_); - } - - std::ostream& operator<<(std::ostream& os, const Rational& r) - { - return os << r.first << "/" << r.second; - } - - std::istream& operator>>(std::istream& is, Rational& r) - { - int32_t nominator; - int32_t denominator; - char c('\0'); - is >> nominator >> c >> denominator; - if (c != '/') is.setstate(std::ios::failbit); - if (is) r = std::make_pair(nominator, denominator); - return is; - } - - std::ostream& operator<<(std::ostream& os, const URational& r) - { - return os << r.first << "/" << r.second; - } - - std::istream& operator>>(std::istream& is, URational& r) - { - uint32_t nominator; - uint32_t denominator; - char c('\0'); - is >> nominator >> c >> denominator; - if (c != '/') is.setstate(std::ios::failbit); - if (is) r = std::make_pair(nominator, denominator); - return is; - } - std::ostream& printValue(std::ostream& os, const Value& value, const ExifData*) { return os << value; @@ -2896,6 +2319,556 @@ namespace Exiv2 { return ur; } +}} // namespace Internal, Exiv2 + +namespace Exiv2 { + + using namespace Internal; + + //! @cond IGNORE + IfdInfo::Item::Item(const std::string& item) + { + i_ = item; + } + //! @endcond + + bool IfdInfo::operator==(IfdId ifdId) const + { + return ifdId_ == ifdId; + } + + bool IfdInfo::operator==(const Item& item) const + { + return 0 == strcmp(item.i_.c_str(), item_); + } + + // Important: IFD item must be unique! + const IfdInfo ExifTags::ifdInfo_[] = { + { ifdIdNotSet, "(Unknown IFD)", "(Unknown item)", 0 }, + { ifd0Id, "IFD0", "Image", ExifTags::ifdTagList }, + { exifIfdId, "Exif", "Photo", ExifTags::exifTagList }, // just to avoid 'Exif.Exif.*' keys + { gpsIfdId, "GPSInfo", "GPSInfo", ExifTags::gpsTagList }, + { iopIfdId, "Iop", "Iop", ExifTags::iopTagList }, + { ifd1Id, "IFD1", "Thumbnail", ExifTags::ifdTagList }, + { ifd2Id, "IFD2", "Image2", ExifTags::ifdTagList }, + { ifd3Id, "IFD3", "Image3", ExifTags::ifdTagList }, + { subImage1Id, "SubImage1", "SubImage1", ExifTags::ifdTagList }, + { subImage2Id, "SubImage2", "SubImage2", ExifTags::ifdTagList }, + { subImage3Id, "SubImage3", "SubImage3", ExifTags::ifdTagList }, + { subImage4Id, "SubImage4", "SubImage4", ExifTags::ifdTagList }, + { subImage5Id, "SubImage5", "SubImage5", ExifTags::ifdTagList }, + { subImage6Id, "SubImage6", "SubImage6", ExifTags::ifdTagList }, + { subImage7Id, "SubImage7", "SubImage7", ExifTags::ifdTagList }, + { subImage8Id, "SubImage8", "SubImage8", ExifTags::ifdTagList }, + { subImage9Id, "SubImage9", "SubImage9", ExifTags::ifdTagList }, + { mnIfdId, "Makernote", "MakerNote", ExifTags::mnTagList }, + { canonIfdId, "Makernote", "Canon", CanonMakerNote::tagList }, + { canonCsIfdId, "Makernote", "CanonCs", CanonMakerNote::tagListCs }, + { canonSiIfdId, "Makernote", "CanonSi", CanonMakerNote::tagListSi }, + { canonCfIfdId, "Makernote", "CanonCf", CanonMakerNote::tagListCf }, + { canonPiIfdId, "Makernote", "CanonPi", CanonMakerNote::tagListPi }, + { canonFiIfdId, "Makernote", "CanonFi", CanonMakerNote::tagListFi }, + { canonPaIfdId, "Makernote", "CanonPa", CanonMakerNote::tagListPa }, + { fujiIfdId, "Makernote", "Fujifilm", FujiMakerNote::tagList }, + { minoltaIfdId, "Makernote", "Minolta", MinoltaMakerNote::tagList }, + { minoltaCs5DIfdId, "Makernote", "MinoltaCs5D", MinoltaMakerNote::tagListCs5D }, + { minoltaCs7DIfdId, "Makernote", "MinoltaCs7D", MinoltaMakerNote::tagListCs7D }, + { minoltaCsOldIfdId, "Makernote", "MinoltaCsOld", MinoltaMakerNote::tagListCsStd }, + { minoltaCsNewIfdId, "Makernote", "MinoltaCsNew", MinoltaMakerNote::tagListCsStd }, + { nikon1IfdId, "Makernote", "Nikon1", Nikon1MakerNote::tagList }, + { nikon2IfdId, "Makernote", "Nikon2", Nikon2MakerNote::tagList }, + { nikon3IfdId, "Makernote", "Nikon3", Nikon3MakerNote::tagList }, + { nikonPvIfdId, "Makernote", "NikonPreview", ExifTags::ifdTagList }, + { nikonVrIfdId, "Makernote", "NikonVr", Nikon3MakerNote::tagListVr }, + { nikonPcIfdId, "Makernote", "NikonPc", Nikon3MakerNote::tagListPc }, + { nikonWtIfdId, "Makernote", "NikonWt", Nikon3MakerNote::tagListWt }, + { nikonIiIfdId, "Makernote", "NikonIi", Nikon3MakerNote::tagListIi }, + { nikonAfIfdId, "Makernote", "NikonAf", Nikon3MakerNote::tagListAf }, + { nikonAf2IfdId, "Makernote", "NikonAf2", Nikon3MakerNote::tagListAf2 }, + { nikonFiIfdId, "Makernote", "NikonFi", Nikon3MakerNote::tagListFi }, + { nikonMeIfdId, "Makernote", "NikonMe", Nikon3MakerNote::tagListMe }, + { nikonFl1IfdId, "Makernote", "NikonFl1", Nikon3MakerNote::tagListFl1 }, + { nikonFl2IfdId, "Makernote", "NikonFl2", Nikon3MakerNote::tagListFl2 }, + { nikonFl3IfdId, "Makernote", "NikonFl3", Nikon3MakerNote::tagListFl3 }, + { nikonSi1IfdId, "Makernote", "NikonSiD80", Nikon3MakerNote::tagListSi1 }, + { nikonSi2IfdId, "Makernote", "NikonSiD40", Nikon3MakerNote::tagListSi2 }, + { nikonSi3IfdId, "Makernote", "NikonSiD300a", Nikon3MakerNote::tagListSi3 }, + { nikonSi4IfdId, "Makernote", "NikonSiD300b", Nikon3MakerNote::tagListSi4 }, + { nikonSi5IfdId, "Makernote", "NikonSi02xx", Nikon3MakerNote::tagListSi5 }, + { nikonSi6IfdId, "Makernote", "NikonSi01xx", Nikon3MakerNote::tagListSi5 }, + { nikonCb1IfdId, "Makernote", "NikonCb1", Nikon3MakerNote::tagListCb1 }, + { nikonCb2IfdId, "Makernote", "NikonCb2", Nikon3MakerNote::tagListCb2 }, + { nikonCb2aIfdId, "Makernote", "NikonCb2a", Nikon3MakerNote::tagListCb2a }, + { nikonCb2bIfdId, "Makernote", "NikonCb2b", Nikon3MakerNote::tagListCb2b }, + { nikonCb3IfdId, "Makernote", "NikonCb3", Nikon3MakerNote::tagListCb3 }, + { nikonCb4IfdId, "Makernote", "NikonCb4", Nikon3MakerNote::tagListCb4 }, + { nikonLd1IfdId, "Makernote", "NikonLd1", Nikon3MakerNote::tagListLd1 }, + { nikonLd2IfdId, "Makernote", "NikonLd2", Nikon3MakerNote::tagListLd2 }, + { nikonLd3IfdId, "Makernote", "NikonLd3", Nikon3MakerNote::tagListLd3 }, + { olympusIfdId, "Makernote", "Olympus", OlympusMakerNote::tagList }, + { olympus2IfdId, "Makernote", "Olympus2", OlympusMakerNote::tagList }, + { olympusCsIfdId, "Makernote", "OlympusCs", OlympusMakerNote::tagListCs }, + { olympusEqIfdId, "Makernote", "OlympusEq", OlympusMakerNote::tagListEq }, + { olympusRdIfdId, "Makernote", "OlympusRd", OlympusMakerNote::tagListRd }, + { olympusRd2IfdId, "Makernote", "OlympusRd2", OlympusMakerNote::tagListRd2 }, + { olympusIpIfdId, "Makernote", "OlympusIp", OlympusMakerNote::tagListIp }, + { olympusFiIfdId, "Makernote", "OlympusFi", OlympusMakerNote::tagListFi }, + { olympusFe1IfdId, "Makernote", "OlympusFe1", OlympusMakerNote::tagListFe }, + { olympusFe2IfdId, "Makernote", "OlympusFe2", OlympusMakerNote::tagListFe }, + { olympusFe3IfdId, "Makernote", "OlympusFe3", OlympusMakerNote::tagListFe }, + { olympusFe4IfdId, "Makernote", "OlympusFe4", OlympusMakerNote::tagListFe }, + { olympusFe5IfdId, "Makernote", "OlympusFe5", OlympusMakerNote::tagListFe }, + { olympusFe6IfdId, "Makernote", "OlympusFe6", OlympusMakerNote::tagListFe }, + { olympusFe7IfdId, "Makernote", "OlympusFe7", OlympusMakerNote::tagListFe }, + { olympusFe8IfdId, "Makernote", "OlympusFe8", OlympusMakerNote::tagListFe }, + { olympusFe9IfdId, "Makernote", "OlympusFe9", OlympusMakerNote::tagListFe }, + { olympusRiIfdId, "Makernote", "OlympusRi", OlympusMakerNote::tagListRi }, + { panasonicIfdId, "Makernote", "Panasonic", PanasonicMakerNote::tagList }, + { panaRawIfdId, "PanaRaw", "PanasonicRaw", PanasonicMakerNote::tagListRaw }, + { pentaxIfdId, "Makernote", "Pentax", PentaxMakerNote::tagList }, + { sigmaIfdId, "Makernote", "Sigma", SigmaMakerNote::tagList }, + { sony1IfdId, "Makernote", "Sony1", SonyMakerNote::tagList }, + { sony2IfdId, "Makernote", "Sony2", SonyMakerNote::tagList }, + { sonyMltIfdId, "Makernote", "SonyMinolta", MinoltaMakerNote::tagList }, + { sony1CsIfdId, "Makernote", "Sony1Cs", SonyMakerNote::tagListCs }, + { sony1Cs2IfdId, "Makernote", "Sony1Cs2", SonyMakerNote::tagListCs2 }, + { sony1MltCs7DIfdId, "Makernote", "Sony1MltCs7D", MinoltaMakerNote::tagListCs7D }, + { sony1MltCsOldIfdId,"Makernote", "Sony1MltCsOld",MinoltaMakerNote::tagListCsStd }, + { sony1MltCsNewIfdId,"Makernote", "Sony1MltCsNew",MinoltaMakerNote::tagListCsStd }, + { sony1MltCsA100IfdId,"Makernote","Sony1MltCsA100",MinoltaMakerNote::tagListCsA100}, + { sony2CsIfdId, "Makernote", "Sony2Cs", SonyMakerNote::tagListCs }, + { sony2Cs2IfdId, "Makernote", "Sony2Cs2", SonyMakerNote::tagListCs2 }, + { lastIfdId, "(Last IFD info)", "(Last IFD item)", 0 } + }; + + const SectionInfo ExifTags::sectionInfo_[] = { + { sectionIdNotSet, "(UnknownSection)", N_("Unknown section") }, + { imgStruct, "ImageStructure", N_("Image data structure") }, + { recOffset, "RecordingOffset", N_("Recording offset") }, + { imgCharacter, "ImageCharacteristics", N_("Image data characteristics") }, + { otherTags, "OtherTags", N_("Other data") }, + { exifFormat, "ExifFormat", N_("Exif data structure") }, + { exifVersion, "ExifVersion", N_("Exif version") }, + { imgConfig, "ImageConfig", N_("Image configuration") }, + { userInfo, "UserInfo", N_("User information") }, + { relatedFile, "RelatedFile", N_("Related file") }, + { dateTime, "DateTime", N_("Date and time") }, + { captureCond, "CaptureConditions", N_("Picture taking conditions") }, + { gpsTags, "GPS", N_("GPS information") }, + { iopTags, "Interoperability", N_("Interoperability information") }, + { makerTags, "Makernote", N_("Vendor specific information") }, + { dngTags, "DngTags", N_("Adobe DNG tags") }, + { panaRaw, "PanasonicRaw", N_("Panasonic RAW tags") }, + { tiffEp, "TIFF/EP", N_("TIFF/EP tags") }, + { tiffPm6, "TIFF&PM6", N_("TIFF PageMaker 6.0 tags") }, + { adobeOpi, "AdobeOPI", N_("Adobe OPI tags") }, + { lastSectionId, "(LastSection)", N_("Last section") } + }; + + TagInfo::TagInfo( + uint16_t tag, + const char* name, + const char* title, + const char* desc, + IfdId ifdId, + SectionId sectionId, + TypeId typeId, + PrintFct printFct + ) + : tag_(tag), name_(name), title_(title), desc_(desc), ifdId_(ifdId), + sectionId_(sectionId), typeId_(typeId), printFct_(printFct) + { + } + + const TagInfo* ExifTags::ifdTagList() + { + return ifdTagInfo; + } + + const TagInfo* ExifTags::exifTagList() + { + return exifTagInfo; + } + + const TagInfo* ExifTags::gpsTagList() + { + return gpsTagInfo; + } + + const TagInfo* ExifTags::iopTagList() + { + return iopTagInfo; + } + + const TagInfo* ExifTags::mnTagList() + { + return mnTagInfo; + } + + const TagInfo* ExifTags::tagList(const std::string& group) + { + const IfdInfo* ii = find(ifdInfo_, IfdInfo::Item(group)); + if (ii == 0 || ii->tagList_ == 0) return 0; + return ii->tagList_(); + } // ExifTags::tagList + + const TagInfo* ExifTags::tagList(IfdId ifdId) + { + const IfdInfo* ii = find(ifdInfo_, ifdId); + if (ii == 0 || ii->tagList_ == 0) return 0; + return ii->tagList_(); + } // ExifTags::tagList + + const TagInfo* ExifTags::tagInfo(uint16_t tag, IfdId ifdId) + { + const TagInfo* ti = tagList(ifdId); + if (ti == 0) return 0; + for (int idx = 0; ti[idx].tag_ != 0xffff; ++idx) { + if (ti[idx].tag_ == tag) return &ti[idx]; + } + return 0; + } // ExifTags::tagInfo + + const TagInfo* ExifTags::tagInfo(const std::string& tagName, IfdId ifdId) + { + const TagInfo* ti = tagList(ifdId); + if (ti == 0) return 0; + const char* tn = tagName.c_str(); + if (tn == 0) return 0; + for (int idx = 0; ti[idx].tag_ != 0xffff; ++idx) { + if (0 == strcmp(ti[idx].name_, tn)) { + return &ti[idx]; + } + } + return 0; + } // ExifTags::tagInfo + + bool ExifTags::isMakerIfd(IfdId ifdId) + { + bool rc = false; + const IfdInfo* ii = find(ifdInfo_, ifdId); + if (ii != 0 && 0 == strcmp(ii->name_, "Makernote")) { + rc = true; + } + return rc; + } // ExifTags::isMakerIfd + + bool ExifTags::isExifIfd(IfdId ifdId) + { + bool rc; + switch (ifdId) { + case ifd0Id: + case exifIfdId: + case gpsIfdId: + case iopIfdId: + case ifd1Id: + case ifd2Id: + case ifd3Id: + case subImage1Id: + case subImage2Id: + case subImage3Id: + case subImage4Id: + case subImage5Id: + case subImage6Id: + case subImage7Id: + case subImage8Id: + case subImage9Id: + case panaRawIfdId: rc = true; break; + default: rc = false; break; + } + return rc; + } // ExifTags::isExifIfd + + std::string ExifTags::tagName(uint16_t tag, IfdId ifdId) + { + const TagInfo* ti = tagInfo(tag, ifdId); + if (ti != 0) return ti->name_; + std::ostringstream os; + os << "0x" << std::setw(4) << std::setfill('0') << std::right + << std::hex << tag; + return os.str(); + } // ExifTags::tagName + + const char* ExifTags::tagTitle(uint16_t tag, IfdId ifdId) + { + return tagLabel(tag, ifdId); + } // ExifTags::tagTitle + + const char* ExifTags::tagLabel(uint16_t tag, IfdId ifdId) + { + const TagInfo* ti = tagInfo(tag, ifdId); + if (ti == 0) return ""; + return _(ti->title_); + } // ExifTags::tagLabel + + const char* ExifTags::tagDesc(uint16_t tag, IfdId ifdId) + { + const TagInfo* ti = tagInfo(tag, ifdId); + if (ti == 0) return ""; + return _(ti->desc_); + } // ExifTags::tagDesc + + TypeId ExifTags::tagType(uint16_t tag, IfdId ifdId) + { + const TagInfo* ti = tagInfo(tag, ifdId); + if (ti == 0) return unknownTag.typeId_; + return ti->typeId_; + } // ExifTags::tagType + + uint16_t ExifTags::tag(const std::string& tagName, IfdId ifdId) + { + const TagInfo* ti = tagInfo(tagName, ifdId); + if (ti != 0) return ti->tag_; + if (!isHex(tagName, 4, "0x")) throw Error(7, tagName, ifdId); + std::istringstream is(tagName); + uint16_t tag; + is >> std::hex >> tag; + return tag; + } // ExifTags::tag + + IfdId ExifTags::ifdIdByIfdItem(const std::string& ifdItem) + { + IfdId ifdId = ifdIdNotSet; + const IfdInfo* ii = find(ifdInfo_, IfdInfo::Item(ifdItem)); + if (ii != 0) ifdId = ii->ifdId_; + return ifdId; + } + + const char* ExifTags::sectionName(uint16_t tag, IfdId ifdId) + { + const TagInfo* ti = tagInfo(tag, ifdId); + if (ti == 0) return sectionInfo_[unknownTag.sectionId_].name_; + return sectionInfo_[ti->sectionId_].name_; + } // ExifTags::sectionName + + const char* ExifTags::sectionDesc(uint16_t tag, IfdId ifdId) + { + const TagInfo* ti = tagInfo(tag, ifdId); + if (ti == 0) return _(sectionInfo_[unknownTag.sectionId_].desc_); + return _(sectionInfo_[ti->sectionId_].desc_); + } // ExifTags::sectionDesc + + const char* ExifTags::ifdName(IfdId ifdId) + { + const IfdInfo* ii = find(ifdInfo_, ifdId); + if (ii == 0) return ifdInfo_[0].name_; + return ii->name_; + } // ExifTags::ifdName + + const char* ExifTags::ifdItem(IfdId ifdId) + { + const IfdInfo* ii = find(ifdInfo_, ifdId); + if (ii == 0) return ifdInfo_[0].item_; + return ii->item_; + } // ExifTags::ifdItem + + const char* ExifTags::sectionName(SectionId sectionId) + { + return sectionInfo_[sectionId].name_; + } // ExifTags::sectionName + + SectionId ExifTags::sectionId(const std::string& sectionName) + { + int i; + for (i = int(lastSectionId) - 1; i > 0; --i) { + if (sectionInfo_[i].name_ == sectionName) break; + } + return SectionId(i); + } // ExifTags::sectionId + + std::ostream& ExifTags::printTag(std::ostream& os, + uint16_t tag, + IfdId ifdId, + const Value& value, + const ExifData* pExifData) + { + if (value.count() == 0) return os; + PrintFct fct = printValue; + const TagInfo* ti = tagInfo(tag, ifdId); + if (ti != 0) fct = ti->printFct_; + return fct(os, value, pExifData); + } // ExifTags::printTag + + void ExifTags::taglist(std::ostream& os) + { + for (int i=0; ifdTagInfo[i].tag_ != 0xffff; ++i) { + os << ifdTagInfo[i] << "\n"; + } + for (int i=0; exifTagInfo[i].tag_ != 0xffff; ++i) { + os << exifTagInfo[i] << "\n"; + } + for (int i=0; iopTagInfo[i].tag_ != 0xffff; ++i) { + os << iopTagInfo[i] << "\n"; + } + for (int i=0; gpsTagInfo[i].tag_ != 0xffff; ++i) { + os << gpsTagInfo[i] << "\n"; + } + } // ExifTags::taglist + + void ExifTags::taglist(std::ostream& os, IfdId ifdId) + { + const TagInfo* ti = tagList(ifdId); + if (ti != 0) { + for (int k = 0; ti[k].tag_ != 0xffff; ++k) { + os << ti[k] << "\n"; + } + } + } // ExifTags::taglist + + const char* ExifKey::familyName_ = "Exif"; + + ExifKey::ExifKey(const std::string& key) + : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""), + idx_(0), key_(key) + { + decomposeKey(); + } + + ExifKey::ExifKey(uint16_t tag, const std::string& ifdItem) + : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""), + idx_(0), key_("") + { + IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); + if (!ExifTags::isExifIfd(ifdId) && !ExifTags::isMakerIfd(ifdId)) { + throw Error(23, ifdId); + } + tag_ = tag; + ifdId_ = ifdId; + ifdItem_ = ifdItem; + makeKey(); + } + + ExifKey::ExifKey(const ExifKey& rhs) + : Key(rhs), tag_(rhs.tag_), ifdId_(rhs.ifdId_), ifdItem_(rhs.ifdItem_), + idx_(rhs.idx_), key_(rhs.key_) + { + } + + ExifKey::~ExifKey() + { + } + + ExifKey& ExifKey::operator=(const ExifKey& rhs) + { + if (this == &rhs) return *this; + Key::operator=(rhs); + tag_ = rhs.tag_; + ifdId_ = rhs.ifdId_; + ifdItem_ = rhs.ifdItem_; + idx_ = rhs.idx_; + key_ = rhs.key_; + return *this; + } + + void ExifKey::setIdx(int idx) + { + idx_ = idx; + } + + std::string ExifKey::key() const + { + return key_; + } + + const char* ExifKey::familyName() const + { + return familyName_; + } + + std::string ExifKey::groupName() const + { + return ifdItem(); + } + + std::string ExifKey::tagName() const + { + return ExifTags::tagName(tag_, ifdId_); + } + + std::string ExifKey::tagLabel() const + { + return ExifTags::tagLabel(tag_, ifdId_); + } + + uint16_t ExifKey::tag() const + { + return tag_; + } + + ExifKey::AutoPtr ExifKey::clone() const + { + return AutoPtr(clone_()); + } + + ExifKey* ExifKey::clone_() const + { + return new ExifKey(*this); + } + + std::string ExifKey::sectionName() const + { + return ExifTags::sectionName(tag(), ifdId()); + } + + void ExifKey::decomposeKey() + { + // Get the family name, IFD name and tag name parts of the key + std::string::size_type pos1 = key_.find('.'); + if (pos1 == std::string::npos) throw Error(6, key_); + std::string familyName = key_.substr(0, pos1); + if (0 != strcmp(familyName.c_str(), familyName_)) { + throw Error(6, key_); + } + std::string::size_type pos0 = pos1 + 1; + pos1 = key_.find('.', pos0); + if (pos1 == std::string::npos) throw Error(6, key_); + std::string ifdItem = key_.substr(pos0, pos1 - pos0); + if (ifdItem == "") throw Error(6, key_); + std::string tagName = key_.substr(pos1 + 1); + if (tagName == "") throw Error(6, key_); + + // Find IfdId + IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); + if (ifdId == ifdIdNotSet) throw Error(6, key_); + if (!ExifTags::isExifIfd(ifdId) && !ExifTags::isMakerIfd(ifdId)) { + throw Error(6, key_); + } + // Convert tag + uint16_t tag = ExifTags::tag(tagName, ifdId); + + // Translate hex tag name (0xabcd) to a real tag name if there is one + tagName = ExifTags::tagName(tag, ifdId); + + tag_ = tag; + ifdId_ = ifdId; + ifdItem_ = ifdItem; + key_ = familyName + "." + ifdItem + "." + tagName; + } + + void ExifKey::makeKey() + { + key_ = std::string(familyName_) + + "." + ifdItem_ + + "." + ExifTags::tagName(tag_, ifdId_); + } + + // ************************************************************************* + // free functions + + std::ostream& operator<<(std::ostream& os, const TagInfo& ti) + { + ExifKey exifKey(ti.tag_, ExifTags::ifdItem(ti.ifdId_)); + return os << ExifTags::tagName(ti.tag_, ti.ifdId_) << ",\t" + << std::dec << ti.tag_ << ",\t" + << "0x" << std::setw(4) << std::setfill('0') + << std::right << std::hex << ti.tag_ << ",\t" + << ExifTags::ifdName(ti.ifdId_) << ",\t" + << exifKey.key() << ",\t" + << TypeInfo::typeName( + ExifTags::tagType(ti.tag_, ti.ifdId_)) << ",\t" + << ExifTags::tagDesc(ti.tag_, ti.ifdId_); + } + } // namespace Exiv2 namespace { diff --git a/src/tags.hpp b/src/tags.hpp index 9e857a8a..1d4539df 100644 --- a/src/tags.hpp +++ b/src/tags.hpp @@ -34,12 +34,10 @@ // included header files #include "metadatum.hpp" #include "types.hpp" -#include "value.hpp" // + standard includes #include -#include // for std::pair -#include +#include #include // ***************************************************************************** @@ -120,118 +118,6 @@ namespace Exiv2 { PrintFct printFct_; //!< Pointer to tag print function }; // struct TagInfo - /*! - @brief Helper structure for lookup tables for translations of numeric - tag values to human readable labels. - */ - struct EXIV2API TagDetails { - long val_; //!< Tag value - const char* label_; //!< Translation of the tag value - - //! Comparison operator for use with the find template - bool operator==(long key) const { return val_ == key; } - }; // struct TagDetails - - /*! - @brief Helper structure for lookup tables for translations of bitmask - values to human readable labels. - */ - struct EXIV2API TagDetailsBitmask { - uint32_t mask_; //!< Bitmask value - const char* label_; //!< Description of the tag value - }; // struct TagDetailsBitmask - - /*! - @brief Helper structure for lookup tables for translations of controlled - vocabulary strings to their descriptions. - */ - struct EXIV2API TagVocabulary { - const char* voc_; //!< Vocabulary string - const char* label_; //!< Description of the vocabulary string - - /*! - @brief Comparison operator for use with the find template - - Compare vocabulary strings like "PR-NON" with keys like - "http://ns.useplus.org/ldf/vocab/PR-NON" and return true if the vocabulary - string matches the end of the key. - */ - bool operator==(const std::string& key) const; - }; // struct TagDetails - - /*! - @brief Generic pretty-print function to translate a long value to a description - by looking up a reference table. - */ - template - std::ostream& printTag(std::ostream& os, const Value& value, const ExifData*) - { - const TagDetails* td = find(array, value.toLong()); - if (td) { - os << exvGettext(td->label_); - } - else { - os << "(" << value << ")"; - } - return os; - } - -//! Shortcut for the printTag template which requires typing the array name only once. -#define EXV_PRINT_TAG(array) printTag - - /*! - @brief Generic print function to translate a long value to a description - by looking up bitmasks in a reference table. - */ - template - std::ostream& printTagBitmask(std::ostream& os, const Value& value, const ExifData*) - { - const uint32_t val = static_cast(value.toLong()); - if (val == 0 && N > 0) { - const TagDetailsBitmask* td = *(&array); - if (td->mask_ == 0) return os << exvGettext(td->label_); - } - bool sep = false; - for (int i = 0; i < N; ++i) { - // *& acrobatics is a workaround for a MSVC 7.1 bug - const TagDetailsBitmask* td = *(&array) + i; - - if (val & td->mask_) { - if (sep) { - os << ", " << exvGettext(td->label_); - } - else { - os << exvGettext(td->label_); - sep = true; - } - } - } - return os; - } - -//! Shortcut for the printTagBitmask template which requires typing the array name only once. -#define EXV_PRINT_TAG_BITMASK(array) printTagBitmask - - /*! - @brief Generic pretty-print function to translate a controlled vocabulary value (string) - to a description by looking up a reference table. - */ - template - std::ostream& printTagVocabulary(std::ostream& os, const Value& value, const ExifData*) - { - const TagVocabulary* td = find(array, value.toString()); - if (td) { - os << exvGettext(td->label_); - } - else { - os << "(" << value << ")"; - } - return os; - } - -//! Shortcut for the printTagVocabulary template which requires typing the array name only once. -#define EXV_PRINT_VOCABULARY(array) printTagVocabulary - //! Exif tag reference, implemented as a static class. class EXIV2API ExifTags { //! Prevent construction: not implemented. @@ -471,114 +357,6 @@ namespace Exiv2 { //! Output operator for TagInfo EXIV2API std::ostream& operator<<(std::ostream& os, const TagInfo& ti); - //! @name Functions printing interpreted tag values - //@{ - //! Default print function, using the Value output operator - EXIV2API std::ostream& printValue(std::ostream& os, const Value& value, const ExifData*); - //! Print the value converted to a long - EXIV2API std::ostream& printLong(std::ostream& os, const Value& value, const ExifData*); - //! Print a Rational or URational value in floating point format - EXIV2API std::ostream& printFloat(std::ostream& os, const Value& value, const ExifData*); - //! Print a longitude or latitude value - EXIV2API std::ostream& printDegrees(std::ostream& os, const Value& value, const ExifData*); - //! Print function converting from UCS-2LE to UTF-8 - EXIV2API std::ostream& printUcs2(std::ostream& os, const Value& value, const ExifData*); - //! Print function for Exif units - EXIV2API std::ostream& printExifUnit(std::ostream& os, const Value& value, const ExifData*); - //! Print GPS version - EXIV2API std::ostream& print0x0000(std::ostream& os, const Value& value, const ExifData*); - //! Print GPS altitude ref - EXIV2API std::ostream& print0x0005(std::ostream& os, const Value& value, const ExifData*); - //! Print GPS altitude - EXIV2API std::ostream& print0x0006(std::ostream& os, const Value& value, const ExifData*); - //! Print GPS timestamp - EXIV2API std::ostream& print0x0007(std::ostream& os, const Value& value, const ExifData*); - //! Print GPS status - EXIV2API std::ostream& print0x0009(std::ostream& os, const Value& value, const ExifData*); - //! Print GPS measurement mode - EXIV2API std::ostream& print0x000a(std::ostream& os, const Value& value, const ExifData*); - //! Print GPS speed ref - EXIV2API std::ostream& print0x000c(std::ostream& os, const Value& value, const ExifData*); - //! Print GPS destination distance ref - EXIV2API std::ostream& print0x0019(std::ostream& os, const Value& value, const ExifData*); - //! Print GPS differential correction - EXIV2API std::ostream& print0x001e(std::ostream& os, const Value& value, const ExifData*); - //! Print orientation - EXIV2API std::ostream& print0x0112(std::ostream& os, const Value& value, const ExifData*); - //! Print YCbCrPositioning - EXIV2API std::ostream& print0x0213(std::ostream& os, const Value& value, const ExifData*); - //! Print the copyright - EXIV2API std::ostream& print0x8298(std::ostream& os, const Value& value, const ExifData*); - //! Print the exposure time - EXIV2API std::ostream& print0x829a(std::ostream& os, const Value& value, const ExifData*); - //! Print the f-number - EXIV2API std::ostream& print0x829d(std::ostream& os, const Value& value, const ExifData*); - //! Print exposure program - EXIV2API std::ostream& print0x8822(std::ostream& os, const Value& value, const ExifData*); - //! Print ISO speed ratings - EXIV2API std::ostream& print0x8827(std::ostream& os, const Value& value, const ExifData*); - //! Print components configuration specific to compressed data - EXIV2API std::ostream& print0x9101(std::ostream& os, const Value& value, const ExifData*); - //! Print exposure time converted from APEX shutter speed value - EXIV2API std::ostream& print0x9201(std::ostream& os, const Value& value, const ExifData*); - //! Print f-number converted from APEX aperture value - EXIV2API std::ostream& print0x9202(std::ostream& os, const Value& value, const ExifData*); - //! Print the exposure bias value - EXIV2API std::ostream& print0x9204(std::ostream& os, const Value& value, const ExifData*); - //! Print the subject distance - EXIV2API std::ostream& print0x9206(std::ostream& os, const Value& value, const ExifData*); - //! Print metering mode - EXIV2API std::ostream& print0x9207(std::ostream& os, const Value& value, const ExifData*); - //! Print light source - EXIV2API std::ostream& print0x9208(std::ostream& os, const Value& value, const ExifData*); - //! Print the actual focal length of the lens - EXIV2API std::ostream& print0x920a(std::ostream& os, const Value& value, const ExifData*); - //! Print the user comment - EXIV2API std::ostream& print0x9286(std::ostream& os, const Value& value, const ExifData*); - //! Print color space - EXIV2API std::ostream& print0xa001(std::ostream& os, const Value& value, const ExifData*); - //! Print sensing method - EXIV2API std::ostream& print0xa217(std::ostream& os, const Value& value, const ExifData*); - //! Print file source - EXIV2API std::ostream& print0xa300(std::ostream& os, const Value& value, const ExifData*); - //! Print scene type - EXIV2API std::ostream& print0xa301(std::ostream& os, const Value& value, const ExifData*); - //! Print custom rendered - EXIV2API std::ostream& print0xa401(std::ostream& os, const Value& value, const ExifData*); - //! Print exposure mode - EXIV2API std::ostream& print0xa402(std::ostream& os, const Value& value, const ExifData*); - //! Print white balance - EXIV2API std::ostream& print0xa403(std::ostream& os, const Value& value, const ExifData*); - //! Print digital zoom ratio - EXIV2API std::ostream& print0xa404(std::ostream& os, const Value& value, const ExifData*); - //! Print 35mm equivalent focal length - EXIV2API std::ostream& print0xa405(std::ostream& os, const Value& value, const ExifData*); - //! Print scene capture type - EXIV2API std::ostream& print0xa406(std::ostream& os, const Value& value, const ExifData*); - //! Print gain control - EXIV2API std::ostream& print0xa407(std::ostream& os, const Value& value, const ExifData*); - //! Print saturation - EXIV2API std::ostream& print0xa409(std::ostream& os, const Value& value, const ExifData*); - //! Print subject distance range - EXIV2API std::ostream& print0xa40c(std::ostream& os, const Value& value, const ExifData*); - //! Print GPS direction ref - EXIV2API std::ostream& printGPSDirRef(std::ostream& os, const Value& value, const ExifData*); - //! Print contrast, sharpness (normal, soft, hard) - EXIV2API std::ostream& printNormalSoftHard(std::ostream& os, const Value& value, const ExifData*); - //! Print any version packed in 4 Bytes format : major major minor minor - EXIV2API std::ostream& printExifVersion(std::ostream& os, const Value& value, const ExifData*); - //! Print any version encoded in the ASCII string majormajorminorminor - EXIV2API std::ostream& printXmpVersion(std::ostream& os, const Value& value, const ExifData*); - //! Print a date following the format YYYY-MM-DDTHH:MM:SSZ - EXIV2API std::ostream& printXmpDate(std::ostream& os, const Value& value, const ExifData*); - //@} - - //! Calculate F number from an APEX aperture value - EXIV2API float fnumber(float apertureValue); - - //! Calculate the exposure time from an APEX shutter speed value - EXIV2API URational exposureTime(float shutterSpeedValue); - } // namespace Exiv2 #endif // #ifndef TAGS_HPP_ diff --git a/src/tags_int.hpp b/src/tags_int.hpp new file mode 100644 index 00000000..67d61eff --- /dev/null +++ b/src/tags_int.hpp @@ -0,0 +1,278 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2004-2010 Andreas Huggel + * + * This program is part of the Exiv2 distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/*! + @file tags_int.hpp + @brief Internal Exif tag and type information + @version $Rev$ + @author Andreas Huggel (ahu) + ahuggel@gmx.net + @date 15-Jan-04, ahu: created
+ 11-Feb-04, ahu: isolated as a component + */ +#ifndef TAGS_INT_HPP_ +#define TAGS_INT_HPP_ + +// ***************************************************************************** +// included header files +#include "types.hpp" +#include "value.hpp" + +// + standard includes +#include +#include +#include + +// ***************************************************************************** +// namespace extensions +namespace Exiv2 { + class ExifData; + + namespace Internal { + +// ***************************************************************************** +// class definitions + + /*! + @brief Helper structure for lookup tables for translations of numeric + tag values to human readable labels. + */ + struct TagDetails { + long val_; //!< Tag value + const char* label_; //!< Translation of the tag value + + //! Comparison operator for use with the find template + bool operator==(long key) const { return val_ == key; } + }; // struct TagDetails + + /*! + @brief Helper structure for lookup tables for translations of bitmask + values to human readable labels. + */ + struct TagDetailsBitmask { + uint32_t mask_; //!< Bitmask value + const char* label_; //!< Description of the tag value + }; // struct TagDetailsBitmask + + /*! + @brief Helper structure for lookup tables for translations of controlled + vocabulary strings to their descriptions. + */ + struct TagVocabulary { + const char* voc_; //!< Vocabulary string + const char* label_; //!< Description of the vocabulary string + + /*! + @brief Comparison operator for use with the find template + + Compare vocabulary strings like "PR-NON" with keys like + "http://ns.useplus.org/ldf/vocab/PR-NON" and return true if the vocabulary + string matches the end of the key. + */ + bool operator==(const std::string& key) const; + }; // struct TagDetails + + /*! + @brief Generic pretty-print function to translate a long value to a description + by looking up a reference table. + */ + template + std::ostream& printTag(std::ostream& os, const Value& value, const ExifData*) + { + const TagDetails* td = find(array, value.toLong()); + if (td) { + os << exvGettext(td->label_); + } + else { + os << "(" << value << ")"; + } + return os; + } + +//! Shortcut for the printTag template which requires typing the array name only once. +#define EXV_PRINT_TAG(array) printTag + + /*! + @brief Generic print function to translate a long value to a description + by looking up bitmasks in a reference table. + */ + template + std::ostream& printTagBitmask(std::ostream& os, const Value& value, const ExifData*) + { + const uint32_t val = static_cast(value.toLong()); + if (val == 0 && N > 0) { + const TagDetailsBitmask* td = *(&array); + if (td->mask_ == 0) return os << exvGettext(td->label_); + } + bool sep = false; + for (int i = 0; i < N; ++i) { + // *& acrobatics is a workaround for a MSVC 7.1 bug + const TagDetailsBitmask* td = *(&array) + i; + + if (val & td->mask_) { + if (sep) { + os << ", " << exvGettext(td->label_); + } + else { + os << exvGettext(td->label_); + sep = true; + } + } + } + return os; + } + +//! Shortcut for the printTagBitmask template which requires typing the array name only once. +#define EXV_PRINT_TAG_BITMASK(array) printTagBitmask + + /*! + @brief Generic pretty-print function to translate a controlled vocabulary value (string) + to a description by looking up a reference table. + */ + template + std::ostream& printTagVocabulary(std::ostream& os, const Value& value, const ExifData*) + { + const TagVocabulary* td = find(array, value.toString()); + if (td) { + os << exvGettext(td->label_); + } + else { + os << "(" << value << ")"; + } + return os; + } + +//! Shortcut for the printTagVocabulary template which requires typing the array name only once. +#define EXV_PRINT_VOCABULARY(array) printTagVocabulary + +// ***************************************************************************** +// free functions + + //! @name Functions printing interpreted tag values + //@{ + //! Default print function, using the Value output operator + std::ostream& printValue(std::ostream& os, const Value& value, const ExifData*); + //! Print the value converted to a long + std::ostream& printLong(std::ostream& os, const Value& value, const ExifData*); + //! Print a Rational or URational value in floating point format + std::ostream& printFloat(std::ostream& os, const Value& value, const ExifData*); + //! Print a longitude or latitude value + std::ostream& printDegrees(std::ostream& os, const Value& value, const ExifData*); + //! Print function converting from UCS-2LE to UTF-8 + std::ostream& printUcs2(std::ostream& os, const Value& value, const ExifData*); + //! Print function for Exif units + std::ostream& printExifUnit(std::ostream& os, const Value& value, const ExifData*); + //! Print GPS version + std::ostream& print0x0000(std::ostream& os, const Value& value, const ExifData*); + //! Print GPS altitude ref + std::ostream& print0x0005(std::ostream& os, const Value& value, const ExifData*); + //! Print GPS altitude + std::ostream& print0x0006(std::ostream& os, const Value& value, const ExifData*); + //! Print GPS timestamp + std::ostream& print0x0007(std::ostream& os, const Value& value, const ExifData*); + //! Print GPS status + std::ostream& print0x0009(std::ostream& os, const Value& value, const ExifData*); + //! Print GPS measurement mode + std::ostream& print0x000a(std::ostream& os, const Value& value, const ExifData*); + //! Print GPS speed ref + std::ostream& print0x000c(std::ostream& os, const Value& value, const ExifData*); + //! Print GPS destination distance ref + std::ostream& print0x0019(std::ostream& os, const Value& value, const ExifData*); + //! Print GPS differential correction + std::ostream& print0x001e(std::ostream& os, const Value& value, const ExifData*); + //! Print orientation + std::ostream& print0x0112(std::ostream& os, const Value& value, const ExifData*); + //! Print YCbCrPositioning + std::ostream& print0x0213(std::ostream& os, const Value& value, const ExifData*); + //! Print the copyright + std::ostream& print0x8298(std::ostream& os, const Value& value, const ExifData*); + //! Print the exposure time + std::ostream& print0x829a(std::ostream& os, const Value& value, const ExifData*); + //! Print the f-number + std::ostream& print0x829d(std::ostream& os, const Value& value, const ExifData*); + //! Print exposure program + std::ostream& print0x8822(std::ostream& os, const Value& value, const ExifData*); + //! Print ISO speed ratings + std::ostream& print0x8827(std::ostream& os, const Value& value, const ExifData*); + //! Print components configuration specific to compressed data + std::ostream& print0x9101(std::ostream& os, const Value& value, const ExifData*); + //! Print exposure time converted from APEX shutter speed value + std::ostream& print0x9201(std::ostream& os, const Value& value, const ExifData*); + //! Print f-number converted from APEX aperture value + std::ostream& print0x9202(std::ostream& os, const Value& value, const ExifData*); + //! Print the exposure bias value + std::ostream& print0x9204(std::ostream& os, const Value& value, const ExifData*); + //! Print the subject distance + std::ostream& print0x9206(std::ostream& os, const Value& value, const ExifData*); + //! Print metering mode + std::ostream& print0x9207(std::ostream& os, const Value& value, const ExifData*); + //! Print light source + std::ostream& print0x9208(std::ostream& os, const Value& value, const ExifData*); + //! Print the actual focal length of the lens + std::ostream& print0x920a(std::ostream& os, const Value& value, const ExifData*); + //! Print the user comment + std::ostream& print0x9286(std::ostream& os, const Value& value, const ExifData*); + //! Print color space + std::ostream& print0xa001(std::ostream& os, const Value& value, const ExifData*); + //! Print sensing method + std::ostream& print0xa217(std::ostream& os, const Value& value, const ExifData*); + //! Print file source + std::ostream& print0xa300(std::ostream& os, const Value& value, const ExifData*); + //! Print scene type + std::ostream& print0xa301(std::ostream& os, const Value& value, const ExifData*); + //! Print custom rendered + std::ostream& print0xa401(std::ostream& os, const Value& value, const ExifData*); + //! Print exposure mode + std::ostream& print0xa402(std::ostream& os, const Value& value, const ExifData*); + //! Print white balance + std::ostream& print0xa403(std::ostream& os, const Value& value, const ExifData*); + //! Print digital zoom ratio + std::ostream& print0xa404(std::ostream& os, const Value& value, const ExifData*); + //! Print 35mm equivalent focal length + std::ostream& print0xa405(std::ostream& os, const Value& value, const ExifData*); + //! Print scene capture type + std::ostream& print0xa406(std::ostream& os, const Value& value, const ExifData*); + //! Print gain control + std::ostream& print0xa407(std::ostream& os, const Value& value, const ExifData*); + //! Print saturation + std::ostream& print0xa409(std::ostream& os, const Value& value, const ExifData*); + //! Print subject distance range + std::ostream& print0xa40c(std::ostream& os, const Value& value, const ExifData*); + //! Print GPS direction ref + std::ostream& printGPSDirRef(std::ostream& os, const Value& value, const ExifData*); + //! Print contrast, sharpness (normal, soft, hard) + std::ostream& printNormalSoftHard(std::ostream& os, const Value& value, const ExifData*); + //! Print any version packed in 4 Bytes format : major major minor minor + std::ostream& printExifVersion(std::ostream& os, const Value& value, const ExifData*); + //! Print any version encoded in the ASCII string majormajorminorminor + std::ostream& printXmpVersion(std::ostream& os, const Value& value, const ExifData*); + //! Print a date following the format YYYY-MM-DDTHH:MM:SSZ + std::ostream& printXmpDate(std::ostream& os, const Value& value, const ExifData*); + //@} + + //! Calculate F number from an APEX aperture value + float fnumber(float apertureValue); + + //! Calculate the exposure time from an APEX shutter speed value + URational exposureTime(float shutterSpeedValue); + +}} // namespace Internal, Exiv2 + +#endif // #ifndef TAGS_INT_HPP_ diff --git a/src/types.cpp b/src/types.cpp index e037d11b..75975291 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -177,6 +177,38 @@ namespace Exiv2 { // ************************************************************************* // free functions + std::ostream& operator<<(std::ostream& os, const Rational& r) + { + return os << r.first << "/" << r.second; + } + + std::istream& operator>>(std::istream& is, Rational& r) + { + int32_t nominator; + int32_t denominator; + char c('\0'); + is >> nominator >> c >> denominator; + if (c != '/') is.setstate(std::ios::failbit); + if (is) r = std::make_pair(nominator, denominator); + return is; + } + + std::ostream& operator<<(std::ostream& os, const URational& r) + { + return os << r.first << "/" << r.second; + } + + std::istream& operator>>(std::istream& is, URational& r) + { + uint32_t nominator; + uint32_t denominator; + char c('\0'); + is >> nominator >> c >> denominator; + if (c != '/') is.setstate(std::ios::failbit); + if (is) r = std::make_pair(nominator, denominator); + return is; + } + uint16_t getUShort(const byte* buf, ByteOrder byteOrder) { if (byteOrder == littleEndian) { @@ -241,8 +273,12 @@ namespace Exiv2 { // type is the 4-byte IEEE 754 binary32 format, which is common but not // required by the C++ standard. assert(sizeof(float) == 4); - uint32_t ul = getULong(buf, byteOrder); - return *reinterpret_cast(&ul); + union { + uint32_t ul_; + float f_; + } u; + u.ul_ = getULong(buf, byteOrder); + return u.f_; } double getDouble(const byte* buf, ByteOrder byteOrder) @@ -251,28 +287,32 @@ namespace Exiv2 { // type is the 8-byte IEEE 754 binary64 format, which is common but not // required by the C++ standard. assert(sizeof(double) == 8); - uint64_t ull = 0; + union { + uint64_t ull_; + double d_; + } u; + u.ull_ = 0; if (byteOrder == littleEndian) { - ull = static_cast(buf[7]) << 56 - | static_cast(buf[6]) << 48 - | static_cast(buf[5]) << 40 - | static_cast(buf[4]) << 32 - | static_cast(buf[3]) << 24 - | static_cast(buf[2]) << 16 - | static_cast(buf[1]) << 8 - | static_cast(buf[0]); + u.ull_ = static_cast(buf[7]) << 56 + | static_cast(buf[6]) << 48 + | static_cast(buf[5]) << 40 + | static_cast(buf[4]) << 32 + | static_cast(buf[3]) << 24 + | static_cast(buf[2]) << 16 + | static_cast(buf[1]) << 8 + | static_cast(buf[0]); } else { - ull = static_cast(buf[0]) << 56 - | static_cast(buf[1]) << 48 - | static_cast(buf[2]) << 40 - | static_cast(buf[3]) << 32 - | static_cast(buf[4]) << 24 - | static_cast(buf[5]) << 16 - | static_cast(buf[6]) << 8 - | static_cast(buf[7]); + u.ull_ = static_cast(buf[0]) << 56 + | static_cast(buf[1]) << 48 + | static_cast(buf[2]) << 40 + | static_cast(buf[3]) << 32 + | static_cast(buf[4]) << 24 + | static_cast(buf[5]) << 16 + | static_cast(buf[6]) << 8 + | static_cast(buf[7]); } - return *reinterpret_cast(&ull); + return u.d_; } long us2Data(byte* buf, uint16_t s, ByteOrder byteOrder) @@ -355,8 +395,12 @@ namespace Exiv2 { // type is the 4-byte IEEE 754 binary32 format, which is common but not // required by the C++ standard. assert(sizeof(float) == 4); - uint32_t ul = *reinterpret_cast(&f); - return ul2Data(buf, ul, byteOrder); + union { + uint32_t ul_; + float f_; + } u; + u.f_ = f; + return ul2Data(buf, u.ul_, byteOrder); } long d2Data(byte* buf, double d, ByteOrder byteOrder) @@ -365,26 +409,31 @@ namespace Exiv2 { // type is the 8-byte IEEE 754 binary64 format, which is common but not // required by the C++ standard. assert(sizeof(double) == 8); - uint64_t ull = *reinterpret_cast(&d); + union { + uint64_t ull_; + double d_; + } u; + u.d_ = d; + uint64_t m = 0xff; if (byteOrder == littleEndian) { - buf[0] = (byte)(ull & 0x00000000000000ff); - buf[1] = (byte)((ull & 0x000000000000ff00) >> 8); - buf[2] = (byte)((ull & 0x0000000000ff0000) >> 16); - buf[3] = (byte)((ull & 0x00000000ff000000) >> 24); - buf[4] = (byte)((ull & 0x000000ff00000000) >> 32); - buf[5] = (byte)((ull & 0x0000ff0000000000) >> 40); - buf[6] = (byte)((ull & 0x00ff000000000000) >> 48); - buf[7] = (byte)((ull & 0xff00000000000000) >> 56); + buf[0] = (byte)(u.ull_ & m); + buf[1] = (byte)((u.ull_ & (m << 8)) >> 8); + buf[2] = (byte)((u.ull_ & (m << 16)) >> 16); + buf[3] = (byte)((u.ull_ & (m << 24)) >> 24); + buf[4] = (byte)((u.ull_ & (m << 32)) >> 32); + buf[5] = (byte)((u.ull_ & (m << 40)) >> 40); + buf[6] = (byte)((u.ull_ & (m << 48)) >> 48); + buf[7] = (byte)((u.ull_ & (m << 56)) >> 56); } else { - buf[0] = (byte)((ull & 0xff00000000000000) >> 56); - buf[1] = (byte)((ull & 0x00ff000000000000) >> 48); - buf[2] = (byte)((ull & 0x0000ff0000000000) >> 40); - buf[3] = (byte)((ull & 0x000000ff00000000) >> 32); - buf[4] = (byte)((ull & 0x00000000ff000000) >> 24); - buf[5] = (byte)((ull & 0x0000000000ff0000) >> 16); - buf[6] = (byte)((ull & 0x000000000000ff00) >> 8); - buf[7] = (byte)(ull & 0x00000000000000ff); + buf[0] = (byte)((u.ull_ & (m << 56)) >> 56); + buf[1] = (byte)((u.ull_ & (m << 48)) >> 48); + buf[2] = (byte)((u.ull_ & (m << 40)) >> 40); + buf[3] = (byte)((u.ull_ & (m << 32)) >> 32); + buf[4] = (byte)((u.ull_ & (m << 24)) >> 24); + buf[5] = (byte)((u.ull_ & (m << 16)) >> 16); + buf[6] = (byte)((u.ull_ & (m << 8)) >> 8); + buf[7] = (byte)(u.ull_ & m); } return 8; }