Changed MakerNoteFactory according to ImageFactory. Removes the need to link applications with mn.o. Fixes bug #427

v0.27.3
Andreas Huggel 20 years ago
parent ac13e33080
commit a70511cc4a

@ -126,9 +126,6 @@
<File
RelativePath="..\..\src\addmoddel.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
</Filter>
<Filter
Name="Header Files"

@ -126,9 +126,6 @@
<File
RelativePath="..\..\src\exifcomment.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
</Filter>
<Filter
Name="Header Files"

@ -126,9 +126,6 @@
<File
RelativePath="..\..\src\exifprint.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
</Filter>
<Filter
Name="Header Files"

@ -135,9 +135,6 @@
<File
RelativePath="..\..\src\localtime.c">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
<File
RelativePath="..\..\src\utils.cpp">
</File>

@ -241,21 +241,6 @@
<File
RelativePath="..\..\src\metadatum.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\nikonmn.cpp">
</File>
@ -396,6 +381,9 @@
<File
RelativePath="..\..\src\metadatum.hpp">
</File>
<File
RelativePath="..\..\src\mn.hpp">
</File>
<File
RelativePath="..\..\src\nikonmn.hpp">
</File>

@ -132,21 +132,6 @@
<File
RelativePath=".\exivsimple.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath=".\stdafx.cpp">
<FileConfiguration

@ -124,9 +124,6 @@
<File
RelativePath="..\..\src\ifd-test.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
</Filter>
<Filter
Name="Header Files"

@ -124,9 +124,6 @@
<File
RelativePath="..\..\src\iptceasy.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
</Filter>
<Filter
Name="Header Files"

@ -124,9 +124,6 @@
<File
RelativePath="..\..\src\iptcprint.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
</Filter>
<Filter
Name="Header Files"

@ -125,9 +125,6 @@
<File
RelativePath="..\..\src\iptctest.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
</Filter>
<Filter
Name="Header Files"

@ -124,9 +124,6 @@
<File
RelativePath="..\..\src\makernote-test.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
</Filter>
<Filter
Name="Header Files"

@ -129,9 +129,6 @@
<File
RelativePath="..\..\src\metacopy.cpp">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
<File
RelativePath="..\..\src\utils.cpp">
</File>

@ -123,9 +123,6 @@
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\src\mn.cpp">
</File>
<File
RelativePath="..\..\src\taglist.cpp">
</File>

@ -126,9 +126,6 @@
<File
RelativePath="..\..\src\getopt_win32.c">
</File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
<File
RelativePath="..\..\src\utils.cpp">
</File>

@ -123,9 +123,6 @@
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\src\mn.cpp">
</File>
<File
RelativePath="..\..\src\write-test.cpp">
</File>

@ -123,9 +123,6 @@
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\src\mn.cpp">
</File>
<File
RelativePath="..\..\src\write2-test.cpp">
</File>

@ -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

@ -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_[] = {

@ -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_

@ -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<const char*>(make->data()),
reinterpret_cast<const char*>(model->data()),
false,
pos->data(),
pos->size(),
byteOrder(),
pExifIfd_->offset() + pos->offset()).release();
pMakerNote_ = MakerNoteFactory::create(
reinterpret_cast<const char*>(make->data()),
reinterpret_cast<const char*>(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());
}

@ -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_[] = {

@ -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_

@ -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;

@ -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<std::pair<std::string, CreateFct> > ModelRegistry;
//! Type used to store a list of make labels and model registries
@ -472,12 +462,10 @@ namespace Exiv2 {
typedef std::map<IfdId, MakerNote*> 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

@ -0,0 +1,42 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@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 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)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@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_

@ -1,28 +0,0 @@
#! /bin/sh
################################################################################
# File : mn.sh
# Version : $Rev$
# Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
# 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

@ -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_[] = {

@ -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_

@ -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_[] = {

@ -20,9 +20,11 @@
*/
/*!
@file olympusmn.hpp
@brief Olympus MakerNote implemented according to the specification
<a href="http://?????">
Olympus MakerNote Documentation</a> by ???.
@brief Olympus MakerNote implemented using the following references:
<a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html#APP1">Exif file format, Appendix 1: MakerNote of Olympus Digicams</a> by TsuruZoh Tachibanaya,
Olympus.pm of <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/">ExifTool</a> by Phil Harvey,
<a href="http://www.ozhiker.com/electronics/pjmt/jpeg_info/olympus_mn.html">Olympus Makernote Format Specification</a> by Evan Hunter,
email communication with <a href="mailto:wstokes@gmail.com">Will Stokes</a>
@version $Rev$
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@ -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_

@ -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_[] = {

@ -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_

@ -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_[] = {

@ -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_

@ -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;

@ -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 <iostream>
#include <iomanip>
@ -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

@ -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 };

@ -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:

Loading…
Cancel
Save