[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