diff --git a/msvc/addmoddel/addmoddel.vcproj b/msvc/addmoddel/addmoddel.vcproj
index ccd159e5..40a920f2 100644
--- a/msvc/addmoddel/addmoddel.vcproj
+++ b/msvc/addmoddel/addmoddel.vcproj
@@ -126,9 +126,6 @@
-
-
-
-
-
-
-
-
diff --git a/msvc/exiv2lib/exiv2lib.vcproj b/msvc/exiv2lib/exiv2lib.vcproj
index b40b7040..ba40be46 100644
--- a/msvc/exiv2lib/exiv2lib.vcproj
+++ b/msvc/exiv2lib/exiv2lib.vcproj
@@ -241,21 +241,6 @@
-
-
-
-
-
-
-
-
@@ -396,6 +381,9 @@
+
+
diff --git a/msvc/exivsimple/exivsimple.vcproj b/msvc/exivsimple/exivsimple.vcproj
index d8b7f3bb..22a82520 100644
--- a/msvc/exivsimple/exivsimple.vcproj
+++ b/msvc/exivsimple/exivsimple.vcproj
@@ -132,21 +132,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/msvc/taglist/taglist.vcproj b/msvc/taglist/taglist.vcproj
index bc78dd5c..ffda2dee 100644
--- a/msvc/taglist/taglist.vcproj
+++ b/msvc/taglist/taglist.vcproj
@@ -123,9 +123,6 @@
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
-
-
diff --git a/msvc/utiltest/utiltest.vcproj b/msvc/utiltest/utiltest.vcproj
index de1fefe6..4a00fb20 100644
--- a/msvc/utiltest/utiltest.vcproj
+++ b/msvc/utiltest/utiltest.vcproj
@@ -126,9 +126,6 @@
-
-
diff --git a/msvc/write-test/write-test.vcproj b/msvc/write-test/write-test.vcproj
index 507f74db..81827f4b 100644
--- a/msvc/write-test/write-test.vcproj
+++ b/msvc/write-test/write-test.vcproj
@@ -123,9 +123,6 @@
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
-
-
diff --git a/msvc/write2-test/write2-test.vcproj b/msvc/write2-test/write2-test.vcproj
index 5b35022e..03bc97fb 100644
--- a/msvc/write2-test/write2-test.vcproj
+++ b/msvc/write2-test/write2-test.vcproj
@@ -123,9 +123,6 @@
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
-
-
diff --git a/src/Makefile b/src/Makefile
index ccec948e..1b074700 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -48,7 +48,7 @@ include $(top_srcdir)/config/config.mk
# Source files
# Add standalone C++ header files to this list
-CCHDR = exv_conf.h exv_msvc.h rcsid.hpp
+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 \
@@ -87,7 +87,7 @@ LIBRARY = libexiv2.la
# Defines, Includes and Libraries
CXXDEFS = $(DEFS)
CXXINCS = $(INCS)
-LDLIBS = $(LIBS) mn.o $(LIBRARY)
+LDLIBS = $(LIBS) $(LIBRARY)
# ******************************************************************************
# ==============================================================================
@@ -146,7 +146,7 @@ endif
$(OBJ): %.o: %.cpp
@$(LIBTOOL) --mode=compile $(CXX) $(CXXFLAGS) $(CXXDEFS) $(CXXINCS) -c $<
-$(sort $(BINOBJ) $(EXIV2OBJ) $(MCOBJ) mn.o): %.o: %.cpp
+$(sort $(BINOBJ) $(EXIV2OBJ) $(MCOBJ)): %.o: %.cpp
$(CXX) $(CXXFLAGS) $(CXXDEFS) $(CXXINCS) -c $<
%.o: %.c
@@ -179,9 +179,6 @@ actions.cpp exiv2.cpp image.cpp utils.cpp: exv_conf.h
exv_conf.h: $(top_srcdir)/config/config.h
sed 's/#define \([A-Z]\)/#define EXV_\1/; s/#undef \([A-Z]\)/#undef EXV_\1/' < $< > $@
-mn.cpp: ./mn.sh
- ./mn.sh
-
$(LIBTOOL): $(LIBTOOL_DEPS)
$(SHELL) $(top_srcdir)/config.status --recheck
@@ -194,13 +191,13 @@ lib: $(OBJ)
path-test: path-test.o utils.o
$(CXX) $(CXXFLAGS) path-test.o utils.o -o $@
-$(BINARY): %: %.o lib mn.o
+$(BINARY): %: %.o lib
@$(LIBTOOL) --mode=link $(CXX) $(CXXFLAGS) $(LDLIBS) $@.o $(LDFLAGS) -o $@ -rpath $(libdir)
-$(EXIV2BIN): lib $(EXIV2OBJ) $(EXIV2COBJ) mn.o
+$(EXIV2BIN): lib $(EXIV2OBJ) $(EXIV2COBJ)
@$(LIBTOOL) --mode=link $(CXX) $(CXXFLAGS) $(EXIV2OBJ) $(EXIV2COBJ) $(LDLIBS) $(LDFLAGS) -o $@ -rpath $(libdir)
-$(MCBIN): lib $(MCOBJ) mn.o
+$(MCBIN): lib $(MCOBJ)
@$(LIBTOOL) --mode=link $(CXX) $(CXXFLAGS) $(MCOBJ) $(LDLIBS) $(LDFLAGS) -o $@ -rpath $(libdir)
install-header:
@@ -247,7 +244,8 @@ mostlyclean:
$(RM) core
$(RM) $(CCSRC:.cpp=.ii)
$(RM) lib
- @$(LIBTOOL) --mode=clean $(RM) $(LOBJ) $(sort $(BINOBJ) $(EXIV2OBJ) $(EXIV2COBJ) $(MCOBJ) mn.o)
+ $(RM) path-test.o
+ @$(LIBTOOL) --mode=clean $(RM) $(LOBJ) $(sort $(BINOBJ) $(EXIV2OBJ) $(EXIV2COBJ) $(MCOBJ))
clean: mostlyclean
@$(LIBTOOL) --mode=clean $(RM) $(LIBRARY)
@@ -265,4 +263,3 @@ distclean: clean
# that may need special tools to rebuild.
maintainer-clean: uninstall distclean
$(RM) $(DEP)
- $(RM) mn.cpp
diff --git a/src/canonmn.cpp b/src/canonmn.cpp
index 32b60b9a..a431b6c0 100644
--- a/src/canonmn.cpp
+++ b/src/canonmn.cpp
@@ -77,7 +77,26 @@ namespace {
// class member definitions
namespace Exiv2 {
- const CanonMakerNote::RegisterMakerNote CanonMakerNote::register_;
+ //! @cond IGNORE
+ CanonMakerNote::RegisterMn::RegisterMn()
+ {
+ MakerNoteFactory::registerMakerNote("Canon", "*", createCanonMakerNote);
+
+ MakerNoteFactory::registerMakerNote(
+ canonIfdId, MakerNote::AutoPtr(new CanonMakerNote));
+ MakerNoteFactory::registerMakerNote(
+ canonCs1IfdId, MakerNote::AutoPtr(new CanonMakerNote));
+ MakerNoteFactory::registerMakerNote(
+ canonCs2IfdId, MakerNote::AutoPtr(new CanonMakerNote));
+ MakerNoteFactory::registerMakerNote(
+ canonCfIfdId, MakerNote::AutoPtr(new CanonMakerNote));
+
+ ExifTags::registerMakerTagInfo(canonIfdId, tagInfo_);
+ ExifTags::registerMakerTagInfo(canonCs1IfdId, tagInfoCs1_);
+ ExifTags::registerMakerTagInfo(canonCs2IfdId, tagInfoCs2_);
+ ExifTags::registerMakerTagInfo(canonCfIfdId, tagInfoCf_);
+ }
+ //! @endcond
// Canon MakerNote Tag Info
const TagInfo CanonMakerNote::tagInfo_[] = {
diff --git a/src/canonmn.hpp b/src/canonmn.hpp
index 54188fb6..890c5247 100644
--- a/src/canonmn.hpp
+++ b/src/canonmn.hpp
@@ -189,6 +189,13 @@ namespace Exiv2 {
static std::ostream& printCs20x0013(std::ostream& os, const Value& value);
//@}
+ //! @cond IGNORE
+ // Public only so that we can create a static instance
+ struct RegisterMn {
+ RegisterMn();
+ };
+ //! @endcond
+
private:
//! @name Manipulators
//@{
@@ -223,45 +230,9 @@ namespace Exiv2 {
static const TagInfo tagInfoCs2_[];
static const TagInfo tagInfoCf_[];
- //! Structure used to auto-register the MakerNote.
- struct RegisterMakerNote {
- //! Default constructor
- RegisterMakerNote()
- {
- MakerNoteFactory& mnf = MakerNoteFactory::instance();
- mnf.registerMakerNote("Canon", "*", createCanonMakerNote);
-
- mnf.registerMakerNote(canonIfdId,
- MakerNote::AutoPtr(new CanonMakerNote));
- mnf.registerMakerNote(canonCs1IfdId,
- MakerNote::AutoPtr(new CanonMakerNote));
- mnf.registerMakerNote(canonCs2IfdId,
- MakerNote::AutoPtr(new CanonMakerNote));
- mnf.registerMakerNote(canonCfIfdId,
- MakerNote::AutoPtr(new CanonMakerNote));
-
- ExifTags::registerMakerTagInfo(canonIfdId, tagInfo_);
- ExifTags::registerMakerTagInfo(canonCs1IfdId, tagInfoCs1_);
- ExifTags::registerMakerTagInfo(canonCs2IfdId, tagInfoCs2_);
- ExifTags::registerMakerTagInfo(canonCfIfdId, tagInfoCf_);
- }
- };
- /*!
- The static member variable is (see note) initialized before main and
- will in the process register the MakerNote class. (Remember the
- definition of the variable in the implementation file!)
-
- @note The standard says that, if no function is explicitly called ever
- in a module, then that module's static data might be never
- initialized. This clause was introduced to allow dynamic link
- libraries. The idea is, with this clause the loader is not
- forced to eagerly load all modules, but load them only on
- demand.
- */
- static const RegisterMakerNote register_;
-
}; // class CanonMakerNote
+ static CanonMakerNote::RegisterMn registerCanonMakerNote;
} // namespace Exiv2
#endif // #ifndef CANONMN_HPP_
diff --git a/src/exif.cpp b/src/exif.cpp
index 59b0649c..7b907407 100644
--- a/src/exif.cpp
+++ b/src/exif.cpp
@@ -479,16 +479,16 @@ namespace Exiv2 {
Ifd::iterator model = pIfd0_->findTag(0x0110);
if ( pos != pExifIfd_->end()
&& make != pIfd0_->end() && model != pIfd0_->end()) {
- MakerNoteFactory& mnf = MakerNoteFactory::instance();
// Todo: The conversion to string assumes that there is a \0 at the end
// Todo: How to avoid the cast (is that a MSVC thing?)
- pMakerNote_ = mnf.create(reinterpret_cast(make->data()),
- reinterpret_cast(model->data()),
- false,
- pos->data(),
- pos->size(),
- byteOrder(),
- pExifIfd_->offset() + pos->offset()).release();
+ pMakerNote_ = MakerNoteFactory::create(
+ reinterpret_cast(make->data()),
+ reinterpret_cast(model->data()),
+ false,
+ pos->data(),
+ pos->size(),
+ byteOrder(),
+ pExifIfd_->offset() + pos->offset()).release();
}
// Read the MakerNote
if (pMakerNote_) {
@@ -738,8 +738,7 @@ namespace Exiv2 {
{
if (ExifTags::isMakerIfd(exifdatum.ifdId())) {
if (pMakerNote_ == 0) {
- MakerNoteFactory& mnf = MakerNoteFactory::instance();
- pMakerNote_ = mnf.create(exifdatum.ifdId()).release();
+ pMakerNote_ = MakerNoteFactory::create(exifdatum.ifdId()).release();
}
if (pMakerNote_ == 0) throw Error(23, exifdatum.ifdId());
}
diff --git a/src/fujimn.cpp b/src/fujimn.cpp
index be940b8d..c1b811c2 100644
--- a/src/fujimn.cpp
+++ b/src/fujimn.cpp
@@ -53,7 +53,16 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions
namespace Exiv2 {
- const FujiMakerNote::RegisterMakerNote FujiMakerNote::register_;
+ //! @cond IGNORE
+ FujiMakerNote::RegisterMn::RegisterMn()
+ {
+ MakerNoteFactory::registerMakerNote("FUJIFILM", "*", createFujiMakerNote);
+ MakerNoteFactory::registerMakerNote(
+ fujiIfdId, MakerNote::AutoPtr(new FujiMakerNote));
+
+ ExifTags::registerMakerTagInfo(fujiIfdId, tagInfo_);
+ }
+ //! @endcond
// Fujifilm MakerNote Tag Info
const TagInfo FujiMakerNote::tagInfo_[] = {
diff --git a/src/fujimn.hpp b/src/fujimn.hpp
index 6be13ec2..e64cf324 100644
--- a/src/fujimn.hpp
+++ b/src/fujimn.hpp
@@ -138,6 +138,13 @@ namespace Exiv2 {
static std::ostream& print0x1031(std::ostream& os, const Value& value);
//@}
+ //! @cond IGNORE
+ // Public only so that we can create a static instance
+ struct RegisterMn {
+ RegisterMn();
+ };
+ //! @endcond
+
private:
//! Internal virtual create function.
FujiMakerNote* create_(bool alloc =true) const;
@@ -147,34 +154,9 @@ namespace Exiv2 {
//! Tag information
static const TagInfo tagInfo_[];
- //! Structure used to auto-register the MakerNote.
- struct RegisterMakerNote {
- //! Default constructor
- RegisterMakerNote()
- {
- MakerNoteFactory& mnf = MakerNoteFactory::instance();
- mnf.registerMakerNote("FUJIFILM", "*", createFujiMakerNote);
- mnf.registerMakerNote(fujiIfdId,
- MakerNote::AutoPtr(new FujiMakerNote));
- ExifTags::registerMakerTagInfo(fujiIfdId, tagInfo_);
- }
- };
- /*!
- The static member variable is initialized before main (see note) and
- will in the process register the MakerNote class. (Remember the
- definition of the variable in the implementation file!)
-
- @note The standard says that, if no function is explicitly called ever
- in a module, then that module's static data might be never
- initialized. This clause was introduced to allow dynamic link
- libraries. The idea is, with this clause the loader is not
- forced to eagerly load all modules, but load them only on
- demand.
- */
- static const RegisterMakerNote register_;
-
}; // class FujiMakerNote
+ static FujiMakerNote::RegisterMn registerFujiMakerNote;
} // namespace Exiv2
#endif // #ifndef FUJIMN_HPP_
diff --git a/src/makernote.cpp b/src/makernote.cpp
index 8886fb36..f5a5158e 100644
--- a/src/makernote.cpp
+++ b/src/makernote.cpp
@@ -187,28 +187,33 @@ namespace Exiv2 {
return AutoPtr(clone_());
}
- MakerNoteFactory* MakerNoteFactory::pInstance_ = 0;
+ MakerNoteFactory::Registry* MakerNoteFactory::pRegistry_ = 0;
+ MakerNoteFactory::IfdIdRegistry* MakerNoteFactory::pIfdIdRegistry_ = 0;
- MakerNoteFactory& MakerNoteFactory::instance()
+ void MakerNoteFactory::init()
{
- if (0 == pInstance_) {
- pInstance_ = new MakerNoteFactory;
+ if (0 == pRegistry_) {
+ pRegistry_ = new Registry;
}
- return *pInstance_;
- } // MakerNoteFactory::instance
+ if (0 == pIfdIdRegistry_) {
+ pIfdIdRegistry_ = new IfdIdRegistry;
+ }
+ } // MakerNoteFactory::init
void MakerNoteFactory::registerMakerNote(IfdId ifdId,
MakerNote::AutoPtr makerNote)
{
+ init();
MakerNote* pMakerNote = makerNote.release();
assert(pMakerNote);
- ifdIdRegistry_[ifdId] = pMakerNote;
+ (*pIfdIdRegistry_)[ifdId] = pMakerNote;
} // MakerNoteFactory::registerMakerNote
- MakerNote::AutoPtr MakerNoteFactory::create(IfdId ifdId, bool alloc) const
+ MakerNote::AutoPtr MakerNoteFactory::create(IfdId ifdId, bool alloc)
{
- IfdIdRegistry::const_iterator i = ifdIdRegistry_.find(ifdId);
- if (i == ifdIdRegistry_.end()) return MakerNote::AutoPtr(0);
+ assert(pIfdIdRegistry_ != 0);
+ IfdIdRegistry::const_iterator i = pIfdIdRegistry_->find(ifdId);
+ if (i == pIfdIdRegistry_->end()) return MakerNote::AutoPtr(0);
assert(i->second);
return i->second->create(alloc);
} // MakerNoteFactory::create
@@ -221,14 +226,15 @@ namespace Exiv2 {
std::cerr << "Registering MakerNote create function for \""
<< make << "\" and \"" << model << "\".\n";
#endif
-
+ init();
// Todo: use case insensitive make and model comparisons
// Find or create a registry entry for make
ModelRegistry* pModelRegistry = 0;
- Registry::const_iterator end1 = registry_.end();
+ assert(pRegistry_ != 0);
+ Registry::const_iterator end1 = pRegistry_->end();
Registry::const_iterator pos1;
- for (pos1 = registry_.begin(); pos1 != end1; ++pos1) {
+ for (pos1 = pRegistry_->begin(); pos1 != end1; ++pos1) {
if (pos1->first == make) break;
}
if (pos1 != end1) {
@@ -236,7 +242,7 @@ namespace Exiv2 {
}
else {
pModelRegistry = new ModelRegistry;
- registry_.push_back(std::make_pair(make, pModelRegistry));
+ pRegistry_->push_back(std::make_pair(make, pModelRegistry));
}
// Find or create a registry entry for model
ModelRegistry::iterator end2 = pModelRegistry->end();
@@ -258,7 +264,7 @@ namespace Exiv2 {
const byte* buf,
long len,
ByteOrder byteOrder,
- long offset) const
+ long offset)
{
#ifdef DEBUG_REGISTRY
std::cerr << "Entering MakerNoteFactory::create(\""
@@ -272,9 +278,10 @@ namespace Exiv2 {
std::string makeMatch;
std::cerr << "Searching make registry...\n";
#endif
- Registry::const_iterator end1 = registry_.end();
+ assert(pRegistry_ != 0);
+ Registry::const_iterator end1 = pRegistry_->end();
Registry::const_iterator pos1;
- for (pos1 = registry_.begin(); pos1 != end1; ++pos1) {
+ for (pos1 = pRegistry_->begin(); pos1 != end1; ++pos1) {
int rc = match(pos1->first, make);
if (rc > score) {
score = rc;
diff --git a/src/makernote.hpp b/src/makernote.hpp
index fde5975b..a604c159 100644
--- a/src/makernote.hpp
+++ b/src/makernote.hpp
@@ -88,9 +88,9 @@ namespace Exiv2 {
See existing makernote implementations for examples, e.g., CanonMakerNote
or FujiMakerNote.
- Finally, the implementation files should be named *mn.[ch]pp, so that the
- magic, which ensures that the makernote is automatically registered
- in the factory, will pick it up (see mn.sh for details).
+ Finally, the header file which defines the static variable
+ \em register*MakerNote needs to be included from mn.hpp, to ensure that
+ the makernote is automatically registered in the factory.
*/
class MakerNote {
//! @name Not implemented
@@ -340,19 +340,10 @@ namespace Exiv2 {
Maintains an associative list (tree) of camera makes/models and
corresponding %MakerNote create functions. Creates an instance of the
%MakerNote for one camera make/model. The factory is implemented as a
- singleton, which can be accessed only through the static member function
- instance().
+ static class.
*/
class MakerNoteFactory {
public:
- /*!
- @brief Access the MakerNote factory. Clients access the task factory
- exclusively through this method.
- */
- static MakerNoteFactory& instance();
-
- //! @name Manipulators
- //@{
/*!
@brief Register a %MakerNote create function for a camera make and
model.
@@ -371,16 +362,13 @@ namespace Exiv2 {
@param createMakerNote Pointer to a function to create a new
%MakerNote of a particular type.
*/
- void registerMakerNote(const std::string& make,
- const std::string& model,
- CreateFct createMakerNote);
-
+ static void registerMakerNote(const std::string& make,
+ const std::string& model,
+ CreateFct createMakerNote);
+
//! Register a %MakerNote prototype in the IFD id registry.
- void registerMakerNote(IfdId ifdId, MakerNote::AutoPtr makerNote);
- //@}
+ static void registerMakerNote(IfdId ifdId, MakerNote::AutoPtr makerNote);
- //! @name Accessors
- //@{
/*!
@brief Create the appropriate %MakerNote based on camera make and
model and possibly the contents of the makernote itself, return
@@ -424,17 +412,16 @@ namespace Exiv2 {
@return An auto-pointer that owns a %MakerNote for the camera model.
If the camera is not supported, the pointer is 0.
*/
- MakerNote::AutoPtr create(const std::string& make,
- const std::string& model,
- bool alloc,
- const byte* buf,
- long len,
- ByteOrder byteOrder,
- long offset) const;
+ static MakerNote::AutoPtr create(const std::string& make,
+ const std::string& model,
+ bool alloc,
+ const byte* buf,
+ long len,
+ ByteOrder byteOrder,
+ long offset);
//! Create a %MakerNote for an IFD id.
- MakerNote::AutoPtr create(IfdId ifdId, bool alloc =true) const;
- //@}
+ static MakerNote::AutoPtr create(IfdId ifdId, bool alloc =true);
/*!
@brief Match a registry entry with a key (used for make and model).
@@ -458,12 +445,15 @@ namespace Exiv2 {
private:
//! @name Creators
//@{
- //! Prevent construction other than through instance().
+ //! Prevent construction: not implemented.
MakerNoteFactory() {}
//! Prevent copy construction: not implemented.
MakerNoteFactory(const MakerNoteFactory& rhs);
//@}
+ //! Creates the private static instance
+ static void init();
+
//! Type used to store model labels and %MakerNote create functions
typedef std::vector > ModelRegistry;
//! Type used to store a list of make labels and model registries
@@ -472,12 +462,10 @@ namespace Exiv2 {
typedef std::map IfdIdRegistry;
// DATA
- //! Pointer to the one and only instance of this class.
- static MakerNoteFactory* pInstance_;
//! List of makernote types and corresponding makernote create functions.
- Registry registry_;
+ static Registry* pRegistry_;
//! List of makernote IFD ids and corresponding create functions.
- IfdIdRegistry ifdIdRegistry_;
+ static IfdIdRegistry* pIfdIdRegistry_;
}; // class MakerNoteFactory
diff --git a/src/mn.hpp b/src/mn.hpp
new file mode 100644
index 00000000..158acda1
--- /dev/null
+++ b/src/mn.hpp
@@ -0,0 +1,42 @@
+// ***************************************************************** -*- C++ -*-
+/*
+ * Copyright (C) 2004, 2005 Andreas Huggel
+ *
+ * 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 mn.hpp
+ @brief Include all makernote header files. Makes sure that the static
+ variable used to register makernotes is instantiated.
+ @version $Rev$
+ @author Andreas Huggel (ahu)
+ ahuggel@gmx.net
+ @date 28-May-05, ahu: created
+ */
+#ifndef MN_HPP_
+#define MN_HPP_
+
+// *****************************************************************************
+// included header files
+#include "canonmn.hpp"
+#include "fujimn.hpp"
+#include "nikonmn.hpp"
+#include "olympusmn.hpp"
+#include "sigmamn.hpp"
+#include "sonymn.hpp"
+
+#endif // #ifndef MN_HPP_
diff --git a/src/mn.sh b/src/mn.sh
deleted file mode 100755
index 87ceb592..00000000
--- a/src/mn.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#! /bin/sh
-################################################################################
-# File : mn.sh
-# Version : $Rev$
-# Author(s): Andreas Huggel (ahu)
-# History : 08-Mar-04, ahu: created
-#
-# Description:
-# Create a module mn.cpp that depends on all MakerNote subclasses
-# to force initialisation of static data in the corresponding
-# components when using the static library.
-################################################################################
-
-rm -f mn.cpp
-echo "// Generated by mn.sh on" `date` "- do not edit" > mn.cpp
-for file in *mn.hpp; do
- echo "#include \""$file"\"" >> mn.cpp
-done
-echo "namespace {" >> mn.cpp
-for file in *mn.hpp; do
- awk '
- /class .*MakerNote.*:/ {
- name = $2;
- sub(/MakerNote.*/, "mn", name);
- printf " Exiv2::%s %s;\n", $2, tolower(name);
- }' $file >> mn.cpp
-done
-echo "}" >> mn.cpp
diff --git a/src/nikonmn.cpp b/src/nikonmn.cpp
index e3346591..9ecab5bc 100644
--- a/src/nikonmn.cpp
+++ b/src/nikonmn.cpp
@@ -52,7 +52,16 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions
namespace Exiv2 {
- const Nikon1MakerNote::RegisterMakerNote Nikon1MakerNote::register_;
+ //! @cond IGNORE
+ Nikon1MakerNote::RegisterMn::RegisterMn()
+ {
+ MakerNoteFactory::registerMakerNote("NIKON*", "*", createNikonMakerNote);
+ MakerNoteFactory::registerMakerNote(
+ nikon1IfdId, MakerNote::AutoPtr(new Nikon1MakerNote));
+
+ ExifTags::registerMakerTagInfo(nikon1IfdId, tagInfo_);
+ }
+ //! @endcond
// Nikon1 MakerNote Tag Info
const TagInfo Nikon1MakerNote::tagInfo_[] = {
@@ -189,7 +198,15 @@ namespace Exiv2 {
return os;
}
- const Nikon2MakerNote::RegisterMakerNote Nikon2MakerNote::register_;
+ //! @cond IGNORE
+ Nikon2MakerNote::RegisterMn::RegisterMn()
+ {
+ MakerNoteFactory::registerMakerNote(
+ nikon2IfdId, MakerNote::AutoPtr(new Nikon2MakerNote));
+
+ ExifTags::registerMakerTagInfo(nikon2IfdId, tagInfo_);
+ }
+ //! @endcond
// Nikon2 MakerNote Tag Info
const TagInfo Nikon2MakerNote::tagInfo_[] = {
@@ -364,7 +381,15 @@ namespace Exiv2 {
return os;
}
- const Nikon3MakerNote::RegisterMakerNote Nikon3MakerNote::register_;
+ //! @cond IGNORE
+ Nikon3MakerNote::RegisterMn::RegisterMn()
+ {
+ MakerNoteFactory::registerMakerNote(
+ nikon3IfdId, MakerNote::AutoPtr(new Nikon3MakerNote));
+
+ ExifTags::registerMakerTagInfo(nikon3IfdId, tagInfo_);
+ }
+ //! @endcond
// Nikon3 MakerNote Tag Info
const TagInfo Nikon3MakerNote::tagInfo_[] = {
diff --git a/src/nikonmn.hpp b/src/nikonmn.hpp
index 18ce60b2..5498b532 100644
--- a/src/nikonmn.hpp
+++ b/src/nikonmn.hpp
@@ -139,6 +139,13 @@ namespace Exiv2 {
static std::ostream& print0x0088(std::ostream& os, const Value& value);
//@}
+ //! @cond IGNORE
+ // Public only so that we can create a static instance
+ struct RegisterMn {
+ RegisterMn();
+ };
+ //! @endcond
+
private:
//! Internal virtual create function.
Nikon1MakerNote* create_(bool alloc =true) const;
@@ -148,35 +155,10 @@ namespace Exiv2 {
//! Tag information
static const TagInfo tagInfo_[];
- //! Structure used to auto-register the MakerNote.
- struct RegisterMakerNote {
- //! Default constructor
- RegisterMakerNote()
- {
- MakerNoteFactory& mnf = MakerNoteFactory::instance();
- mnf.registerMakerNote("NIKON*", "*", createNikonMakerNote);
- mnf.registerMakerNote(nikon1IfdId,
- MakerNote::AutoPtr(new Nikon1MakerNote));
- ExifTags::registerMakerTagInfo(nikon1IfdId, tagInfo_);
- }
- };
- // DATA
- /*!
- The static member variable is initialized before main (see note) and
- will in the process register the MakerNote class. (Remember the
- definition of the variable in the implementation file!)
-
- @note The standard says that, if no function is explicitly called ever
- in a module, then that module's static data might be never
- initialized. This clause was introduced to allow dynamic link
- libraries. The idea is, with this clause the loader is not
- forced to eagerly load all modules, but load them only on
- demand.
- */
- static const RegisterMakerNote register_;
-
}; // class Nikon1MakerNote
+ static Nikon1MakerNote::RegisterMn registerNikon1MakerNote;
+
/*!
@brief A second MakerNote format used by Nikon cameras, including the
E700, E800, E900, E900S, E910, E950
@@ -229,6 +211,13 @@ namespace Exiv2 {
static std::ostream& print0x000a(std::ostream& os, const Value& value);
//@}
+ //! @cond IGNORE
+ // Public only so that we can create a static instance
+ struct RegisterMn {
+ RegisterMn();
+ };
+ //! @endcond
+
private:
//! Internal virtual create function.
Nikon2MakerNote* create_(bool alloc =true) const;
@@ -238,34 +227,10 @@ namespace Exiv2 {
//! Tag information
static const TagInfo tagInfo_[];
- //! Structure used to auto-register the MakerNote.
- struct RegisterMakerNote {
- //! Default constructor
- RegisterMakerNote()
- {
- MakerNoteFactory& mnf = MakerNoteFactory::instance();
- mnf.registerMakerNote(nikon2IfdId,
- MakerNote::AutoPtr(new Nikon2MakerNote));
- ExifTags::registerMakerTagInfo(nikon2IfdId, tagInfo_);
- }
- };
- // DATA
- /*!
- The static member variable is initialized before main (see note) and
- will in the process register the MakerNote class. (Remember the
- definition of the variable in the implementation file!)
-
- @note The standard says that, if no function is explicitly called ever
- in a module, then that module's static data might be never
- initialized. This clause was introduced to allow dynamic link
- libraries. The idea is, with this clause the loader is not
- forced to eagerly load all modules, but load them only on
- demand.
- */
- static const RegisterMakerNote register_;
-
}; // class Nikon2MakerNote
+ static Nikon2MakerNote::RegisterMn registerNikon2MakerNote;
+
//! A third MakerNote format used by Nikon cameras, e.g., E5400, SQ, D2H, D70
class Nikon3MakerNote : public IfdMakerNote {
public:
@@ -317,6 +282,13 @@ namespace Exiv2 {
static std::ostream& print0x008b(std::ostream& os, const Value& value);
//@}
+ //! @cond IGNORE
+ // Public only so that we can create a static instance
+ struct RegisterMn {
+ RegisterMn();
+ };
+ //! @endcond
+
private:
//! Internal virtual create function.
Nikon3MakerNote* create_(bool alloc =true) const;
@@ -326,41 +298,10 @@ namespace Exiv2 {
//! Tag information
static const TagInfo tagInfo_[];
- //! Structure used to auto-register the MakerNote and %TagInfos
- struct RegisterMakerNote {
- //! Default constructor
- RegisterMakerNote()
- {
- MakerNoteFactory& mnf = MakerNoteFactory::instance();
- mnf.registerMakerNote(nikon3IfdId,
- MakerNote::AutoPtr(new Nikon3MakerNote));
- mnf.registerMakerNote(nikon3ThumbIfdId,
- MakerNote::AutoPtr(new Nikon3MakerNote));
- ExifTags::registerMakerTagInfo(nikon3IfdId, tagInfo_);
- ExifTags::registerBaseTagInfo(nikon3ThumbIfdId);
- }
- };
-
- // DATA
- /*!
- The static member variable is initialized before main (see note) and
- will in the process register the MakerNote class. (Remember the
- definition of the variable in the implementation file!)
-
- @note The standard says that, if no function is explicitly called ever
- in a module, then that module's static data might be never
- initialized. This clause was introduced to allow dynamic link
- libraries. The idea is, with this clause the loader is not
- forced to eagerly load all modules, but load them only on
- demand.
- */
- static const RegisterMakerNote register_;
-
- //! All makernote entries
- Entries entries_;
-
}; // class Nikon3MakerNote
+ static Nikon3MakerNote::RegisterMn registerNikon3MakerNote;
+
} // namespace Exiv2
#endif // #ifndef NIKONMN_HPP_
diff --git a/src/olympusmn.cpp b/src/olympusmn.cpp
index 0aa6f7e6..0c680f0d 100644
--- a/src/olympusmn.cpp
+++ b/src/olympusmn.cpp
@@ -53,7 +53,17 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions
namespace Exiv2 {
- const OlympusMakerNote::RegisterMakerNote OlympusMakerNote::register_;
+ //! @cond IGNORE
+ OlympusMakerNote::RegisterMn::RegisterMn()
+ {
+ MakerNoteFactory::registerMakerNote(
+ "OLYMPUS*", "*", createOlympusMakerNote);
+ MakerNoteFactory::registerMakerNote(
+ olympusIfdId, MakerNote::AutoPtr(new OlympusMakerNote));
+
+ ExifTags::registerMakerTagInfo(olympusIfdId, tagInfo_);
+ }
+ //! @endcond
// Olympus Tag Info
const TagInfo OlympusMakerNote::tagInfo_[] = {
diff --git a/src/olympusmn.hpp b/src/olympusmn.hpp
index 8c8834ef..b7360a39 100644
--- a/src/olympusmn.hpp
+++ b/src/olympusmn.hpp
@@ -20,9 +20,11 @@
*/
/*!
@file olympusmn.hpp
- @brief Olympus MakerNote implemented according to the specification
-
- Olympus MakerNote Documentation by ???.
+ @brief Olympus MakerNote implemented using the following references:
+ Exif file format, Appendix 1: MakerNote of Olympus Digicams by TsuruZoh Tachibanaya,
+ Olympus.pm of ExifTool by Phil Harvey,
+ Olympus Makernote Format Specification by Evan Hunter,
+ email communication with Will Stokes
@version $Rev$
@author Andreas Huggel (ahu)
ahuggel@gmx.net
@@ -132,6 +134,13 @@ namespace Exiv2 {
static std::ostream& print0x0f00_150_151(std::ostream& os, long l1, long l2);
//@}
+ //! @cond IGNORE
+ // Public only so that we can create a static instance
+ struct RegisterMn {
+ RegisterMn();
+ };
+ //! @endcond
+
private:
//! Internal virtual create function.
OlympusMakerNote* create_(bool alloc =true) const;
@@ -141,35 +150,9 @@ namespace Exiv2 {
//! Tag information
static const TagInfo tagInfo_[];
- //! Structure used to auto-register the MakerNote.
- struct RegisterMakerNote {
- //! Default constructor
- RegisterMakerNote()
- {
- MakerNoteFactory& mnf = MakerNoteFactory::instance();
- mnf.registerMakerNote("OLYMPUS*", "*", createOlympusMakerNote);
- mnf.registerMakerNote(olympusIfdId,
- MakerNote::AutoPtr(new OlympusMakerNote));
- ExifTags::registerMakerTagInfo(olympusIfdId, tagInfo_);
- }
- };
- // DATA
- /*!
- The static member variable is initialized before main (see note) and
- will in the process register the MakerNote class. (Remember the
- definition of the variable in the implementation file!)
-
- @note The standard says that, if no function is explicitly called ever
- in a module, then that module's static data might be never
- initialized. This clause was introduced to allow dynamic link
- libraries. The idea is, with this clause the loader is not
- forced to eagerly load all modules, but load them only on
- demand.
- */
- static const RegisterMakerNote register_;
-
}; // class OlympusMakerNote
+ static OlympusMakerNote::RegisterMn registerOlympusMakerNote;
} // namespace Exiv2
#endif // #ifndef OLYMPUSMN_HPP_
diff --git a/src/sigmamn.cpp b/src/sigmamn.cpp
index c25d5c63..7d63365f 100644
--- a/src/sigmamn.cpp
+++ b/src/sigmamn.cpp
@@ -51,7 +51,17 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions
namespace Exiv2 {
- const SigmaMakerNote::RegisterMakerNote SigmaMakerNote::register_;
+ //! @cond IGNORE
+ SigmaMakerNote::RegisterMn::RegisterMn()
+ {
+ MakerNoteFactory::registerMakerNote("SIGMA", "*", createSigmaMakerNote);
+ MakerNoteFactory::registerMakerNote("FOVEON", "*", createSigmaMakerNote);
+ MakerNoteFactory::registerMakerNote(
+ sigmaIfdId, MakerNote::AutoPtr(new SigmaMakerNote));
+
+ ExifTags::registerMakerTagInfo(sigmaIfdId, tagInfo_);
+ }
+ //! @endcond
// Sigma (Foveon) MakerNote Tag Info
const TagInfo SigmaMakerNote::tagInfo_[] = {
diff --git a/src/sigmamn.hpp b/src/sigmamn.hpp
index e304f8d8..8fbdba79 100644
--- a/src/sigmamn.hpp
+++ b/src/sigmamn.hpp
@@ -127,6 +127,13 @@ namespace Exiv2 {
static std::ostream& print0x0009(std::ostream& os, const Value& value);
//@}
+ //! @cond IGNORE
+ // Public only so that we can create a static instance
+ struct RegisterMn {
+ RegisterMn();
+ };
+ //! @endcond
+
private:
//! Internal virtual create function.
SigmaMakerNote* create_(bool alloc =true) const;
@@ -136,36 +143,9 @@ namespace Exiv2 {
//! Tag information
static const TagInfo tagInfo_[];
- //! Structure used to auto-register the MakerNote.
- struct RegisterMakerNote {
- //! Default constructor
- RegisterMakerNote()
- {
- MakerNoteFactory& mnf = MakerNoteFactory::instance();
- mnf.registerMakerNote("SIGMA", "*", createSigmaMakerNote);
- mnf.registerMakerNote("FOVEON", "*", createSigmaMakerNote);
- mnf.registerMakerNote(sigmaIfdId,
- MakerNote::AutoPtr(new SigmaMakerNote));
- ExifTags::registerMakerTagInfo(sigmaIfdId, tagInfo_);
- }
- };
- // DATA
- /*!
- The static member variable is initialized before main (see note) and
- will in the process register the MakerNote class. (Remember the
- definition of the variable in the implementation file!)
-
- @note The standard says that, if no function is explicitly called ever
- in a module, then that module's static data might be never
- initialized. This clause was introduced to allow dynamic link
- libraries. The idea is, with this clause the loader is not
- forced to eagerly load all modules, but load them only on
- demand.
- */
- static const RegisterMakerNote register_;
-
}; // class SigmaMakerNote
+ static SigmaMakerNote::RegisterMn registerSigmaMakerNote;
} // namespace Exiv2
#endif // #ifndef SIGMAMN_HPP_
diff --git a/src/sonymn.cpp b/src/sonymn.cpp
index aac1e5b8..051029c7 100644
--- a/src/sonymn.cpp
+++ b/src/sonymn.cpp
@@ -48,7 +48,16 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions
namespace Exiv2 {
- const SonyMakerNote::RegisterMakerNote SonyMakerNote::register_;
+ //! @cond IGNORE
+ SonyMakerNote::RegisterMn::RegisterMn()
+ {
+ MakerNoteFactory::registerMakerNote("SONY", "*", createSonyMakerNote);
+ MakerNoteFactory::registerMakerNote(
+ sonyIfdId, MakerNote::AutoPtr(new SonyMakerNote));
+
+ ExifTags::registerMakerTagInfo(sonyIfdId, tagInfo_);
+ }
+ //! @endcond
// Sony MakerNote Tag Info
const TagInfo SonyMakerNote::tagInfo_[] = {
diff --git a/src/sonymn.hpp b/src/sonymn.hpp
index f3426c2f..2cfce8bb 100644
--- a/src/sonymn.hpp
+++ b/src/sonymn.hpp
@@ -115,6 +115,13 @@ namespace Exiv2 {
AutoPtr clone() const;
//@}
+ //! @cond IGNORE
+ // Public only so that we can create a static instance
+ struct RegisterMn {
+ RegisterMn();
+ };
+ //! @endcond
+
private:
//! Internal virtual create function.
SonyMakerNote* create_(bool alloc =true) const;
@@ -124,35 +131,9 @@ namespace Exiv2 {
//! Tag information
static const TagInfo tagInfo_[];
- //! Structure used to auto-register the MakerNote.
- struct RegisterMakerNote {
- //! Default constructor
- RegisterMakerNote()
- {
- MakerNoteFactory& mnf = MakerNoteFactory::instance();
- mnf.registerMakerNote("SONY", "*", createSonyMakerNote);
- mnf.registerMakerNote(sonyIfdId,
- MakerNote::AutoPtr(new SonyMakerNote));
- ExifTags::registerMakerTagInfo(sonyIfdId, tagInfo_);
- }
- };
- // DATA
- /*!
- The static member variable is initialized before main (see note) and
- will in the process register the MakerNote class. (Remember the
- definition of the variable in the implementation file!)
-
- @note The standard says that, if no function is explicitly called ever
- in a module, then that module's static data might be never
- initialized. This clause was introduced to allow dynamic link
- libraries. The idea is, with this clause the loader is not
- forced to eagerly load all modules, but load them only on
- demand.
- */
- static const RegisterMakerNote register_;
-
}; // class SonyMakerNote
+ static SonyMakerNote::RegisterMn registerSonyMakerNote;
} // namespace Exiv2
#endif // #ifndef SONYMN_HPP_
diff --git a/src/taglist.cpp b/src/taglist.cpp
index 832727ea..f6a0a5fd 100644
--- a/src/taglist.cpp
+++ b/src/taglist.cpp
@@ -52,7 +52,7 @@ try {
}
if (rc) {
std::cout << "Usage: " << argv[0]
- << " [Canon|Fujifilm|Nikon1|Nikon2|Nikon3|Sigma|Iptc]\n"
+ << " [Canon|Fujifilm|Nikon1|Nikon2|Nikon3|Olympus|Sigma|Sony|Iptc]\n"
<< "Print Exif tags, MakerNote tags, or Iptc datasets\n";
}
return rc;
diff --git a/src/tags.cpp b/src/tags.cpp
index 4dd32793..62e7120b 100644
--- a/src/tags.cpp
+++ b/src/tags.cpp
@@ -37,6 +37,7 @@ EXIV2_RCSID("@(#) $Id$");
#include "ifd.hpp"
#include "value.hpp"
#include "makernote.hpp"
+#include "mn.hpp" // To ensure that all makernotes are registered
#include
#include
@@ -71,7 +72,6 @@ namespace Exiv2 {
IfdInfo(nikon1IfdId, "Makernote", "Nikon1"),
IfdInfo(nikon2IfdId, "Makernote", "Nikon2"),
IfdInfo(nikon3IfdId, "Makernote", "Nikon3"),
- IfdInfo(nikon3ThumbIfdId, "Makernote", "Nikon3Thumb"),
IfdInfo(olympusIfdId, "Makernote", "Olympus"),
IfdInfo(sigmaIfdId, "Makernote", "Sigma"),
IfdInfo(sonyIfdId, "Makernote", "Sony"),
@@ -545,8 +545,7 @@ namespace Exiv2 {
{
IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem);
if (ExifTags::isMakerIfd(ifdId)) {
- MakerNote::AutoPtr makerNote
- = MakerNoteFactory::instance().create(ifdId);
+ MakerNote::AutoPtr makerNote = MakerNoteFactory::create(ifdId);
if (makerNote.get() == 0) throw Error(23, ifdId);
}
tag_ = tag;
@@ -626,8 +625,7 @@ namespace Exiv2 {
IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem);
if (ifdId == ifdIdNotSet) throw Error(6, key_);
if (ExifTags::isMakerIfd(ifdId)) {
- MakerNote::AutoPtr makerNote
- = MakerNoteFactory::instance().create(ifdId);
+ MakerNote::AutoPtr makerNote = MakerNoteFactory::create(ifdId);
if (makerNote.get() == 0) throw Error(6, key_);
}
// Convert tag
diff --git a/src/types.hpp b/src/types.hpp
index 55a81567..646ebd44 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -89,8 +89,7 @@ namespace Exiv2 {
enum IfdId { ifdIdNotSet,
ifd0Id, exifIfdId, gpsIfdId, iopIfdId, ifd1Id,
canonIfdId, canonCs1IfdId, canonCs2IfdId, canonCfIfdId,
- fujiIfdId,
- nikon1IfdId, nikon2IfdId, nikon3IfdId, nikon3ThumbIfdId,
+ fujiIfdId, nikon1IfdId, nikon2IfdId, nikon3IfdId,
olympusIfdId, sigmaIfdId, sonyIfdId,
lastIfdId };
diff --git a/test/data/exiv2-test.out b/test/data/exiv2-test.out
index c7f9de3c..64676e19 100644
--- a/test/data/exiv2-test.out
+++ b/test/data/exiv2-test.out
@@ -30,6 +30,7 @@ Options:
-V Show the program version and exit.
-v Be verbose during the program run.
-f Do not prompt before overwriting existing files (force).
+ -F Do not prompt before renaming existing files (Force).
-a time Time adjustment in the format [-]HH[:MM[:SS]]. This option
is only used with the `adjust' action.
-p mode Print mode for the `print' action. Possible modes are: