From 808494f0a12f871e4053d6e9da840302cbf91076 Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Mon, 2 Feb 2009 11:53:00 +0000 Subject: [PATCH] Refactored TiffCreator: simplified, fixed several todo's, laid the ground work for multiple TIFF tree structures. --- src/cr2image.cpp | 3 +- src/orfimage.cpp | 3 +- src/rw2image.cpp | 4 +- src/tiffcomposite.cpp | 116 ++++------ src/tiffcomposite_int.hpp | 122 +++++----- src/tifffwd_int.hpp | 16 +- src/tiffimage.cpp | 456 ++++++++++++++++++++++---------------- src/tiffimage_int.hpp | 78 ++++++- src/tiffparse.cpp | 7 +- src/tiffvisitor.cpp | 28 +-- src/tiffvisitor_int.hpp | 25 +-- 11 files changed, 453 insertions(+), 405 deletions(-) diff --git a/src/cr2image.cpp b/src/cr2image.cpp index e0122200..afe4c5ed 100644 --- a/src/cr2image.cpp +++ b/src/cr2image.cpp @@ -41,7 +41,6 @@ EXIV2_RCSID("@(#) $Id$") #include "cr2image_int.hpp" #include "tiffcomposite_int.hpp" #include "tiffimage_int.hpp" -#include "tiffvisitor_int.hpp" #include "image.hpp" #include "error.hpp" #include "futils.hpp" @@ -143,7 +142,7 @@ namespace Exiv2 { xmpData, pData, size, - TiffCreator::create, + Tag::root, TiffMapping::findDecoder, &cr2Header); } diff --git a/src/orfimage.cpp b/src/orfimage.cpp index b91ac8c7..1cca1c08 100644 --- a/src/orfimage.cpp +++ b/src/orfimage.cpp @@ -39,6 +39,7 @@ EXIV2_RCSID("@(#) $Id$") #include "orfimage.hpp" #include "orfimage_int.hpp" +#include "tiffcomposite_int.hpp" #include "tiffimage_int.hpp" #include "image.hpp" #include "basicio.hpp" @@ -141,7 +142,7 @@ namespace Exiv2 { xmpData, pData, size, - TiffCreator::create, + Tag::root, TiffMapping::findDecoder, &orfHeader); } diff --git a/src/rw2image.cpp b/src/rw2image.cpp index e3987f3a..bdec8ab7 100644 --- a/src/rw2image.cpp +++ b/src/rw2image.cpp @@ -39,6 +39,8 @@ EXIV2_RCSID("@(#) $Id$") #include "rw2image.hpp" #include "rw2image_int.hpp" +#include "tiffcomposite_int.hpp" +#include "tiffimage_int.hpp" #include "image.hpp" #include "error.hpp" #include "futils.hpp" @@ -138,7 +140,7 @@ namespace Exiv2 { xmpData, pData, size, - TiffCreator::create, + Tag::root, TiffMapping::findDecoder, &rw2Header); } diff --git a/src/tiffcomposite.cpp b/src/tiffcomposite.cpp index 6f4c3e4c..8e7a7049 100644 --- a/src/tiffcomposite.cpp +++ b/src/tiffcomposite.cpp @@ -36,6 +36,7 @@ EXIV2_RCSID("@(#) $Id$") # include "exv_conf.h" #endif +#include "tiffimage_int.hpp" #include "tiffcomposite_int.hpp" #include "tiffvisitor_int.hpp" #include "makernote_int.hpp" @@ -148,12 +149,6 @@ namespace Exiv2 { return gi->group_; } - bool TiffStructure::operator==(const TiffStructure::Key& key) const - { - return (Tag::all == extendedTag_ || key.e_ == extendedTag_) - && key.g_ == group_; - } - bool TiffMappingInfo::operator==(const TiffMappingInfo::Key& key) const { std::string make(make_); @@ -385,25 +380,23 @@ namespace Exiv2 { TiffComponent* TiffDirectory::doAddPath(uint16_t tag, TiffPath& tiffPath) { + assert(tiffPath.size() > 1); tiffPath.pop(); - assert(!tiffPath.empty()); - const TiffStructure* ts = tiffPath.top(); - assert(ts != 0); - // Prevent dangling subIFD tags: Do not add a subIFD tag if it has no child - if (tiffPath.size() == 1 && ts->newTiffCompFct_ == newTiffSubIfd) return 0; + const TiffPathItem tpi = tiffPath.top(); + TiffComponent* tc = 0; - // Allow duplicate entries but not for subIFDs and the MakerNote tag. So we - // only check if the new component already exists if there is still at least - // one composite tag on the stack, or it is a subIFD or the MakerNote tag. + // Try to use an existing component if there is still at least one + // composite tag on the stack or the tag to add is the MakerNote tag. + // This is used to prevent duplicate entries. SubIFDs also, but the > 1 + // condition takes care of them, see below. if ( tiffPath.size() > 1 - || ts->newTiffCompFct_ == newTiffSubIfd - || (ts->extendedTag_ == 0x927c && ts->group_ == Group::exif)) { - if (ts->extendedTag_ == Tag::next) { + || (tpi.extendedTag() == 0x927c && tpi.group() == Group::exif)) { + if (tpi.extendedTag() == Tag::next) { tc = pNext_; } else { for (Components::iterator i = components_.begin(); i != components_.end(); ++i) { - if ((*i)->tag() == ts->tag() && (*i)->group() == ts->group_) { + if ((*i)->tag() == tpi.tag() && (*i)->group() == tpi.group()) { tc = *i; break; } @@ -411,10 +404,14 @@ namespace Exiv2 { } } if (tc == 0) { - assert(ts->newTiffCompFct_ != 0); - uint16_t tg = tiffPath.size() == 1 ? tag : ts->tag(); - TiffComponent::AutoPtr atc(ts->newTiffCompFct_(tg, ts)); - if (ts->extendedTag_ == Tag::next) { + TiffComponent::AutoPtr atc = TiffCreator::create(tpi.extendedTag(), tpi.group()); + assert(atc.get() != 0); + + // Prevent dangling subIFD tags: Do not add a subIFD component without children. + // Todo: How to check before creating the component? + if (tiffPath.size() == 1 && dynamic_cast(atc.get()) != 0) return 0; + + if (tpi.extendedTag() == Tag::next) { tc = this->addNext(atc); } else { @@ -426,26 +423,25 @@ namespace Exiv2 { TiffComponent* TiffSubIfd::doAddPath(uint16_t tag, TiffPath& tiffPath) { - const TiffStructure* ts1 = tiffPath.top(); - assert(ts1 != 0); + assert(!tiffPath.empty()); + const TiffPathItem tpi1 = tiffPath.top(); tiffPath.pop(); if (tiffPath.empty()) { - // If the last element in the path is the sub-IFD tag itself we're done + // If the last element in the path is the sub-IFD tag itself we're done. + // But that shouldn't happen - see TiffDirectory::doAddPath return this; } - const TiffStructure* ts2 = tiffPath.top(); - assert(ts2 != 0); - tiffPath.push(ts1); - uint16_t dt = ts1->tag(); + const TiffPathItem tpi2 = tiffPath.top(); + tiffPath.push(tpi1); TiffComponent* tc = 0; for (Ifds::iterator i = ifds_.begin(); i != ifds_.end(); ++i) { - if ((*i)->group() == ts2->group_) { + if ((*i)->group() == tpi2.group()) { tc = *i; break; } } if (tc == 0) { - TiffComponent::AutoPtr atc(new TiffDirectory(dt, ts2->group_)); + TiffComponent::AutoPtr atc(new TiffDirectory(tpi1.tag(), tpi2.group())); tc = addChild(atc); setCount(static_cast(ifds_.size())); } @@ -454,19 +450,18 @@ namespace Exiv2 { TiffComponent* TiffMnEntry::doAddPath(uint16_t tag, TiffPath& tiffPath) { - const TiffStructure* ts1 = tiffPath.top(); - assert(ts1 != 0); + assert(!tiffPath.empty()); + const TiffPathItem tpi1 = tiffPath.top(); tiffPath.pop(); if (tiffPath.empty()) { // If the last element in the path is the makernote tag itself we're done return this; } - const TiffStructure* ts2 = tiffPath.top(); - assert(ts2 != 0); - tiffPath.push(ts1); + const TiffPathItem tpi2 = tiffPath.top(); + tiffPath.push(tpi1); if (mn_ == 0) { - mnGroup_ = ts2->group_; - mn_ = TiffMnCreator::create(ts1->tag(), ts1->group_, mnGroup_); + mnGroup_ = tpi2.group(); + mn_ = TiffMnCreator::create(tpi1.tag(), tpi1.group(), mnGroup_); assert(mn_); } return mn_->addPath(tag, tiffPath); @@ -474,26 +469,25 @@ namespace Exiv2 { TiffComponent* TiffArrayEntry::doAddPath(uint16_t tag, TiffPath& tiffPath) { + assert(tiffPath.size() > 1); tiffPath.pop(); - assert(!tiffPath.empty()); - const TiffStructure* ts = tiffPath.top(); - assert(ts != 0); + const TiffPathItem tpi = tiffPath.top(); TiffComponent* tc = 0; // To allow duplicate entries, we only check if the new component already // exists if there is still at least one composite tag on the stack if (tiffPath.size() > 1) { for (Components::iterator i = elements_.begin(); i != elements_.end(); ++i) { - if ((*i)->tag() == ts->tag() && (*i)->group() == ts->group_) { + if ((*i)->tag() == tpi.tag() && (*i)->group() == tpi.group()) { tc = *i; break; } } } if (tc == 0) { - assert(ts->newTiffCompFct_ != 0); - uint16_t tg = tiffPath.size() == 1 ? tag : ts->tag(); - TiffComponent::AutoPtr atc(ts->newTiffCompFct_(tg, ts)); - assert(ts->extendedTag_ != Tag::next); + TiffComponent::AutoPtr atc = TiffCreator::create(tpi.extendedTag(), tpi.group()); + assert(atc.get() != 0); + + assert(tpi.extendedTag() != Tag::next); tc = addChild(atc); setCount(static_cast(elements_.size())); } @@ -1419,36 +1413,14 @@ namespace Exiv2 { return lhs->idx() < rhs->idx(); } - TiffComponent::AutoPtr newTiffDirectory(uint16_t tag, - const TiffStructure* ts) + TiffComponent::AutoPtr newTiffEntry(uint16_t tag, uint16_t group) { - assert(ts); - return TiffComponent::AutoPtr(new TiffDirectory(tag, ts->newGroup_)); + return TiffComponent::AutoPtr(new TiffEntry(tag, group)); } - TiffComponent::AutoPtr newTiffEntry(uint16_t tag, - const TiffStructure* ts) + TiffComponent::AutoPtr newTiffMnEntry(uint16_t tag, uint16_t group) { - assert(ts); - return TiffComponent::AutoPtr(new TiffEntry(tag, ts->newGroup_)); - } - - TiffComponent::AutoPtr newTiffSubIfd(uint16_t tag, - const TiffStructure* ts) - { - assert(ts); - return TiffComponent::AutoPtr(new TiffSubIfd(tag, - ts->group_, - ts->newGroup_)); - } - - TiffComponent::AutoPtr newTiffMnEntry(uint16_t tag, - const TiffStructure* ts) - { - assert(ts); - return TiffComponent::AutoPtr(new TiffMnEntry(tag, - ts->group_, - ts->newGroup_)); + return TiffComponent::AutoPtr(new TiffMnEntry(tag, group, Group::mn)); } }} // namespace Internal, Exiv2 diff --git a/src/tiffcomposite_int.hpp b/src/tiffcomposite_int.hpp index b4ccf711..38c21066 100644 --- a/src/tiffcomposite_int.hpp +++ b/src/tiffcomposite_int.hpp @@ -105,6 +105,27 @@ namespace Exiv2 { const uint32_t next = 0x30000; //!< Special tag: next IFD const uint32_t all = 0x40000; //!< Special tag: all tags in a group } + + /*! + @brief A tupel consisting of extended Tag and group used as an item in + TIFF paths. + */ + class TiffPathItem { + public: + //! Constructor + TiffPathItem(uint32_t extendedTag, uint16_t group) + : extendedTag_(extendedTag), group_(group) {} + //! Return the tag corresponding to the extended tag + uint16_t tag() const { return static_cast(extendedTag_ & 0xffff); } + //! Return the extended tag (32 bit so that it can contain special tags) + uint32_t extendedTag() const { return extendedTag_; } + //! Return the group + uint16_t group() const { return group_; } + + private: + uint32_t extendedTag_; + uint16_t group_; + }; // class TiffPathItem /*! @brief Interface class for components of a TIFF directory hierarchy @@ -311,36 +332,6 @@ namespace Exiv2 { }; // class TiffComponent - /*! - @brief Data structure used as a row (element) of a table (array) - describing the TIFF structure of an image format for reading and - writing. Different tables can be used to support different TIFF - based image formats. - */ - struct TiffStructure { - struct Key; - //! Comparison operator to compare a TiffStructure with a TiffStructure::Key - bool operator==(const Key& key) const; - //! Return the tag corresponding to the extended tag - uint16_t tag() const { return static_cast(extendedTag_ & 0xffff); } - - // DATA - uint32_t extendedTag_; //!< Tag (32 bit so that it can contain special tags) - uint16_t group_; //!< Group that contains the tag - uint16_t newGroup_; //!< Group of the newly created component - uint32_t parentExtTag_; //!< Parent tag (32 bit so that it can contain special tags) - uint16_t parentGroup_; //!< Parent group - NewTiffCompFct newTiffCompFct_; //!< Function to create the correct TIFF component - }; - - //! Search key for TIFF structure. - struct TiffStructure::Key { - //! Constructor - Key(uint32_t e, uint16_t g) : e_(e), g_(g) {} - uint32_t e_; //!< Extended tag - uint16_t g_; //!< %Group - }; - //! TIFF mapping table for functions to decode special cases struct TiffMappingInfo { struct Key; @@ -1219,88 +1210,79 @@ namespace Exiv2 { //! Return the TIFF group id for a group name uint16_t tiffGroupId(const std::string& groupName); - //! Function to create and initialize a new TIFF directory - TiffComponent::AutoPtr newTiffDirectory(uint16_t tag, - const TiffStructure* ts); - //! Function to create and initialize a new TIFF entry - TiffComponent::AutoPtr newTiffEntry(uint16_t tag, - const TiffStructure* ts); - - //! Function to create and initialize a new TIFF sub-directory - TiffComponent::AutoPtr newTiffSubIfd(uint16_t tag, - const TiffStructure* ts); + TiffComponent::AutoPtr newTiffEntry(uint16_t tag, uint16_t group); //! Function to create and initialize a new TIFF makernote entry - TiffComponent::AutoPtr newTiffMnEntry(uint16_t tag, - const TiffStructure* ts); + TiffComponent::AutoPtr newTiffMnEntry(uint16_t tag, uint16_t group); + + //! Function to create and initialize a new TIFF directory + template + TiffComponent::AutoPtr newTiffDirectory(uint16_t tag, uint16_t /*group*/) + { + return TiffComponent::AutoPtr(new TiffDirectory(tag, newGroup)); + } + + //! Function to create and initialize a new TIFF sub-directory + template + TiffComponent::AutoPtr newTiffSubIfd(uint16_t tag, uint16_t group) + { + return TiffComponent::AutoPtr(new TiffSubIfd(tag, group, newGroup)); + } //! Function to create and initialize a new array entry - template - TiffComponent::AutoPtr newTiffArrayEntry(uint16_t tag, - const TiffStructure* ts) + template + TiffComponent::AutoPtr newTiffArrayEntry(uint16_t tag, uint16_t group) { - assert(ts); return TiffComponent::AutoPtr( - new TiffArrayEntry(tag, ts->group_, ts->newGroup_, tiffType, addSizeElement)); + new TiffArrayEntry(tag, group, newGroup, tiffType, addSizeElement)); } //! Function to create and initialize a new array element template - TiffComponent::AutoPtr newTiffArrayElement(uint16_t tag, - const TiffStructure* ts) + TiffComponent::AutoPtr newTiffArrayElement(uint16_t tag, uint16_t group) { - assert(ts); return TiffComponent::AutoPtr( - new TiffArrayElement(tag, ts->group_, tiffType, byteOrder)); + new TiffArrayElement(tag, group, tiffType, byteOrder)); } template - TiffComponent::AutoPtr newTiffArrayElement(uint16_t tag, - const TiffStructure* ts) + TiffComponent::AutoPtr newTiffArrayElement(uint16_t tag, uint16_t group) { - return newTiffArrayElement(tag, ts); + return newTiffArrayElement(tag, group); } //! Function to create and initialize a new TIFF entry for a thumbnail (data) template - TiffComponent::AutoPtr newTiffThumbData(uint16_t tag, - const TiffStructure* ts) + TiffComponent::AutoPtr newTiffThumbData(uint16_t tag, uint16_t group) { - assert(ts); return TiffComponent::AutoPtr( - new TiffDataEntry(tag, ts->group_, szTag, szGroup)); + new TiffDataEntry(tag, group, szTag, szGroup)); } //! Function to create and initialize a new TIFF entry for a thumbnail (size) template - TiffComponent::AutoPtr newTiffThumbSize(uint16_t tag, - const TiffStructure* ts) + TiffComponent::AutoPtr newTiffThumbSize(uint16_t tag, uint16_t group) { - assert(ts); return TiffComponent::AutoPtr( - new TiffSizeEntry(tag, ts->group_, dtTag, dtGroup)); + new TiffSizeEntry(tag, group, dtTag, dtGroup)); } //! Function to create and initialize a new TIFF entry for image data template - TiffComponent::AutoPtr newTiffImageData(uint16_t tag, - const TiffStructure* ts) + TiffComponent::AutoPtr newTiffImageData(uint16_t tag, uint16_t group) { - assert(ts); return TiffComponent::AutoPtr( - new TiffImageEntry(tag, ts->group_, szTag, szGroup)); + new TiffImageEntry(tag, group, szTag, szGroup)); } //! Function to create and initialize a new TIFF entry for image data (size) template - TiffComponent::AutoPtr newTiffImageSize(uint16_t tag, - const TiffStructure* ts) + TiffComponent::AutoPtr newTiffImageSize(uint16_t tag, uint16_t group) { // Todo: Same as newTiffThumbSize - consolidate (rename)? - assert(ts); return TiffComponent::AutoPtr( - new TiffSizeEntry(tag, ts->group_, dtTag, dtGroup)); + new TiffSizeEntry(tag, group, dtTag, dtGroup)); } }} // namespace Internal, Exiv2 diff --git a/src/tifffwd_int.hpp b/src/tifffwd_int.hpp index 58f53b37..561156e0 100644 --- a/src/tifffwd_int.hpp +++ b/src/tifffwd_int.hpp @@ -47,7 +47,6 @@ namespace Exiv2 { class TiffHeaderBase; class TiffComponent; - struct TiffStructure; class TiffEntryBase; class TiffEntry; class TiffDataEntry; @@ -68,6 +67,7 @@ namespace Exiv2 { class TiffPrinter; class TiffRwState; + class TiffPathItem; struct TiffMappingInfo; // ***************************************************************************** @@ -102,18 +102,10 @@ namespace Exiv2 { Use TiffComponent::AutoPtr, it is not used in this declaration only to reduce dependencies. */ - typedef std::auto_ptr (*NewTiffCompFct)( uint16_t tag, - const TiffStructure* ts); - //! Stack to hold a path from the TIFF root element to a TIFF entry - typedef std::stack TiffPath; + typedef std::auto_ptr (*NewTiffCompFct)(uint16_t tag, uint16_t group); - /*! - @brief Type for a factory function to create new TIFF components. - Use TiffComponent::AutoPtr, it is not used in this declaration only - to reduce dependencies. - */ - typedef std::auto_ptr (*TiffCompFactoryFct)(uint32_t extendedTag, - uint16_t group); + //! Stack to hold a path from the TIFF root element to a TIFF entry + typedef std::stack TiffPath; }} // namespace Internal, Exiv2 diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp index e8a2ed6c..5c301f1a 100644 --- a/src/tiffimage.cpp +++ b/src/tiffimage.cpp @@ -59,9 +59,6 @@ EXIV2_RCSID("@(#) $Id$") Todo: - + Can NewTiffCompFct and TiffCompFactoryFct be combined? - + Create function is repeated when actually only the table changes. Fix it. - + Is it easier (for writing) to combine all creation tables into one? + CR2 Makernotes don't seem to have a next pointer but Canon Jpeg Makernotes do. What a mess. (That'll become an issue when it comes to writing to CR2) + Sony makernotes in RAW files do not seem to have header like those in Jpegs. @@ -197,7 +194,7 @@ namespace Exiv2 { xmpData, pData, size, - TiffCreator::create, + Tag::root, TiffMapping::findDecoder); } // TiffParser::decode @@ -218,7 +215,7 @@ namespace Exiv2 { exifData, iptcData, xmpData, - TiffCreator::create, + Tag::root, TiffMapping::findEncoder, header.get()); } // TiffParser::encode @@ -255,264 +252,329 @@ namespace Exiv2 { namespace Exiv2 { namespace Internal { + /* + This table lists for each group in a tree, its parent group and tag. + Root identifies the root of a TIFF tree, as there is a need for multiple + trees. Groups are the nodes of a TIFF tree. A group is an IFD or any + other composite component. + + With this table, it is possible, for a given group (and tag) to find a + path, i.e., a list of groups and tags, from the root to that group (tag). + */ + const TiffTreeStruct TiffCreator::tiffTreeStruct_[] = { + // root group parent group parent tag + //--------- ----------------- ----------------- ---------- + { Tag::root, Group::none, Group::none, Tag::root }, + { Tag::root, Group::ifd0, Group::none, Tag::root }, + { Tag::root, Group::subimg1, Group::ifd0, 0x014a }, + { Tag::root, Group::subimg2, Group::ifd0, 0x014a }, + { Tag::root, Group::subimg3, Group::ifd0, 0x014a }, + { Tag::root, Group::subimg4, Group::ifd0, 0x014a }, + { Tag::root, Group::exif, Group::ifd0, 0x8769 }, + { Tag::root, Group::gps, Group::ifd0, 0x8825 }, + { Tag::root, Group::iop, Group::exif, 0xa005 }, + { Tag::root, Group::ifd1, Group::ifd0, Tag::next }, + { Tag::root, Group::ifd2, Group::ifd1, Tag::next }, + { Tag::root, Group::olymp1mn, Group::exif, 0x927c }, + { Tag::root, Group::olymp2mn, Group::exif, 0x927c }, + { Tag::root, Group::olympeq, Group::olymp2mn, 0x2010 }, + { Tag::root, Group::olympcs, Group::olymp2mn, 0x2020 }, + { Tag::root, Group::olymprd, Group::olymp2mn, 0x2030 }, + { Tag::root, Group::olymprd2, Group::olymp2mn, 0x2031 }, + { Tag::root, Group::olympip, Group::olymp2mn, 0x2040 }, + { Tag::root, Group::olympfi, Group::olymp2mn, 0x2050 }, + { Tag::root, Group::olympfe1, Group::olymp2mn, 0x2100 }, + { Tag::root, Group::olympfe2, Group::olymp2mn, 0x2200 }, + { Tag::root, Group::olympfe3, Group::olymp2mn, 0x2300 }, + { Tag::root, Group::olympfe4, Group::olymp2mn, 0x2400 }, + { Tag::root, Group::olympfe5, Group::olymp2mn, 0x2500 }, + { Tag::root, Group::olympfe6, Group::olymp2mn, 0x2600 }, + { Tag::root, Group::olympfe7, Group::olymp2mn, 0x2700 }, + { Tag::root, Group::olympfe8, Group::olymp2mn, 0x2800 }, + { Tag::root, Group::olympfe9, Group::olymp2mn, 0x2900 }, + { Tag::root, Group::olympri, Group::olymp2mn, 0x3000 }, + { Tag::root, Group::fujimn, Group::exif, 0x927c }, + { Tag::root, Group::canonmn, Group::exif, 0x927c }, + { Tag::root, Group::canoncs, Group::canonmn, 0x0001 }, + { Tag::root, Group::canonsi, Group::canonmn, 0x0004 }, + { Tag::root, Group::canonpa, Group::canonmn, 0x0005 }, + { Tag::root, Group::canoncf, Group::canonmn, 0x000f }, + { Tag::root, Group::canonpi, Group::canonmn, 0x0012 }, + { Tag::root, Group::nikon1mn, Group::exif, 0x927c }, + { Tag::root, Group::nikon2mn, Group::exif, 0x927c }, + { Tag::root, Group::nikon3mn, Group::exif, 0x927c }, + { Tag::root, Group::nikonpv, Group::nikon3mn, 0x0011 }, + { Tag::root, Group::panamn, Group::exif, 0x927c }, + { Tag::root, Group::pentaxmn, Group::exif, 0x927c }, + { Tag::root, Group::sigmamn, Group::exif, 0x927c }, + { Tag::root, Group::sony1mn, Group::exif, 0x927c }, + { Tag::root, Group::sony2mn, Group::exif, 0x927c }, + { Tag::root, Group::minoltamn, Group::exif, 0x927c }, + { Tag::root, Group::minocso, Group::minoltamn, 0x0001 }, + { Tag::root, Group::minocsn, Group::minoltamn, 0x0003 }, + { Tag::root, Group::minocs7, Group::minoltamn, 0x0004 }, + { Tag::root, Group::minocs5, Group::minoltamn, 0x0114 } + }; + /* - This table describes the standard TIFF layout (including non-standard - Makernote structures) and determines the corresponding Exiv2 TIFF - components. The key of the table consists of the first two attributes, - (extended) tag and group. Tag is the TIFF tag or one of a few extended - tags, group identifies the IFD or any other composite TIFF component. - Each entry of the table defines for a particular tag and group - combination, which create function is used, what the group and parent tag - and group of the new component are. + This table describes the layout of each known TIFF group (including + non-standard structures and IFDs only seen in RAW images). + + The key of the table consists of the first two attributes, (extended) tag + and group. Tag is the TIFF tag or one of a few extended tags, group + identifies the IFD or any other composite component. + + Each entry of the table defines for a particular tag and group combination + the corresponding TIFF component create function. */ - const TiffStructure TiffCreator::tiffStructure_[] = { - // ext. tag group child group parent tag parent group create function - //--------- ----------------- ----------------- ---------- ----------------- ------------------- + const TiffGroupStruct TiffCreator::tiffGroupStruct_[] = { + // ext. tag group create function + //--------- ----------------- ----------------------------------------- // Root directory - { Tag::root, Group::none, Group::ifd0, Tag::root, Group::none, newTiffDirectory }, + { Tag::root, Group::none, newTiffDirectory }, // IFD0 - { 0x8769, Group::ifd0, Group::exif, Tag::root, Group::none, newTiffSubIfd }, - { 0x8825, Group::ifd0, Group::gps, Tag::root, Group::none, newTiffSubIfd }, - { 0x0111, Group::ifd0, Group::ifd0, Tag::root, Group::none, newTiffImageData<0x0117, Group::ifd0> }, - { 0x0117, Group::ifd0, Group::ifd0, Tag::root, Group::none, newTiffImageSize<0x0111, Group::ifd0> }, - { 0x0144, Group::ifd0, Group::ifd0, Tag::root, Group::none, newTiffImageData<0x0145, Group::ifd0> }, - { 0x0145, Group::ifd0, Group::ifd0, Tag::root, Group::none, newTiffImageSize<0x0144, Group::ifd0> }, - { 0x0201, Group::ifd0, Group::ifd0, Tag::root, Group::none, newTiffImageData<0x0202, Group::ifd0> }, - { 0x0202, Group::ifd0, Group::ifd0, Tag::root, Group::none, newTiffImageSize<0x0201, Group::ifd0> }, - { 0x014a, Group::ifd0, Group::subimg1, Tag::root, Group::none, newTiffSubIfd }, - { Tag::next, Group::ifd0, Group::ifd1, Tag::root, Group::none, newTiffDirectory }, - { Tag::all, Group::ifd0, Group::ifd0, Tag::root, Group::none, newTiffEntry }, + { 0x8769, Group::ifd0, newTiffSubIfd }, + { 0x8825, Group::ifd0, newTiffSubIfd }, + { 0x0111, Group::ifd0, newTiffImageData<0x0117, Group::ifd0> }, + { 0x0117, Group::ifd0, newTiffImageSize<0x0111, Group::ifd0> }, + { 0x0144, Group::ifd0, newTiffImageData<0x0145, Group::ifd0> }, + { 0x0145, Group::ifd0, newTiffImageSize<0x0144, Group::ifd0> }, + { 0x0201, Group::ifd0, newTiffImageData<0x0202, Group::ifd0> }, + { 0x0202, Group::ifd0, newTiffImageSize<0x0201, Group::ifd0> }, + { 0x014a, Group::ifd0, newTiffSubIfd }, + { Tag::next, Group::ifd0, newTiffDirectory }, + { Tag::all, Group::ifd0, newTiffEntry }, // Subdir subimg1 - { 0x0111, Group::subimg1, Group::subimg1, 0x014a, Group::ifd0, newTiffImageData<0x0117, Group::subimg1> }, - { 0x0117, Group::subimg1, Group::subimg1, 0x014a, Group::ifd0, newTiffImageSize<0x0111, Group::subimg1> }, - { 0x0144, Group::subimg1, Group::subimg1, 0x014a, Group::ifd0, newTiffImageData<0x0145, Group::subimg1> }, - { 0x0145, Group::subimg1, Group::subimg1, 0x014a, Group::ifd0, newTiffImageSize<0x0144, Group::subimg1> }, - { 0x0201, Group::subimg1, Group::subimg1, 0x014a, Group::ifd0, newTiffImageData<0x0202, Group::subimg1> }, - { 0x0202, Group::subimg1, Group::subimg1, 0x014a, Group::ifd0, newTiffImageSize<0x0201, Group::subimg1> }, - { Tag::next, Group::subimg1, Group::ignr, 0x014a, Group::ifd0, newTiffDirectory }, - { Tag::all, Group::subimg1, Group::subimg1, 0x014a, Group::ifd0, newTiffEntry }, + { 0x0111, Group::subimg1, newTiffImageData<0x0117, Group::subimg1> }, + { 0x0117, Group::subimg1, newTiffImageSize<0x0111, Group::subimg1> }, + { 0x0144, Group::subimg1, newTiffImageData<0x0145, Group::subimg1> }, + { 0x0145, Group::subimg1, newTiffImageSize<0x0144, Group::subimg1> }, + { 0x0201, Group::subimg1, newTiffImageData<0x0202, Group::subimg1> }, + { 0x0202, Group::subimg1, newTiffImageSize<0x0201, Group::subimg1> }, + { Tag::next, Group::subimg1, newTiffDirectory }, + { Tag::all, Group::subimg1, newTiffEntry }, // Subdir subimg2 - { 0x0111, Group::subimg2, Group::subimg2, 0x014a, Group::ifd0, newTiffImageData<0x0117, Group::subimg2> }, - { 0x0117, Group::subimg2, Group::subimg2, 0x014a, Group::ifd0, newTiffImageSize<0x0111, Group::subimg2> }, - { 0x0144, Group::subimg2, Group::subimg2, 0x014a, Group::ifd0, newTiffImageData<0x0145, Group::subimg2> }, - { 0x0145, Group::subimg2, Group::subimg2, 0x014a, Group::ifd0, newTiffImageSize<0x0144, Group::subimg2> }, - { 0x0201, Group::subimg2, Group::subimg2, 0x014a, Group::ifd0, newTiffImageData<0x0202, Group::subimg2> }, - { 0x0202, Group::subimg2, Group::subimg2, 0x014a, Group::ifd0, newTiffImageSize<0x0201, Group::subimg2> }, - { Tag::next, Group::subimg2, Group::ignr, 0x014a, Group::ifd0, newTiffDirectory }, - { Tag::all, Group::subimg2, Group::subimg2, 0x014a, Group::ifd0, newTiffEntry }, + { 0x0111, Group::subimg2, newTiffImageData<0x0117, Group::subimg2> }, + { 0x0117, Group::subimg2, newTiffImageSize<0x0111, Group::subimg2> }, + { 0x0144, Group::subimg2, newTiffImageData<0x0145, Group::subimg2> }, + { 0x0145, Group::subimg2, newTiffImageSize<0x0144, Group::subimg2> }, + { 0x0201, Group::subimg2, newTiffImageData<0x0202, Group::subimg2> }, + { 0x0202, Group::subimg2, newTiffImageSize<0x0201, Group::subimg2> }, + { Tag::next, Group::subimg2, newTiffDirectory }, + { Tag::all, Group::subimg2, newTiffEntry }, // Subdir subimg3 - { 0x0111, Group::subimg3, Group::subimg3, 0x014a, Group::ifd0, newTiffImageData<0x0117, Group::subimg3> }, - { 0x0117, Group::subimg3, Group::subimg3, 0x014a, Group::ifd0, newTiffImageSize<0x0111, Group::subimg3> }, - { 0x0144, Group::subimg3, Group::subimg3, 0x014a, Group::ifd0, newTiffImageData<0x0145, Group::subimg3> }, - { 0x0145, Group::subimg3, Group::subimg3, 0x014a, Group::ifd0, newTiffImageSize<0x0144, Group::subimg3> }, - { 0x0201, Group::subimg3, Group::subimg3, 0x014a, Group::ifd0, newTiffImageData<0x0202, Group::subimg3> }, - { 0x0202, Group::subimg3, Group::subimg3, 0x014a, Group::ifd0, newTiffImageSize<0x0201, Group::subimg3> }, - { Tag::next, Group::subimg3, Group::ignr, 0x014a, Group::ifd0, newTiffDirectory }, - { Tag::all, Group::subimg3, Group::subimg3, 0x014a, Group::ifd0, newTiffEntry }, + { 0x0111, Group::subimg3, newTiffImageData<0x0117, Group::subimg3> }, + { 0x0117, Group::subimg3, newTiffImageSize<0x0111, Group::subimg3> }, + { 0x0144, Group::subimg3, newTiffImageData<0x0145, Group::subimg3> }, + { 0x0145, Group::subimg3, newTiffImageSize<0x0144, Group::subimg3> }, + { 0x0201, Group::subimg3, newTiffImageData<0x0202, Group::subimg3> }, + { 0x0202, Group::subimg3, newTiffImageSize<0x0201, Group::subimg3> }, + { Tag::next, Group::subimg3, newTiffDirectory }, + { Tag::all, Group::subimg3, newTiffEntry }, // Subdir subimg4 - { 0x0111, Group::subimg4, Group::subimg4, 0x014a, Group::ifd0, newTiffImageData<0x0117, Group::subimg4> }, - { 0x0117, Group::subimg4, Group::subimg4, 0x014a, Group::ifd0, newTiffImageSize<0x0111, Group::subimg4> }, - { 0x0144, Group::subimg4, Group::subimg4, 0x014a, Group::ifd0, newTiffImageData<0x0145, Group::subimg4> }, - { 0x0145, Group::subimg4, Group::subimg4, 0x014a, Group::ifd0, newTiffImageSize<0x0144, Group::subimg4> }, - { 0x0201, Group::subimg4, Group::subimg4, 0x014a, Group::ifd0, newTiffImageData<0x0202, Group::subimg4> }, - { 0x0202, Group::subimg4, Group::subimg4, 0x014a, Group::ifd0, newTiffImageSize<0x0201, Group::subimg4> }, - { Tag::next, Group::subimg4, Group::ignr, 0x014a, Group::ifd0, newTiffDirectory }, - { Tag::all, Group::subimg4, Group::subimg4, 0x014a, Group::ifd0, newTiffEntry }, + { 0x0111, Group::subimg4, newTiffImageData<0x0117, Group::subimg4> }, + { 0x0117, Group::subimg4, newTiffImageSize<0x0111, Group::subimg4> }, + { 0x0144, Group::subimg4, newTiffImageData<0x0145, Group::subimg4> }, + { 0x0145, Group::subimg4, newTiffImageSize<0x0144, Group::subimg4> }, + { 0x0201, Group::subimg4, newTiffImageData<0x0202, Group::subimg4> }, + { 0x0202, Group::subimg4, newTiffImageSize<0x0201, Group::subimg4> }, + { Tag::next, Group::subimg4, newTiffDirectory }, + { Tag::all, Group::subimg4, newTiffEntry }, // Exif subdir - { 0xa005, Group::exif, Group::iop, 0x8769, Group::ifd0, newTiffSubIfd }, - { 0x927c, Group::exif, Group::mn, 0x8769, Group::ifd0, newTiffMnEntry }, - { Tag::next, Group::exif, Group::ignr, 0x8769, Group::ifd0, newTiffDirectory }, - { Tag::all, Group::exif, Group::exif, 0x8769, Group::ifd0, newTiffEntry }, + { 0xa005, Group::exif, newTiffSubIfd }, + { 0x927c, Group::exif, newTiffMnEntry }, + { Tag::next, Group::exif, newTiffDirectory }, + { Tag::all, Group::exif, newTiffEntry }, // GPS subdir - { Tag::next, Group::gps, Group::ignr, 0x8825, Group::ifd0, newTiffDirectory }, - { Tag::all, Group::gps, Group::gps, 0x8825, Group::ifd0, newTiffEntry }, + { Tag::next, Group::gps, newTiffDirectory }, + { Tag::all, Group::gps, newTiffEntry }, // IOP subdir - { Tag::next, Group::iop, Group::ignr, 0xa005, Group::exif, newTiffDirectory }, - { Tag::all, Group::iop, Group::iop, 0xa005, Group::exif, newTiffEntry }, + { Tag::next, Group::iop, newTiffDirectory }, + { Tag::all, Group::iop, newTiffEntry }, // IFD1 - { 0x0111, Group::ifd1, Group::ifd1, Tag::next, Group::ifd0, newTiffThumbData<0x0117, Group::ifd1> }, - { 0x0117, Group::ifd1, Group::ifd1, Tag::next, Group::ifd0, newTiffThumbSize<0x0111, Group::ifd1> }, - { 0x0201, Group::ifd1, Group::ifd1, Tag::next, Group::ifd0, newTiffThumbData<0x0202, Group::ifd1> }, - { 0x0202, Group::ifd1, Group::ifd1, Tag::next, Group::ifd0, newTiffThumbSize<0x0201, Group::ifd1> }, - { Tag::next, Group::ifd1, Group::ifd2, Tag::next, Group::ifd0, newTiffDirectory }, - { Tag::all, Group::ifd1, Group::ifd1, Tag::next, Group::ifd0, newTiffEntry }, + { 0x0111, Group::ifd1, newTiffThumbData<0x0117, Group::ifd1> }, + { 0x0117, Group::ifd1, newTiffThumbSize<0x0111, Group::ifd1> }, + { 0x0201, Group::ifd1, newTiffThumbData<0x0202, Group::ifd1> }, + { 0x0202, Group::ifd1, newTiffThumbSize<0x0201, Group::ifd1> }, + { Tag::next, Group::ifd1, newTiffDirectory }, + { Tag::all, Group::ifd1, newTiffEntry }, // IFD2 (eg, in Pentax PEF files) - { 0x0111, Group::ifd2, Group::ifd2, Tag::next, Group::ifd1, newTiffImageData<0x0117, Group::ifd2> }, - { 0x0117, Group::ifd2, Group::ifd2, Tag::next, Group::ifd1, newTiffImageSize<0x0111, Group::ifd2> }, - { 0x0201, Group::ifd2, Group::ifd2, Tag::next, Group::ifd1, newTiffImageData<0x0202, Group::ifd2> }, - { 0x0202, Group::ifd2, Group::ifd2, Tag::next, Group::ifd1, newTiffImageSize<0x0201, Group::ifd2> }, - { Tag::next, Group::ifd2, Group::ignr, Tag::next, Group::ifd1, newTiffDirectory }, - { Tag::all, Group::ifd2, Group::ifd2, Tag::next, Group::ifd1, newTiffEntry }, + { 0x0111, Group::ifd2, newTiffImageData<0x0117, Group::ifd2> }, + { 0x0117, Group::ifd2, newTiffImageSize<0x0111, Group::ifd2> }, + { 0x0201, Group::ifd2, newTiffImageData<0x0202, Group::ifd2> }, + { 0x0202, Group::ifd2, newTiffImageSize<0x0201, Group::ifd2> }, + { Tag::next, Group::ifd2, newTiffDirectory }, + { Tag::all, Group::ifd2, newTiffEntry }, // Olympus makernote - some Olympus cameras use Minolta structures // Todo: Adding such tags will not work (maybe result in a Minolta makernote), need separate groups - { 0x0001, Group::olymp1mn, Group::minocso, 0x927c, Group::exif, newTiffArrayEntry }, - { 0x0003, Group::olymp1mn, Group::minocsn, 0x927c, Group::exif, newTiffArrayEntry }, - { Tag::next, Group::olymp1mn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::olymp1mn, Group::olymp1mn, 0x927c, Group::exif, newTiffEntry }, + { 0x0001, Group::olymp1mn, newTiffArrayEntry }, + { 0x0003, Group::olymp1mn, newTiffArrayEntry }, + { Tag::next, Group::olymp1mn, newTiffDirectory }, + { Tag::all, Group::olymp1mn, newTiffEntry }, // Olympus2 makernote - { 0x0001, Group::olymp2mn, Group::minocso, 0x927c, Group::exif, newTiffArrayEntry }, - { 0x0003, Group::olymp2mn, Group::minocsn, 0x927c, Group::exif, newTiffArrayEntry }, - { 0x2010, Group::olymp2mn, Group::olympeq, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2020, Group::olymp2mn, Group::olympcs, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2030, Group::olymp2mn, Group::olymprd, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2031, Group::olymp2mn, Group::olymprd2, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2040, Group::olymp2mn, Group::olympip, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2050, Group::olymp2mn, Group::olympfi, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2100, Group::olymp2mn, Group::olympfe1, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2200, Group::olymp2mn, Group::olympfe2, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2300, Group::olymp2mn, Group::olympfe3, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2400, Group::olymp2mn, Group::olympfe4, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2500, Group::olymp2mn, Group::olympfe5, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2600, Group::olymp2mn, Group::olympfe6, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2700, Group::olymp2mn, Group::olympfe7, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2800, Group::olymp2mn, Group::olympfe8, 0x927c, Group::exif, newTiffSubIfd }, - { 0x2900, Group::olymp2mn, Group::olympfe9, 0x927c, Group::exif, newTiffSubIfd }, - { 0x3000, Group::olymp2mn, Group::olympri, 0x927c, Group::exif, newTiffSubIfd }, - { Tag::next, Group::olymp2mn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::olymp2mn, Group::olymp2mn, 0x927c, Group::exif, newTiffEntry }, + { 0x0001, Group::olymp2mn, newTiffArrayEntry }, + { 0x0003, Group::olymp2mn, newTiffArrayEntry }, + { 0x2010, Group::olymp2mn, newTiffSubIfd }, + { 0x2020, Group::olymp2mn, newTiffSubIfd }, + { 0x2030, Group::olymp2mn, newTiffSubIfd }, + { 0x2031, Group::olymp2mn, newTiffSubIfd }, + { 0x2040, Group::olymp2mn, newTiffSubIfd }, + { 0x2050, Group::olymp2mn, newTiffSubIfd }, + { 0x2100, Group::olymp2mn, newTiffSubIfd }, + { 0x2200, Group::olymp2mn, newTiffSubIfd }, + { 0x2300, Group::olymp2mn, newTiffSubIfd }, + { 0x2400, Group::olymp2mn, newTiffSubIfd }, + { 0x2500, Group::olymp2mn, newTiffSubIfd }, + { 0x2600, Group::olymp2mn, newTiffSubIfd }, + { 0x2700, Group::olymp2mn, newTiffSubIfd }, + { 0x2800, Group::olymp2mn, newTiffSubIfd }, + { 0x2900, Group::olymp2mn, newTiffSubIfd }, + { 0x3000, Group::olymp2mn, newTiffSubIfd }, + { Tag::next, Group::olymp2mn, newTiffDirectory }, + { Tag::all, Group::olymp2mn, newTiffEntry }, // Olympus2 equipment subdir - { Tag::all, Group::olympeq, Group::olympeq, 0x2010, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympeq, newTiffEntry }, // Olympus2 camera settings subdir - { 0x0101, Group::olympcs, Group::olympcs, 0x2020, Group::olymp2mn, newTiffImageData<0x0102, Group::olympcs> }, - { 0x0102, Group::olympcs, Group::olympcs, 0x2020, Group::olymp2mn, newTiffImageSize<0x0101, Group::olympcs> }, - { Tag::all, Group::olympcs, Group::olympcs, 0x2020, Group::olymp2mn, newTiffEntry }, + { 0x0101, Group::olympcs, newTiffImageData<0x0102, Group::olympcs> }, + { 0x0102, Group::olympcs, newTiffImageSize<0x0101, Group::olympcs> }, + { Tag::all, Group::olympcs, newTiffEntry }, // Olympus2 raw development subdir - { Tag::all, Group::olymprd, Group::olymprd, 0x2030, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olymprd, newTiffEntry }, // Olympus2 raw development 2 subdir - { Tag::all, Group::olymprd2, Group::olymprd2, 0x2031, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olymprd2, newTiffEntry }, // Olympus2 image processing subdir - { Tag::all, Group::olympip, Group::olympip, 0x2040, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympip, newTiffEntry }, // Olympus2 focus info subdir - { Tag::all, Group::olympfi, Group::olympfi, 0x2050, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympfi, newTiffEntry }, // Olympus2 FE 1 subdir - { Tag::all, Group::olympfe1, Group::olympfe1, 0x2100, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympfe1, newTiffEntry }, // Olympus2 FE 2 subdir - { Tag::all, Group::olympfe2, Group::olympfe2, 0x2200, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympfe2, newTiffEntry }, // Olympus2 FE 3 subdir - { Tag::all, Group::olympfe3, Group::olympfe3, 0x2300, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympfe3, newTiffEntry }, // Olympus2 FE 4 subdir - { Tag::all, Group::olympfe4, Group::olympfe4, 0x2400, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympfe4, newTiffEntry }, // Olympus2 FE 5 subdir - { Tag::all, Group::olympfe5, Group::olympfe5, 0x2500, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympfe5, newTiffEntry }, // Olympus2 FE 6 subdir - { Tag::all, Group::olympfe6, Group::olympfe6, 0x2600, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympfe6, newTiffEntry }, // Olympus2 FE 7 subdir - { Tag::all, Group::olympfe7, Group::olympfe7, 0x2700, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympfe7, newTiffEntry }, // Olympus2 FE 8 subdir - { Tag::all, Group::olympfe8, Group::olympfe8, 0x2800, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympfe8, newTiffEntry }, // Olympus2 FE 9 subdir - { Tag::all, Group::olympfe9, Group::olympfe9, 0x2900, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympfe9, newTiffEntry }, // Olympus2 Raw Info subdir - { Tag::all, Group::olympri, Group::olympri, 0x3000, Group::olymp2mn, newTiffEntry }, + { Tag::all, Group::olympri, newTiffEntry }, // Fujifilm makernote - { Tag::next, Group::fujimn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::fujimn, Group::fujimn, 0x927c, Group::exif, newTiffEntry }, + { Tag::next, Group::fujimn, newTiffDirectory }, + { Tag::all, Group::fujimn, newTiffEntry }, // Canon makernote - { 0x0001, Group::canonmn, Group::canoncs, 0x927c, Group::exif, newTiffArrayEntry }, - { 0x0004, Group::canonmn, Group::canonsi, 0x927c, Group::exif, newTiffArrayEntry }, - { 0x0005, Group::canonmn, Group::canonpa, 0x927c, Group::exif, newTiffArrayEntry }, - { 0x000f, Group::canonmn, Group::canoncf, 0x927c, Group::exif, newTiffArrayEntry }, - { 0x0012, Group::canonmn, Group::canonpi, 0x927c, Group::exif, newTiffArrayEntry }, - { Tag::next, Group::canonmn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::canonmn, Group::canonmn, 0x927c, Group::exif, newTiffEntry }, + { 0x0001, Group::canonmn, newTiffArrayEntry }, + { 0x0004, Group::canonmn, newTiffArrayEntry }, + { 0x0005, Group::canonmn, newTiffArrayEntry }, + { 0x000f, Group::canonmn, newTiffArrayEntry }, + { 0x0012, Group::canonmn, newTiffArrayEntry }, + { Tag::next, Group::canonmn, newTiffDirectory }, + { Tag::all, Group::canonmn, newTiffEntry }, // Canon makernote composite tags - { Tag::all, Group::canoncs, Group::canoncs, 0x0001, Group::canonmn, newTiffArrayElement }, - { Tag::all, Group::canonsi, Group::canonsi, 0x0004, Group::canonmn, newTiffArrayElement }, - { Tag::all, Group::canonpa, Group::canonpa, 0x0005, Group::canonmn, newTiffArrayElement }, - { Tag::all, Group::canoncf, Group::canoncf, 0x000f, Group::canonmn, newTiffArrayElement }, - { Tag::all, Group::canonpi, Group::canonpi, 0x0012, Group::canonmn, newTiffArrayElement }, + { Tag::all, Group::canoncs, newTiffArrayElement }, + { Tag::all, Group::canonsi, newTiffArrayElement }, + { Tag::all, Group::canonpa, newTiffArrayElement }, + { Tag::all, Group::canoncf, newTiffArrayElement }, + { Tag::all, Group::canonpi, newTiffArrayElement }, // Nikon1 makernote - { Tag::next, Group::nikon1mn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::nikon1mn, Group::nikon1mn, 0x927c, Group::exif, newTiffEntry }, + { Tag::next, Group::nikon1mn, newTiffDirectory }, + { Tag::all, Group::nikon1mn, newTiffEntry }, // Nikon2 makernote - { Tag::next, Group::nikon2mn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::nikon2mn, Group::nikon2mn, 0x927c, Group::exif, newTiffEntry }, + { Tag::next, Group::nikon2mn, newTiffDirectory }, + { Tag::all, Group::nikon2mn, newTiffEntry }, // Nikon3 makernote - { Tag::next, Group::nikon3mn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { 0x0011, Group::nikon3mn, Group::nikonpv, 0x927c, Group::exif, newTiffSubIfd }, - { Tag::all, Group::nikon3mn, Group::nikon3mn, 0x927c, Group::exif, newTiffEntry }, + { Tag::next, Group::nikon3mn, newTiffDirectory }, + { 0x0011, Group::nikon3mn, newTiffSubIfd }, + { Tag::all, Group::nikon3mn, newTiffEntry }, // Nikon3 makernote preview subdir - { 0x0201, Group::nikonpv, Group::nikonpv, 0x0011, Group::nikon3mn, newTiffThumbData<0x0202, Group::nikonpv> }, - { 0x0202, Group::nikonpv, Group::nikonpv, 0x0011, Group::nikon3mn, newTiffThumbSize<0x0201, Group::nikonpv> }, - { Tag::next, Group::nikonpv, Group::ignr, 0x0011, Group::nikon3mn, newTiffDirectory }, - { Tag::all, Group::nikonpv, Group::nikonpv, 0x0011, Group::nikon3mn, newTiffEntry }, + { 0x0201, Group::nikonpv, newTiffThumbData<0x0202, Group::nikonpv> }, + { 0x0202, Group::nikonpv, newTiffThumbSize<0x0201, Group::nikonpv> }, + { Tag::next, Group::nikonpv, newTiffDirectory }, + { Tag::all, Group::nikonpv, newTiffEntry }, // Panasonic makernote - { Tag::next, Group::panamn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::panamn, Group::panamn, 0x927c, Group::exif, newTiffEntry }, + { Tag::next, Group::panamn, newTiffDirectory }, + { Tag::all, Group::panamn, newTiffEntry }, // Pentax makernote - { 0x0003, Group::pentaxmn, Group::pentaxmn, 0x927c, Group::exif, newTiffThumbSize<0x0004, Group::pentaxmn> }, - { 0x0004, Group::pentaxmn, Group::pentaxmn, 0x927c, Group::exif, newTiffThumbData<0x0003, Group::pentaxmn> }, - { Tag::next, Group::pentaxmn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::pentaxmn, Group::pentaxmn, 0x927c, Group::exif, newTiffEntry }, + { 0x0003, Group::pentaxmn, newTiffThumbSize<0x0004, Group::pentaxmn> }, + { 0x0004, Group::pentaxmn, newTiffThumbData<0x0003, Group::pentaxmn> }, + { Tag::next, Group::pentaxmn, newTiffDirectory }, + { Tag::all, Group::pentaxmn, newTiffEntry }, // Sigma/Foveon makernote - { Tag::next, Group::sigmamn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::sigmamn, Group::sigmamn, 0x927c, Group::exif, newTiffEntry }, + { Tag::next, Group::sigmamn, newTiffDirectory }, + { Tag::all, Group::sigmamn, newTiffEntry }, // Sony1 makernote - { Tag::next, Group::sony1mn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::sony1mn, Group::sony1mn, 0x927c, Group::exif, newTiffEntry }, + { Tag::next, Group::sony1mn, newTiffDirectory }, + { Tag::all, Group::sony1mn, newTiffEntry }, // Sony2 makernote - { Tag::next, Group::sony2mn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::sony2mn, Group::sony2mn, 0x927c, Group::exif, newTiffEntry }, + { Tag::next, Group::sony2mn, newTiffDirectory }, + { Tag::all, Group::sony2mn, newTiffEntry }, // Minolta makernote - { 0x0001, Group::minoltamn, Group::minocso, 0x927c, Group::exif, newTiffArrayEntry }, - { 0x0003, Group::minoltamn, Group::minocsn, 0x927c, Group::exif, newTiffArrayEntry }, - { 0x0004, Group::minoltamn, Group::minocs7, 0x927c, Group::exif, newTiffArrayEntry }, - { 0x0088, Group::minoltamn, Group::minoltamn, 0x927c, Group::exif, newTiffThumbData<0x0089, Group::minoltamn> }, - { 0x0089, Group::minoltamn, Group::minoltamn, 0x927c, Group::exif, newTiffThumbSize<0x0088, Group::minoltamn> }, - { 0x0114, Group::minoltamn, Group::minocs5, 0x927c, Group::exif, newTiffArrayEntry }, - { Tag::next, Group::minoltamn, Group::ignr, 0x927c, Group::exif, newTiffDirectory }, - { Tag::all, Group::minoltamn, Group::minoltamn, 0x927c, Group::exif, newTiffEntry }, + { 0x0001, Group::minoltamn, newTiffArrayEntry }, + { 0x0003, Group::minoltamn, newTiffArrayEntry }, + { 0x0004, Group::minoltamn, newTiffArrayEntry }, + { 0x0088, Group::minoltamn, newTiffThumbData<0x0089, Group::minoltamn>}, + { 0x0089, Group::minoltamn, newTiffThumbSize<0x0088, Group::minoltamn>}, + { 0x0114, Group::minoltamn, newTiffArrayEntry }, + { Tag::next, Group::minoltamn, newTiffDirectory }, + { Tag::all, Group::minoltamn, newTiffEntry }, // Minolta makernote composite tags - { Tag::all, Group::minocso, Group::minocso, 0x0001, Group::minoltamn, newTiffArrayElement }, - { Tag::all, Group::minocsn, Group::minocsn, 0x0003, Group::minoltamn, newTiffArrayElement }, - { Tag::all, Group::minocs7, Group::minocs7, 0x0004, Group::minoltamn, newTiffArrayElement }, - { Tag::all, Group::minocs5, Group::minocs5, 0x0114, Group::minoltamn, newTiffArrayElement }, + { Tag::all, Group::minocso, newTiffArrayElement }, + { Tag::all, Group::minocsn, newTiffArrayElement }, + { Tag::all, Group::minocs7, newTiffArrayElement }, + { Tag::all, Group::minocs5, newTiffArrayElement }, // Tags which are not de/encoded - { Tag::next, Group::ignr, Group::ignr, Tag::none, Group::none, newTiffDirectory }, - { Tag::all, Group::ignr, Group::ignr, Tag::none, Group::none, newTiffEntry } + { Tag::next, Group::ignr, newTiffDirectory }, + { Tag::all, Group::ignr, newTiffEntry } }; // TIFF mapping table for special decoding and encoding requirements @@ -558,15 +620,26 @@ namespace Exiv2 { return encoderFct; } + bool TiffGroupStruct::operator==(const TiffGroupStruct::Key& key) const + { + return (Tag::all == extendedTag_ || key.e_ == extendedTag_) + && key.g_ == group_; + } + + bool TiffTreeStruct::operator==(const TiffTreeStruct::Key& key) const + { + return key.r_ == root_ && key.g_ == group_; + } + TiffComponent::AutoPtr TiffCreator::create(uint32_t extendedTag, uint16_t group) { TiffComponent::AutoPtr tc(0); uint16_t tag = static_cast(extendedTag & 0xffff); - const TiffStructure* ts = find(tiffStructure_, - TiffStructure::Key(extendedTag, group)); + const TiffGroupStruct* ts = find(tiffGroupStruct_, + TiffGroupStruct::Key(extendedTag, group)); if (ts && ts->newTiffCompFct_) { - tc = ts->newTiffCompFct_(tag, ts); + tc = ts->newTiffCompFct_(tag, group); } #ifdef DEBUG else { @@ -584,16 +657,19 @@ namespace Exiv2 { return tc; } // TiffCreator::create - void TiffCreator::getPath(TiffPath& tiffPath, uint32_t extendedTag, uint16_t group) + void TiffCreator::getPath(TiffPath& tiffPath, + uint32_t extendedTag, + uint16_t group, + uint32_t root) { - const TiffStructure* ts = 0; + const TiffTreeStruct* ts = 0; do { - ts = find(tiffStructure_, TiffStructure::Key(extendedTag, group)); + tiffPath.push(TiffPathItem(extendedTag, group)); + ts = find(tiffTreeStruct_, TiffTreeStruct::Key(root, group)); assert(ts != 0); - tiffPath.push(ts); extendedTag = ts->parentExtTag_; group = ts->parentGroup_; - } while (!(ts->extendedTag_ == Tag::root && ts->group_ == Group::none)); + } while (!(ts->root_ == root && ts->group_ == Group::none)); } // TiffCreator::getPath @@ -603,7 +679,7 @@ namespace Exiv2 { XmpData& xmpData, const byte* pData, uint32_t size, - TiffCompFactoryFct createFct, + uint32_t root, FindDecoderFct findDecoderFct, TiffHeaderBase* pHeader ) @@ -614,7 +690,7 @@ namespace Exiv2 { ph = std::auto_ptr(new TiffHeader); pHeader = ph.get(); } - TiffComponent::AutoPtr rootDir = parse(pData, size, createFct, pHeader); + TiffComponent::AutoPtr rootDir = parse(pData, size, root, pHeader); if (0 != rootDir.get()) { TiffDecoder decoder(exifData, iptcData, @@ -634,7 +710,7 @@ namespace Exiv2 { const ExifData& exifData, const IptcData& iptcData, const XmpData& xmpData, - TiffCompFactoryFct createFct, + uint32_t root, FindEncoderFct findEncoderFct, TiffHeaderBase* pHeader ) @@ -651,7 +727,7 @@ namespace Exiv2 { blob.clear(); WriteMethod writeMethod = wmIntrusive; TiffComponent::AutoPtr createdTree; - TiffComponent::AutoPtr parsedTree = parse(pData, size, createFct, pHeader); + TiffComponent::AutoPtr parsedTree = parse(pData, size, root, pHeader); if (0 != parsedTree.get()) { // Attempt to update existing TIFF components based on metadata entries TiffEncoder encoder(exifData, @@ -664,7 +740,7 @@ namespace Exiv2 { if (!encoder.dirty()) writeMethod = wmNonIntrusive; } if (writeMethod == wmIntrusive) { - createdTree = createFct(Tag::root, Group::none); + createdTree = TiffCreator::create(root, Group::none); TiffEncoder encoder(exifData, iptcData, xmpData, @@ -672,7 +748,7 @@ namespace Exiv2 { pHeader->byteOrder(), findEncoderFct); // Add entries from metadata to composite - encoder.add(createdTree.get(), parsedTree.get(), createFct); + encoder.add(createdTree.get(), parsedTree.get(), root); // Write binary representation from the composite tree uint32_t offset = pHeader->write(blob); uint32_t imageIdx(uint32_t(-1)); @@ -694,7 +770,7 @@ namespace Exiv2 { TiffComponent::AutoPtr TiffParserWorker::parse( const byte* pData, uint32_t size, - TiffCompFactoryFct createFct, + uint32_t root, TiffHeaderBase* pHeader ) { @@ -702,11 +778,11 @@ namespace Exiv2 { if (!pHeader->read(pData, size) || pHeader->offset() >= size) { throw Error(3, "TIFF"); } - TiffComponent::AutoPtr rootDir = createFct(Tag::root, Group::none); + TiffComponent::AutoPtr rootDir = TiffCreator::create(root, Group::none); if (0 != rootDir.get()) { rootDir->setStart(pData + pHeader->offset()); TiffRwState::AutoPtr state( - new TiffRwState(pHeader->byteOrder(), 0, createFct)); + new TiffRwState(pHeader->byteOrder(), 0)); TiffReader reader(pData, size, rootDir.get(), state); rootDir->accept(reader); } diff --git a/src/tiffimage_int.hpp b/src/tiffimage_int.hpp index 1e192922..ba67de87 100644 --- a/src/tiffimage_int.hpp +++ b/src/tiffimage_int.hpp @@ -137,28 +137,82 @@ namespace Exiv2 { }; // class TiffHeader /*! - @brief TIFF component factory for standard TIFF components. + @brief Data structure used as a row (element) of a table (array) + defining the TIFF component used for each tag in a group. + */ + struct TiffGroupStruct { + struct Key; + //! Comparison operator to compare a TiffGroupStruct with a TiffGroupStruct::Key + bool operator==(const Key& key) const; + //! Return the tag corresponding to the extended tag + uint16_t tag() const { return static_cast(extendedTag_ & 0xffff); } + + // DATA + uint32_t extendedTag_; //!< Tag (32 bit so that it can contain special tags) + uint16_t group_; //!< Group that contains the tag + NewTiffCompFct newTiffCompFct_; //!< Function to create the correct TIFF component + }; + + //! Search key for TIFF group structure. + struct TiffGroupStruct::Key { + //! Constructor + Key(uint32_t e, uint16_t g) : e_(e), g_(g) {} + uint32_t e_; //!< Extended tag + uint16_t g_; //!< %Group + }; + + /*! + @brief Data structure used as a row of the table which describes TIFF trees. + Multiple trees are needed as TIFF-based RAW image formats do not always + use standard TIFF layout. + */ + struct TiffTreeStruct { + struct Key; + //! Comparison operator to compare a TiffTreeStruct with a TiffTreeStruct::Key + bool operator==(const Key& key) const; + + // DATA + uint32_t root_; //!< Tree root element, identifies a tree + uint16_t group_; //!< Each group is a node in the tree + uint16_t parentGroup_; //!< Parent group + uint32_t parentExtTag_; //!< Parent tag (32 bit so that it can contain special tags) + }; + + //! Search key for TIFF tree structure. + struct TiffTreeStruct::Key { + //! Constructor + Key(uint32_t r, uint16_t g) : r_(r), g_(g) {} + uint32_t r_; //!< Root + uint16_t g_; //!< %Group + }; + + /*! + @brief TIFF component factory. */ class TiffCreator { public: /*! @brief Create the TiffComponent for TIFF entry \em extendedTag and - \em group based on the embedded lookup table. If the pointer - that is returned is 0, then the TIFF entry should be ignored. + \em group. The embedded lookup table is used to find the correct + component creation function. If the pointer that is returned + is 0, then the TIFF entry should be ignored. */ static std::auto_ptr create(uint32_t extendedTag, uint16_t group); /*! - @brief Get the path, i.e., a list of TiffStructure pointers, from - the root TIFF element to the TIFF entry \em extendedTag and + @brief Get the path, i.e., a list of extended tag and group pairs, from + the \em root TIFF element to the TIFF entry \em extendedTag and \em group. */ static void getPath(TiffPath& tiffPath, uint32_t extendedTag, - uint16_t group); + uint16_t group, + uint32_t root); private: - static const TiffStructure tiffStructure_[]; // parse(const byte* pData, uint32_t size, - TiffCompFactoryFct createFct, + uint32_t root, TiffHeaderBase* pHeader); }; // class TiffParserWorker diff --git a/src/tiffparse.cpp b/src/tiffparse.cpp index 31f0d5be..e24f118c 100644 --- a/src/tiffparse.cpp +++ b/src/tiffparse.cpp @@ -41,16 +41,13 @@ try { TiffHeader tiffHeader; if (!tiffHeader.read(buf.pData_, buf.size_)) throw Error(3, "TIFF"); - TiffCompFactoryFct createFct = TiffCreator::create; - - TiffComponent::AutoPtr rootDir = createFct(Tag::root, Group::none); + TiffComponent::AutoPtr rootDir = TiffCreator::create(Tag::root, Group::none); if (0 == rootDir.get()) { throw Error(1, "No root element defined in TIFF structure"); } rootDir->setStart(buf.pData_ + tiffHeader.offset()); - TiffRwState::AutoPtr state( - new TiffRwState(tiffHeader.byteOrder(), 0, createFct)); + TiffRwState::AutoPtr state(new TiffRwState(tiffHeader.byteOrder(), 0)); TiffReader reader(buf.pData_, buf.size_, diff --git a/src/tiffvisitor.cpp b/src/tiffvisitor.cpp index c69789db..12a63f14 100644 --- a/src/tiffvisitor.cpp +++ b/src/tiffvisitor.cpp @@ -873,9 +873,9 @@ namespace Exiv2 { } void TiffEncoder::add( - TiffComponent* pRootDir, - TiffComponent* pSourceDir, - TiffCompFactoryFct createFct + TiffComponent* pRootDir, + TiffComponent* pSourceDir, + uint32_t root ) { assert(pRootDir != 0); @@ -894,12 +894,8 @@ namespace Exiv2 { if (group == Group::mn) continue; // Assumption is that the corresponding TIFF entry doesn't exist - - // Todo: getPath depends on the Creator class, not the createFct - // how to get it through to here??? - TiffPath tiffPath; - TiffCreator::getPath(tiffPath, i->tag(), group); + TiffCreator::getPath(tiffPath, i->tag(), group, root); TiffComponent* tc = pRootDir->addPath(i->tag(), tiffPath); TiffEntryBase* object = dynamic_cast(tc); #ifdef DEBUG @@ -1067,8 +1063,6 @@ namespace Exiv2 { { if (state.get() != 0) { if (pOrigState_ != pState_) delete pState_; - // 0 for create function indicates 'no change' - if (state->createFct_ == 0) state->createFct_ = pState_->createFct_; // invalidByteOrder indicates 'no change' if (state->byteOrder_ == invalidByteOrder) state->byteOrder_ = pState_->byteOrder_; pState_ = state.release(); @@ -1087,14 +1081,6 @@ namespace Exiv2 { return pState_->baseOffset_; } - TiffComponent::AutoPtr TiffReader::create(uint32_t extendedTag, - uint16_t group) const - { - assert(pState_); - assert(pState_->createFct_); - return pState_->createFct_(extendedTag, group); - } - void TiffReader::readDataEntryBase(TiffDataEntryBase* object) { assert(object != 0); @@ -1195,7 +1181,7 @@ namespace Exiv2 { return; } uint16_t tag = getUShort(p, byteOrder()); - TiffComponent::AutoPtr tc = create(tag, object->group()); + TiffComponent::AutoPtr tc = TiffCreator::create(tag, object->group()); // The assertion typically fails if a component is not configured in // the TIFF structure table assert(tc.get()); @@ -1216,7 +1202,7 @@ namespace Exiv2 { TiffComponent::AutoPtr tc(0); uint32_t next = getLong(p, byteOrder()); if (next) { - tc = create(Tag::next, object->group()); + tc = TiffCreator::create(Tag::next, object->group()); #ifndef SUPPRESS_WARNINGS if (tc.get() == 0) { std::cerr << "Warning: " @@ -1447,7 +1433,7 @@ namespace Exiv2 { const uint16_t sz = static_cast(object->size_ / object->elSize()); for (uint16_t i = 0; i < sz; ++i) { uint16_t tag = i; - TiffComponent::AutoPtr tc = create(tag, object->elGroup()); + TiffComponent::AutoPtr tc = TiffCreator::create(tag, object->elGroup()); assert(tc.get()); tc->setStart(object->pData() + i * object->elSize()); object->addChild(tc); diff --git a/src/tiffvisitor_int.hpp b/src/tiffvisitor_int.hpp index 23244449..3652c0a4 100644 --- a/src/tiffvisitor_int.hpp +++ b/src/tiffvisitor_int.hpp @@ -426,9 +426,9 @@ namespace Exiv2 { each existing component. */ void add( - TiffComponent* pRootDir, - TiffComponent* pSourceDir, - TiffCompFactoryFct createFct + TiffComponent* pRootDir, + TiffComponent* pSourceDir, + uint32_t root ); //! Set the dirty flag and end of traversing signal. void setDirty(bool flag =true); @@ -510,11 +510,9 @@ namespace Exiv2 { //@{ //! Constructor. TiffRwState(ByteOrder byteOrder, - uint32_t baseOffset, - TiffCompFactoryFct createFct =0) + uint32_t baseOffset) : byteOrder_(byteOrder), - baseOffset_(baseOffset), - createFct_(createFct) {} + baseOffset_(baseOffset) {} //@} //! @name Accessors @@ -536,21 +534,11 @@ namespace Exiv2 { to the basis for such makernote offsets. */ uint32_t baseOffset() const { return baseOffset_; } - /*! - @brief Return the factory function to create new TIFF components. - - Different create functions may use different lookup tables, so that - makernotes can independently use their own factory function and lookup - table, which can be defined together with the makernote - implementation. - */ - TiffCompFactoryFct createFct() const { return createFct_; } //@} private: ByteOrder byteOrder_; const uint32_t baseOffset_; - TiffCompFactoryFct createFct_; }; // TiffRwState /*! @@ -625,9 +613,6 @@ namespace Exiv2 { ByteOrder byteOrder() const; //! Return the base offset. See class TiffRwState for details uint32_t baseOffset() const; - //! Create a TIFF component for \em extendedTag and group - std::auto_ptr create(uint32_t extendedTag, - uint16_t group) const; //@} private: