From 73c42ee8f6b42e100de87f07f06784815570509c Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Thu, 20 Apr 2006 17:46:41 +0000 Subject: [PATCH] TIFF parser checkpoint (experimental): Added Canon makernote. Uses a Canon TIFF component factory when the makernote is parsed. Added TiffArrayEntry and TiffArrayElement components. --- src/Makefile | 68 +++++++++++++++++++----- src/canonmn2.cpp | 103 ++++++++++++++++++++++++++++++++++++ src/canonmn2.hpp | 109 ++++++++++++++++++++++++++++++++++++++ src/fujimn2.cpp | 3 +- src/fujimn2.hpp | 3 +- src/makernote2.cpp | 12 +++-- src/makernote2.hpp | 46 ++++++++++++---- src/mnreg.cpp | 8 +-- src/tiffcomposite.cpp | 95 ++++++++++++++++++++++++++++++--- src/tiffcomposite.hpp | 119 ++++++++++++++++++++++++++++++++++++++++++ src/tiffparse.cpp | 2 + src/tiffparser.cpp | 36 ++----------- src/tiffparser.hpp | 48 ----------------- src/tiffvisitor.cpp | 89 ++++++++++++++++++++++++++++++- src/tiffvisitor.hpp | 20 +++++++ 15 files changed, 643 insertions(+), 118 deletions(-) create mode 100644 src/canonmn2.cpp create mode 100644 src/canonmn2.hpp diff --git a/src/Makefile b/src/Makefile index 7d9a76a8..8d944380 100644 --- a/src/Makefile +++ b/src/Makefile @@ -47,15 +47,44 @@ include $(top_srcdir)/config/config.mk # Source files # Add standalone C++ header files to this list -CCHDR = exv_conf.h exv_msvc.h mn.hpp rcsid.hpp +CCHDR = exv_conf.h \ + exv_msvc.h \ + mn.hpp \ + rcsid.hpp # Add library C++ source files to this list -CCSRC = basicio.cpp canonmn.cpp crwimage.cpp datasets.cpp error.cpp exif.cpp \ - futils.cpp fujimn.cpp fujimn2.cpp ifd.cpp image.cpp imgreg.cpp iptc.cpp \ - jpgimage.cpp makernote.cpp makernote2.cpp metadatum.cpp mnreg.cpp \ - nikonmn.cpp olympusmn.cpp olympusmn2.cpp panasonicmn.cpp sigmamn.cpp \ - sonymn.cpp tags.cpp tiffcomposite.cpp tiffimage.cpp tiffparser.cpp \ - tiffvisitor.cpp types.cpp value.cpp +CCSRC = basicio.cpp \ + canonmn.cpp \ + canonmn2.cpp \ + crwimage.cpp \ + datasets.cpp \ + error.cpp \ + exif.cpp \ + futils.cpp \ + fujimn.cpp \ + fujimn2.cpp \ + ifd.cpp \ + image.cpp \ + imgreg.cpp \ + iptc.cpp \ + jpgimage.cpp \ + makernote.cpp \ + makernote2.cpp \ + metadatum.cpp \ + mnreg.cpp \ + nikonmn.cpp \ + olympusmn.cpp \ + olympusmn2.cpp \ + panasonicmn.cpp \ + sigmamn.cpp \ + sonymn.cpp \ + tags.cpp \ + tiffcomposite.cpp \ + tiffimage.cpp \ + tiffparser.cpp \ + tiffvisitor.cpp \ + types.cpp \ + value.cpp # Add library C source files to this list ifndef HAVE_TIMEGM @@ -63,15 +92,30 @@ CSRC = localtime.c endif # Add source files of simple applications to this list -BINSRC = addmoddel.cpp crwedit.cpp crwparse.cpp dataarea-test.cpp \ - exifcomment.cpp exifdata-test.cpp exifprint.cpp ifd-test.cpp iotest.cpp \ - iptceasy.cpp iptcprint.cpp iptctest.cpp key-test.cpp makernote-test.cpp \ - taglist.cpp write-test.cpp write2-test.cpp tiffparse.cpp +BINSRC = addmoddel.cpp \ + crwedit.cpp \ + crwparse.cpp \ + dataarea-test.cpp \ + exifcomment.cpp \ + exifdata-test.cpp \ + exifprint.cpp \ + ifd-test.cpp \ + iotest.cpp \ + iptceasy.cpp \ + iptcprint.cpp \ + iptctest.cpp \ + key-test.cpp \ + makernote-test.cpp \ + taglist.cpp \ + write-test.cpp \ + write2-test.cpp \ + tiffparse.cpp # Main source file of the Exiv2 application EXIV2MAIN = exiv2.cpp # Add additional source files of the Exiv2 application to this list -EXIV2SRC = actions.cpp utils.cpp +EXIV2SRC = actions.cpp \ + utils.cpp # C source files of the Exiv2 application ifndef HAVE_TIMEGM EXIVCSRC = localtime.c diff --git a/src/canonmn2.cpp b/src/canonmn2.cpp new file mode 100644 index 00000000..fcccace2 --- /dev/null +++ b/src/canonmn2.cpp @@ -0,0 +1,103 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2006 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: canonmn2.cpp + Version: $Rev$ + Author(s): Andreas Huggel (ahu) + History: 18-Apr-06, ahu: created + */ +// ***************************************************************************** +#include "rcsid.hpp" +EXIV2_RCSID("@(#) $Id$"); + +// Define DEBUG to output debug information to std::cerr, e.g, by calling make +// like this: make DEFS=-DDEBUG makernote2.o +//#define DEBUG + +// ***************************************************************************** +// included header files +#ifdef _MSC_VER +# include "exv_msvc.h" +#else +# include "exv_conf.h" +#endif + +#include "canonmn2.hpp" +#include "tiffcomposite.hpp" +#include "types.hpp" + +// + standard includes + +// ***************************************************************************** +// class member definitions +namespace Exiv2 { + + const TiffStructure TiffCanonCreator::tiffStructure_[] = { + // ext. tag group create function new group + //--------- -------------- ------------------- -------------- + { 0x0001, Group::canonmn, newTiffArrayEntry, Group::canoncs }, + { 0x0004, Group::canonmn, newTiffArrayEntry, Group::canonsi }, + { 0x000f, Group::canonmn, newTiffArrayEntry, Group::canoncf }, + { Tag::all, Group::canoncs, newTiffArrayElement, Group::canoncs }, + { Tag::all, Group::canonsi, newTiffArrayElement, Group::canonsi }, + { Tag::all, Group::canoncf, newTiffArrayElement, Group::canoncf } + }; + + TiffComponent::AutoPtr TiffCanonCreator::create(uint32_t extendedTag, + uint16_t group) + { + const TiffStructure* ts = find(tiffStructure_, + TiffStructure::Key(extendedTag, group)); + TiffComponent::AutoPtr tc(0); + uint16_t tag = static_cast(extendedTag & 0xffff); + if (ts && ts->newTiffCompFct_) { + tc = ts->newTiffCompFct_(tag, ts); + } + if (!ts) { + tc = TiffComponent::AutoPtr(new TiffEntry(tag, group)); + } + return tc; + } // TiffCanonCreator::create + + TiffRwState::AutoPtr TiffCanonMn::doGetState(uint32_t /*mnOffset*/, + ByteOrder byteOrder) const + { + // Byteorder: No change + // Offsets : No change (relative to the start of the TIFF header) + // Creator : Canon TIFF component factory + return TiffRwState::AutoPtr( + new TiffRwState(byteOrder, 0, TiffCanonCreator::create)); + } + + // ************************************************************************* + // free functions + + TiffComponent* newCanonMn(uint16_t tag, + uint16_t group, + uint16_t mnGroup, + const byte* /*pData*/, + uint32_t /*size*/, + ByteOrder /*byteOrder*/) + { + return new TiffCanonMn(tag, group, mnGroup); + } + +} // namespace Exiv2 diff --git a/src/canonmn2.hpp b/src/canonmn2.hpp new file mode 100644 index 00000000..3879d0b4 --- /dev/null +++ b/src/canonmn2.hpp @@ -0,0 +1,109 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2006 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 canonmn2.hpp + @brief TIFF Canon makernote + @version $Rev$ + @author Andreas Huggel (ahu) + ahuggel@gmx.net + @date 18-Apr-06, ahu: created + */ +#ifndef CANONMN2_HPP_ +#define CANONMN2_HPP_ + +// ***************************************************************************** +// included header files +#include "makernote2.hpp" +#include "tiffcomposite.hpp" +#include "types.hpp" + +// + standard includes + +// ***************************************************************************** +// namespace extensions +namespace Exiv2 { + +// ***************************************************************************** +// class definitions + + namespace Group { + const uint16_t canonmn = 259; //!< Canon makernote + const uint16_t canoncs = 260; //!< Canon camera settings + const uint16_t canonsi = 261; //!< Canon shot info + const uint16_t canoncf = 262; //!< Canon customer functions + } + + /*! + @brief Canon Makernote + */ + class TiffCanonMn : public TiffIfdMakernote { + public: + //! @name Creators + //@{ + //! Default constructor + TiffCanonMn(uint16_t tag, uint16_t group, uint16_t mnGroup) + : TiffIfdMakernote(tag, group, mnGroup) {} + //! Virtual destructor + virtual ~TiffCanonMn() {} + //@} + private: + //! @name Accessors + //@{ + virtual TiffRwState::AutoPtr doGetState(uint32_t mnOffset, + ByteOrder byteOrder) const; + //@} + + }; // class TiffCanonMn + + /*! + @brief TIFF component factory for Canon TIFF components. + */ + class TiffCanonCreator { + public: + /*! + @brief Create the TiffComponent for TIFF entry \em extendedTag and + \em group based on the embedded lookup table. + + If a tag and group combination is not found in the table, a TiffEntry + is created. If the pointer that is returned is 0, then the TIFF entry + should be ignored. + */ + static TiffComponent::AutoPtr create(uint32_t extendedTag, + uint16_t group); + + private: + static const TiffStructure tiffStructure_[]; //addChild(tiffComponent); } // TiffMnEntry::doAddChild + void TiffArrayEntry::doAddChild(TiffComponent::AutoPtr tiffComponent) + { + elements_.push_back(tiffComponent.release()); + } // TiffArrayEntry::doAddChild + void TiffComponent::addNext(TiffComponent::AutoPtr tiffComponent) { doAddNext(tiffComponent); @@ -209,7 +233,64 @@ namespace Exiv2 { if (mn_) mn_->accept(visitor); } // TiffMnEntry::doAccept + void TiffArrayEntry::doAccept(TiffVisitor& visitor) + { + visitor.visitArrayEntry(this); + Components::const_iterator b = elements_.begin(); + Components::const_iterator e = elements_.end(); + for (Components::const_iterator i = b; visitor.go() && i != e; ++i) { + (*i)->accept(visitor); + } + } // TiffArrayEntry::doAccept + + void TiffArrayElement::doAccept(TiffVisitor& visitor) + { + visitor.visitArrayElement(this); + } // TiffArrayElement::doAccept + // ************************************************************************* // free functions + TiffComponent::AutoPtr newTiffDirectory(uint16_t tag, + const TiffStructure* ts) + { + assert(ts); + return TiffComponent::AutoPtr(new TiffDirectory(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_)); + } + + TiffComponent::AutoPtr newTiffArrayEntry(uint16_t tag, + const TiffStructure* ts) + { + assert(ts); + return TiffComponent::AutoPtr(new TiffArrayEntry(tag, + ts->group_, + ts->newGroup_)); + } + + TiffComponent::AutoPtr newTiffArrayElement(uint16_t tag, + const TiffStructure* ts) + { + assert(ts); + return TiffComponent::AutoPtr(new TiffArrayElement(tag, + ts->group_)); + } + } // namespace Exiv2 diff --git a/src/tiffcomposite.hpp b/src/tiffcomposite.hpp index 32bd3af9..c7cbd73b 100644 --- a/src/tiffcomposite.hpp +++ b/src/tiffcomposite.hpp @@ -52,6 +52,7 @@ namespace Exiv2 { class TiffMetadataDecoder; class TiffPrinter; class TiffIfdMakernote; + struct TiffStructure; // ***************************************************************************** // class definitions @@ -82,6 +83,7 @@ namespace Exiv2 { const uint32_t none = 0x10000; //!< Dummy tag const uint32_t root = 0x20000; //!< Special tag: root IFD const uint32_t next = 0x30000; //!< Special tag: next IFD + const uint32_t all = 0x40000; //!< Special tag: all tags in a group } /*! @@ -224,6 +226,40 @@ namespace Exiv2 { }; // class TiffComponent + /*! + Type for a function pointer for a function to create a TIFF component. + */ + typedef TiffComponent::AutoPtr (*NewTiffCompFct)(uint16_t tag, + const TiffStructure* ts); + + /*! + @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 + NewTiffCompFct newTiffCompFct_; //!< Function to create the correct TIFF component + uint16_t newGroup_; //!< Group of the newly created 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 + }; + /*! Type for a factory function to create new TIFF components. */ @@ -406,6 +442,89 @@ namespace Exiv2 { }; // class TiffMnEntry + /*! + @brief Composite to model an array of tags, each consisting of one + unsigned short value. Canon makernotes use such tags. The + elements of this component are usually of type TiffArrayElement. + If the type of the entry is not unsigned short, it degenerates + to a standard TIFF entry. + */ + class TiffArrayEntry : public TiffEntryBase { + public: + //! @name Creators + //@{ + //! Default constructor + TiffArrayEntry(uint16_t tag, uint16_t group, uint16_t elGroup) + : TiffEntryBase(tag, group), elGroup_(elGroup) {} + //! Virtual destructor + virtual ~TiffArrayEntry(); + //@} + + //! @name Accessors + //@{ + //! Return the group for the array elements + uint16_t elGroup() const { return elGroup_; } + //@} + + private: + //! @name Manipulators + //@{ + virtual void doAddChild(TiffComponent::AutoPtr tiffComponent); + virtual void doAccept(TiffVisitor& visitor); + //@} + + private: + // DATA + uint16_t elGroup_; //!< Group for the elements + Components elements_; //!< List of elements in this composite + }; // class TiffArrayEntry + + /*! + @brief Element of a TiffArrayEntry. The value is exactly one unsigned + short component. Canon makernotes use arrays of such elements. + */ + class TiffArrayElement : public TiffEntryBase { + public: + //! @name Creators + //@{ + //! Constructor + TiffArrayElement(uint16_t tag, uint16_t group) + : TiffEntryBase(tag, group) {} + //! Virtual destructor. + virtual ~TiffArrayElement() {} + //@} + + private: + //! @name Manipulators + //@{ + virtual void doAccept(TiffVisitor& visitor); + //@} + + }; // class TiffArrayElement + +// ***************************************************************************** +// template, inline and free functions + + //! 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 sub-directory + TiffComponent::AutoPtr newTiffSubIfd(uint16_t tag, + const TiffStructure* ts); + + //! Function to create and initialize a new TIFF makernote entry + TiffComponent::AutoPtr newTiffMnEntry(uint16_t tag, + const TiffStructure* ts); + + //! Function to create and initialize a new array entry + TiffComponent::AutoPtr newTiffArrayEntry(uint16_t tag, + const TiffStructure* ts); + + //! Function to create and initialize a new array element + TiffComponent::AutoPtr newTiffArrayElement(uint16_t tag, + const TiffStructure* ts); + } // namespace Exiv2 #endif // #ifndef TIFFCOMPOSITE_HPP_ diff --git a/src/tiffparse.cpp b/src/tiffparse.cpp index d6db126b..973e722f 100644 --- a/src/tiffparse.cpp +++ b/src/tiffparse.cpp @@ -3,6 +3,8 @@ // Print the structure of a TIFF file #include "tiffparser.hpp" +#include "tiffcomposite.hpp" +#include "tiffvisitor.hpp" #include "tiffimage.hpp" #include "futils.hpp" diff --git a/src/tiffparser.cpp b/src/tiffparser.cpp index e47339c8..61285661 100644 --- a/src/tiffparser.cpp +++ b/src/tiffparser.cpp @@ -43,6 +43,8 @@ EXIV2_RCSID("@(#) $Id$"); #include "tiffparser.hpp" #include "tiffcomposite.hpp" +#include "tiffvisitor.hpp" +#include "error.hpp" // + standard includes #include @@ -94,22 +96,17 @@ namespace Exiv2 { { Tag::next, Group::ifd0, newTiffDirectory, Group::ifd0 } }; - bool TiffStructure::operator==(const TiffStructure::Key& key) const - { - return key.e_ == extendedTag_ && key.g_ == group_; - } - TiffComponent::AutoPtr TiffCreator::create(uint32_t extendedTag, uint16_t group) { const TiffStructure* ts = find(tiffStructure_, TiffStructure::Key(extendedTag, group)); TiffComponent::AutoPtr tc(0); + uint16_t tag = static_cast(extendedTag & 0xffff); if (ts && ts->newTiffCompFct_) { - tc = ts->newTiffCompFct_(ts); + tc = ts->newTiffCompFct_(tag, ts); } if (!ts) { - uint16_t tag = static_cast(extendedTag & 0xffff); tc = TiffComponent::AutoPtr(new TiffEntry(tag, group)); } return tc; @@ -141,29 +138,4 @@ namespace Exiv2 { } // TiffParser::decode - // ************************************************************************* - // free functions - - TiffComponent::AutoPtr newTiffDirectory(const TiffStructure* ts) - { - assert(ts); - return TiffComponent::AutoPtr(new TiffDirectory(ts->tag(), ts->newGroup_)); - } - - TiffComponent::AutoPtr newTiffSubIfd(const TiffStructure* ts) - { - assert(ts); - return TiffComponent::AutoPtr(new TiffSubIfd(ts->tag(), - ts->group_, - ts->newGroup_)); - } - - TiffComponent::AutoPtr newTiffMnEntry(const TiffStructure* ts) - { - assert(ts); - return TiffComponent::AutoPtr(new TiffMnEntry(ts->tag(), - ts->group_, - ts->newGroup_)); - } - } // namespace Exiv2 diff --git a/src/tiffparser.hpp b/src/tiffparser.hpp index 75675d9f..d28eb5a4 100644 --- a/src/tiffparser.hpp +++ b/src/tiffparser.hpp @@ -32,8 +32,6 @@ // ***************************************************************************** // included header files #include "tiffcomposite.hpp" -#include "tiffvisitor.hpp" -#include "error.hpp" #include "types.hpp" // + standard includes @@ -47,45 +45,11 @@ namespace Exiv2 { // ***************************************************************************** // class declarations - struct TiffStructure; class Image; // ***************************************************************************** // class definitions - /*! - Type for a function pointer for a function to create a TIFF component. - */ - typedef TiffComponent::AutoPtr (*NewTiffCompFct)(const TiffStructure* ts); - - /*! - @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 - NewTiffCompFct newTiffCompFct_; //!< Function to create the correct TIFF component - uint16_t newGroup_; //!< Group of the newly created 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 - }; - /*! @brief TIFF component factory for standard TIFF components. */ @@ -133,18 +97,6 @@ namespace Exiv2 { TiffCompFactoryFct createFct); }; // class TiffParser -// ***************************************************************************** -// template, inline and free functions - - //! Function to create and initialize a new TIFF directory - TiffComponent::AutoPtr newTiffDirectory(const TiffStructure* ts); - - //! Function to create and initialize a new TIFF sub-directory - TiffComponent::AutoPtr newTiffSubIfd(const TiffStructure* ts); - - //! Function to create and initialize a new TIFF makernote entry - TiffComponent::AutoPtr newTiffMnEntry(const TiffStructure* ts); - } // namespace Exiv2 #endif // #ifndef TIFFPARSER_HPP_ diff --git a/src/tiffvisitor.cpp b/src/tiffvisitor.cpp index be4ea9a7..1341dc34 100644 --- a/src/tiffvisitor.cpp +++ b/src/tiffvisitor.cpp @@ -97,6 +97,16 @@ namespace Exiv2 { findObject(object); } + void TiffFinder::visitArrayEntry(TiffArrayEntry* object) + { + findObject(object); + } + + void TiffFinder::visitArrayElement(TiffArrayElement* object) + { + findObject(object); + } + void TiffMetadataDecoder::visitEntry(TiffEntry* object) { decodeTiffEntry(object); @@ -133,6 +143,21 @@ namespace Exiv2 { pImage_->exifData().add(k, object->pValue()); } // TiffMetadataDecoder::decodeTiffEntry + void TiffMetadataDecoder::visitArrayEntry(TiffArrayEntry* object) + { + assert(object != 0); + + // Array entry degenerates to a normal entry if type is not unsignedShort + if (object->typeId() != unsignedShort) { + decodeTiffEntry(object); + } + } + + void TiffMetadataDecoder::visitArrayElement(TiffArrayElement* object) + { + decodeTiffEntry(object); + } + const std::string TiffPrinter::indent_(" "); void TiffPrinter::incIndent() @@ -215,6 +240,24 @@ namespace Exiv2 { } // TiffPrinter::printTiffEntry + void TiffPrinter::visitArrayEntry(TiffArrayEntry* object) + { + // Array entry degenerates to a normal entry if type is not unsignedShort + if (object->typeId() != unsignedShort) { + printTiffEntry(object, prefix()); + } + else { + os_ << prefix() << "Array Entry " << object->groupName() + << " tag 0x" << std::setw(4) << std::setfill('0') + << std::hex << std::right << object->tag() << "\n"; + } + } // TiffPrinter::visitArrayEntry + + void TiffPrinter::visitArrayElement(TiffArrayElement* object) + { + printTiffEntry(object, prefix()); + } // TiffPrinter::visitArrayElement + TiffReader::TiffReader(const byte* pData, uint32_t size, TiffComponent* pRoot, @@ -402,7 +445,7 @@ namespace Exiv2 { } // Modify reader for Makernote peculiarities, byte order, offset, // component factory - changeState(object->getState(object->start() - pData_)); + changeState(object->getState(object->start() - pData_, byteOrder())); object->ifd_.setStart(object->start() + object->ifdOffset()); } // TiffReader::visitIfdMakernote @@ -484,4 +527,48 @@ namespace Exiv2 { } // TiffReader::readTiffEntry + void TiffReader::visitArrayEntry(TiffArrayEntry* object) + { + assert(object != 0); + + readTiffEntry(object); + if (object->typeId() == unsignedShort) { + for (uint16_t i = 0; i < static_cast(object->count()); ++i) { + uint16_t tag = i; + TiffComponent::AutoPtr tc = create(tag, object->elGroup()); + tc->setStart(object->pData() + i * 2); + object->addChild(tc); + } + } + + } // TiffReader::visitArrayEntry + + void TiffReader::visitArrayElement(TiffArrayElement* object) + { + assert(object != 0); + + const byte* p = object->start(); + assert(p >= pData_); + + if (p + 2 > pLast_) { +#ifndef SUPPRESS_WARNINGS + std::cerr << "Error: Array element in group " << object->groupName() + << "requests access to memory beyond the data buffer. " + << "Skipping element.\n"; +#endif + return; + } + object->type_ = unsignedShort; + object->count_ = 1; + object->size_ = TypeInfo::typeSize(object->typeId()) * object->count(); + object->offset_ = 0; + object->pData_ = p; + Value::AutoPtr v = Value::create(object->typeId()); + if (v.get()) { + v->read(object->pData(), object->size(), byteOrder()); + object->pValue_ = v.release(); + } + + } // TiffReader::visitArrayElement + } // namespace Exiv2 diff --git a/src/tiffvisitor.hpp b/src/tiffvisitor.hpp index 342e5d37..0a25d034 100644 --- a/src/tiffvisitor.hpp +++ b/src/tiffvisitor.hpp @@ -104,6 +104,10 @@ namespace Exiv2 { virtual void visitIfdMakernote(TiffIfdMakernote* object) =0; //! Operation to perform after processing an IFD makernote virtual void visitIfdMakernoteEnd(TiffIfdMakernote* object) {} + //! Operation to perform for an array entry (as found in Canon makernotes) + virtual void visitArrayEntry(TiffArrayEntry* object) =0; + //! Operation to perform for an array element + virtual void visitArrayElement(TiffArrayElement* object) =0; //@} //! @name Accessors @@ -146,6 +150,10 @@ namespace Exiv2 { virtual void visitMnEntry(TiffMnEntry* object); //! Find tag and group in an IFD makernote virtual void visitIfdMakernote(TiffIfdMakernote* object); + //! Find tag and group in an array entry component + virtual void visitArrayEntry(TiffArrayEntry* object); + //! Find tag and group in an array element + virtual void visitArrayElement(TiffArrayElement* object); //! Check if \em object matches \em tag and \em group void findObject(TiffComponent* object); @@ -196,6 +204,10 @@ namespace Exiv2 { virtual void visitMnEntry(TiffMnEntry* object); //! Decode an IFD makernote virtual void visitIfdMakernote(TiffIfdMakernote* object); + //! Decode an array entry component + virtual void visitArrayEntry(TiffArrayEntry* object); + //! Decode an array element + virtual void visitArrayElement(TiffArrayElement* object); //! Decode a standard TIFF entry void decodeTiffEntry(const TiffEntryBase* object); @@ -288,6 +300,10 @@ namespace Exiv2 { virtual void visitIfdMakernote(TiffIfdMakernote* object); //! Reset reader to its original state, undo makernote specific settings virtual void visitIfdMakernoteEnd(TiffIfdMakernote* object); + //! Read an array entry component from the data buffer + virtual void visitArrayEntry(TiffArrayEntry* object); + //! Read an array element from the data buffer + virtual void visitArrayElement(TiffArrayElement* object); //! Read a standard TIFF entry from the data buffer void readTiffEntry(TiffEntryBase* object); @@ -349,6 +365,10 @@ namespace Exiv2 { virtual void visitMnEntry(TiffMnEntry* object); //! Print an IFD makernote virtual void visitIfdMakernote(TiffIfdMakernote* object); + //! Print an array entry component + virtual void visitArrayEntry(TiffArrayEntry* object); + //! Print an array element + virtual void visitArrayElement(TiffArrayElement* object); //! Increment the indent by one level void incIndent();