[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a
Maximiliano Curia
maxy at moszumanska.debian.org
Thu Jul 13 17:37:29 UTC 2017
Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=973e046
The following commit has been merged in the master branch:
commit 973e046a21ee5641a958687050a803267592cf6a
Author: Andreas Huggel <ahuggel at gmx.net>
Date: Mon Apr 10 17:08:49 2006 +0000
Implemented the TIFF component factory as a policy class (TiffCreator), used by TiffParser and TiffReader. Added Stephan's find template to search static arrays.
---
src/tiffimage.cpp | 13 +--
src/tiffimage.hpp | 10 --
src/tiffparse.cpp | 18 +---
src/tiffparser.cpp | 243 ++++--------------------------------------
src/tiffparser.hpp | 301 ++++++++++++++++++++++++++++++++++++++++++++++-------
src/types.hpp | 52 +++++++++
6 files changed, 341 insertions(+), 296 deletions(-)
diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp
index 64a6cae..68e5a0e 100644
--- a/src/tiffimage.cpp
+++ b/src/tiffimage.cpp
@@ -55,16 +55,6 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions
namespace Exiv2 {
- const TiffStructure TiffImage::tiffStructure_[] = {
- { Tag::root, Group::none, newTiffDirectory, Group::ifd0 },
- { 0x8769, Group::ifd0, newTiffSubIfd, Group::exif },
- { 0x8825, Group::ifd0, newTiffSubIfd, Group::gps },
- { 0xa005, Group::exif, newTiffSubIfd, Group::iop },
- { Tag::next, Group::ifd0, newTiffDirectory, Group::ifd0 },
- // End of list marker
- { Tag::none, Group::none, 0, Group::none }
- };
-
TiffImage::TiffImage(BasicIo::AutoPtr io, bool create)
: Image(mdExif | mdComment), io_(io)
{
@@ -145,8 +135,7 @@ namespace Exiv2 {
io_->read(buf.pData_, len);
if (io_->error() || io_->eof()) throw Error(14);
- TiffMetadataDecoder decoder(this);
- TiffParser::decode(buf.pData_, buf.size_, tiffStructure_, decoder);
+ TiffParser<TiffCreator>::decode(this, buf.pData_, buf.size_);
} // TiffImage::readMetadata
void TiffImage::writeMetadata()
diff --git a/src/tiffimage.hpp b/src/tiffimage.hpp
index 3c5ba00..0a91039 100644
--- a/src/tiffimage.hpp
+++ b/src/tiffimage.hpp
@@ -43,14 +43,6 @@
namespace Exiv2 {
// *****************************************************************************
-// class declarations
-
- struct TiffStructure;
-
-// *****************************************************************************
-// type definitions
-
-// *****************************************************************************
// class definitions
// Add TIFF to the supported image formats
@@ -167,8 +159,6 @@ namespace Exiv2 {
IptcData iptcData_; //!< IPTC data container
std::string comment_; //!< User comment
- static const TiffStructure tiffStructure_[]; //<! TIFF structure
-
}; // class TiffImage
// *****************************************************************************
diff --git a/src/tiffparse.cpp b/src/tiffparse.cpp
index c7eb141..557fff2 100644
--- a/src/tiffparse.cpp
+++ b/src/tiffparse.cpp
@@ -36,28 +36,14 @@ try {
io.read(buf.pData_, len);
if (io.error() || io.eof()) throw Error(14);
- const TiffStructure tiffStructure[] = {
- { Tag::root, Group::none, newTiffDirectory, Group::ifd0 },
- { 0x8769, Group::ifd0, newTiffSubIfd, Group::exif },
- { 0x8825, Group::ifd0, newTiffSubIfd, Group::gps },
- { 0xa005, Group::exif, newTiffSubIfd, Group::iop },
- { Tag::next, Group::ifd0, newTiffDirectory, Group::ifd0 },
- // End of list marker
- { Tag::none, Group::none, 0, Group::none }
- };
-
TiffHeade2 tiffHeader;
if (!tiffHeader.read(buf.pData_, buf.size_)) throw Error(3, "TIFF");
- TiffComponent::AutoPtr rootDir
- = TiffParser::create(Tag::root, Group::none, tiffStructure);
+ TiffComponent::AutoPtr rootDir = TiffCreator::create(Tag::root, Group::none);
if (0 == rootDir.get()) {
throw Error(1, "No root element defined in TIFF structure");
}
- TiffReader reader(buf.pData_,
- buf.size_,
- tiffHeader.byteOrder(),
- tiffStructure);
+ TiffReader<TiffCreator> reader(buf.pData_, buf.size_, tiffHeader.byteOrder());
rootDir->setStart(buf.pData_ + tiffHeader.offset());
rootDir->accept(reader);
diff --git a/src/tiffparser.cpp b/src/tiffparser.cpp
index 02e1a6a..1513383 100644
--- a/src/tiffparser.cpp
+++ b/src/tiffparser.cpp
@@ -53,16 +53,17 @@ EXIV2_RCSID("@(#) $Id$");
#include <iomanip>
#include <cassert>
-
/* --------------------------------------------------------------------------
Todo:
+ Add further child mgmt stuff to TIFF composite: remove, find
- + Review boundary checking, is it better to check the offsets
+ + Review boundary checking, is it better to check the offsets?
+ Define and implement consistent error handling for recursive hierarchy
- + Better handling of TiffStructure
+ Add Makernote support
+ + Make TiffImage a template StandardImage, which can be parametrized with
+ a parser and the necessary checking functions to cover all types of
+ images which need to be loaded completely.
in crwimage.* :
@@ -78,46 +79,24 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions
namespace Exiv2 {
- void TiffParser::decode(const byte* pData,
- uint32_t size,
- const TiffStructure* pTiffStructure,
- TiffVisitor& decoder)
- {
- assert(pData != 0);
-
- TiffHeade2 tiffHeader;
- if (!tiffHeader.read(pData, size) || tiffHeader.offset() >= size) {
- throw Error(3, "TIFF");
- }
- TiffComponent::AutoPtr rootDir
- = TiffParser::create(Tag::root, Group::none, pTiffStructure);
- if (0 == rootDir.get()) return;
-
- TiffReader reader(pData,
- size,
- tiffHeader.byteOrder(),
- pTiffStructure);
- rootDir->setStart(pData + tiffHeader.offset());
- rootDir->accept(reader);
-
- rootDir->accept(decoder);
-
- } // TiffParser::decode
+ const TiffStructure TiffCreator::tiffStructure_[] = {
+ { Tag::root, Group::none, newTiffDirectory, Group::ifd0 },
+ { 0x8769, Group::ifd0, newTiffSubIfd, Group::exif },
+ { 0x8825, Group::ifd0, newTiffSubIfd, Group::gps },
+ { 0xa005, Group::exif, newTiffSubIfd, Group::iop },
+ { Tag::next, Group::ifd0, newTiffDirectory, Group::ifd0 }
+ };
- TiffComponent::AutoPtr TiffParser::create(uint32_t extendedTag,
- uint16_t group,
- const TiffStructure* pTiffStructure)
+ bool TiffStructure::operator==(const TiffStructure::Key& key) const
{
- const TiffStructure* ts = 0;
- int idx = 0;
- for (; pTiffStructure[idx].extendedTag_ != Tag::none; ++idx) {
- if ( extendedTag == pTiffStructure[idx].extendedTag_
- && group == pTiffStructure[idx].group_) {
- ts = &pTiffStructure[idx];
- break;
- }
- }
+ 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);
if (ts && ts->newTiffCompFct_) {
tc = ts->newTiffCompFct_(ts);
@@ -127,7 +106,7 @@ namespace Exiv2 {
tc = TiffComponent::AutoPtr(new TiffEntry(tag, group));
}
return tc;
- } // TiffParser::create
+ } // TiffCreator::create
TiffDirectory::~TiffDirectory()
{
@@ -352,188 +331,6 @@ namespace Exiv2 {
pImage_->exifData().add(k, object->pValue());
} // TiffMetadataDecoder::decodeTiffEntry
- TiffReader::TiffReader(const byte* pData,
- uint32_t size,
- ByteOrder byteOrder,
- const TiffStructure* pTiffStructure)
- : pData_(pData),
- size_(size),
- pLast_(pData + size - 1),
- byteOrder_(byteOrder),
- pTiffStructure_(pTiffStructure)
- {
- assert(pData);
- assert(size > 0);
- assert(pTiffStructure);
- } // TiffReader::TiffReader
-
- void TiffReader::visitEntry(TiffEntry* object)
- {
- readTiffEntry(object);
- }
-
- void TiffReader::visitDirectory(TiffDirectory* object)
- {
- assert(object != 0);
-
- byte* p = const_cast<byte*>(object->start());
- assert(p >= pData_);
-
- if (p + 2 > pLast_) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Error: "
- << "Directory " << object->groupName() << ": "
- << " IFD exceeds data buffer, cannot read entry count.
";
-#endif
- return;
- }
- const uint16_t n = getUShort(p, byteOrder_);
- p += 2;
- for (uint16_t i = 0; i < n; ++i) {
- if (p + 12 > pLast_) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Error: "
- << "Directory " << object->groupName() << ": "
- << " IFD entry " << i
- << " lies outside of the data buffer.
";
-#endif
- return;
- }
- uint16_t tag = getUShort(p, byteOrder_);
- TiffComponent::AutoPtr tc
- = TiffParser::create(tag, object->group(), pTiffStructure_);
- tc->setStart(p);
- object->addChild(tc);
- p += 12;
- }
-
- if (p + 4 > pLast_) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Error: "
- << "Directory " << object->groupName() << ": "
- << " IFD exceeds data buffer, cannot read next pointer.
";
-#endif
- return;
- }
- uint32_t next = getLong(p, byteOrder_);
- if (next) {
- TiffComponent::AutoPtr tc
- = TiffParser::create(Tag::next, object->group(), pTiffStructure_);
- if (next > size_) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Error: "
- << "Directory " << object->groupName() << ": "
- << " Next pointer is out of bounds.
";
-#endif
- return;
- }
- tc->setStart(pData_ + next);
- object->addNext(tc);
- }
-
- } // TiffReader::visitDirectory
-
- void TiffReader::visitSubIfd(TiffSubIfd* object)
- {
- assert(object != 0);
-
- readTiffEntry(object);
- if (object->typeId() == unsignedLong && object->count() >= 1) {
- uint32_t offset = getULong(object->pData(), byteOrder_);
- if (offset > size_) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Error: "
- << "Directory " << object->groupName()
- << ", entry 0x" << std::setw(4)
- << std::setfill('0') << std::hex << object->tag()
- << " Sub-IFD pointer is out of bounds; ignoring it.
";
-#endif
- return;
- }
- object->ifd_.setStart(pData_ + offset);
- }
-#ifndef SUPPRESS_WARNINGS
- else {
- std::cerr << "Warning: "
- << "Directory " << object->groupName()
- << ", entry 0x" << std::setw(4)
- << std::setfill('0') << std::hex << object->tag()
- << " doesn't look like a sub-IFD.";
- }
-#endif
-
- } // TiffReader::visitSubIfd
-
- void TiffReader::readTiffEntry(TiffEntryBase* object)
- {
- assert(object != 0);
-
- byte* p = const_cast<byte*>(object->start());
- assert(p >= pData_);
-
- if (p + 12 > pLast_) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Error: Entry in directory " << object->groupName()
- << "requests access to memory beyond the data buffer. "
- << "Skipping entry.
";
-#endif
- return;
- }
- // Component already has tag
- p += 2;
- object->type_ = getUShort(p, byteOrder_);
- // todo: check type
- p += 2;
- object->count_ = getULong(p, byteOrder_);
- p += 4;
- object->size_ = TypeInfo::typeSize(object->typeId()) * object->count();
- object->offset_ = getULong(p, byteOrder_);
- object->pData_ = p;
- if (object->size() > 4) {
- if (object->offset() >= size_) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Error: Offset of "
- << "directory " << object->groupName() << ", "
- << " entry 0x" << std::setw(4)
- << std::setfill('0') << std::hex << object->tag()
- << " is out of bounds:
"
- << "Offset = 0x" << std::setw(8)
- << std::setfill('0') << std::hex << object->offset()
- << "; truncating the entry
";
-#endif
- object->size_ = 0;
- object->count_ = 0;
- object->offset_ = 0;
- return;
- }
- object->pData_ = pData_ + object->offset();
- if (object->pData() + object->size() > pLast_) {
-#ifndef SUPPRESS_WARNINGS
- std::cerr << "Warning: Upper boundary of data for "
- << "directory " << object->groupName() << ", "
- << " entry 0x" << std::setw(4)
- << std::setfill('0') << std::hex << object->tag()
- << " is out of bounds:
"
- << "Offset = 0x" << std::setw(8)
- << std::setfill('0') << std::hex << object->offset()
- << ", size = " << std::dec << object->size()
- << ", exceeds buffer size by "
- // cast to make MSVC happy
- << static_cast<uint32_t>(object->pData() + object->size() - pLast_)
- << " Bytes; adjusting the size
";
-#endif
- object->size_ = size_ - object->offset();
- // todo: adjust count_, make size_ a multiple of typeSize
- }
- }
- Value::AutoPtr v = Value::create(object->typeId());
- if (v.get()) {
- v->read(object->pData(), object->size(), byteOrder_);
- object->pValue_ = v.release();
- }
-
- } // TiffReader::readTiffEntry
-
// *************************************************************************
// free functions
diff --git a/src/tiffparser.hpp b/src/tiffparser.hpp
index 3115f95..d83120c 100644
--- a/src/tiffparser.hpp
+++ b/src/tiffparser.hpp
@@ -31,16 +31,18 @@
// *****************************************************************************
// included header files
+#include "image.hpp"
#include "exif.hpp"
#include "iptc.hpp"
-#include "image.hpp"
#include "types.hpp"
+#include "error.hpp"
// + standard includes
#include <iostream>
-#include <iosfwd>
+#include <iomanip>
#include <string>
#include <vector>
+#include <cassert>
// *****************************************************************************
// namespace extensions
@@ -219,9 +221,11 @@ namespace Exiv2 {
/*!
@brief TIFF composite visitor to read the TIFF structure from a block of
memory and build the composite from it (Visitor pattern). Used by
- TiffParser to read the TIFF data from a block of memory.
+ TiffParser to read the TIFF data from a block of memory. Uses
+ the policy class CreationPolicy for the creation of TIFF components.
*/
- class TiffReader : public TiffVisitor {
+ template<typename CreationPolicy>
+ class TiffReader : public TiffVisitor, public CreationPolicy {
public:
//! @name Creators
//@{
@@ -231,13 +235,10 @@ namespace Exiv2 {
@param pData Pointer to the data buffer, starting with a TIFF header.
@param size Number of bytes in the data buffer.
@param byteOrder Applicable byte order (little or big endian).
- @param pTiffStructure Pointer to a table describing the TIFF structure
- used to decode the data.
*/
TiffReader(const byte* pData,
uint32_t size,
- ByteOrder byteOrder,
- const TiffStructure* pTiffStructure);
+ ByteOrder byteOrder);
//! Virtual destructor
virtual ~TiffReader() {}
@@ -261,7 +262,6 @@ namespace Exiv2 {
const uint32_t size_; //!< Size of the buffer
const byte* pLast_; //!< Pointer to the last byte
const ByteOrder byteOrder_; //!< Byteorder for the image
- const TiffStructure* pTiffStructure_; //!< Pointer to the TIFF structure
}; // class TiffReader
@@ -372,7 +372,8 @@ namespace Exiv2 {
entry.
*/
class TiffEntryBase : public TiffComponent {
- friend void TiffReader::readTiffEntry(TiffEntryBase* object);
+ template<typename CreationPolicy>
+ friend void TiffReader<CreationPolicy>::readTiffEntry(TiffEntryBase* object);
public:
//! @name Creators
//@{
@@ -497,7 +498,8 @@ namespace Exiv2 {
GPS tags.
*/
class TiffSubIfd : public TiffEntryBase {
- friend void TiffReader::visitSubIfd(TiffSubIfd* object);
+ template<typename CreationPolicy>
+ friend void TiffReader<CreationPolicy>::visitSubIfd(TiffSubIfd* object);
public:
//! @name Creators
//@{
@@ -552,47 +554,67 @@ namespace Exiv2 {
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
+
+ struct Key;
+ //! Comparison operator to compare a TiffStructure with a TiffStructure::Key
+ bool operator==(const Key& key) const;
+ };
+
+ //! 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. This class is
+ meant to be used as a policy class.
+ */
+ class TiffCreator {
+ 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);
+ protected:
+ //! Prevent destruction
+ ~TiffCreator() {}
+ private:
+ static const TiffStructure tiffStructure_[]; //<! TIFF structure
+ }; // class TiffCreator
+
+ /*!
@brief Stateless parser class for data in TIFF format. Images use this
- class to decode and encode TIFF-based data.
+ class to decode and encode TIFF-based data. Uses class
+ CreationPolicy for the creation of TIFF components.
*/
- class TiffParser {
+ template<typename CreationPolicy>
+ class TiffParser : public CreationPolicy {
public:
/*!
@brief Decode TIFF metadata from a data buffer \em pData of length
- \em size into \em image.
+ \em size into \em pImage.
This is the entry point to access image data in TIFF format. The
parser uses classes TiffHeade2 and the TiffComponent and TiffVisitor
hierarchies.
+ @param pImage Pointer to the image to hold the metadata
@param pData Pointer to the data buffer. Must point to data
in TIFF format; no checks are performed.
@param size Length of the data buffer.
- @param pTiffStructure Pointer to a table describing the TIFF structure
- used to decode the data.
- @param decoder Reference to a TIFF visitor to decode and extract
- the metadata from the TIFF composite structure.
-
- @throw Error If the data buffer cannot be parsed.
- */
- static void decode(const byte* pData,
- uint32_t size,
- const TiffStructure* pTiffStructure,
- TiffVisitor& decoder);
- /*!
- @brief Create the TiffComponent for TIFF entry \em tag in \em group
- based on the lookup list \em pTiffStructure.
-
- If a tag, group tupel 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,
- const TiffStructure* pTiffStructure);
+ static void decode( Image* pImage,
+ const byte* pData,
+ uint32_t size);
}; // class TiffParser
// *****************************************************************************
@@ -604,6 +626,215 @@ namespace Exiv2 {
//! Function to create and initialize a new TIFF sub-directory
TiffComponent::AutoPtr newTiffSubIfd(const TiffStructure* ts);
+ template<typename CreationPolicy>
+ void TiffParser<CreationPolicy>::decode(Image* pImage,
+ const byte* pData,
+ uint32_t size)
+ {
+ assert(pImage != 0);
+ assert(pData != 0);
+
+ TiffHeade2 tiffHeader;
+ if (!tiffHeader.read(pData, size) || tiffHeader.offset() >= size) {
+ throw Error(3, "TIFF");
+ }
+ TiffComponent::AutoPtr rootDir = CreationPolicy::create(Tag::root,
+ Group::none);
+ if (0 == rootDir.get()) return;
+ rootDir->setStart(pData + tiffHeader.offset());
+
+ TiffReader<CreationPolicy> reader(pData,
+ size,
+ tiffHeader.byteOrder());
+ rootDir->accept(reader);
+
+ TiffMetadataDecoder decoder(pImage);
+ rootDir->accept(decoder);
+
+ } // TiffParser::decode
+
+ template<typename CreationPolicy>
+ TiffReader<CreationPolicy>::TiffReader(const byte* pData,
+ uint32_t size,
+ ByteOrder byteOrder)
+ : pData_(pData),
+ size_(size),
+ pLast_(pData + size - 1),
+ byteOrder_(byteOrder)
+ {
+ assert(pData);
+ assert(size > 0);
+ } // TiffReader::TiffReader
+
+ template<typename CreationPolicy>
+ void TiffReader<CreationPolicy>::visitEntry(TiffEntry* object)
+ {
+ readTiffEntry(object);
+ }
+
+ template<typename CreationPolicy>
+ void TiffReader<CreationPolicy>::visitDirectory(TiffDirectory* object)
+ {
+ assert(object != 0);
+
+ byte* p = const_cast<byte*>(object->start());
+ assert(p >= pData_);
+
+ if (p + 2 > pLast_) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Error: "
+ << "Directory " << object->groupName() << ": "
+ << " IFD exceeds data buffer, cannot read entry count.
";
+#endif
+ return;
+ }
+ const uint16_t n = getUShort(p, byteOrder_);
+ p += 2;
+ for (uint16_t i = 0; i < n; ++i) {
+ if (p + 12 > pLast_) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Error: "
+ << "Directory " << object->groupName() << ": "
+ << " IFD entry " << i
+ << " lies outside of the data buffer.
";
+#endif
+ return;
+ }
+ uint16_t tag = getUShort(p, byteOrder_);
+ TiffComponent::AutoPtr tc = CreationPolicy::create(tag, object->group());
+ tc->setStart(p);
+ object->addChild(tc);
+ p += 12;
+ }
+
+ if (p + 4 > pLast_) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Error: "
+ << "Directory " << object->groupName() << ": "
+ << " IFD exceeds data buffer, cannot read next pointer.
";
+#endif
+ return;
+ }
+ uint32_t next = getLong(p, byteOrder_);
+ if (next) {
+ TiffComponent::AutoPtr tc = CreationPolicy::create(Tag::next, object->group());
+ if (next > size_) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Error: "
+ << "Directory " << object->groupName() << ": "
+ << " Next pointer is out of bounds.
";
+#endif
+ return;
+ }
+ tc->setStart(pData_ + next);
+ object->addNext(tc);
+ }
+
+ } // TiffReader::visitDirectory
+
+ template<typename CreationPolicy>
+ void TiffReader<CreationPolicy>::visitSubIfd(TiffSubIfd* object)
+ {
+ assert(object != 0);
+
+ readTiffEntry(object);
+ if (object->typeId() == unsignedLong && object->count() >= 1) {
+ uint32_t offset = getULong(object->pData(), byteOrder_);
+ if (offset > size_) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Error: "
+ << "Directory " << object->groupName()
+ << ", entry 0x" << std::setw(4)
+ << std::setfill('0') << std::hex << object->tag()
+ << " Sub-IFD pointer is out of bounds; ignoring it.
";
+#endif
+ return;
+ }
+ object->ifd_.setStart(pData_ + offset);
+ }
+#ifndef SUPPRESS_WARNINGS
+ else {
+ std::cerr << "Warning: "
+ << "Directory " << object->groupName()
+ << ", entry 0x" << std::setw(4)
+ << std::setfill('0') << std::hex << object->tag()
+ << " doesn't look like a sub-IFD.";
+ }
+#endif
+
+ } // TiffReader::visitSubIfd
+
+ template<typename CreationPolicy>
+ void TiffReader<CreationPolicy>::readTiffEntry(TiffEntryBase* object)
+ {
+ assert(object != 0);
+
+ byte* p = const_cast<byte*>(object->start());
+ assert(p >= pData_);
+
+ if (p + 12 > pLast_) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Error: Entry in directory " << object->groupName()
+ << "requests access to memory beyond the data buffer. "
+ << "Skipping entry.
";
+#endif
+ return;
+ }
+ // Component already has tag
+ p += 2;
+ object->type_ = getUShort(p, byteOrder_);
+ // todo: check type
+ p += 2;
+ object->count_ = getULong(p, byteOrder_);
+ p += 4;
+ object->size_ = TypeInfo::typeSize(object->typeId()) * object->count();
+ object->offset_ = getULong(p, byteOrder_);
+ object->pData_ = p;
+ if (object->size() > 4) {
+ if (object->offset() >= size_) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Error: Offset of "
+ << "directory " << object->groupName() << ", "
+ << " entry 0x" << std::setw(4)
+ << std::setfill('0') << std::hex << object->tag()
+ << " is out of bounds:
"
+ << "Offset = 0x" << std::setw(8)
+ << std::setfill('0') << std::hex << object->offset()
+ << "; truncating the entry
";
+#endif
+ object->size_ = 0;
+ object->count_ = 0;
+ object->offset_ = 0;
+ return;
+ }
+ object->pData_ = pData_ + object->offset();
+ if (object->pData() + object->size() > pLast_) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Warning: Upper boundary of data for "
+ << "directory " << object->groupName() << ", "
+ << " entry 0x" << std::setw(4)
+ << std::setfill('0') << std::hex << object->tag()
+ << " is out of bounds:
"
+ << "Offset = 0x" << std::setw(8)
+ << std::setfill('0') << std::hex << object->offset()
+ << ", size = " << std::dec << object->size()
+ << ", exceeds buffer size by "
+ // cast to make MSVC happy
+ << static_cast<uint32_t>(object->pData() + object->size() - pLast_)
+ << " Bytes; adjusting the size
";
+#endif
+ object->size_ = size_ - object->offset();
+ // todo: adjust count_, make size_ a multiple of typeSize
+ }
+ }
+ Value::AutoPtr v = Value::create(object->typeId());
+ if (v.get()) {
+ v->read(object->pData(), object->size(), byteOrder_);
+ object->pValue_ = v.release();
+ }
+
+ } // TiffReader::readTiffEntry
+
} // namespace Exiv2
#endif // #ifndef TIFFPARSER_HPP_
diff --git a/src/types.hpp b/src/types.hpp
index 855c5e4..272e0b1 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -43,6 +43,7 @@
#include <string>
#include <iosfwd>
#include <utility>
+#include <algorithm>
#include <sstream>
#ifdef EXV_HAVE_STDINT_H
# include <stdint.h>
@@ -300,6 +301,57 @@ namespace Exiv2 {
// *****************************************************************************
// template and inline definitions
+ /*!
+ @brief Find an element that matches \em key in the array \em src.
+
+ Designed to be used with lookup tables as shown in the example below.
+ Requires a %Key structure (ideally in the array) and a comparison operator
+ to compare a key with an array element. The size of the array is
+ determined automagically. Thanks to Stephan Broennimann for this nifty
+ implementation.
+
+ @code
+ struct Bar {
+ int i;
+ int k;
+ const char* data;
+
+ struct Key;
+ bool operator==(const Bar::Key& rhs) const;
+ };
+
+ struct Bar::Key {
+ Key(int a, int b) : i(a), k(b) {}
+ int i;
+ int k;
+ };
+
+ bool Bar::operator==(const Bar::Key& key) const // definition
+ {
+ return i == key.i && k == key.k;
+ }
+
+ const Bar bars[] = {
+ { 1, 1, "bar data 1" },
+ { 1, 2, "bar data 2" },
+ { 1, 3, "bar data 3" }
+ };
+
+ int main ( void ) {
+ const Bar* bar = find(bars, Bar::Key(1, 3));
+ if (bar) std::cout << bar->data << "
";
+ else std::cout << "Key not found.
";
+ return 0;
+ }
+ @endcode
+ */
+ template<typename T, typename K, int N>
+ const T* find(T (&src)[N], const K& key)
+ {
+ const T* rc = std::find(src, src + N, key);
+ return rc == src + N ? 0 : rc;
+ }
+
//! Utility function to convert the argument of any type to a string
template<typename T>
std::string toString(const T& arg)
--
exiv2 packaging
More information about the pkg-kde-commits
mailing list