TIFF parser checkpoint (experimental): Added Canon makernote. Uses a Canon TIFF component factory when the makernote is parsed. Added TiffArrayEntry and TiffArrayElement components.

v0.27.3
Andreas Huggel 19 years ago
parent 0fa2d525fc
commit 73c42ee8f6

@ -47,15 +47,44 @@ include $(top_srcdir)/config/config.mk
# Source files # Source files
# Add standalone C++ header files to this list # 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 # Add library C++ source files to this list
CCSRC = basicio.cpp canonmn.cpp crwimage.cpp datasets.cpp error.cpp exif.cpp \ CCSRC = basicio.cpp \
futils.cpp fujimn.cpp fujimn2.cpp ifd.cpp image.cpp imgreg.cpp iptc.cpp \ canonmn.cpp \
jpgimage.cpp makernote.cpp makernote2.cpp metadatum.cpp mnreg.cpp \ canonmn2.cpp \
nikonmn.cpp olympusmn.cpp olympusmn2.cpp panasonicmn.cpp sigmamn.cpp \ crwimage.cpp \
sonymn.cpp tags.cpp tiffcomposite.cpp tiffimage.cpp tiffparser.cpp \ datasets.cpp \
tiffvisitor.cpp types.cpp value.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 # Add library C source files to this list
ifndef HAVE_TIMEGM ifndef HAVE_TIMEGM
@ -63,15 +92,30 @@ CSRC = localtime.c
endif endif
# Add source files of simple applications to this list # Add source files of simple applications to this list
BINSRC = addmoddel.cpp crwedit.cpp crwparse.cpp dataarea-test.cpp \ BINSRC = addmoddel.cpp \
exifcomment.cpp exifdata-test.cpp exifprint.cpp ifd-test.cpp iotest.cpp \ crwedit.cpp \
iptceasy.cpp iptcprint.cpp iptctest.cpp key-test.cpp makernote-test.cpp \ crwparse.cpp \
taglist.cpp write-test.cpp write2-test.cpp tiffparse.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 # Main source file of the Exiv2 application
EXIV2MAIN = exiv2.cpp EXIV2MAIN = exiv2.cpp
# Add additional source files of the Exiv2 application to this list # 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 # C source files of the Exiv2 application
ifndef HAVE_TIMEGM ifndef HAVE_TIMEGM
EXIVCSRC = localtime.c EXIVCSRC = localtime.c

@ -0,0 +1,103 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2006 Andreas Huggel <ahuggel@gmx.net>
*
* 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) <ahuggel@gmx.net>
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<uint16_t>(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

@ -0,0 +1,109 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2006 Andreas Huggel <ahuggel@gmx.net>
*
* 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)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@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_[]; //<! TIFF structure
}; // class TiffCanonCreator
// *****************************************************************************
// template, inline and free functions
//! Function to create a Canon makernote
TiffComponent* newCanonMn(uint16_t tag,
uint16_t group,
uint16_t mnGroup,
const byte* pData,
uint32_t size,
ByteOrder byteOrder);
} // namespace Exiv2
#endif // #ifndef CANONMN2_HPP_

@ -106,7 +106,8 @@ namespace Exiv2 {
return header_.ifdOffset(); return header_.ifdOffset();
} }
TiffRwState::AutoPtr TiffFujiMn::doGetState(uint32_t mnOffset) const TiffRwState::AutoPtr TiffFujiMn::doGetState(uint32_t mnOffset,
ByteOrder /*byteOrder*/) const
{ {
// Byteorder: from the header (little endian) // Byteorder: from the header (little endian)
// Offsets : relative to the start of the makernote // Offsets : relative to the start of the makernote

@ -108,7 +108,8 @@ namespace Exiv2 {
//@{ //@{
virtual bool doCheckHeader() const; virtual bool doCheckHeader() const;
virtual uint32_t doIfdOffset() const; virtual uint32_t doIfdOffset() const;
virtual TiffRwState::AutoPtr doGetState(uint32_t mnOffset) const; virtual TiffRwState::AutoPtr doGetState(uint32_t mnOffset,
ByteOrder byteOrder) const;
//@} //@}
private: private:

@ -57,6 +57,10 @@ namespace Exiv2 {
return make == key.make_.substr(0, make.length()); return make == key.make_.substr(0, make.length());
} }
TiffIfdMakernote::~TiffIfdMakernote()
{
}
bool TiffIfdMakernote::readHeader(const byte* pData, bool TiffIfdMakernote::readHeader(const byte* pData,
uint32_t size, uint32_t size,
ByteOrder byteOrder) ByteOrder byteOrder)
@ -74,12 +78,14 @@ namespace Exiv2 {
return doIfdOffset(); return doIfdOffset();
} }
TiffRwState::AutoPtr TiffIfdMakernote::getState(uint32_t mnOffset) const TiffRwState::AutoPtr TiffIfdMakernote::getState(uint32_t mnOffset,
ByteOrder byteOrder) const
{ {
return doGetState(mnOffset); return doGetState(mnOffset, byteOrder);
} }
TiffRwState::AutoPtr TiffIfdMakernote::doGetState(uint32_t mnOffset) const TiffRwState::AutoPtr TiffIfdMakernote::doGetState(uint32_t /*mnOffset*/,
ByteOrder /*byteOrder*/) const
{ {
return TiffRwState::AutoPtr(0); return TiffRwState::AutoPtr(0);
} }

@ -150,7 +150,7 @@ namespace Exiv2 {
TiffIfdMakernote(uint16_t tag, uint16_t group, uint16_t mnGroup) TiffIfdMakernote(uint16_t tag, uint16_t group, uint16_t mnGroup)
: TiffComponent(tag, group), ifd_(tag, mnGroup) {} : TiffComponent(tag, group), ifd_(tag, mnGroup) {}
//! Virtual destructor //! Virtual destructor
virtual ~TiffIfdMakernote() {} virtual ~TiffIfdMakernote() =0;
//@} //@}
//! @name Manipulators //! @name Manipulators
@ -178,8 +178,11 @@ namespace Exiv2 {
@param mnOffset Offset to the makernote from the start of the @param mnOffset Offset to the makernote from the start of the
TIFF header. TIFF header.
@param byteOrder Byte order in use at the point where the function
is called.
*/ */
TiffRwState::AutoPtr getState(uint32_t mnOffset) const; TiffRwState::AutoPtr getState(uint32_t mnOffset,
ByteOrder byteOrder) const;
//@} //@}
protected: protected:
@ -188,20 +191,43 @@ namespace Exiv2 {
virtual void doAddChild(TiffComponent::AutoPtr tiffComponent); virtual void doAddChild(TiffComponent::AutoPtr tiffComponent);
virtual void doAddNext(TiffComponent::AutoPtr tiffComponent); virtual void doAddNext(TiffComponent::AutoPtr tiffComponent);
virtual void doAccept(TiffVisitor& visitor); virtual void doAccept(TiffVisitor& visitor);
//! Implements readHeader(); /*!
@brief Implements readHeader().
The default implementation simply returns true. Derived classes for
makernotes which have a header should overwrite this.
*/
virtual bool doReadHeader(const byte* pData, virtual bool doReadHeader(const byte* pData,
uint32_t size, uint32_t size,
ByteOrder byteOrder) =0; ByteOrder byteOrder) { return true; }
//@} //@}
//! @name Accessors //! @name Accessors
//@{ //@{
//! Implements checkHeader() /*!
virtual bool doCheckHeader() const =0; @brief Implements checkHeader().
//! Implements ifdOffset()
virtual uint32_t doIfdOffset() const =0; Default implementation simply returns true. Derived classes for
//! Implements getState(). The default implementation returns a 0-pointer. makernotes which have a header should overwrite this.
virtual TiffRwState::AutoPtr doGetState(uint32_t mnOffset) const; */
virtual bool doCheckHeader() const { return true; }
/*!
@brief Implements ifdOffset().
Default implementation returns 0. Derived classes for makernotes
with an IFD which doesn't start at the beginning of the buffer
should overwrite this.
*/
virtual uint32_t doIfdOffset() const { return 0; }
/*!
@brief Implements getState().
Default implementation returns a 0-pointer. Derived classes for
makernotes which need a different byte order, base offset or
TIFF component factory should overwrite this.
*/
virtual TiffRwState::AutoPtr doGetState(uint32_t mnOffset,
ByteOrder byteOrder) const;
//@} //@}
private: private:

@ -32,8 +32,9 @@ EXIV2_RCSID("@(#) $Id$");
// ***************************************************************************** // *****************************************************************************
// included header files // included header files
#include "makernote2.hpp" #include "makernote2.hpp"
#include "olympusmn2.hpp" #include "canonmn2.hpp"
#include "fujimn2.hpp" #include "fujimn2.hpp"
#include "olympusmn2.hpp"
// + standard includes // + standard includes
@ -42,8 +43,9 @@ EXIV2_RCSID("@(#) $Id$");
namespace Exiv2 { namespace Exiv2 {
const TiffMnRegistry TiffMnCreator::registry_[] = { const TiffMnRegistry TiffMnCreator::registry_[] = {
{ "OLYMPUS", newOlympusMn, Group::olympmn }, { "Canon", newCanonMn, Group::canonmn },
{ "FUJIFILM", newFujiMn, Group::fujimn } { "FUJIFILM", newFujiMn, Group::fujimn },
{ "OLYMPUS", newOlympusMn, Group::olympmn }
}; };

@ -54,6 +54,12 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions // class member definitions
namespace Exiv2 { namespace Exiv2 {
bool TiffStructure::operator==(const TiffStructure::Key& key) const
{
return key.e_ == extendedTag_ && key.g_ == group_
|| Tag::all == extendedTag_ && key.g_ == group_;
}
void TiffHeade2::print(std::ostream& os, const std::string& prefix) const void TiffHeade2::print(std::ostream& os, const std::string& prefix) const
{ {
os << prefix os << prefix
@ -92,6 +98,15 @@ namespace Exiv2 {
delete mn_; delete mn_;
} // TiffMnEntry::~TiffMnEntry } // TiffMnEntry::~TiffMnEntry
TiffArrayEntry::~TiffArrayEntry()
{
Components::iterator b = elements_.begin();
Components::iterator e = elements_.end();
for (Components::iterator i = b; i != e; ++i) {
delete *i;
}
} // TiffArrayEntry::~TiffArrayEntry
const uint16_t TiffHeade2::tag_ = 42; const uint16_t TiffHeade2::tag_ = 42;
bool TiffHeade2::read(const byte* pData, uint32_t size) bool TiffHeade2::read(const byte* pData, uint32_t size)
@ -126,6 +141,10 @@ namespace Exiv2 {
case 5: group = "Iop"; break; case 5: group = "Iop"; break;
case 257: group = "Olympus"; break; case 257: group = "Olympus"; break;
case 258: group = "Fujifilm"; break; case 258: group = "Fujifilm"; break;
case 259: group = "Canon"; break;
case 260: group = "CanonCs1"; break;
case 261: group = "CanonCs2"; break;
case 262: group = "CanonCf"; break;
default: group = "Unknown"; break; default: group = "Unknown"; break;
} }
return group; return group;
@ -151,6 +170,11 @@ namespace Exiv2 {
if (mn_) mn_->addChild(tiffComponent); if (mn_) mn_->addChild(tiffComponent);
} // TiffMnEntry::doAddChild } // TiffMnEntry::doAddChild
void TiffArrayEntry::doAddChild(TiffComponent::AutoPtr tiffComponent)
{
elements_.push_back(tiffComponent.release());
} // TiffArrayEntry::doAddChild
void TiffComponent::addNext(TiffComponent::AutoPtr tiffComponent) void TiffComponent::addNext(TiffComponent::AutoPtr tiffComponent)
{ {
doAddNext(tiffComponent); doAddNext(tiffComponent);
@ -209,7 +233,64 @@ namespace Exiv2 {
if (mn_) mn_->accept(visitor); if (mn_) mn_->accept(visitor);
} // TiffMnEntry::doAccept } // 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 // 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 } // namespace Exiv2

@ -52,6 +52,7 @@ namespace Exiv2 {
class TiffMetadataDecoder; class TiffMetadataDecoder;
class TiffPrinter; class TiffPrinter;
class TiffIfdMakernote; class TiffIfdMakernote;
struct TiffStructure;
// ***************************************************************************** // *****************************************************************************
// class definitions // class definitions
@ -82,6 +83,7 @@ namespace Exiv2 {
const uint32_t none = 0x10000; //!< Dummy tag const uint32_t none = 0x10000; //!< Dummy tag
const uint32_t root = 0x20000; //!< Special tag: root IFD const uint32_t root = 0x20000; //!< Special tag: root IFD
const uint32_t next = 0x30000; //!< Special tag: next 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 }; // 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<uint16_t>(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. Type for a factory function to create new TIFF components.
*/ */
@ -406,6 +442,89 @@ namespace Exiv2 {
}; // class TiffMnEntry }; // 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 } // namespace Exiv2
#endif // #ifndef TIFFCOMPOSITE_HPP_ #endif // #ifndef TIFFCOMPOSITE_HPP_

@ -3,6 +3,8 @@
// Print the structure of a TIFF file // Print the structure of a TIFF file
#include "tiffparser.hpp" #include "tiffparser.hpp"
#include "tiffcomposite.hpp"
#include "tiffvisitor.hpp"
#include "tiffimage.hpp" #include "tiffimage.hpp"
#include "futils.hpp" #include "futils.hpp"

@ -43,6 +43,8 @@ EXIV2_RCSID("@(#) $Id$");
#include "tiffparser.hpp" #include "tiffparser.hpp"
#include "tiffcomposite.hpp" #include "tiffcomposite.hpp"
#include "tiffvisitor.hpp"
#include "error.hpp"
// + standard includes // + standard includes
#include <cassert> #include <cassert>
@ -94,22 +96,17 @@ namespace Exiv2 {
{ Tag::next, Group::ifd0, newTiffDirectory, Group::ifd0 } { 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, TiffComponent::AutoPtr TiffCreator::create(uint32_t extendedTag,
uint16_t group) uint16_t group)
{ {
const TiffStructure* ts = find(tiffStructure_, const TiffStructure* ts = find(tiffStructure_,
TiffStructure::Key(extendedTag, group)); TiffStructure::Key(extendedTag, group));
TiffComponent::AutoPtr tc(0); TiffComponent::AutoPtr tc(0);
uint16_t tag = static_cast<uint16_t>(extendedTag & 0xffff);
if (ts && ts->newTiffCompFct_) { if (ts && ts->newTiffCompFct_) {
tc = ts->newTiffCompFct_(ts); tc = ts->newTiffCompFct_(tag, ts);
} }
if (!ts) { if (!ts) {
uint16_t tag = static_cast<uint16_t>(extendedTag & 0xffff);
tc = TiffComponent::AutoPtr(new TiffEntry(tag, group)); tc = TiffComponent::AutoPtr(new TiffEntry(tag, group));
} }
return tc; return tc;
@ -141,29 +138,4 @@ namespace Exiv2 {
} // TiffParser::decode } // 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 } // namespace Exiv2

@ -32,8 +32,6 @@
// ***************************************************************************** // *****************************************************************************
// included header files // included header files
#include "tiffcomposite.hpp" #include "tiffcomposite.hpp"
#include "tiffvisitor.hpp"
#include "error.hpp"
#include "types.hpp" #include "types.hpp"
// + standard includes // + standard includes
@ -47,45 +45,11 @@ namespace Exiv2 {
// ***************************************************************************** // *****************************************************************************
// class declarations // class declarations
struct TiffStructure;
class Image; class Image;
// ***************************************************************************** // *****************************************************************************
// class definitions // 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<uint16_t>(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. @brief TIFF component factory for standard TIFF components.
*/ */
@ -133,18 +97,6 @@ namespace Exiv2 {
TiffCompFactoryFct createFct); TiffCompFactoryFct createFct);
}; // class TiffParser }; // 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 } // namespace Exiv2
#endif // #ifndef TIFFPARSER_HPP_ #endif // #ifndef TIFFPARSER_HPP_

@ -97,6 +97,16 @@ namespace Exiv2 {
findObject(object); findObject(object);
} }
void TiffFinder::visitArrayEntry(TiffArrayEntry* object)
{
findObject(object);
}
void TiffFinder::visitArrayElement(TiffArrayElement* object)
{
findObject(object);
}
void TiffMetadataDecoder::visitEntry(TiffEntry* object) void TiffMetadataDecoder::visitEntry(TiffEntry* object)
{ {
decodeTiffEntry(object); decodeTiffEntry(object);
@ -133,6 +143,21 @@ namespace Exiv2 {
pImage_->exifData().add(k, object->pValue()); pImage_->exifData().add(k, object->pValue());
} // TiffMetadataDecoder::decodeTiffEntry } // 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_(" "); const std::string TiffPrinter::indent_(" ");
void TiffPrinter::incIndent() void TiffPrinter::incIndent()
@ -215,6 +240,24 @@ namespace Exiv2 {
} // TiffPrinter::printTiffEntry } // 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, TiffReader::TiffReader(const byte* pData,
uint32_t size, uint32_t size,
TiffComponent* pRoot, TiffComponent* pRoot,
@ -402,7 +445,7 @@ namespace Exiv2 {
} }
// Modify reader for Makernote peculiarities, byte order, offset, // Modify reader for Makernote peculiarities, byte order, offset,
// component factory // component factory
changeState(object->getState(object->start() - pData_)); changeState(object->getState(object->start() - pData_, byteOrder()));
object->ifd_.setStart(object->start() + object->ifdOffset()); object->ifd_.setStart(object->start() + object->ifdOffset());
} // TiffReader::visitIfdMakernote } // TiffReader::visitIfdMakernote
@ -484,4 +527,48 @@ namespace Exiv2 {
} // TiffReader::readTiffEntry } // TiffReader::readTiffEntry
void TiffReader::visitArrayEntry(TiffArrayEntry* object)
{
assert(object != 0);
readTiffEntry(object);
if (object->typeId() == unsignedShort) {
for (uint16_t i = 0; i < static_cast<uint16_t>(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 } // namespace Exiv2

@ -104,6 +104,10 @@ namespace Exiv2 {
virtual void visitIfdMakernote(TiffIfdMakernote* object) =0; virtual void visitIfdMakernote(TiffIfdMakernote* object) =0;
//! Operation to perform after processing an IFD makernote //! Operation to perform after processing an IFD makernote
virtual void visitIfdMakernoteEnd(TiffIfdMakernote* object) {} 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 //! @name Accessors
@ -146,6 +150,10 @@ namespace Exiv2 {
virtual void visitMnEntry(TiffMnEntry* object); virtual void visitMnEntry(TiffMnEntry* object);
//! Find tag and group in an IFD makernote //! Find tag and group in an IFD makernote
virtual void visitIfdMakernote(TiffIfdMakernote* object); 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 //! Check if \em object matches \em tag and \em group
void findObject(TiffComponent* object); void findObject(TiffComponent* object);
@ -196,6 +204,10 @@ namespace Exiv2 {
virtual void visitMnEntry(TiffMnEntry* object); virtual void visitMnEntry(TiffMnEntry* object);
//! Decode an IFD makernote //! Decode an IFD makernote
virtual void visitIfdMakernote(TiffIfdMakernote* object); 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 //! Decode a standard TIFF entry
void decodeTiffEntry(const TiffEntryBase* object); void decodeTiffEntry(const TiffEntryBase* object);
@ -288,6 +300,10 @@ namespace Exiv2 {
virtual void visitIfdMakernote(TiffIfdMakernote* object); virtual void visitIfdMakernote(TiffIfdMakernote* object);
//! Reset reader to its original state, undo makernote specific settings //! Reset reader to its original state, undo makernote specific settings
virtual void visitIfdMakernoteEnd(TiffIfdMakernote* object); 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 //! Read a standard TIFF entry from the data buffer
void readTiffEntry(TiffEntryBase* object); void readTiffEntry(TiffEntryBase* object);
@ -349,6 +365,10 @@ namespace Exiv2 {
virtual void visitMnEntry(TiffMnEntry* object); virtual void visitMnEntry(TiffMnEntry* object);
//! Print an IFD makernote //! Print an IFD makernote
virtual void visitIfdMakernote(TiffIfdMakernote* object); 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 //! Increment the indent by one level
void incIndent(); void incIndent();

Loading…
Cancel
Save