[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:13 UTC 2017


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=489fff1

The following commit has been merged in the master branch:
commit 489fff191d6149179d048ec085f25ac34d5f72f2
Author: Andreas Huggel <ahuggel at gmx.net>
Date:   Sun Sep 11 08:41:54 2005 +0000

    Canon CRW read support, first try. Introduces a new approach to parsing metadata. Cluttered by some related additions to the Canon makernote note and a bit of cleanup.
---
 src/Makefile                |  10 +-
 src/actions.cpp             |  22 +-
 src/basicio.hpp             |   2 -
 src/canonmn.cpp             |  64 ++---
 src/canonmn.hpp             |  25 ++
 src/crwimage.cpp            | 686 ++++++++++++++++++++++++++++++++++++++++++++
 src/crwimage.hpp            | 608 +++++++++++++++++++++++++++++++++++++++
 src/error.cpp               |   4 +
 src/exif.cpp                |   2 +-
 src/image.cpp               |   1 +
 src/image.hpp               |   2 +-
 src/nikonmn.cpp             |  11 +-
 src/olympusmn.cpp           |   6 +-
 src/panasonicmn.cpp         |  10 +-
 src/tags.cpp                |  55 +++-
 src/tags.hpp                |  21 +-
 src/types.cpp               |  31 +-
 src/types.hpp               |  55 +++-
 test/data/exifdata-test.out |  32 +--
 test/data/exiv2-test.out    |  42 +--
 test/data/modify-test.out   |   4 +-
 test/data/write-test.out    |  64 ++---
 test/data/write2-test.out   |   8 +-
 23 files changed, 1578 insertions(+), 187 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index 6f75213..c08624f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -51,16 +51,16 @@ include $(top_srcdir)/config/config.mk
 CCHDR = exv_conf.h exv_msvc.h mn.hpp rcsid.hpp 
 
 # Add library C++ source files to this list
-CCSRC = basicio.cpp canonmn.cpp datasets.cpp error.cpp exif.cpp futils.cpp \
-	fujimn.cpp ifd.cpp image.cpp iptc.cpp jpgimage.cpp makernote.cpp \
-        metadatum.cpp nikonmn.cpp olympusmn.cpp panasonicmn.cpp sigmamn.cpp \
-	sonymn.cpp tags.cpp types.cpp value.cpp 
+CCSRC = basicio.cpp canonmn.cpp crwimage.cpp datasets.cpp error.cpp exif.cpp \
+	futils.cpp fujimn.cpp ifd.cpp image.cpp iptc.cpp jpgimage.cpp \
+	makernote.cpp metadatum.cpp nikonmn.cpp olympusmn.cpp panasonicmn.cpp \
+	sigmamn.cpp sonymn.cpp tags.cpp types.cpp value.cpp 
 
 # Add source files of simple applications to this list
 BINSRC = addmoddel.cpp dataarea-test.cpp exifcomment.cpp exifdata-test.cpp \
          exifprint.cpp ifd-test.cpp iotest.cpp iptceasy.cpp iptcprint.cpp \
          iptctest.cpp key-test.cpp makernote-test.cpp taglist.cpp write-test.cpp \
-         write2-test.cpp 
+         write2-test.cpp
 
 # Main source file of the Exiv2 application
 EXIV2MAIN = exiv2.cpp
diff --git a/src/actions.cpp b/src/actions.cpp
index f2eb9d1..1b031eb 100644
--- a/src/actions.cpp
+++ b/src/actions.cpp
@@ -229,28 +229,28 @@ namespace Action {
             md = exifData.findKey(
                 Exiv2::ExifKey("Exif.Photo.ShutterSpeedValue"));
             if (md != exifData.end()) {
-                double tmp = exp(log(2.0) * md->toFloat()) + 0.5;
+                double tmp = exp(log(2.0) * md->toFloat());
                 if (tmp > 1) {
-                    std::cout << "1/" << static_cast<long>(tmp) << " s";
+                    std::cout << "1/" << static_cast<long>(tmp + 0.5);
                 }
                 else {
-                    std::cout << static_cast<long>(1/tmp) << " s";
+                    std::cout << static_cast<long>(1/tmp + 0.5);
                 }
+                std::cout << " s";
             }
         }
         std::cout << std::endl;
 
         // Aperture
         // Get if from FNumber and, failing that, try ApertureValue
+        bool done = false;
         std::cout << std::setw(align_) << std::setfill(' ') << std::left
                   << "Aperture" << ": ";
-        if (0 == printTag(exifData, "Exif.Photo.FNumber")) {
-            md = exifData.findKey(
-                Exiv2::ExifKey("Exif.Photo.ApertureValue"));
-            if (md != exifData.end()) {
-                std::cout << std::fixed << std::setprecision(1)
-                          << "F" << exp(log(2.0) * md->toFloat() / 2);
-            }
+        if (!done) {
+            done = 0 != printTag(exifData, "Exif.Photo.FNumber");
+        }
+        if (!done) {
+            done = 0 != printTag(exifData, "Exif.Photo.ApertureValue");
         }
         std::cout << std::endl;
 
@@ -262,7 +262,7 @@ namespace Action {
 
         // Todo: Flash bias, flash energy
         // Todo: Implement this for other cameras
-        bool done = false;
+        done = false;
         std::cout << std::setw(align_) << std::setfill(' ') << std::left
                   << "Flash bias" << ": ";        
         if (!done) {
diff --git a/src/basicio.hpp b/src/basicio.hpp
index a651fb4..291c048 100644
--- a/src/basicio.hpp
+++ b/src/basicio.hpp
@@ -406,8 +406,6 @@ namespace Exiv2 {
         /*!
           @brief Flush any buffered writes and get the current file size
               in bytes. 
-          @note On Win32 systems the file must be closed prior to calling this
-              function.
           @return Size of the file in bytes;<BR>
                  -1 if failure;
          */
diff --git a/src/canonmn.cpp b/src/canonmn.cpp
index 3ff4871..f60d0cf 100644
--- a/src/canonmn.cpp
+++ b/src/canonmn.cpp
@@ -50,27 +50,6 @@ EXIV2_RCSID("@(#) $Id$");
 #include <cmath>
 
 // *****************************************************************************
-// local declarations
-namespace {
-    /* 
-       @brief Convert Canon hex-based EV (modulo 0x20) to real number
-              Ported from Phil Harvey's Image::ExifTool::Canon::CanonEv 
-              by Will Stokes
-
-       0x00 -> 0
-       0x0c -> 0.33333
-       0x10 -> 0.5
-       0x14 -> 0.66666
-       0x20 -> 1  
-       ..
-       160 -> 5
-       128 -> 4
-       143 -> 4.46875
-     */
-    float canonEv(long val);
-}
-
-// *****************************************************************************
 // class member definitions
 namespace Exiv2 {
 
@@ -163,8 +142,8 @@ namespace Exiv2 {
         TagInfo(0x0001, "0x0001", "0x0001", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
         TagInfo(0x0002, "ISOSpeed", "ISOSpeed", "ISO speed used", canonCs2IfdId, makerTags, unsignedShort, printCs20x0002),
         TagInfo(0x0003, "0x0003", "0x0003", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
-        TagInfo(0x0004, "0x0004", "0x0004", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
-        TagInfo(0x0005, "0x0005", "0x0005", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
+        TagInfo(0x0004, "TargetAperture", "TargetAperture", "Target Aperture", canonCs2IfdId, makerTags, unsignedShort, printCs20x0015),
+        TagInfo(0x0005, "TargetShutterSpeed", "TargetShutterSpeed", "Target shutter speed", canonCs2IfdId, makerTags, unsignedShort, printCs20x0016),
         TagInfo(0x0006, "0x0006", "0x0006", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
         TagInfo(0x0007, "WhiteBalance", "WhiteBalance", "White balance setting", canonCs2IfdId, makerTags, unsignedShort, printCs20x0007),
         TagInfo(0x0008, "0x0008", "0x0008", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
@@ -180,8 +159,8 @@ namespace Exiv2 {
         TagInfo(0x0012, "0x0012", "0x0012", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
         TagInfo(0x0013, "SubjectDistance", "SubjectDistance", "Subject distance (units are not clear)", canonCs2IfdId, makerTags, unsignedShort, printCs20x0013),
         TagInfo(0x0014, "0x0014", "0x0014", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
-        TagInfo(0x0015, "0x0015", "0x0015", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
-        TagInfo(0x0016, "0x0016", "0x0016", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
+        TagInfo(0x0015, "ApertureValue", "ApertureValue", "Aperture", canonCs2IfdId, makerTags, unsignedShort, printCs20x0015),
+        TagInfo(0x0016, "ShutterSpeedValue", "ShutterSpeedValue", "Shutter speed", canonCs2IfdId, makerTags, unsignedShort, printCs20x0016),
         TagInfo(0x0017, "0x0017", "0x0017", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
         TagInfo(0x0018, "0x0018", "0x0018", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
         TagInfo(0x0019, "0x0019", "0x0019", "Unknown", canonCs2IfdId, makerTags, unsignedShort, printValue),
@@ -893,6 +872,33 @@ namespace Exiv2 {
         return os;
     }
 
+    std::ostream& CanonMakerNote::printCs20x0015(std::ostream& os,
+                                                 const Value& value)
+    {
+        if (value.typeId() != unsignedShort) return os << value;
+
+        std::ostringstream oss;
+        oss.copyfmt(os);
+        os << std::setprecision(2)
+           << "F" << fnumber(canonEv(value.toLong()));
+        os.copyfmt(oss);
+
+        return os;
+    }
+
+    std::ostream& CanonMakerNote::printCs20x0016(std::ostream& os,
+                                                 const Value& value)
+    {
+        if (value.typeId() != unsignedShort) return os << value;
+
+        URational ur = exposureTime(canonEv(value.toLong()));
+        os << ur.first;
+        if (ur.second > 1) {
+            os << "/" << ur.second;
+        }
+        return os << " s";
+    }
+
 // *****************************************************************************
 // free functions
 
@@ -905,12 +911,6 @@ namespace Exiv2 {
         return MakerNote::AutoPtr(new CanonMakerNote(alloc));
     }
 
-}                                       // namespace Exiv2
-
-// *****************************************************************************
-// local definitions
-namespace {
-
     float canonEv(long val)
     {
         // temporarily remove sign
@@ -932,4 +932,4 @@ namespace {
         return sign * (val + frac) / 32.0f;
     }
 
-}
+}                                       // namespace Exiv2
diff --git a/src/canonmn.hpp b/src/canonmn.hpp
index 87dcba0..cb64c5e 100644
--- a/src/canonmn.hpp
+++ b/src/canonmn.hpp
@@ -188,6 +188,10 @@ namespace Exiv2 {
         static std::ostream& printCs20x000f(std::ostream& os, const Value& value);
         //! Subject distance
         static std::ostream& printCs20x0013(std::ostream& os, const Value& value);
+        //! Aperture
+        static std::ostream& printCs20x0015(std::ostream& os, const Value& value);
+        //! Shutter speed
+        static std::ostream& printCs20x0016(std::ostream& os, const Value& value);
         //@}
 
         //! @cond IGNORE
@@ -234,6 +238,27 @@ namespace Exiv2 {
     }; // class CanonMakerNote
 
     static CanonMakerNote::RegisterMn registerCanonMakerNote;
+
+// *****************************************************************************
+// template, inline and free functions
+
+    /*!
+       @brief Convert Canon hex-based EV (modulo 0x20) to real number
+              Ported from Phil Harvey's Image::ExifTool::Canon::CanonEv 
+              by Will Stokes
+
+       0x00 -> 0
+       0x0c -> 0.33333
+       0x10 -> 0.5
+       0x14 -> 0.66666
+       0x20 -> 1  
+       ..
+       160 -> 5
+       128 -> 4
+       143 -> 4.46875
+     */
+    float canonEv(long val);
+
 }                                       // namespace Exiv2
 
 #endif                                  // #ifndef CANONMN_HPP_
diff --git a/src/crwimage.cpp b/src/crwimage.cpp
new file mode 100644
index 0000000..a5c7b67
--- /dev/null
+++ b/src/crwimage.cpp
@@ -0,0 +1,686 @@
+// ***************************************************************** -*- C++ -*-
+/*
+ * Copyright (C) 2005 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+/*
+  File:      crwimage.cpp
+  Version:   $Rev$
+  Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
+  History:   28-Aug-05, ahu: created
+             
+ */
+// *****************************************************************************
+#include "rcsid.hpp"
+EXIV2_RCSID("@(#) $Id$");
+
+// Define DEBUG to output debug information to std::cerr, e.g, by calling make
+// like this: make DEFS=-DDEBUG crwimage.o
+//#define DEBUG
+
+// *****************************************************************************
+// included header files
+#ifdef _MSC_VER
+# include "exv_msvc.h"
+#else
+# include "exv_conf.h"
+#endif
+
+#include "crwimage.hpp"
+#include "error.hpp"
+#include "futils.hpp"
+#include "value.hpp"
+#include "tags.hpp"
+#include "canonmn.hpp"
+
+// + standard includes
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <cmath>
+
+// *****************************************************************************
+// class member definitions
+namespace Exiv2 {
+
+    // Local functions. These could be static private functions on Image
+    // subclasses but then ImageFactory needs to be made a friend. 
+    /*!
+      @brief Create a new CrwImage 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 newCrwInstance(BasicIo::AutoPtr io, bool create);
+
+    //! Check if the file iIo is a CRW image.
+    bool isCrwType(BasicIo& iIo, bool advance);
+
+    const byte CrwImage::blank_[] = {
+        0x00 
+    };
+
+    CrwImage::CrwImage(BasicIo::AutoPtr io, bool create)
+        : io_(io)
+    {
+        if (create) {
+            initImage(blank_, sizeof(blank_));
+        }
+    } // CrwImage::CrwImage
+
+    int CrwImage::initImage(const byte initData[], size_t dataSize)
+    {
+        if (io_->open() != 0) {
+            return 4;
+        }
+        IoCloser closer(*io_);
+        if (static_cast<size_t>(io_->write(initData, dataSize)) != dataSize) {
+            return 4;
+        }
+        return 0;
+    } // CrwImage::initImage
+
+    bool CrwImage::good() const
+    {
+        if (io_->open() != 0) return false;
+        IoCloser closer(*io_);
+        return isThisType(*io_, false);
+    }
+
+    void CrwImage::clearMetadata()
+    {
+        clearExifData();
+        clearComment();
+    }
+    
+    void CrwImage::setMetadata(const Image& image)
+    {
+        setExifData(image.exifData());
+        setComment(image.comment());
+    }
+
+    void CrwImage::clearExifData()
+    {
+        exifData_.clear();
+    }
+
+    void CrwImage::setExifData(const ExifData& exifData)
+    {
+        exifData_ = exifData;
+    }
+
+    void CrwImage::clearIptcData()
+    {
+        throw Error(31, "CrwImage::clearIptcData");
+    }
+
+    void CrwImage::setIptcData(const IptcData& iptcData)
+    {
+        throw Error(31, "CrwImage::setIptcData");
+    }
+
+    void CrwImage::clearComment()
+    {
+        comment_.erase();
+    }
+
+    void CrwImage::setComment(const std::string& comment)
+    { 
+        comment_ = comment;
+    }
+
+    void CrwImage::readMetadata()
+    {
+#ifdef DEBUG
+        std::cerr << "Reading CRW 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
+        size_t imageSize = io_->size();
+        DataBuf image(imageSize);
+        io_->read(image.pData_, imageSize);
+        if (io_->error() || io_->eof()) throw Error(14);
+
+        // Parse the image
+        RawMetadata::AutoPtr parseTree(new CrwHeader);
+        parseTree->read(image.pData_, image.size_, 0, invalidByteOrder);
+#ifdef DEBUG
+        parseTree->print(std::cerr, invalidByteOrder);
+#endif
+        parseTree->extract(*this, invalidByteOrder);
+
+    } // CrwImage::readMetadata
+
+    void CrwImage::writeMetadata()
+    {
+        // Todo: implement me!
+    } // CrwImage::writeMetadata
+
+    //! @cond IGNORE
+    CrwImage::CrwRegister::CrwRegister()
+    {
+        ImageFactory::registerImage(
+            Image::crw, newCrwInstance, isCrwType);
+    }
+    //! @endcond
+
+    bool CrwImage::isThisType(BasicIo& iIo, bool advance) const
+    {
+        return isCrwType(iIo, advance);
+    }
+
+    TypeId CrwEntry::typeId(uint16_t tag)
+    {
+        TypeId ti = invalidTypeId;
+        switch (tag & 0x3800) {
+        case 0x0000: ti = unsignedByte; break;
+        case 0x0800: ti = asciiString; break;
+        case 0x1000: ti = unsignedShort; break;
+        case 0x1800: ti = unsignedLong; break;
+        case 0x2000: ti = undefined; break;
+        case 0x2800: // fallthrough
+        case 0x3000: ti = directory; break;
+        }
+        return ti;
+    } // CrwEntry::typeId
+
+    DataLocId CrwEntry::dataLocation(uint16_t tag)
+    {
+        DataLocId di = invalidDataLocId;
+        switch (tag & 0xc000) {
+        case 0x0000: di = valueData; break;
+        case 0x4000: di = directoryData; break;
+        }
+        return di;
+    } // CrwEntry::dataLocation
+
+    void CrwEntry::add(RawMetadata::AutoPtr component)
+    {
+        throw Error(34, "CrwEntry::add");
+    } // CrwEntry::add
+
+    void CrwEntry::read(const byte* buf, 
+                        size_t len, 
+                        size_t start, 
+                        ByteOrder byteOrder,
+                        long /*shift*/)
+    {
+        if (len < 10) throw Error(33);
+        tag_ = getUShort(buf + start, byteOrder);
+        switch (dataLocation()) {
+        case valueData:
+            size_ = getULong(buf + start + 2, byteOrder);
+            offset_ = getULong(buf + start + 6, byteOrder);
+            break;
+        case directoryData:
+            size_ = 8;
+            offset_ = start + 2;
+            break;
+        case invalidDataLocId:
+        case lastDataLocId:
+            // empty
+            break;
+        }
+        pData_ = buf + offset_;
+    } // CrwEntry::read
+
+    void CrwEntry::extract(Image& image, ByteOrder byteOrder) const
+    {
+        CrwMap::extract(*this, image, byteOrder);
+    } // CrwEntry::extract
+    
+    void CrwEntry::print(std::ostream& os, 
+                         ByteOrder byteOrder,
+                         const std::string& prefix) const
+    {
+        os << prefix 
+           << "tag = 0x" << std::setw(4) << std::setfill('0')
+           << std::hex << std::right << tagId()
+           << ", dir = 0x" << std::setw(4) << std::setfill('0')
+           << std::hex << std::right << dir()
+           << ", type = " << TypeInfo::typeName(typeId())
+           << ", size = " << std::dec << size_
+           << ", offset = " << offset_ << "
";
+
+        Value::AutoPtr value;
+        if (typeId() != directory) {
+            value = Value::create(typeId());
+            value->read(pData_, size_, byteOrder);
+            if (value->size() < 100) {
+                os << prefix << *value << "
";
+            }
+        }
+
+    } // CrwEntry::print
+
+    CrwDirectory::~CrwDirectory()
+    {
+        RawMetadata::Components::iterator b = components_.begin();
+        RawMetadata::Components::iterator e = components_.end();
+        for (RawMetadata::Components::iterator i = b; i != e; ++i) {
+            delete *i;
+        }
+    }
+
+    void CrwDirectory::add(RawMetadata::AutoPtr component)
+    {
+        components_.push_back(component.release());
+    } // CrwEntry::add
+
+    void CrwDirectory::read(const byte* buf, 
+                            size_t len, 
+                            size_t start, 
+                            ByteOrder byteOrder,
+                            long /*shift*/)
+    {
+        CrwEntry::read(buf, len, start, byteOrder);
+        readDirectory(buf + offset(), size(), 0, byteOrder, 0);
+    } // CrwDirectory::read
+
+    void CrwDirectory::extract(Image& image, ByteOrder byteOrder) const
+    {
+        RawMetadata::Components::const_iterator b = components_.begin();
+        RawMetadata::Components::const_iterator e = components_.end();
+        for (RawMetadata::Components::const_iterator i = b; i != e; ++i) {
+            (*i)->extract(image, byteOrder);
+        }
+    } // CrwDirectory::extract
+
+    void CrwDirectory::print(std::ostream& os, 
+                             ByteOrder byteOrder,
+                             const std::string& prefix) const
+    {
+        CrwEntry::print(os, byteOrder, prefix);
+        RawMetadata::Components::const_iterator b = components_.begin();
+        RawMetadata::Components::const_iterator e = components_.end();
+        for (RawMetadata::Components::const_iterator i = b; i != e; ++i) {
+            (*i)->print(os, byteOrder, prefix + "   ");
+        }
+    } // CrwDirectory::print
+
+    void CrwDirectory::readDirectory(const byte* buf, 
+                                     size_t len, 
+                                     size_t start, 
+                                     ByteOrder byteOrder, 
+                                     long /*shift*/)
+    {
+        uint32_t dataSize = getULong(buf + len - 4, byteOrder);
+        uint32_t o = start + dataSize;
+        if (o + 2 > len) throw Error(33);
+        uint16_t count = getUShort(buf + o, byteOrder);
+        o += 2;
+        for (uint16_t i = 0; i < count; ++i) {
+            if (o + 10 > len) throw Error(33);
+            uint16_t tag = getUShort(buf + o, byteOrder);
+            CrwEntry* p = 0;
+            switch (CrwEntry::typeId(tag)) {
+            case directory: p = new CrwDirectory; break;
+            default: p = new CrwEntry; break;
+            }
+            p->setDir(this->tag());
+            RawMetadata::AutoPtr m(p);
+            m->read(buf, len, o, byteOrder);
+            add(m);
+            o += 10;
+        }
+    }  // CrwDirectory::readDirectory
+
+    const char CrwHeader::signature_[] = "HEAPCCDR";
+
+    CrwHeader::~CrwHeader()
+    {
+        delete rootDirectory_;
+    }
+
+    void CrwHeader::add(RawMetadata::AutoPtr component)
+    {
+        throw Error(34, "CrwHeader::add");
+    } // CrwEntry::add
+
+    void CrwHeader::read(const byte* buf, 
+                         size_t len, 
+                         size_t start, 
+                         ByteOrder byteOrder,
+                         long /*shift*/)
+    {
+        if (len < 14) throw Error(33);
+
+        if (buf[0] == 0x49 && buf[1] == 0x49) {
+            byteOrder_ = littleEndian;
+        }
+        else if (buf[0] == 0x4d && buf[1] == 0x4d) {
+            byteOrder_ = bigEndian;
+        }
+        else {
+            throw Error(33);
+        }
+        offset_ = getULong(buf + 2, byteOrder_);
+        if (std::memcmp(buf + 6, signature_, 8) != 0) {
+            throw Error(33);
+        }
+
+        rootDirectory_ = new CrwDirectory;
+        rootDirectory_->readDirectory(buf + offset_, len - offset_, 0, byteOrder_);
+    } // CrwHeader::read
+
+    void CrwHeader::extract(Image& image, ByteOrder byteOrder) const
+    {
+        // Nothing to extract from the header itself, just add correct byte order
+        if (rootDirectory_) rootDirectory_->extract(image, byteOrder_);
+    } // CrwHeader::extract
+
+    void CrwHeader::print(std::ostream& os, 
+                          ByteOrder byteOrder,
+                          const std::string& prefix) const
+    {
+        os << prefix 
+           << "Header, offset = 0x" << std::setw(8) << std::setfill('0')
+           << std::hex << std::right << offset_ << "
";
+        if (rootDirectory_) rootDirectory_->print(os, byteOrder_, prefix);
+    } // CrwHeader::print
+
+    const CrwMapInfo CrwMap::crwMapInfos_[] = {
+        CrwMapInfo(0x0805, 0x300a, 0, 0x9286, exifIfdId, extract0x0805, 0), 
+        CrwMapInfo(0x080a, 0x2807, 0, 0x010f, ifd0Id, extract0x080a, 0),
+        CrwMapInfo(0x080a, 0x2807, 0, 0x0110, ifd0Id, 0, 0),
+        CrwMapInfo(0x080b, 0x3004, 0, 0x0007, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x0810, 0x2807, 0, 0x0009, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x0815, 0x2804, 0, 0x0006, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x1029, 0x300b, 0, 0x0002, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x102a, 0x300b, 0, 0x0004, canonIfdId, extract0x102a, 0),
+        CrwMapInfo(0x102d, 0x300b, 0, 0x0001, canonIfdId, extract0x102d, 0),
+        CrwMapInfo(0x1033, 0x300b, 0, 0x000f, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x1038, 0x300b, 0, 0x0012, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x10a9, 0x300b, 0, 0x00a9, canonIfdId, extractBasic, 0),
+//        CrwMapInfo(0x10b4, 0x300b, 0, 0x00b4, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x10b4, 0x300b, 0, 0xa001, exifIfdId, extractBasic, 0),
+        CrwMapInfo(0x10b5, 0x300b, 0, 0x00b5, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x10c0, 0x300b, 0, 0x00c0, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x10c1, 0x300b, 0, 0x00c1, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x1807, 0x3002, 0, 0x9206, exifIfdId, extractBasic, 0),
+        CrwMapInfo(0x180b, 0x2807, 0, 0x000c, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x180e, 0x300a, 0, 0x9003, exifIfdId, extract0x180e, 0),
+        CrwMapInfo(0x1810, 0x300a, 0, 0xa002, exifIfdId, extract0x1810, 0),
+        CrwMapInfo(0x1810, 0x300a, 0, 0xa003, exifIfdId, extract0x1810, 0),
+        CrwMapInfo(0x1817, 0x300a, 4, 0x0008, canonIfdId, extractBasic, 0),
+//        CrwMapInfo(0x1818, 0x3002, 0, 0x9204, exifIfdId, extractBasic, 0),
+        CrwMapInfo(0x183b, 0x300b, 0, 0x0015, canonIfdId, extractBasic, 0),
+        CrwMapInfo(0x2008, 0x0000, 0, 0x0201, ifd1Id, extract0x2008, 0),
+        CrwMapInfo(0x2008, 0x0000, 0, 0x0202, ifd1Id, 0, 0),
+        CrwMapInfo(0x2008, 0x0000, 0, 0x0103, ifd1Id, 0, 0),
+        CrwMapInfo(0x0000, 0x0000, 0, 0x0000, ifdIdNotSet, extractBasic, 0)
+    }; // CrwMap::crwMapInfos_[]
+
+    void CrwMap::extract(const CrwEntry& crwEntry, 
+                         Image& image,
+                         ByteOrder byteOrder)
+    {
+        const CrwMapInfo* cmi = crwMapInfo(crwEntry.dir(), crwEntry.tagId());
+        if (cmi && cmi->toExif_) {
+            cmi->toExif_(crwEntry, cmi, image, byteOrder);
+        }
+    } // CrwMap::extract
+
+    const CrwMapInfo* CrwMap::crwMapInfo(uint16_t dir, uint16_t tagId)
+    {
+        for (int i = 0; crwMapInfos_[i].ifdId_ != ifdIdNotSet; ++i) {
+            if (   crwMapInfos_[i].crwDir_ == dir 
+                && crwMapInfos_[i].crwTagId_ == tagId) {
+                return &(crwMapInfos_[i]);
+            }
+        }
+        return 0;
+    } // CrwMap::crwMapInfo
+
+    void CrwMap::extract0x0805(const CrwEntry& crwEntry,
+                               const CrwMapInfo* crwMapInfo, 
+                               Image& image,
+                               ByteOrder /*byteOrder*/)
+    {
+        std::string s(reinterpret_cast<const char*>(crwEntry.pData()));
+        image.setComment(s);
+    } // CrwMap::extract0x0805
+
+    void CrwMap::extract0x080a(const CrwEntry& crwEntry,
+                               const CrwMapInfo* crwMapInfo, 
+                               Image& image,
+                               ByteOrder byteOrder)
+    {
+        if (crwEntry.typeId() != asciiString) {
+            return extractBasic(crwEntry, crwMapInfo, image, byteOrder);
+        }
+
+        // Make
+        ExifKey key1("Exif.Image.Make");
+        Value::AutoPtr value1 = Value::create(crwEntry.typeId());
+        uint32_t i = 0;
+        for (; i < crwEntry.size() && crwEntry.pData()[i] != '

-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list