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: