TIFF parser checkpoint (experimental): Added Canon makernote. Uses a Canon TIFF component factory when the makernote is parsed. Added TiffArrayEntry and TiffArrayElement components.
This commit is contained in:
parent
0fa2d525fc
commit
73c42ee8f6
68
src/Makefile
68
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
|
||||
|
||||
103
src/canonmn2.cpp
Normal file
103
src/canonmn2.cpp
Normal file
@ -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
|
||||
109
src/canonmn2.hpp
Normal file
109
src/canonmn2.hpp
Normal file
@ -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();
|
||||
}
|
||||
|
||||
TiffRwState::AutoPtr TiffFujiMn::doGetState(uint32_t mnOffset) const
|
||||
TiffRwState::AutoPtr TiffFujiMn::doGetState(uint32_t mnOffset,
|
||||
ByteOrder /*byteOrder*/) const
|
||||
{
|
||||
// Byteorder: from the header (little endian)
|
||||
// Offsets : relative to the start of the makernote
|
||||
|
||||
@ -108,7 +108,8 @@ namespace Exiv2 {
|
||||
//@{
|
||||
virtual bool doCheckHeader() 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:
|
||||
|
||||
@ -57,6 +57,10 @@ namespace Exiv2 {
|
||||
return make == key.make_.substr(0, make.length());
|
||||
}
|
||||
|
||||
TiffIfdMakernote::~TiffIfdMakernote()
|
||||
{
|
||||
}
|
||||
|
||||
bool TiffIfdMakernote::readHeader(const byte* pData,
|
||||
uint32_t size,
|
||||
ByteOrder byteOrder)
|
||||
@ -74,12 +78,14 @@ namespace Exiv2 {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ namespace Exiv2 {
|
||||
TiffIfdMakernote(uint16_t tag, uint16_t group, uint16_t mnGroup)
|
||||
: TiffComponent(tag, group), ifd_(tag, mnGroup) {}
|
||||
//! Virtual destructor
|
||||
virtual ~TiffIfdMakernote() {}
|
||||
virtual ~TiffIfdMakernote() =0;
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
@ -178,8 +178,11 @@ namespace Exiv2 {
|
||||
|
||||
@param mnOffset Offset to the makernote from the start of the
|
||||
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:
|
||||
@ -188,20 +191,43 @@ namespace Exiv2 {
|
||||
virtual void doAddChild(TiffComponent::AutoPtr tiffComponent);
|
||||
virtual void doAddNext(TiffComponent::AutoPtr tiffComponent);
|
||||
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,
|
||||
uint32_t size,
|
||||
ByteOrder byteOrder) =0;
|
||||
ByteOrder byteOrder) { return true; }
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Implements checkHeader()
|
||||
virtual bool doCheckHeader() const =0;
|
||||
//! Implements ifdOffset()
|
||||
virtual uint32_t doIfdOffset() const =0;
|
||||
//! Implements getState(). The default implementation returns a 0-pointer.
|
||||
virtual TiffRwState::AutoPtr doGetState(uint32_t mnOffset) const;
|
||||
/*!
|
||||
@brief Implements checkHeader().
|
||||
|
||||
Default implementation simply returns true. Derived classes for
|
||||
makernotes which have a header should overwrite this.
|
||||
*/
|
||||
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:
|
||||
|
||||
@ -32,8 +32,9 @@ EXIV2_RCSID("@(#) $Id$");
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "makernote2.hpp"
|
||||
#include "olympusmn2.hpp"
|
||||
#include "canonmn2.hpp"
|
||||
#include "fujimn2.hpp"
|
||||
#include "olympusmn2.hpp"
|
||||
|
||||
// + standard includes
|
||||
|
||||
@ -42,8 +43,9 @@ EXIV2_RCSID("@(#) $Id$");
|
||||
namespace Exiv2 {
|
||||
|
||||
const TiffMnRegistry TiffMnCreator::registry_[] = {
|
||||
{ "OLYMPUS", newOlympusMn, Group::olympmn },
|
||||
{ "FUJIFILM", newFujiMn, Group::fujimn }
|
||||
{ "Canon", newCanonMn, Group::canonmn },
|
||||
{ "FUJIFILM", newFujiMn, Group::fujimn },
|
||||
{ "OLYMPUS", newOlympusMn, Group::olympmn }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -54,6 +54,12 @@ EXIV2_RCSID("@(#) $Id$");
|
||||
// class member definitions
|
||||
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
|
||||
{
|
||||
os << prefix
|
||||
@ -92,6 +98,15 @@ namespace Exiv2 {
|
||||
delete mn_;
|
||||
} // 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;
|
||||
|
||||
bool TiffHeade2::read(const byte* pData, uint32_t size)
|
||||
@ -119,14 +134,18 @@ namespace Exiv2 {
|
||||
// Possibly the whole function shouldn't be in this class...
|
||||
std::string group;
|
||||
switch (group_) {
|
||||
case 1: group = "Image"; break;
|
||||
case 1: group = "Image"; break;
|
||||
case 2: group = "Thumbnail"; break;
|
||||
case 3: group = "Photo"; break;
|
||||
case 4: group = "GPSInfo"; break;
|
||||
case 5: group = "Iop"; break;
|
||||
case 257: group = "Olympus"; break;
|
||||
case 258: group = "Fujifilm"; break;
|
||||
default: group = "Unknown"; break;
|
||||
case 3: group = "Photo"; break;
|
||||
case 4: group = "GPSInfo"; break;
|
||||
case 5: group = "Iop"; break;
|
||||
case 257: group = "Olympus"; 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;
|
||||
}
|
||||
return group;
|
||||
}
|
||||
@ -151,6 +170,11 @@ namespace Exiv2 {
|
||||
if (mn_) mn_->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
|
||||
|
||||
@ -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<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.
|
||||
*/
|
||||
@ -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_
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -43,6 +43,8 @@ EXIV2_RCSID("@(#) $Id$");
|
||||
|
||||
#include "tiffparser.hpp"
|
||||
#include "tiffcomposite.hpp"
|
||||
#include "tiffvisitor.hpp"
|
||||
#include "error.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <cassert>
|
||||
@ -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<uint16_t>(extendedTag & 0xffff);
|
||||
if (ts && ts->newTiffCompFct_) {
|
||||
tc = ts->newTiffCompFct_(ts);
|
||||
tc = ts->newTiffCompFct_(tag, ts);
|
||||
}
|
||||
if (!ts) {
|
||||
uint16_t tag = static_cast<uint16_t>(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
|
||||
|
||||
@ -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<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.
|
||||
*/
|
||||
@ -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_
|
||||
|
||||
@ -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<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
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user