[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:28 UTC 2017
Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=ef30cbb
The following commit has been merged in the master branch:
commit ef30cbbd50af0a3466eef9b8869b59e82ff0390b
Author: Andreas Huggel <ahuggel at gmx.net>
Date: Sun Apr 2 17:24:11 2006 +0000
Alpha status TIFF image and parser, not yet added to Makefile
---
src/tiffimage.cpp | 226 ++++++++++++++++++++++++
src/tiffimage.hpp | 191 +++++++++++++++++++++
src/tiffparser.cpp | 411 ++++++++++++++++++++++++++++++++++++++++++++
src/tiffparser.hpp | 491 +++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 1319 insertions(+)
diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp
new file mode 100644
index 0000000..9c38672
--- /dev/null
+++ b/src/tiffimage.cpp
@@ -0,0 +1,226 @@
+// ***************************************************************** -*- C++ -*-
+/*
+ * Copyright (C) 2006 Andreas Huggel <ahuggel at 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: tiffimage.cpp
+ Version: $Rev$
+ Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
+ History: 15-Mar-06, ahu: created
+
+ */
+// *****************************************************************************
+#include "rcsid.hpp"
+EXIV2_RCSID("@(#) $Id: tiffparser.cpp 675 2006-01-25 04:16:58Z ahuggel $");
+
+// Define DEBUG to output debug information to std::cerr, e.g, by calling make
+// like this: make DEFS=-DDEBUG tiffparser.o
+//#define DEBUG
+
+// *****************************************************************************
+// included header files
+#ifdef _MSC_VER
+# include "exv_msvc.h"
+#else
+# include "exv_conf.h"
+#endif
+
+#include "tiffimage.hpp"
+#include "tiffparser.hpp"
+#include "image.hpp"
+#include "error.hpp"
+#include "futils.hpp"
+
+// + standard includes
+#include <iostream>
+#include <cassert>
+
+// *****************************************************************************
+// 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)
+ {
+ if (create) {
+ IoCloser closer(*io_);
+ io_->open();
+ }
+ } // TiffImage::TiffImage
+
+ bool TiffImage::good() const
+ {
+ if (io_->open() != 0) return false;
+ IoCloser closer(*io_);
+ return isThisType(*io_, false);
+ }
+
+ void TiffImage::clearMetadata()
+ {
+ clearExifData();
+ clearComment();
+ }
+
+ void TiffImage::setMetadata(const Image& image)
+ {
+ setExifData(image.exifData());
+ setComment(image.comment());
+ }
+
+ void TiffImage::clearExifData()
+ {
+ exifData_.clear();
+ }
+
+ void TiffImage::setExifData(const ExifData& exifData)
+ {
+ exifData_ = exifData;
+ }
+
+ void TiffImage::clearIptcData()
+ {
+ // not supported
+ }
+
+ void TiffImage::setIptcData(const IptcData& /*iptcData*/)
+ {
+ // not supported
+ }
+
+ void TiffImage::clearComment()
+ {
+ comment_.erase();
+ }
+
+ void TiffImage::setComment(const std::string& comment)
+ {
+ comment_ = comment;
+ }
+
+ void TiffImage::readMetadata()
+ {
+#ifdef DEBUG
+ std::cerr << "Reading TIFF file " << io_->path() << "
";
+#endif
+ if (io_->open() != 0) {
+ throw Error(9, io_->path(), strError());
+ }
+ IoCloser closer(*io_);
+ // Ensure that this is the correct image type
+ if (!isThisType(*io_, false)) {
+ if (io_->error() || io_->eof()) throw Error(14);
+ throw Error(33);
+ }
+ clearMetadata();
+
+ // Read the image into a memory buffer
+ long len = io_->size();
+ DataBuf buf(len);
+ io_->read(buf.pData_, len);
+ if (io_->error() || io_->eof()) throw Error(14);
+
+ TiffParser::decode(this, tiffStructure_, buf.pData_, buf.size_);
+ } // TiffImage::readMetadata
+
+ void TiffImage::writeMetadata()
+ {
+/*
+
+ Todo: implement me!
+
+#ifdef DEBUG
+ std::cerr << "Writing TIFF file " << io_->path() << "
";
+#endif
+ // Read existing image
+ DataBuf buf;
+ if (io_->open() == 0) {
+ IoCloser closer(*io_);
+ // Ensure that this is the correct image type
+ if (isThisType(*io_, false)) {
+ // Read the image into a memory buffer
+ buf.alloc(io_->size());
+ io_->read(buf.pData_, buf.size_);
+ if (io_->error() || io_->eof()) {
+ buf.reset();
+ }
+ }
+ }
+
+ // Parse image, starting with a TIFF header component
+ TiffHeade2::AutoPtr head(new TiffHeade2);
+ if (buf.size_ != 0) {
+ head->read(buf.pData_, buf.size_);
+ }
+
+ Blob blob;
+ TiffParser::encode(blob, head.get(), this);
+
+ // Write new buffer to file
+ BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
+ assert (tempIo.get() != 0);
+ tempIo->write(&blob[0], static_cast<long>(blob.size()));
+ io_->close();
+ io_->transfer(*tempIo); // may throw
+*/
+ } // TiffImage::writeMetadata
+
+ bool TiffImage::isThisType(BasicIo& iIo, bool advance) const
+ {
+ return isTiffType(iIo, advance);
+ }
+
+ // *************************************************************************
+ // free functions
+
+ Image::AutoPtr newTiffInstance(BasicIo::AutoPtr io, bool create)
+ {
+ Image::AutoPtr image(new TiffImage(io, create));
+ if (!image->good()) {
+ image.reset();
+ }
+ return image;
+ }
+
+ bool isTiffType(BasicIo& iIo, bool advance)
+ {
+ const uint32_t len = 8;
+ byte buf[len];
+ iIo.read(buf, len);
+ if (iIo.error() || iIo.eof()) {
+ return false;
+ }
+ TiffHeade2 tiffHeader;
+ bool rc = tiffHeader.read(buf, len);
+ if (!advance || !rc) {
+ iIo.seek(-len, BasicIo::cur);
+ }
+ return rc;
+ }
+
+} // namespace Exiv2
diff --git a/src/tiffimage.hpp b/src/tiffimage.hpp
new file mode 100644
index 0000000..356f9a7
--- /dev/null
+++ b/src/tiffimage.hpp
@@ -0,0 +1,191 @@
+// ***************************************************************** -*- C++ -*-
+/*
+ * Copyright (C) 2006 Andreas Huggel <ahuggel at 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 tiffimage.hpp
+ @brief Class TiffImage
+ @version $Rev$
+ @author Andreas Huggel (ahu)
+ <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
+ @date 15-Mar-06, ahu: created
+ */
+#ifndef TIFFIMAGE_HPP_
+#define TIFFIMAGE_HPP_
+
+// *****************************************************************************
+// included header files
+#include "exif.hpp"
+#include "iptc.hpp"
+#include "image.hpp"
+
+// + standard includes
+#include <string>
+
+// *****************************************************************************
+// namespace extensions
+namespace Exiv2 {
+
+// *****************************************************************************
+// class declarations
+
+ struct TiffStructure;
+
+// *****************************************************************************
+// type definitions
+
+// *****************************************************************************
+// class definitions
+
+ // Add TIFF to the supported image formats
+ namespace ImageType {
+ const int tiff = 4; //!< TIFF image type (see class TiffImage)
+ }
+
+ /*!
+ @brief Class to access raw TIFF images. Only Exif metadata and a comment
+ are supported. TIFF format does not contain IPTC metadata.
+ */
+ class TiffImage : public Image {
+ friend bool isTiffType(BasicIo& iIo, bool advance);
+
+ //! @name NOT Implemented
+ //@{
+ //! Copy constructor
+ TiffImage(const TiffImage& rhs);
+ //! Assignment operator
+ TiffImage& operator=(const TiffImage& rhs);
+ //@}
+
+ public:
+ //! @name Creators
+ //@{
+ /*!
+ @brief Constructor that can either open an existing TIFF image or create
+ a new image from scratch. If a new image is to be created, any
+ existing data is overwritten. Since the constructor can not return
+ a result, callers should check the good() method after object
+ construction to determine success or failure.
+ @param io An auto-pointer that owns a BasicIo instance used for
+ reading and writing image metadata. Important: The constructor
+ takes ownership of the passed in BasicIo instance through the
+ auto-pointer. Callers should not continue to use the BasicIo
+ instance after it is passed to this method. Use the Image::io()
+ method to get a temporary reference.
+ @param create Specifies if an existing image should be read (false)
+ or if a new file should be created (true).
+ */
+ TiffImage(BasicIo::AutoPtr io, bool create);
+ //! Destructor
+ ~TiffImage() {}
+ //@}
+
+ //! @name Manipulators
+ //@{
+ void readMetadata();
+ /*!
+ @brief Todo: Write metadata back to the image. This method is not
+ yet implemented.
+ */
+ void writeMetadata();
+ void setExifData(const ExifData& exifData);
+ void clearExifData();
+ /*!
+ @brief Not supported. TIFF format does not contain IPTC metadata.
+ Calling this function will do nothing.
+ */
+ void setIptcData(const IptcData& iptcData);
+ /*!
+ @brief Not supported. TIFF format does not contain IPTC metadata.
+ Calling this function will do nothing.
+ */
+ void clearIptcData();
+ void setComment(const std::string& comment);
+ void clearComment();
+ void setMetadata(const Image& image);
+ void clearMetadata();
+ ExifData& exifData() { return exifData_; }
+ IptcData& iptcData() { return iptcData_; }
+ //@}
+
+ //! @name Accessors
+ //@{
+ bool good() const;
+ const ExifData& exifData() const { return exifData_; }
+ const IptcData& iptcData() const { return iptcData_; }
+ std::string comment() const { return comment_; }
+ BasicIo& io() const { return *io_; }
+ //@}
+
+ private:
+ //! @name Accessors
+ //@{
+ /*!
+ @brief Determine if the content of the BasicIo instance is a TIFF image.
+
+ The advance flag determines if the read position in the stream is
+ moved (see below). This applies only if the type matches and the
+ function returns true. If the type does not match, the stream
+ position is not changed. However, if reading from the stream fails,
+ the stream position is undefined. Consult the stream state to obtain
+ more information in this case.
+
+ @param iIo BasicIo instance to read from.
+ @param advance Flag indicating whether the position of the io
+ should be advanced by the number of characters read to
+ analyse the data (true) or left at its original
+ position (false). This applies only if the type matches.
+ @return true if the data matches the type of this class;<BR>
+ false if the data does not match
+ */
+ bool isThisType(BasicIo& iIo, bool advance) const;
+ /*!
+ @brief Todo: Write TIFF header. Not implemented yet.
+ */
+ int writeHeader(BasicIo& oIo) const;
+ //@}
+
+ // DATA
+ BasicIo::AutoPtr io_; //!< Image data io pointer
+ ExifData exifData_; //!< Exif data container
+ IptcData iptcData_; //!< IPTC data container
+ std::string comment_; //!< User comment
+
+ static const TiffStructure tiffStructure_[]; //<! TIFF structure
+
+ }; // class TiffImage
+
+// *****************************************************************************
+// template, inline and free functions
+
+ // These could be static private functions on Image subclasses but then
+ // ImageFactory needs to be made a friend.
+ /*!
+ @brief Create a new TiffImage instance and return an auto-pointer to it.
+ Caller owns the returned object and the auto-pointer ensures that
+ it will be deleted.
+ */
+ Image::AutoPtr newTiffInstance(BasicIo::AutoPtr io, bool create);
+
+ //! Check if the file iIo is a TIFF image.
+ bool isTiffType(BasicIo& iIo, bool advance);
+
+} // namespace Exiv2
+
+#endif // #ifndef TIFFIMAGE_HPP_
diff --git a/src/tiffparser.cpp b/src/tiffparser.cpp
new file mode 100644
index 0000000..0bdf69c
--- /dev/null
+++ b/src/tiffparser.cpp
@@ -0,0 +1,411 @@
+// ***************************************************************** -*- C++ -*-
+/*
+ * Copyright (C) 2006 Andreas Huggel <ahuggel at 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: tiffparser.cpp
+ Version: $Rev$
+ Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
+ History: 15-Mar-06, ahu: created
+
+ */
+// *****************************************************************************
+#include "rcsid.hpp"
+EXIV2_RCSID("@(#) $Id: tiffparser.cpp 675 2006-01-25 04:16:58Z ahuggel $");
+
+// Define DEBUG to output debug information to std::cerr, e.g, by calling make
+// like this: make DEFS=-DDEBUG tiffparser.o
+//#define DEBUG
+
+// *****************************************************************************
+// included header files
+#ifdef _MSC_VER
+# include "exv_msvc.h"
+#else
+# include "exv_conf.h"
+#endif
+
+#include "tiffparser.hpp"
+#include "image.hpp"
+#include "exif.hpp"
+#include "tags.hpp"
+#include "error.hpp"
+#include "futils.hpp"
+
+// + standard includes
+#include <iostream>
+#include <iomanip>
+#include <cassert>
+
+
+/* --------------------------------------------------------------------------
+
+ Todo:
+
+ + Fix CiffHeader according to TiffHeade2
+ + Combine Error(15) and Error(33), add format argument %1
+ + Search crwimage for todos, fix writeMetadata comment
+ + rename all Ciff stuff to Crw for easier reference
+
+ -------------------------------------------------------------------------- */
+
+
+// *****************************************************************************
+// class member definitions
+namespace Exiv2 {
+
+ void TiffParser::decode(Image* pImage,
+ const TiffStructure* pTiffStructure,
+ 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
+ = create(Tag::root, Group::none, pTiffStructure);
+ if (0 == rootDir.get()) return;
+ rootDir->read(pData, size, tiffHeader.offset(), tiffHeader.byteOrder());
+
+#ifdef DEBUG
+ tiffHeader.print(std::cerr);
+ rootDir->print(std::cerr, tiffHeader.byteOrder());
+#endif
+
+ rootDir->decode(*pImage, tiffHeader.byteOrder());
+
+ } // TiffParser::decode
+
+ TiffComponent::AutoPtr TiffParser::create(int32_t tag,
+ uint16_t group,
+ const TiffStructure* pTiffStructure)
+ {
+ const TiffStructure* ts = 0;
+ for (int i = 0; pTiffStructure[i].tag_ != Tag::none; ++i) {
+ if (tag == pTiffStructure[i].tag_ && group == pTiffStructure[i].group_) {
+ ts = &pTiffStructure[i];
+ break;
+ }
+ }
+ TiffComponent::AutoPtr tc(0);
+ if (ts && ts->newTiffCompFct_) {
+ tc = ts->newTiffCompFct_(ts->newGroup_, pTiffStructure);
+ }
+ if (!ts) {
+ tc = TiffComponent::AutoPtr(new TiffEntry);
+ }
+ return tc;
+ } // TiffParser::create
+
+ TiffDirectory::~TiffDirectory()
+ {
+ Components::iterator b = components_.begin();
+ Components::iterator e = components_.end();
+ for (Components::iterator i = b; i != e; ++i) {
+ delete *i;
+ }
+ delete pNext_;
+ } // TiffDirectory::~TiffDirectory
+
+ TiffEntryBase::~TiffEntryBase()
+ {
+ if (isAllocated_) delete[] pData_;
+ } // TiffEntryBase::~TiffEntryBase
+
+ const uint16_t TiffHeade2::tag_ = 42;
+
+ bool TiffHeade2::read(const byte* pData, uint32_t size)
+ {
+ if (size < 8) return false;
+
+ if (pData[0] == 0x49 && pData[1] == 0x49) {
+ byteOrder_ = littleEndian;
+ }
+ else if (pData[0] == 0x4d && pData[1] == 0x4d) {
+ byteOrder_ = bigEndian;
+ }
+ else {
+ return false;
+ }
+ if (tag_ != getUShort(pData + 2, byteOrder_)) return false;
+ offset_ = getULong(pData + 4, byteOrder_);
+
+ return true;
+ } // TiffHeade2::read
+
+ void TiffComponent::read(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder)
+ {
+ doRead(pData, size, start, byteOrder);
+ } // TiffComponent::read
+
+ void TiffEntryBase::doRead(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder)
+ {
+ if (size - start < 12) throw Error(3, "TIFF");
+ const byte* p = pData + start;
+ tag_ = getUShort(p, byteOrder);
+ p += 2;
+ type_ = getUShort(p, byteOrder);
+ // todo: check type
+ p += 2;
+ count_ = getULong(p, byteOrder);
+ p += 4;
+ offset_ = getULong(p, byteOrder);
+#ifdef DEBUG
+ std::cout << "TiffEntryBase for "
+ << "tag 0x" << std::hex << tag_
+ << ", type " << std::dec << type_
+ << ", count " << count_
+ << ", offset 0x" << std::hex << offset_
+ << std::dec"
";
+#endif
+ size_ = TypeInfo::typeSize(typeId()) * count();
+ if (size_ > 4) {
+ if (size < offset() + size_) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Warning: Upper boundary of data for "
+ << "directory " << group() << ", " // todo: ExifTags::ifdName(ifdId_)
+ << " entry 0x" << std::setw(4)
+ << std::setfill('0') << std::hex << tag()
+ << " is out of bounds:
"
+ << " Offset = 0x" << std::setw(8)
+ << std::setfill('0') << std::hex << offset()
+ << ", size = " << std::dec << size_
+ << ", exceeds buffer size by "
+ << offset() + size_ - size
+ << " Bytes; adjusting the size
";
+#endif
+ size_ = size - offset();
+ // todo: adjust count_, make size_ a multiple of typeSize
+ }
+ pData_ = pData + offset();
+ }
+ else {
+ pData_ = pData + start + 8;
+ }
+
+ } // TiffEntryBase::doRead
+
+ void TiffEntry::doRead(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder)
+ {
+ TiffEntryBase::doRead(pData, size, start, byteOrder);
+ } // TiffEntry::doRead
+
+ void TiffDirectory::doRead(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder)
+ {
+ if (size < start + 2) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Error: "
+ << "Directory " << group() << ": " // todo: ExifTags::ifdName(ifdId_)
+ << " IFD exceeds data buffer, cannot read entry count.
";
+#endif
+ return;
+ }
+ uint32_t o = start;
+ const uint16_t n = getUShort(pData + o, byteOrder);
+ o += 2;
+
+ for (uint16_t i = 0; i < n; ++i) {
+ if (size < o + 12) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Error: "
+ << "Directory " << group() << ": " // todo: ExifTags::ifdName(ifdId_)
+ << " IFD entry " << i
+ << " lies outside of the data buffer.
";
+#endif
+ return;
+ }
+ uint16_t tag = getUShort(pData + o, byteOrder);
+ TiffComponent::AutoPtr tc
+ = TiffParser::create(tag, group(), pTiffStructure());
+ tc->read(pData, size, o, byteOrder);
+ components_.push_back(tc.release());
+ o += 12;
+ }
+ if (size < o + 4) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Error: "
+ << "Directory " << group() << ": " // todo: ExifTags::ifdName(ifdId_)
+ << " IFD exceeds data buffer, cannot read next pointer.
";
+#endif
+ return;
+ }
+ uint32_t next = getLong(pData + o, byteOrder);
+ if (next) {
+ pNext_ = TiffParser::create(Tag::next, group(), pTiffStructure()).release();
+ pNext_->read(pData, size, next, byteOrder);
+ }
+
+ } // TiffDirectory::doRead
+
+ void TiffSubIfd::doRead(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder)
+ {
+ TiffEntryBase::doRead(pData, size, start, byteOrder);
+ if (typeId() == unsignedLong && count() >= 1) {
+ uint32_t offset = getULong(this->pData(), byteOrder);
+ ifd_.read(pData, size, offset, byteOrder);
+ }
+#ifndef SUPPRESS_WARNINGS
+ else {
+ std::cerr << "Warning: "
+ << "Directory " << group() << ", " // todo: ExifTags::ifdName(ifdId_)
+ << " entry 0x" << std::setw(4)
+ << std::setfill('0') << std::hex << tag()
+ << " doesn't look like a sub-IFD.";
+ }
+#endif
+ } // TiffSubIfd::read
+
+ void TiffComponent::decode(Image& image, ByteOrder byteOrder) const
+ {
+ doDecode(image, byteOrder);
+ } // TiffComponent::decode
+
+ void TiffEntryBase::doDecode(Image& image, ByteOrder byteOrder) const
+ {
+ ExifKey k(tag(), "Image"); // todo needs ifdItem
+ TypeId t = typeId();
+ Value::AutoPtr v = Value::create(t);
+ v->read(pData_, size_, byteOrder);
+ image.exifData().add(k, v.get());
+ } // TiffEntryBase::doDecode
+
+ void TiffEntry::doDecode(Image& image, ByteOrder byteOrder) const
+ {
+ TiffEntryBase::doDecode(image, byteOrder);
+ } // TiffEntry::doDecode
+
+ void TiffDirectory::doDecode(Image& image, ByteOrder byteOrder) const
+ {
+ Components::const_iterator b = components_.begin();
+ Components::const_iterator e = components_.end();
+ for (Components::const_iterator i = b; i != e; ++i) {
+ (*i)->decode(image, byteOrder);
+ }
+ if (pNext_) pNext_->decode(image, byteOrder);
+ } // TiffDirectory::doDecode
+
+ void TiffSubIfd::doDecode(Image& image, ByteOrder byteOrder) const
+ {
+ ifd_.decode(image, byteOrder);
+ } // TiffSubIfd::doDecode
+
+ void TiffHeade2::print(std::ostream& os, const std::string& prefix) const
+ {
+ os << prefix
+ << "Header, offset = 0x" << std::setw(8) << std::setfill('0')
+ << std::hex << std::right << offset_ << "
";
+ } // TiffHeade2::print
+
+ void TiffComponent::print(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix) const
+ {
+ doPrint(os, byteOrder, prefix);
+ } // TiffComponent::print
+
+ void TiffEntryBase::doPrint(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix) const
+ {
+ os << prefix
+ << "tag = 0x" << std::setw(4) << std::setfill('0')
+ << std::hex << std::right << tag()
+ << ", type = " << TypeInfo::typeName(typeId())
+ << ", count = " << std::dec << count()
+ << ", offset = " << offset() << "
";
+
+ TypeId t = typeId();
+ Value::AutoPtr v = Value::create(t);
+ v->read(pData_, size_, byteOrder);
+ if (v->size() < 100) {
+ os << prefix << *v << "
";
+ }
+ } // TiffEntryBase::doPrint
+
+ void TiffEntry::doPrint(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix) const
+ {
+ TiffEntryBase::doPrint(os, byteOrder, prefix);
+ } // TiffEntry::doPrint
+
+ void TiffDirectory::doPrint(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix) const
+ {
+ os << prefix << "Directory " << group()
+ << " with " << components_.size() << " entries.
";
+ Components::const_iterator b = components_.begin();
+ Components::const_iterator e = components_.end();
+ for (Components::const_iterator i = b; i != e; ++i) {
+ (*i)->print(os, byteOrder, prefix + " ");
+ }
+ if (pNext_) {
+ os << prefix << "Next directory:
";
+ pNext_->print(os, byteOrder, prefix);
+ }
+ else {
+ os << prefix << "No next directory.
";
+ }
+ } // TiffDirectory::doPrint
+
+ void TiffSubIfd::doPrint(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix) const
+ {
+ TiffEntryBase::doPrint(os, byteOrder, prefix);
+ ifd_.print(os, byteOrder, prefix);
+ } // TiffSubIfd::doPrint
+
+ // *************************************************************************
+ // free functions
+
+ TiffComponent::AutoPtr newTiffDirectory(uint16_t group,
+ const TiffStructure* pTiffStructure)
+ {
+ return TiffComponent::AutoPtr(new TiffDirectory(group, pTiffStructure));
+ }
+
+ TiffComponent::AutoPtr newTiffSubIfd(uint16_t group,
+ const TiffStructure* pTiffStructure)
+ {
+ return TiffComponent::AutoPtr(new TiffSubIfd(group, pTiffStructure));
+ }
+
+} // namespace Exiv2
diff --git a/src/tiffparser.hpp b/src/tiffparser.hpp
new file mode 100644
index 0000000..015fbca
--- /dev/null
+++ b/src/tiffparser.hpp
@@ -0,0 +1,491 @@
+// ***************************************************************** -*- C++ -*-
+/*
+ * Copyright (C) 2006 Andreas Huggel <ahuggel at 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 tiffparser.hpp
+ @brief Class TiffParser to parse TIFF data.
+ @version $Rev$
+ @author Andreas Huggel (ahu)
+ <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
+ @date 15-Mar-06, ahu: created
+ */
+#ifndef TIFFPARSER_HPP_
+#define TIFFPARSER_HPP_
+
+// *****************************************************************************
+// included header files
+#include "exif.hpp"
+#include "iptc.hpp"
+#include "image.hpp"
+#include "types.hpp"
+
+// + standard includes
+#include <iostream>
+#include <iosfwd>
+#include <string>
+#include <vector>
+
+// *****************************************************************************
+// namespace extensions
+namespace Exiv2 {
+
+// *****************************************************************************
+// class declarations
+
+ struct TiffStructure;
+
+// *****************************************************************************
+// type definitions
+
+// *****************************************************************************
+// class definitions
+
+ /*!
+ Known TIFF groups
+
+ Todo: what exactly are these and where should they go?
+ Are they going to be mapped to the second part of an Exif key or are they
+ the second part of the key?
+ */
+ namespace Group {
+ const uint16_t none = 0; //!< Dummy group
+ const uint16_t ifd0 = 1; //!< Exif IFD0
+ const uint16_t ifd1 = 2; //!< Thumbnail IFD
+ const uint16_t exif = 3; //!< Exif IFD
+ const uint16_t gps = 4; //!< GPS IFD
+ const uint16_t iop = 5; //!< Interoperability IFD
+ const uint16_t makernote = 256; //!< Makernote
+ const uint16_t canonmn = 257; //!< Canon makernote
+ }
+
+ /*!
+ Known TIFF tags
+
+ Todo: Same Q as above...
+ */
+ namespace Tag {
+ const int32_t none = -1; //!< Dummy tag
+ const int32_t root = -2; //!< Special tag: root IFD
+ const int32_t next = -3; //!< Special tag: next IFD
+ }
+
+ /*!
+ @brief Interface class for components of a TIFF directory hierarchy. Both
+ TIFF directories as well as entries implement this interface. This
+ class is implemented as NVI (non-virtual interface).
+ */
+ class TiffComponent {
+ public:
+ //! TiffComponent auto_ptr type
+ typedef std::auto_ptr<TiffComponent> AutoPtr;
+ //! Container type to hold all metadata
+ typedef std::vector<TiffComponent*> Components;
+
+ //! @name Creators
+ //@{
+ //! Constructor
+ TiffComponent(uint16_t group, const TiffStructure* pTiffStructure)
+ : group_(group), pTiffStructure_(pTiffStructure) {}
+
+ //! Virtual destructor.
+ virtual ~TiffComponent() {}
+ //@}
+
+ //! @name Manipulators
+ //@{
+ /*!
+ @brief Read a component from a data buffer
+
+ @param pData Pointer to the data buffer, starting with a TIFF header.
+ @param size Number of bytes in the data buffer.
+ @param start Component starts at \em pData + \em start.
+ @param byteOrder Applicable byte order (little or big endian).
+
+ @throw Error If the component cannot be parsed.
+ */
+ void read(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder);
+ //@}
+
+ //! @name Accessors
+ //@{
+ //*! Return the group id of this component
+ uint16_t group() const { return group_; }
+ //*! Return the TIFF structure
+ const TiffStructure* pTiffStructure() const { return pTiffStructure_; }
+ /*!
+ @brief Decode metadata from the component and add it to
+ \em image.
+
+ @param image Image to add the metadata to
+ @param byteOrder Byte order
+ */
+ void decode(Image& image, ByteOrder byteOrder) const;
+ /*!
+ @brief Print debug info about a component to \em os.
+
+ @param os Output stream to write to
+ @param byteOrder Byte order
+ @param prefix Prefix to be written before each line of output
+ */
+ void print(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix ="") const;
+ //@}
+
+ protected:
+ //! @name Manipulators
+ //@{
+ //! Implements read().
+ virtual void doRead(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder) =0;
+ //@}
+
+ //! @name Accessors
+ //@{
+ //! Implements decode()
+ virtual void doDecode(Image& image,
+ ByteOrder byteOrder) const =0;
+ //! Implements print()
+ virtual void doPrint(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix) const =0;
+ //@}
+
+ private:
+ // DATA
+ uint16_t group_; //!< Group id for this component
+ const TiffStructure* pTiffStructure_; //!< TIFF structure for this component
+
+ }; // class TiffComponent
+
+ /*!
+ @brief This baseclass provides the common functionality of an IFD directory entry
+ and defines the interface for derived concrete entries.
+
+ todo: make sure this class is an ABC
+ */
+ class TiffEntryBase : public TiffComponent {
+ public:
+ //! @name Creators
+ //@{
+ //! Default constructor
+ TiffEntryBase()
+ : TiffComponent(Group::none, 0),
+ tag_(0), type_(0), count_(0), offset_(0),
+ size_(0), pData_(0), isAllocated_(false) {}
+ //! Virtual destructor.
+ virtual ~TiffEntryBase();
+ //@}
+
+ //! @name Accessors
+ //@{
+ //! Return the tag of this entry.
+ uint16_t tag() const { return tag_; }
+ //! Return the Exiv2 type which corresponds to the field type.
+ TypeId typeId() const { return TypeId(type_); }
+ //! Return the number of components in this entry.
+ uint32_t count() const { return count_; }
+ //! Return the offset relative to the start of the TIFF header.
+ uint32_t offset() const { return offset_; }
+ //! Return the size of this component in bytes
+ uint32_t size() const { return size_; }
+ //! Return a pointer to the data area of this component
+ const byte* pData() const { return pData_; }
+ //@}
+
+ protected:
+ //! @name Manipulators
+ //@{
+ //! Implements read().
+ virtual void doRead(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder);
+ //@}
+
+ //! @name Accessors
+ //@{
+ //! Implements decode() for a TIFF IFD entry
+ virtual void doDecode(Image& image, ByteOrder byteOrder) const;
+ //! Implements print() for a TIFF IFD entry
+ virtual void doPrint(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix) const;
+ //@}
+
+ private:
+ // DATA
+ uint16_t tag_; //!< Tag that identifies the field
+ uint16_t type_; //!< Field Type
+ uint32_t count_; //!< The number of values of the indicated Type
+ uint32_t offset_; //!< Offset to the data area from start of the TIFF header
+ /*!
+ Size of the data buffer holding the value in bytes, there is no
+ minimum size.
+ */
+ uint32_t size_;
+ const byte* pData_; //!< Pointer to the data area
+ bool isAllocated_; //!< True if this entry owns the value data
+
+ }; // class TiffEntryBase
+
+ /*!
+ @brief A standard TIFF IFD entry. The value is kept in a data buffer.
+ */
+ class TiffEntry : public TiffEntryBase {
+ public:
+ //! @name Creators
+ //@{
+ //! Virtual destructor.
+ virtual ~TiffEntry() {}
+ //@}
+
+ private:
+ //! @name Manipulators
+ //@{
+ //! Implements read().
+ virtual void doRead(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder);
+ //@}
+
+ //! @name Accessors
+ //@{
+ virtual void doDecode(Image& image, ByteOrder byteOrder) const;
+ //! Implements print() for a TIFF IFD entry
+ virtual void doPrint(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix) const;
+ //@}
+
+ }; // class TiffEntry
+
+ //! This class models a TIFF directory (%Ifd).
+ class TiffDirectory : public TiffComponent {
+ public:
+ //! @name Creators
+ //@{
+ //! Default constructor
+ TiffDirectory(uint16_t group, const TiffStructure* pTiffStructure)
+ : TiffComponent(group, pTiffStructure), pNext_(0) {}
+ //! Virtual destructor
+ virtual ~TiffDirectory();
+ //@}
+
+ private:
+ //! @name Manipulators
+ //@{
+ virtual void doRead(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder);
+ //@}
+
+ //! @name Accessors
+ //@{
+ virtual void doDecode(Image& image,
+ ByteOrder byteOrder) const;
+
+ virtual void doPrint(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix) const;
+ //@}
+
+ private:
+ // DATA
+ Components components_; //!< List of components in this directory
+ TiffComponent* pNext_; //!< Pointer to the next IFD
+
+ }; // class TiffDirectory
+
+ //! This class models a TIFF sub-directory (%SubIfd).
+ class TiffSubIfd : public TiffEntryBase {
+ public:
+ //! @name Creators
+ //@{
+ //! Default constructor
+ TiffSubIfd(uint16_t group, const TiffStructure* pTiffStructure)
+ : ifd_(group, pTiffStructure) {}
+ //! Virtual destructor
+ virtual ~TiffSubIfd() {}
+ //@}
+
+ private:
+ //! @name Manipulators
+ //@{
+ virtual void doRead(const byte* pData,
+ uint32_t size,
+ uint32_t start,
+ ByteOrder byteOrder);
+ //@}
+
+ //! @name Accessors
+ //@{
+ virtual void doDecode(Image& image,
+ ByteOrder byteOrder) const;
+
+ virtual void doPrint(std::ostream& os,
+ ByteOrder byteOrder,
+ const std::string& prefix) const;
+ //@}
+
+ private:
+ // DATA
+ TiffDirectory ifd_; //!< The subdirectory
+
+ }; // class TiffDirectory
+
+ /*!
+ @brief This class models a TIFF header structure.
+ */
+ class TiffHeade2 {
+ public:
+ //! @name Creators
+ //@{
+ //! Default constructor
+ TiffHeade2()
+ : byteOrder_ (littleEndian),
+ offset_ (0x00000008)
+ {}
+ //@}
+
+ //! @name Manipulators
+ //@{
+ /*!
+ @brief Read the TIFF header from a data buffer. Return false if the
+ data buffer does not contain a TIFF header, else true.
+
+ @param pData Pointer to the data buffer.
+ @param size Number of bytes in the data buffer.
+ */
+ bool read(const byte* pData, uint32_t size);
+ //@}
+
+ //! @name Accessors
+ //@{
+ /*!
+ @brief Write the TIFF header to the binary image \em blob.
+ This method appends to the blob.
+
+ @param blob Binary image to add to.
+
+ @throw Error If the header cannot be written.
+ */
+ void write(Blob& blob) const;
+ /*!
+ @brief Print debug info for the TIFF header to \em os.
+
+ @param os Output stream to write to.
+ @param prefix Prefix to be written before each line of output.
+ */
+ void print(std::ostream& os, const std::string& prefix ="") const;
+ //! Return the byte order (little or big endian).
+ ByteOrder byteOrder() const { return byteOrder_; }
+ //! Return the offset to the start of the root directory
+ uint32_t offset() const { return offset_; }
+ //@}
+
+ private:
+ // DATA
+ ByteOrder byteOrder_; //!< Applicable byte order
+ uint32_t offset_; //!< Offset to the start of the root dir
+
+ static const uint16_t tag_; //!< 42, identifies the buffer as TIFF data
+
+ }; // class TiffHeade2
+
+ /*!
+ Type for a function pointer for functions to create TIFF components.
+ Todo: This may eventually need to also have access to the image or parse tree
+ in order to make decisions based on the value of other tags.
+ */
+ typedef TiffComponent::AutoPtr (*NewTiffCompFct)(uint16_t group,
+ const TiffStructure* tiffStructure);
+
+ /*!
+ Table 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 {
+ int32_t tag_; //!< Tag
+ 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
+ };
+
+ /*!
+ Stateless parser class for data in TIFF format.
+ */
+ class TiffParser {
+ public:
+ /*!
+ @brief Decode TIFF metadata from a data buffer \em pData of length
+ \em size into \em image.
+
+ This is the entry point to access image data in TIFF format. The
+ parser uses classes TiffHeade2, TiffEntry, TiffDirectory.
+
+ @param pImage Pointer to the %Exiv2 TIFF image to hold the
+ metadata read from the buffer.
+ @param pTiffStructure Pointer to a table describing the TIFF structure
+ used to decode the data.
+ @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.
+
+ @throw Error If the data buffer cannot be parsed.
+ */
+ static void decode( Image* pImage,
+ const TiffStructure* pTiffStructure,
+ const byte* pData,
+ uint32_t size);
+ /*!
+ @brief Create the appropriate TiffComponent to handle the \em tag in
+ \em group.
+
+ Uses table \em pTiffStructure to derive the correct component. 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 tag should be ignored.
+ */
+ static TiffComponent::AutoPtr create( int32_t tag,
+ uint16_t group,
+ const TiffStructure* pTiffStructure);
+ }; // class TiffParser
+
+// *****************************************************************************
+// template, inline and free functions
+
+ //!< Function to create and initialize a new TIFF directory
+ TiffComponent::AutoPtr newTiffDirectory(uint16_t group,
+ const TiffStructure* pTiffStructure);
+
+ //!< Function to create and initialize a new TIFF sub-directory
+ TiffComponent::AutoPtr newTiffSubIfd(uint16_t group,
+ const TiffStructure* pTiffStructure);
+
+} // namespace Exiv2
+
+#endif // #ifndef TIFFPARSER_HPP_
--
exiv2 packaging
More information about the pkg-kde-commits
mailing list