[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a

Maximiliano Curia maxy at moszumanska.debian.org
Thu Jul 13 17:36:05 UTC 2017


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

The following commit has been merged in the master branch:
commit 1f9430989942036b04de6fc87e1727a41c56a5f0
Author: Andreas Huggel <ahuggel at gmx.net>
Date:   Sat Feb 21 11:59:49 2004 +0000

    Added MakerNote support, basics
---
 src/Makefile      |  12 +-
 src/makernote.cpp | 597 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/makernote.hpp | 281 +++++++++++++++++++++++++
 3 files changed, 886 insertions(+), 4 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index 2e63407..cf17aaa 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -20,7 +20,7 @@
 # 02111-1307, USA.
 #
 # File:      Makefile
-# Version:   $Name:  $ $Revision: 1.10 $
+# Version:   $Name:  $ $Revision: 1.11 $
 # Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
 # History:   10-Dec-03, ahu: created
 #
@@ -51,7 +51,7 @@ include $(top_srcdir)/config.mk
 CCHDR = rcsid.hpp error.hpp
 
 # Add library C++ source files to this list
-CCSRC = exif.cpp ifd.cpp image.cpp tags.cpp types.cpp value.cpp
+CCSRC = exif.cpp ifd.cpp image.cpp makernote.cpp tags.cpp types.cpp value.cpp
 
 # Add source files of simple applications to this list
 BINSRC = example1.cpp taglist.cpp exifprint.cpp exiftest.cpp
@@ -130,7 +130,7 @@ ifeq ($(strip $(MAKECMDGOALS)),)
 -include $(DEP)
 else
 # ...or the target is _not_ one in the list of targets below.
-NOINCLUDE = uninstall uninstall-lib check doc mostlyclean clean        \
+NOINCLUDE = uninstall uninstall-lib check doc ctags mostlyclean clean  \
             install-header uninstall-header distclean maintainer-clean \
             uninstall-archive uninstall-sharedlib
 ifneq ($(MAKECMDGOALS), $(filter $(MAKECMDGOALS), $(NOINCLUDE)))
@@ -168,7 +168,7 @@ $(EXIV2BIN): %: %.o
 
 # ******************************************************************************
 # Targets
-.PHONY: all archive sharedlib bin check doc                            \
+.PHONY: all archive sharedlib bin check ctags doc                      \
         clean mostlyclean distclean maintainer-clean                   \
         install install-archive install-header                         \
         install-sharedlib install-lib                                  \
@@ -251,6 +251,10 @@ uninstall-sharedlib:
 
 uninstall-lib: $(UNINSTALL_LIB) uninstall-header
 
+ctags:
+	ctags-exuberant --extra=+q -e *
+	ctags-exuberant --extra=+q *
+
 check:
 	@echo "No checks available for this library."
 
diff --git a/src/makernote.cpp b/src/makernote.cpp
new file mode 100644
index 0000000..a44cf73
--- /dev/null
+++ b/src/makernote.cpp
@@ -0,0 +1,597 @@
+// ***************************************************************** -*- C++ -*-
+/*
+ * Copyright (C) 2004 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:      makernote.cpp
+  Version:   $Name:  $ $Revision: 1.1 $
+  Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
+  History:   18-Feb-04, ahu: created
+  Credits:   Canon MakerNote implemented according to the specification
+             "EXIF MakerNote of Canon" <http://www.burren.cx/david/canon.html>
+             by David Burren
+ */
+// *****************************************************************************
+#include "rcsid.hpp"
+EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.1 $ $RCSfile: makernote.cpp,v $")
+
+// *****************************************************************************
+// included header files
+#include "makernote.hpp"
+#include "value.hpp"
+#include "tags.hpp"                         // for ExifTags::ifdItem, printValue
+#include "error.hpp"
+
+// + standard includes
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+// Define DEBUG_MAKERNOTE to output debug information to std::cerr
+#define DEBUG_MAKERNOTE
+
+// *****************************************************************************
+// class member definitions
+namespace Exif {
+
+    std::string MakerNote::makeKey(uint16 tag) const
+    {
+        return std::string(ExifTags::ifdItem(makerIfd))
+            + "." + sectionName(tag) + "." + tagName(tag);
+    }
+
+    uint16 MakerNote::decomposeKey(const std::string& key) const
+    {
+        // Get the IFD, section name and tag name parts of the key
+        std::string::size_type pos1 = key.find('.');
+        if (pos1 == std::string::npos) throw Error("Invalid key");
+        std::string ifdItem = key.substr(0, pos1);
+        std::string::size_type pos0 = pos1 + 1;
+        pos1 = key.find('.', pos0);
+        if (pos1 == std::string::npos) throw Error("Invalid key");
+        std::string sectionName = key.substr(pos0, pos1 - pos0);
+        pos0 = pos1 + 1;
+        std::string tagName = key.substr(pos0);
+        if (tagName == "") throw Error("Invalid key");
+
+        if (ifdItem != ExifTags::ifdItem(makerIfd)) return 0xffff;
+        uint16 tag = this->tag(tagName);
+        if (tag == 0xffff) return tag;
+        if (sectionName != this->sectionName(tag)) return 0xffff;
+
+        return tag;
+    }
+
+    std::string MakerNote::tagName(uint16 tag) const
+    {
+        std::string tagName;
+        if (mnTagInfo_) {
+            for (int i = 0; mnTagInfo_[i].tag_ != 0xffff; ++i) {
+                if (mnTagInfo_[i].tag_ == tag) {
+                    tagName = mnTagInfo_[i].name_;
+                    break;
+                }
+            }
+        }
+        if (tagName.empty()) {
+            std::ostringstream os;
+            os << "0x" << std::setw(4) << std::setfill('0') << std::right
+               << std::hex << tag;
+            tagName = os.str();
+        }
+        return tagName;
+    }
+
+    uint16 MakerNote::tag(const std::string& tagName) const
+    {
+        uint16 tag = 0xffff;
+        if (mnTagInfo_) {
+            for (int i = 0; mnTagInfo_[i].tag_ != 0xffff; ++i) {
+                if (mnTagInfo_[i].name_ == tagName) {
+                    tag = mnTagInfo_[i].tag_;
+                    break;
+                }
+            }
+        }
+        if (tag == 0xffff) {
+            std::istringstream is(tagName);
+            is >> std::hex >> tag;
+        }
+        return tag;
+    }
+
+    MakerNoteFactory* MakerNoteFactory::instance_ = 0;
+
+    MakerNoteFactory& MakerNoteFactory::instance()
+    {
+        if (0 == instance_) {
+            instance_ = new MakerNoteFactory;
+        }
+        return *instance_;
+    } // MakerNoteFactory::instance
+
+    void MakerNoteFactory::registerMakerNote(const std::string& make, 
+                                             const std::string& model, 
+                                             MakerNote* makerNote)
+    {
+        std::string key = make + "+" + model;
+        Registry::iterator i = registry_.find(key);
+        if (i != registry_.end()) {
+            delete i->second;
+        }
+        registry_[key] = makerNote;
+    } // MakerNoteFactory::registerMakerNote
+
+    MakerNoteFactory::MakerNoteFactory()
+    {
+        // Register a prototype of each known MakerNote
+        registerMakerNote("Canon", "Canon PowerShot S40", new CanonMakerNote);
+    } // MakerNoteFactory c'tor
+
+    MakerNote* MakerNoteFactory::create(const std::string& make, 
+                                        const std::string& model) const
+    {
+        MakerNote* makerNote = 0;
+        std::string key = make + "+" + model;
+        Registry::const_iterator i = registry_.find(key);
+        if (i != registry_.end() && i->second != 0) {
+            makerNote = i->second->clone();
+        }
+        return makerNote;
+    } // MakerNoteFactory::create
+
+    int IfdMakerNote::read(const char* buf,
+                           long len, 
+                           ByteOrder byteOrder, 
+                           long offset)
+    {
+        int rc = ifd_.read(buf, byteOrder, offset);
+        if (rc == 0) {
+            // Todo: Make sure the Next field is 0.
+            Entries::iterator end = ifd_.end();
+            for (Entries::iterator i = ifd_.begin(); i != end; ++i) {
+                i->setMakerNote(this);
+            }
+        }
+#ifdef DEBUG_MAKERNOTE
+        hexdump(std::cerr, buf, len);
+        if (rc == 0) ifd_.print(std::cerr);
+#endif
+        return rc;
+    }
+
+    long IfdMakerNote::copy(char* buf, ByteOrder byteOrder, long offset) const
+    {
+        return ifd_.copy(buf, byteOrder, offset);
+    }
+
+    long IfdMakerNote::size() const
+    {
+         return ifd_.size() + ifd_.dataSize();
+    }
+
+    // Canon MakerNote Tag Info
+    static const MakerNote::MnTagInfo canonMnTagInfo[] = {
+        MakerNote::MnTagInfo(0x0001, "CameraSettings1", "Various camera settings (1)"),
+        MakerNote::MnTagInfo(0x0004, "CameraSettings2", "Various camera settings (2)"),
+        MakerNote::MnTagInfo(0x0006, "ImageType", "Image type"),
+        MakerNote::MnTagInfo(0x0007, "FirmwareVersion", "Firmware version"),
+        MakerNote::MnTagInfo(0x0008, "ImageNumber", "Image number"),
+        MakerNote::MnTagInfo(0x0009, "OwnerName", "Owner Name"),
+        MakerNote::MnTagInfo(0x000c, "SerialNumber", "Camera serial number"),
+        MakerNote::MnTagInfo(0x000f, "EosD30Functions", "EOS D30 Custom Functions"),
+        // End of list marker
+        MakerNote::MnTagInfo(0xffff, "(UnknownCanonMakerNoteTag)", "Unknown CanonMakerNote tag")
+    };
+
+    CanonMakerNote::CanonMakerNote()
+        : IfdMakerNote(canonMnTagInfo), sectionName_("Canon")
+    {
+    }
+
+    MakerNote* CanonMakerNote::clone() const 
+    {
+        return new CanonMakerNote(*this); 
+    }
+
+    std::ostream& CanonMakerNote::printTag(std::ostream& os, 
+                                           uint16 tag, 
+                                           const Value& value) const
+    {
+        switch (tag) {
+        case 0x0001: print0x0001(os, value); break;
+        case 0x0004: print0x0004(os, value); break;
+        case 0x0008: print0x0008(os, value); break;
+        case 0x000c: print0x000c(os, value); break;
+        case 0x000f: print0x000f(os, value); break;
+        default:
+            // All other tags (known or unknown) go here
+            os << value;
+            break;
+        }
+        return os;
+    }
+
+    std::ostream& CanonMakerNote::print0x0001(
+        std::ostream& os, const Value& value) const
+    {
+        if (0 == dynamic_cast<const UShortValue*>(&value)) {
+            return os << value;
+        }
+        const UShortValue& val = dynamic_cast<const UShortValue&>(value);
+        uint32 count = val.count();
+
+        if (count < 2) return os;
+        uint16 s = val.value_[1];
+        os << std::setw(30) << "
   Macro mode ";
+        switch (s) {
+        case 1: os << "On"; break;
+        case 2: os << "Off"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 3) return os;
+        s = val.value_[2];
+        os << std::setw(30) << "
   Self timer ";
+        if (s == 0) {
+            os << "Off";
+        }
+        else { 
+            os << s / 10.0 << " s";
+        }
+        if (count < 4) return os;
+        s = val.value_[3];
+        os << std::setw(30) << "
   Quality ";
+        switch (s) {
+        case 2: os << "Normal"; break;
+        case 3: os << "Fine"; break;
+        case 5: os << "Superfine"; break;
+        default: os << "(" << s << ")"; break;
+        }
+        
+        if (count < 5) return os;
+        s = val.value_[4];
+        os << std::setw(30) << "
   Flash mode ";
+        switch (s) {
+        case 0: os << "Off"; break;
+        case 1: os << "Auto"; break;
+        case 2: os << "On"; break;
+        case 3: os << "Red-eye"; break;
+        case 4: os << "Slow sync"; break;
+        case 5: os << "Auto + red-eye"; break;
+        case 6: os << "On + red-eye"; break;
+        case 16: os << "External"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 6) return os;
+        s = val.value_[5];
+        os << std::setw(30) << "
   Drive mode ";
+        switch (s) {
+        case 0: os << "Single / timer"; break;
+        case 1: os << "Continuous"; break;
+        default: os << "(" << s << ")"; break;
+        }
+    
+        // Meaning of the 6th ushort is unknown - ignore it
+
+        if (count < 8) return os;
+        s = val.value_[7];
+        os << std::setw(30) << "
   Focus mode ";
+        switch (s) {
+        case 0: os << "One shot"; break;
+        case 1: os << "AI servo"; break;
+        case 2: os << "AI Focus"; break;
+        case 3: os << "MF"; break;
+        case 4: os << "Single"; break;
+        case 5: os << "Continuous"; break;
+        case 6: os << "MF"; break;
+        default: os << "(" << s << ")"; break;
+        }
+    
+        // Meaning of the 8th ushort is unknown - ignore it
+        // Meaning of the 9th ushort is unknown - ignore it
+
+        if (count < 11) return os;
+        s = val.value_[10];
+        os << std::setw(30) << "
   Image size ";
+        switch (s) {
+        case 0: os << "Large"; break;
+        case 1: os << "Medium"; break;
+        case 2: os << "Small"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 12) return os;
+        s = val.value_[11];
+        os << std::setw(30) << "
   Easy shooting mode ";
+        switch (s) {
+        case  0: os << "Full auto"; break;
+        case  1: os << "Manual"; break;
+        case  2: os << "Landscape"; break;
+        case  3: os << "Fast shutter"; break;
+        case  4: os << "Slow shutter"; break;
+        case  5: os << "Night"; break;
+        case  6: os << "B&W"; break;
+        case  7: os << "Sepia"; break;
+        case  8: os << "Portrait"; break;
+        case  9: os << "Sports"; break;
+        case 10: os << "Macro / close-up"; break;
+        case 11: os << "Pan focus"; break;
+        default: os << "(" << s << ")"; break;
+        }
+ 
+        if (count < 13) return os;
+        s = val.value_[12];
+        os << std::setw(30) << "
   Digital zoom ";
+        switch (s) {
+        case 0: os << "None"; break;
+        case 1: os << "2x"; break;
+        case 2: os << "4x"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 14) return os;
+        s = val.value_[13];
+        os << std::setw(30) << "
   Contrast ";
+        switch (s) {
+        case 0xffff: os << "Low"; break;
+        case 0x0000: os << "Normal"; break;
+        case 0x0001: os << "High"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 15) return os;
+        s = val.value_[14];
+        os << std::setw(30) << "
   Saturation ";
+        switch (s) {
+        case 0xffff: os << "Low"; break;
+        case 0x0000: os << "Normal"; break;
+        case 0x0001: os << "High"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 16) return os;
+        s = val.value_[15];
+        os << std::setw(30) << "
   Sharpness ";
+        switch (s) {
+        case 0xffff: os << "Low"; break;
+        case 0x0000: os << "Normal"; break;
+        case 0x0001: os << "High"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 17) return os;
+        s = val.value_[16];
+        if (s != 0) {
+            os << std::setw(30) << "
   ISO ";
+            switch (s) {
+            case 15: os << "Auto"; break;
+            case 16: os << "50"; break;
+            case 17: os << "100"; break;
+            case 18: os << "200"; break;
+            case 19: os << "400"; break;
+            default: os << "(" << s << ")"; break;
+            }
+        }
+
+        if (count < 18) return os;
+        s = val.value_[17];
+        os << std::setw(30) << "
   Metering mode ";
+        switch (s) {
+        case 3: os << "Evaluative"; break;
+        case 4: os << "Partial"; break;
+        case 5: os << "Center weighted"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 19) return os;
+        s = val.value_[18];
+        os << std::setw(30) << "
   Focus type ";
+        switch (s) {
+        case 0: os << "Manual"; break;
+        case 1: os << "Auto"; break;
+        case 3: os << "Close-up (macro)"; break;
+        case 8: os << "Locked (pan mode)"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 20) return os;
+        s = val.value_[19];
+        os << std::setw(30) << "
   AF point selected ";
+        switch (s) {
+        case 0x3000: os << "None (MF)"; break;
+        case 0x3001: os << "Auto-selected"; break;
+        case 0x3002: os << "Right"; break;
+        case 0x3003: os << "Center"; break;
+        case 0x3004: os << "Left"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 21) return os;
+        s = val.value_[20];
+        os << std::setw(30) << "
   Exposure mode ";
+        switch (s) {
+        case 0: os << "Easy shooting"; break;
+        case 1: os << "Program"; break;
+        case 2: os << "Tv priority"; break;
+        case 3: os << "Av priority"; break;
+        case 4: os << "Manual"; break;
+        case 5: os << "A-DEP"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        // Meaning of the 21st ushort is unknown - ignore it
+        // Meaning of the 22nd ushort is unknown - ignore it
+
+        if (count < 26) return os;
+        float fu = val.value_[25];
+        float len1 = val.value_[23] / fu;
+        float len2 = val.value_[24] / fu;
+        std::ostringstream oss;
+        oss.copyfmt(os);
+        os << std::setw(30) << "
   Lens "
+           << std::fixed << std::setprecision(1)
+           << len2 << " - " << len1 << " mm";
+        os.copyfmt(oss);
+
+        // Meaning of the 26th ushort is unknown - ignore it
+        // Meaning of the 27th ushort is unknown - ignore it
+
+        if (count < 29) return os;
+        s = val.value_[28];
+        os << std::setw(30) << "
   Flash activity ";
+        switch (s) {
+        case 0: os << "Did not fire"; break;
+        case 1: os << "Fired"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        if (count < 30) return os;
+        s = val.value_[29];
+        // Todo: decode bitmask
+        os << std::setw(30) << "
   Flash details " 
+           << std::dec << s << " (Todo: decode bitmask)";
+
+        // Meaning of the 30th ushort is unknown - ignore it
+        // Meaning of the 31st ushort is unknown - ignore it
+
+        if (count < 33) return os;
+        s = val.value_[32];
+        os << std::setw(30) << "
   Focus mode ";
+        switch (s) {
+        case 0: os << "Single"; break;
+        case 1: os << "Continuous"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        // Meaning of any further ushorts is unknown - ignore them
+        
+        return os;
+
+    } // CanonMakerNote::print0x0001
+
+    std::ostream& CanonMakerNote::print0x0004(
+        std::ostream& os, const Value& value) const
+    {
+        if (0 == dynamic_cast<const UShortValue*>(&value)) {
+            return os << value;
+        }
+        const UShortValue& val = dynamic_cast<const UShortValue&>(value);
+        uint32 count = val.count();
+
+        // Meaning of ushorts 1-6 is unknown - ignore them
+
+        if (count < 8) return os;
+        uint16 s = val.value_[7];
+        os << std::setw(30) << "
   White balance ";
+        switch (s) {
+        case 0: os << "Auto"; break;
+        case 1: os << "Sunny"; break;
+        case 2: os << "Cloudy"; break;
+        case 3: os << "Tungsten"; break;
+        case 4: os << "Fluorescent"; break;
+        case 5: os << "Flash"; break;
+        case 6: os << "Custom"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        // Meaning of ushort 8 is unknown - ignore it
+
+        if (count < 10) return os;
+        s = val.value_[9];
+        os << std::setw(30) << "
   Sequence number " << s << "";
+
+        // Meaning of ushorts 10-13 is unknown - ignore them
+
+        if (count < 15) return os;
+        s = val.value_[14];
+        // Todo: decode bitmask
+        os << std::setw(30) << "
   AF point used " 
+           << s << " (Todo: decode bitmask)";
+        
+        if (count < 16) return os;
+        s = val.value_[15];
+        os << std::setw(30) << "
   Flash bias ";
+        switch (s) {
+        case 0xffc0: os << "-2 EV"; break;
+        case 0xffcc: os << "-1.67 EV"; break;
+        case 0xffd0: os << "-1.50 EV"; break;
+        case 0xffd4: os << "-1.33 EV"; break;
+        case 0xffe0: os << "-1 EV"; break;
+        case 0xffec: os << "-0.67 EV"; break;
+        case 0xfff0: os << "-0.50 EV"; break;
+        case 0xfff4: os << "-0.33 EV"; break;
+        case 0x0000: os << "0 EV"; break;
+        case 0x000c: os << "0.33 EV"; break;
+        case 0x0010: os << "0.50 EV"; break;
+        case 0x0014: os << "0.67 EV"; break;
+        case 0x0020: os << "1 EV"; break;
+        case 0x002c: os << "1.33 EV"; break;
+        case 0x0030: os << "1.50 EV"; break;
+        case 0x0034: os << "1.67 EV"; break;
+        case 0x0040: os << "2 EV"; break;
+        default: os << "(" << s << ")"; break;
+        }
+
+        // Meaning of ushorts 16-18 is unknown - ignore them
+
+        if (count < 20) return os;
+        s = val.value_[19];
+        os << std::setw(30) << "
   Subject distance (0.01m or 0.001m) ";
+        if (s == 0xffff) {
+            os << "Infinite";
+        }
+        else {
+            os << s << "";
+        }
+
+        return os;
+
+    } // CanonMakerNote::print0x0004
+
+    std::ostream& CanonMakerNote::print0x0008(
+        std::ostream& os, const Value& value) const
+    {
+        std::string n = value.toString();
+        return os << n.substr(0, n.length() - 4) << "-" 
+                  << n.substr(n.length() - 4);
+    }
+
+    std::ostream& CanonMakerNote::print0x000c(
+        std::ostream& os, const Value& value) const
+    {
+        std::istringstream is(value.toString());
+        uint32 l;
+        is >> l;
+        return os << std::setw(4) << std::setfill('0') << std::hex 
+                  << ((l & 0xffff0000) >> 16)
+                  << std::setw(5) << std::setfill('0') << std::dec
+                  << (l & 0x0000ffff);
+    }
+
+    std::ostream& CanonMakerNote::print0x000f(
+        std::ostream& os, const Value& value) const
+    {
+        // Todo: Decode EOS D30 Custom Functions
+        return os << "EOS D30 Custom Functions "
+                  << value << " (Todo: decode this field)";
+    }
+
+}                                       // namespace Exif
diff --git a/src/makernote.hpp b/src/makernote.hpp
new file mode 100644
index 0000000..37097c8
--- /dev/null
+++ b/src/makernote.hpp
@@ -0,0 +1,281 @@
+// ***************************************************************** -*- C++ -*-
+/*
+ * Copyright (C) 2004 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    makernote.hpp
+  @brief   
+  @version $Name:  $ $Revision: 1.1 $
+  @author  Andreas Huggel (ahu)
+           <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
+  @date    18-Feb-04, ahu: created
+ */
+#ifndef MAKERNOTE_HPP_
+#define MAKERNOTE_HPP_
+
+// *****************************************************************************
+// included header files
+#include "types.hpp"
+#include "ifd.hpp"
+
+// + standard includes
+#include <string>
+#include <iosfwd>
+#include <map>
+
+// *****************************************************************************
+// namespace extensions
+namespace Exif {
+
+    class Value;
+
+// *****************************************************************************
+// class definitions
+
+    /*!
+      @brief %Exif makernote interface
+
+      Defines methods to
+      - read the makernote from a character buffer
+      - copy the makernote to a character buffer
+      - add the makernote tags to the %Exif metadata
+      - access Makernote specific tag descriptions and print functions
+
+      Todo: Synchronization with ExifData:
+            Add a MakerNote pointer to ExifData (owner) and Metadata
+            Instead of ExifData as the owner, there should be a reference counter
+            Does Entry need a MakerNote poiner too? (not nice cos of the circ deps)
+     */
+    class MakerNote {
+    public:
+
+        //! MakerNote Tag information
+        struct MnTagInfo {
+            //! Constructor
+            MnTagInfo(uint16 tag, const char* name, const char* desc) 
+                : tag_(tag), name_(name), desc_(desc) {}
+
+            uint16 tag_;                //!< Tag
+            const char* name_;          //!< One word tag label
+            const char* desc_;          //!< Short tag description
+        }; // struct MnTagInfo
+
+        //! Constructor. Takes an optional MakerNote info tag array.
+        MakerNote(const MnTagInfo* mnTagInfo =0) : mnTagInfo_(mnTagInfo) {}
+        //! Virtual destructor.
+        virtual ~MakerNote() {}
+        /*!
+          @brief Return a pointer to a copy of itself (deep copy).
+                 The caller owns this copy and is responsible to delete it!
+         */
+        virtual MakerNote* clone() const =0;
+        /*!
+          @brief Read the MakerNote from character buffer buf of length len at
+                 position offset (from the start of the TIFF header) and encoded
+                 in byte order byteOrder.
+         */
+        virtual int read(const char* buf, 
+                         long len, 
+                         ByteOrder byteOrder,
+                         long offset) =0;
+        /*!
+          @brief Copy (write) the makerNote to the character buffer buf at 
+                 position offset (from the start of the TIFF header), encoded
+                 in byte order byteOrder. Return the number of bytes written.
+         */
+        virtual long copy(char* buf, ByteOrder byteOrder, long offset) const =0;
+
+        //! @name Accessors
+        //@{
+        //! Return the size of the makernote in bytes.
+        virtual long size() const =0;
+        //! The first %MakerNote entry
+        virtual Entries::const_iterator begin() const =0;
+        //! End of the %MakerNote entries
+        virtual Entries::const_iterator end() const =0;
+        //! The first %MakerNote entry
+        virtual Entries::iterator begin() =0;
+        //! End of the %MakerNote entries
+        virtual Entries::iterator end() =0;
+        //! Return the key for the tag.
+        std::string makeKey(uint16 tag) const;
+        //! Return the associated tag for a makernote key.
+        uint16 decomposeKey(const std::string& key) const;
+        /*!
+          @brief Return the name of a makernote tag. The default implementation
+                 looks up the %MakerNote info tag array if one is set, else
+                 it translates the tag to a string with the hexadecimal value of
+                 the tag.
+         */
+        virtual std::string tagName(uint16 tag) const;
+        /*!
+          @brief Return the tag associated with a makernote tag name. The
+                 default implementation looks up the %MakerNote info tag array
+                 if one is set, else it expects tag names in the form \"0x01ff\"
+                 and converts them to unsigned integer.
+         */
+        virtual uint16 tag(const std::string& tagName) const;
+        //! Return the name of the makernote section
+        virtual std::string sectionName(uint16 tag) const =0; 
+        //! Interpret and print the value of a makernote tag
+        virtual std::ostream& printTag(std::ostream& os,
+                                       uint16 tag, 
+                                       const Value& value) const =0;
+        //@}
+
+    protected:
+        //! Pointer to an array of MakerNote tag infos
+        const MnTagInfo* mnTagInfo_;   
+
+    }; // class MakerNote
+
+    /*!
+      @brief %MakerNote factory.
+
+      Creates an instance of the %MakerNote for one camera model. The factory is
+      implemented as a singleton, which can be accessed only through the static
+      member function instance().
+
+      Todo: Implement more intelligent registry that allows wildcards in the 
+            make and model strings to register classes
+    */
+    class MakerNoteFactory {
+    public:
+        /*!
+          @brief Access the makerNote factory. Clients access the task factory
+                 exclusively through this method.
+        */
+        static MakerNoteFactory& instance();
+
+        /*!
+          @brief Create the appropriate %MakerNote based on camera make and
+                 model, return a pointer to the newly created MakerNote
+                 instance. Return 0 if no %MakerNote is defined for the camera
+                 model.
+
+          @param make Camera manufacturer. (Typically the string from the %Exif
+                 make tag.)
+          @param model Camera model. (Typically the string from the %Exif
+                 model tag.)
+          @return A pointer that owns a %MakerNote for the camera model.  If
+                 the camera is not supported, the pointer is 0.
+         */
+        MakerNote* create(const std::string& make, 
+                          const std::string& model) const;
+
+        /*!
+          @brief Register a %MakerNote prototype for a camera model.
+
+          The %MakerNote factory creates new %MakerNotes for a camera by cloning
+          the associated prototype. Additional %MakerNotes can be registered.
+          If called for a camera model for which a %MakerNote is already
+          registered, the corresponding prototype is replaced.
+
+          @param make Camera manufacturer. (Typically the string from the %Exif
+                 make tag.)
+          @param model Camera model. (Typically the string from the %Exif
+                 model tag.)
+          @param makerNote Pointer to the prototype. Ownership is transfered to the
+                 %MakerNote factory.
+        */
+        void registerMakerNote(const std::string& make, 
+                               const std::string& model, 
+                               MakerNote* makerNote);
+
+    private:
+        //! Prevent construction other than through instance().
+        MakerNoteFactory();
+        //! Prevent copy construction: not implemented.
+        MakerNoteFactory(const MakerNoteFactory& rhs);
+
+        //! Pointer to the one and only instance of this class.
+        static MakerNoteFactory* instance_;
+        //! Type used to store %MakerNote prototype classes
+        typedef std::map<std::string, MakerNote*> Registry;
+        //! List of makernote types and corresponding prototypes.
+        Registry registry_;
+
+    }; // class MakerNoteFactory
+
+    /*!
+      @brief Interface for MakerNotes in IFD format
+
+      Todo: Allow for a 'prefix' before the IFD (OLYMP, etc)
+            Cater for offsets from start of TIFF header as well as relative to Mn
+     */
+    class IfdMakerNote : public MakerNote {
+    public:
+        //! Constructor. Takes an optional MakerNote info tag array.
+        IfdMakerNote(const MakerNote::MnTagInfo* mnTagInfo =0)
+            : MakerNote(mnTagInfo), ifd_(makerIfd, 0, false) {}
+        virtual ~IfdMakerNote() {}
+        virtual MakerNote* clone() const =0;
+
+        int read(const char* buf, long len, ByteOrder byteOrder, long offset);
+        long copy(char* buf, ByteOrder byteOrder, long offset) const;
+        long size() const;
+        Entries::const_iterator begin() const { return ifd_.begin(); }
+        Entries::const_iterator end() const { return ifd_.end(); }
+        Entries::iterator begin() { return ifd_.begin(); }
+        Entries::iterator end() { return ifd_.end(); }
+        virtual std::string sectionName(uint16 tag) const =0; 
+        virtual std::ostream& printTag(std::ostream& os,
+                                       uint16 tag, 
+                                       const Value& value) const =0;
+
+    protected:
+        Ifd ifd_;                               //!< MakerNote IFD
+
+    }; // class IfdMakerNote
+
+    //! MakerNote for Canon cameras
+    class CanonMakerNote : public IfdMakerNote {
+    public:
+        //! Default constructor
+        CanonMakerNote();
+        virtual ~CanonMakerNote() {}
+        MakerNote* clone() const;
+        //! Return the name of the makernote section ("Canon")
+        std::string sectionName(uint16 tag) const { return sectionName_; }
+        std::ostream& printTag(std::ostream& os,
+                               uint16 tag, 
+                               const Value& value) const;
+
+        //! @name Print functions for Canon %MakerNote tags 
+        //@{
+        //! Print various camera settings, part 1
+        std::ostream& print0x0001(std::ostream& os, const Value& value) const;
+        //! Print various camera settings, part 2
+        std::ostream& print0x0004(std::ostream& os, const Value& value) const;
+        //! Print the image number
+        std::ostream& print0x0008(std::ostream& os, const Value& value) const;
+        //! Print the serial number of the camera
+        std::ostream& print0x000c(std::ostream& os, const Value& value) const;
+        //! Print EOS D30 custom functions
+        std::ostream& print0x000f(std::ostream& os, const Value& value) const;
+        //@}
+
+    private:
+        std::string sectionName_;
+
+    }; // class CanonMakerNote
+   
+}                                       // namespace Exif
+
+#endif                                  // #ifndef MAKERNOTE_HPP_

-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list