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 <File
RelativePath="..\..\src\addmoddel.cpp"> RelativePath="..\..\src\addmoddel.cpp">
</File> </File>
<File
RelativePath="..\..\src\mn.cpp">
</File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"

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

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

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

@ -241,21 +241,6 @@
<File <File
RelativePath="..\..\src\metadatum.cpp"> RelativePath="..\..\src\metadatum.cpp">
</File> </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 <File
RelativePath="..\..\src\nikonmn.cpp"> RelativePath="..\..\src\nikonmn.cpp">
</File> </File>
@ -396,6 +381,9 @@
<File <File
RelativePath="..\..\src\metadatum.hpp"> RelativePath="..\..\src\metadatum.hpp">
</File> </File>
<File
RelativePath="..\..\src\mn.hpp">
</File>
<File <File
RelativePath="..\..\src\nikonmn.hpp"> RelativePath="..\..\src\nikonmn.hpp">
</File> </File>

@ -132,21 +132,6 @@
<File <File
RelativePath=".\exivsimple.cpp"> RelativePath=".\exivsimple.cpp">
</File> </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 <File
RelativePath=".\stdafx.cpp"> RelativePath=".\stdafx.cpp">
<FileConfiguration <FileConfiguration

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

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

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

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

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

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

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

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

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

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

@ -48,7 +48,7 @@ include $(top_srcdir)/config/config.mk
# Source files # Source files
# Add standalone C++ header files to this list # 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 # Add library C++ source files to this list
CCSRC = basicio.cpp canonmn.cpp datasets.cpp error.cpp exif.cpp futils.cpp \ CCSRC = basicio.cpp canonmn.cpp datasets.cpp error.cpp exif.cpp futils.cpp \
@ -87,7 +87,7 @@ LIBRARY = libexiv2.la
# Defines, Includes and Libraries # Defines, Includes and Libraries
CXXDEFS = $(DEFS) CXXDEFS = $(DEFS)
CXXINCS = $(INCS) CXXINCS = $(INCS)
LDLIBS = $(LIBS) mn.o $(LIBRARY) LDLIBS = $(LIBS) $(LIBRARY)
# ****************************************************************************** # ******************************************************************************
# ============================================================================== # ==============================================================================
@ -146,7 +146,7 @@ endif
$(OBJ): %.o: %.cpp $(OBJ): %.o: %.cpp
@$(LIBTOOL) --mode=compile $(CXX) $(CXXFLAGS) $(CXXDEFS) $(CXXINCS) -c $< @$(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 $< $(CXX) $(CXXFLAGS) $(CXXDEFS) $(CXXINCS) -c $<
%.o: %.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 exv_conf.h: $(top_srcdir)/config/config.h
sed 's/#define \([A-Z]\)/#define EXV_\1/; s/#undef \([A-Z]\)/#undef EXV_\1/' < $< > $@ sed 's/#define \([A-Z]\)/#define EXV_\1/; s/#undef \([A-Z]\)/#undef EXV_\1/' < $< > $@
mn.cpp: ./mn.sh
./mn.sh
$(LIBTOOL): $(LIBTOOL_DEPS) $(LIBTOOL): $(LIBTOOL_DEPS)
$(SHELL) $(top_srcdir)/config.status --recheck $(SHELL) $(top_srcdir)/config.status --recheck
@ -194,13 +191,13 @@ lib: $(OBJ)
path-test: path-test.o utils.o path-test: path-test.o utils.o
$(CXX) $(CXXFLAGS) path-test.o utils.o -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) @$(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) @$(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) @$(LIBTOOL) --mode=link $(CXX) $(CXXFLAGS) $(MCOBJ) $(LDLIBS) $(LDFLAGS) -o $@ -rpath $(libdir)
install-header: install-header:
@ -247,7 +244,8 @@ mostlyclean:
$(RM) core $(RM) core
$(RM) $(CCSRC:.cpp=.ii) $(RM) $(CCSRC:.cpp=.ii)
$(RM) lib $(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 clean: mostlyclean
@$(LIBTOOL) --mode=clean $(RM) $(LIBRARY) @$(LIBTOOL) --mode=clean $(RM) $(LIBRARY)
@ -265,4 +263,3 @@ distclean: clean
# that may need special tools to rebuild. # that may need special tools to rebuild.
maintainer-clean: uninstall distclean maintainer-clean: uninstall distclean
$(RM) $(DEP) $(RM) $(DEP)
$(RM) mn.cpp

@ -77,7 +77,26 @@ namespace {
// class member definitions // class member definitions
namespace Exiv2 { 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 // Canon MakerNote Tag Info
const TagInfo CanonMakerNote::tagInfo_[] = { const TagInfo CanonMakerNote::tagInfo_[] = {

@ -189,6 +189,13 @@ namespace Exiv2 {
static std::ostream& printCs20x0013(std::ostream& os, const Value& value); 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: private:
//! @name Manipulators //! @name Manipulators
//@{ //@{
@ -223,45 +230,9 @@ namespace Exiv2 {
static const TagInfo tagInfoCs2_[]; static const TagInfo tagInfoCs2_[];
static const TagInfo tagInfoCf_[]; 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 }; // class CanonMakerNote
static CanonMakerNote::RegisterMn registerCanonMakerNote;
} // namespace Exiv2 } // namespace Exiv2
#endif // #ifndef CANONMN_HPP_ #endif // #ifndef CANONMN_HPP_

@ -479,10 +479,10 @@ namespace Exiv2 {
Ifd::iterator model = pIfd0_->findTag(0x0110); Ifd::iterator model = pIfd0_->findTag(0x0110);
if ( pos != pExifIfd_->end() if ( pos != pExifIfd_->end()
&& make != pIfd0_->end() && model != pIfd0_->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: The conversion to string assumes that there is a \0 at the end
// Todo: How to avoid the cast (is that a MSVC thing?) // Todo: How to avoid the cast (is that a MSVC thing?)
pMakerNote_ = mnf.create(reinterpret_cast<const char*>(make->data()), pMakerNote_ = MakerNoteFactory::create(
reinterpret_cast<const char*>(make->data()),
reinterpret_cast<const char*>(model->data()), reinterpret_cast<const char*>(model->data()),
false, false,
pos->data(), pos->data(),
@ -738,8 +738,7 @@ namespace Exiv2 {
{ {
if (ExifTags::isMakerIfd(exifdatum.ifdId())) { if (ExifTags::isMakerIfd(exifdatum.ifdId())) {
if (pMakerNote_ == 0) { if (pMakerNote_ == 0) {
MakerNoteFactory& mnf = MakerNoteFactory::instance(); pMakerNote_ = MakerNoteFactory::create(exifdatum.ifdId()).release();
pMakerNote_ = mnf.create(exifdatum.ifdId()).release();
} }
if (pMakerNote_ == 0) throw Error(23, exifdatum.ifdId()); if (pMakerNote_ == 0) throw Error(23, exifdatum.ifdId());
} }

@ -53,7 +53,16 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions // class member definitions
namespace Exiv2 { 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 // Fujifilm MakerNote Tag Info
const TagInfo FujiMakerNote::tagInfo_[] = { const TagInfo FujiMakerNote::tagInfo_[] = {

@ -138,6 +138,13 @@ namespace Exiv2 {
static std::ostream& print0x1031(std::ostream& os, const Value& value); 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: private:
//! Internal virtual create function. //! Internal virtual create function.
FujiMakerNote* create_(bool alloc =true) const; FujiMakerNote* create_(bool alloc =true) const;
@ -147,34 +154,9 @@ namespace Exiv2 {
//! Tag information //! Tag information
static const TagInfo tagInfo_[]; 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 }; // class FujiMakerNote
static FujiMakerNote::RegisterMn registerFujiMakerNote;
} // namespace Exiv2 } // namespace Exiv2
#endif // #ifndef FUJIMN_HPP_ #endif // #ifndef FUJIMN_HPP_

@ -187,28 +187,33 @@ namespace Exiv2 {
return AutoPtr(clone_()); 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_) { if (0 == pRegistry_) {
pInstance_ = new MakerNoteFactory; pRegistry_ = new Registry;
} }
return *pInstance_; if (0 == pIfdIdRegistry_) {
} // MakerNoteFactory::instance pIfdIdRegistry_ = new IfdIdRegistry;
}
} // MakerNoteFactory::init
void MakerNoteFactory::registerMakerNote(IfdId ifdId, void MakerNoteFactory::registerMakerNote(IfdId ifdId,
MakerNote::AutoPtr makerNote) MakerNote::AutoPtr makerNote)
{ {
init();
MakerNote* pMakerNote = makerNote.release(); MakerNote* pMakerNote = makerNote.release();
assert(pMakerNote); assert(pMakerNote);
ifdIdRegistry_[ifdId] = pMakerNote; (*pIfdIdRegistry_)[ifdId] = pMakerNote;
} // MakerNoteFactory::registerMakerNote } // 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); assert(pIfdIdRegistry_ != 0);
if (i == ifdIdRegistry_.end()) return MakerNote::AutoPtr(0); IfdIdRegistry::const_iterator i = pIfdIdRegistry_->find(ifdId);
if (i == pIfdIdRegistry_->end()) return MakerNote::AutoPtr(0);
assert(i->second); assert(i->second);
return i->second->create(alloc); return i->second->create(alloc);
} // MakerNoteFactory::create } // MakerNoteFactory::create
@ -221,14 +226,15 @@ namespace Exiv2 {
std::cerr << "Registering MakerNote create function for \"" std::cerr << "Registering MakerNote create function for \""
<< make << "\" and \"" << model << "\".\n"; << make << "\" and \"" << model << "\".\n";
#endif #endif
init();
// Todo: use case insensitive make and model comparisons // Todo: use case insensitive make and model comparisons
// Find or create a registry entry for make // Find or create a registry entry for make
ModelRegistry* pModelRegistry = 0; ModelRegistry* pModelRegistry = 0;
Registry::const_iterator end1 = registry_.end(); assert(pRegistry_ != 0);
Registry::const_iterator end1 = pRegistry_->end();
Registry::const_iterator pos1; 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->first == make) break;
} }
if (pos1 != end1) { if (pos1 != end1) {
@ -236,7 +242,7 @@ namespace Exiv2 {
} }
else { else {
pModelRegistry = new ModelRegistry; 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 // Find or create a registry entry for model
ModelRegistry::iterator end2 = pModelRegistry->end(); ModelRegistry::iterator end2 = pModelRegistry->end();
@ -258,7 +264,7 @@ namespace Exiv2 {
const byte* buf, const byte* buf,
long len, long len,
ByteOrder byteOrder, ByteOrder byteOrder,
long offset) const long offset)
{ {
#ifdef DEBUG_REGISTRY #ifdef DEBUG_REGISTRY
std::cerr << "Entering MakerNoteFactory::create(\"" std::cerr << "Entering MakerNoteFactory::create(\""
@ -272,9 +278,10 @@ namespace Exiv2 {
std::string makeMatch; std::string makeMatch;
std::cerr << "Searching make registry...\n"; std::cerr << "Searching make registry...\n";
#endif #endif
Registry::const_iterator end1 = registry_.end(); assert(pRegistry_ != 0);
Registry::const_iterator end1 = pRegistry_->end();
Registry::const_iterator pos1; Registry::const_iterator pos1;
for (pos1 = registry_.begin(); pos1 != end1; ++pos1) { for (pos1 = pRegistry_->begin(); pos1 != end1; ++pos1) {
int rc = match(pos1->first, make); int rc = match(pos1->first, make);
if (rc > score) { if (rc > score) {
score = rc; score = rc;

@ -88,9 +88,9 @@ namespace Exiv2 {
See existing makernote implementations for examples, e.g., CanonMakerNote See existing makernote implementations for examples, e.g., CanonMakerNote
or FujiMakerNote. or FujiMakerNote.
Finally, the implementation files should be named *mn.[ch]pp, so that the Finally, the header file which defines the static variable
magic, which ensures that the makernote is automatically registered \em register*MakerNote needs to be included from mn.hpp, to ensure that
in the factory, will pick it up (see mn.sh for details). the makernote is automatically registered in the factory.
*/ */
class MakerNote { class MakerNote {
//! @name Not implemented //! @name Not implemented
@ -340,19 +340,10 @@ namespace Exiv2 {
Maintains an associative list (tree) of camera makes/models and Maintains an associative list (tree) of camera makes/models and
corresponding %MakerNote create functions. Creates an instance of the corresponding %MakerNote create functions. Creates an instance of the
%MakerNote for one camera make/model. The factory is implemented as a %MakerNote for one camera make/model. The factory is implemented as a
singleton, which can be accessed only through the static member function static class.
instance().
*/ */
class MakerNoteFactory { class MakerNoteFactory {
public: 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 @brief Register a %MakerNote create function for a camera make and
model. model.
@ -371,16 +362,13 @@ namespace Exiv2 {
@param createMakerNote Pointer to a function to create a new @param createMakerNote Pointer to a function to create a new
%MakerNote of a particular type. %MakerNote of a particular type.
*/ */
void registerMakerNote(const std::string& make, static void registerMakerNote(const std::string& make,
const std::string& model, const std::string& model,
CreateFct createMakerNote); CreateFct createMakerNote);
//! Register a %MakerNote prototype in the IFD id registry. //! 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 @brief Create the appropriate %MakerNote based on camera make and
model and possibly the contents of the makernote itself, return 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. @return An auto-pointer that owns a %MakerNote for the camera model.
If the camera is not supported, the pointer is 0. If the camera is not supported, the pointer is 0.
*/ */
MakerNote::AutoPtr create(const std::string& make, static MakerNote::AutoPtr create(const std::string& make,
const std::string& model, const std::string& model,
bool alloc, bool alloc,
const byte* buf, const byte* buf,
long len, long len,
ByteOrder byteOrder, ByteOrder byteOrder,
long offset) const; long offset);
//! Create a %MakerNote for an IFD id. //! 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). @brief Match a registry entry with a key (used for make and model).
@ -458,12 +445,15 @@ namespace Exiv2 {
private: private:
//! @name Creators //! @name Creators
//@{ //@{
//! Prevent construction other than through instance(). //! Prevent construction: not implemented.
MakerNoteFactory() {} MakerNoteFactory() {}
//! Prevent copy construction: not implemented. //! Prevent copy construction: not implemented.
MakerNoteFactory(const MakerNoteFactory& rhs); MakerNoteFactory(const MakerNoteFactory& rhs);
//@} //@}
//! Creates the private static instance
static void init();
//! Type used to store model labels and %MakerNote create functions //! Type used to store model labels and %MakerNote create functions
typedef std::vector<std::pair<std::string, CreateFct> > ModelRegistry; typedef std::vector<std::pair<std::string, CreateFct> > ModelRegistry;
//! Type used to store a list of make labels and model registries //! Type used to store a list of make labels and model registries
@ -472,12 +462,10 @@ namespace Exiv2 {
typedef std::map<IfdId, MakerNote*> IfdIdRegistry; typedef std::map<IfdId, MakerNote*> IfdIdRegistry;
// DATA // DATA
//! Pointer to the one and only instance of this class.
static MakerNoteFactory* pInstance_;
//! List of makernote types and corresponding makernote create functions. //! List of makernote types and corresponding makernote create functions.
Registry registry_; static Registry* pRegistry_;
//! List of makernote IFD ids and corresponding create functions. //! List of makernote IFD ids and corresponding create functions.
IfdIdRegistry ifdIdRegistry_; static IfdIdRegistry* pIfdIdRegistry_;
}; // class MakerNoteFactory }; // 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 // class member definitions
namespace Exiv2 { 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 // Nikon1 MakerNote Tag Info
const TagInfo Nikon1MakerNote::tagInfo_[] = { const TagInfo Nikon1MakerNote::tagInfo_[] = {
@ -189,7 +198,15 @@ namespace Exiv2 {
return os; 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 // Nikon2 MakerNote Tag Info
const TagInfo Nikon2MakerNote::tagInfo_[] = { const TagInfo Nikon2MakerNote::tagInfo_[] = {
@ -364,7 +381,15 @@ namespace Exiv2 {
return os; 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 // Nikon3 MakerNote Tag Info
const TagInfo Nikon3MakerNote::tagInfo_[] = { const TagInfo Nikon3MakerNote::tagInfo_[] = {

@ -139,6 +139,13 @@ namespace Exiv2 {
static std::ostream& print0x0088(std::ostream& os, const Value& value); 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: private:
//! Internal virtual create function. //! Internal virtual create function.
Nikon1MakerNote* create_(bool alloc =true) const; Nikon1MakerNote* create_(bool alloc =true) const;
@ -148,35 +155,10 @@ namespace Exiv2 {
//! Tag information //! Tag information
static const TagInfo tagInfo_[]; 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 }; // class Nikon1MakerNote
static Nikon1MakerNote::RegisterMn registerNikon1MakerNote;
/*! /*!
@brief A second MakerNote format used by Nikon cameras, including the @brief A second MakerNote format used by Nikon cameras, including the
E700, E800, E900, E900S, E910, E950 E700, E800, E900, E900S, E910, E950
@ -229,6 +211,13 @@ namespace Exiv2 {
static std::ostream& print0x000a(std::ostream& os, const Value& value); 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: private:
//! Internal virtual create function. //! Internal virtual create function.
Nikon2MakerNote* create_(bool alloc =true) const; Nikon2MakerNote* create_(bool alloc =true) const;
@ -238,34 +227,10 @@ namespace Exiv2 {
//! Tag information //! Tag information
static const TagInfo tagInfo_[]; 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 }; // class Nikon2MakerNote
static Nikon2MakerNote::RegisterMn registerNikon2MakerNote;
//! A third MakerNote format used by Nikon cameras, e.g., E5400, SQ, D2H, D70 //! A third MakerNote format used by Nikon cameras, e.g., E5400, SQ, D2H, D70
class Nikon3MakerNote : public IfdMakerNote { class Nikon3MakerNote : public IfdMakerNote {
public: public:
@ -317,6 +282,13 @@ namespace Exiv2 {
static std::ostream& print0x008b(std::ostream& os, const Value& value); 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: private:
//! Internal virtual create function. //! Internal virtual create function.
Nikon3MakerNote* create_(bool alloc =true) const; Nikon3MakerNote* create_(bool alloc =true) const;
@ -326,41 +298,10 @@ namespace Exiv2 {
//! Tag information //! Tag information
static const TagInfo tagInfo_[]; 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 }; // class Nikon3MakerNote
static Nikon3MakerNote::RegisterMn registerNikon3MakerNote;
} // namespace Exiv2 } // namespace Exiv2
#endif // #ifndef NIKONMN_HPP_ #endif // #ifndef NIKONMN_HPP_

@ -53,7 +53,17 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions // class member definitions
namespace Exiv2 { 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 // Olympus Tag Info
const TagInfo OlympusMakerNote::tagInfo_[] = { const TagInfo OlympusMakerNote::tagInfo_[] = {

@ -20,9 +20,11 @@
*/ */
/*! /*!
@file olympusmn.hpp @file olympusmn.hpp
@brief Olympus MakerNote implemented according to the specification @brief Olympus MakerNote implemented using the following references:
<a href="http://?????"> <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 MakerNote Documentation</a> by ???. 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$ @version $Rev$
@author Andreas Huggel (ahu) @author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a> <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); 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: private:
//! Internal virtual create function. //! Internal virtual create function.
OlympusMakerNote* create_(bool alloc =true) const; OlympusMakerNote* create_(bool alloc =true) const;
@ -141,35 +150,9 @@ namespace Exiv2 {
//! Tag information //! Tag information
static const TagInfo tagInfo_[]; 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 }; // class OlympusMakerNote
static OlympusMakerNote::RegisterMn registerOlympusMakerNote;
} // namespace Exiv2 } // namespace Exiv2
#endif // #ifndef OLYMPUSMN_HPP_ #endif // #ifndef OLYMPUSMN_HPP_

@ -51,7 +51,17 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions // class member definitions
namespace Exiv2 { 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 // Sigma (Foveon) MakerNote Tag Info
const TagInfo SigmaMakerNote::tagInfo_[] = { const TagInfo SigmaMakerNote::tagInfo_[] = {

@ -127,6 +127,13 @@ namespace Exiv2 {
static std::ostream& print0x0009(std::ostream& os, const Value& value); 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: private:
//! Internal virtual create function. //! Internal virtual create function.
SigmaMakerNote* create_(bool alloc =true) const; SigmaMakerNote* create_(bool alloc =true) const;
@ -136,36 +143,9 @@ namespace Exiv2 {
//! Tag information //! Tag information
static const TagInfo tagInfo_[]; 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 }; // class SigmaMakerNote
static SigmaMakerNote::RegisterMn registerSigmaMakerNote;
} // namespace Exiv2 } // namespace Exiv2
#endif // #ifndef SIGMAMN_HPP_ #endif // #ifndef SIGMAMN_HPP_

@ -48,7 +48,16 @@ EXIV2_RCSID("@(#) $Id$");
// class member definitions // class member definitions
namespace Exiv2 { 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 // Sony MakerNote Tag Info
const TagInfo SonyMakerNote::tagInfo_[] = { const TagInfo SonyMakerNote::tagInfo_[] = {

@ -115,6 +115,13 @@ namespace Exiv2 {
AutoPtr clone() const; AutoPtr clone() const;
//@} //@}
//! @cond IGNORE
// Public only so that we can create a static instance
struct RegisterMn {
RegisterMn();
};
//! @endcond
private: private:
//! Internal virtual create function. //! Internal virtual create function.
SonyMakerNote* create_(bool alloc =true) const; SonyMakerNote* create_(bool alloc =true) const;
@ -124,35 +131,9 @@ namespace Exiv2 {
//! Tag information //! Tag information
static const TagInfo tagInfo_[]; 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 }; // class SonyMakerNote
static SonyMakerNote::RegisterMn registerSonyMakerNote;
} // namespace Exiv2 } // namespace Exiv2
#endif // #ifndef SONYMN_HPP_ #endif // #ifndef SONYMN_HPP_

@ -52,7 +52,7 @@ try {
} }
if (rc) { if (rc) {
std::cout << "Usage: " << argv[0] 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"; << "Print Exif tags, MakerNote tags, or Iptc datasets\n";
} }
return rc; return rc;

@ -37,6 +37,7 @@ EXIV2_RCSID("@(#) $Id$");
#include "ifd.hpp" #include "ifd.hpp"
#include "value.hpp" #include "value.hpp"
#include "makernote.hpp" #include "makernote.hpp"
#include "mn.hpp" // To ensure that all makernotes are registered
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
@ -71,7 +72,6 @@ namespace Exiv2 {
IfdInfo(nikon1IfdId, "Makernote", "Nikon1"), IfdInfo(nikon1IfdId, "Makernote", "Nikon1"),
IfdInfo(nikon2IfdId, "Makernote", "Nikon2"), IfdInfo(nikon2IfdId, "Makernote", "Nikon2"),
IfdInfo(nikon3IfdId, "Makernote", "Nikon3"), IfdInfo(nikon3IfdId, "Makernote", "Nikon3"),
IfdInfo(nikon3ThumbIfdId, "Makernote", "Nikon3Thumb"),
IfdInfo(olympusIfdId, "Makernote", "Olympus"), IfdInfo(olympusIfdId, "Makernote", "Olympus"),
IfdInfo(sigmaIfdId, "Makernote", "Sigma"), IfdInfo(sigmaIfdId, "Makernote", "Sigma"),
IfdInfo(sonyIfdId, "Makernote", "Sony"), IfdInfo(sonyIfdId, "Makernote", "Sony"),
@ -545,8 +545,7 @@ namespace Exiv2 {
{ {
IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem);
if (ExifTags::isMakerIfd(ifdId)) { if (ExifTags::isMakerIfd(ifdId)) {
MakerNote::AutoPtr makerNote MakerNote::AutoPtr makerNote = MakerNoteFactory::create(ifdId);
= MakerNoteFactory::instance().create(ifdId);
if (makerNote.get() == 0) throw Error(23, ifdId); if (makerNote.get() == 0) throw Error(23, ifdId);
} }
tag_ = tag; tag_ = tag;
@ -626,8 +625,7 @@ namespace Exiv2 {
IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem);
if (ifdId == ifdIdNotSet) throw Error(6, key_); if (ifdId == ifdIdNotSet) throw Error(6, key_);
if (ExifTags::isMakerIfd(ifdId)) { if (ExifTags::isMakerIfd(ifdId)) {
MakerNote::AutoPtr makerNote MakerNote::AutoPtr makerNote = MakerNoteFactory::create(ifdId);
= MakerNoteFactory::instance().create(ifdId);
if (makerNote.get() == 0) throw Error(6, key_); if (makerNote.get() == 0) throw Error(6, key_);
} }
// Convert tag // Convert tag

@ -89,8 +89,7 @@ namespace Exiv2 {
enum IfdId { ifdIdNotSet, enum IfdId { ifdIdNotSet,
ifd0Id, exifIfdId, gpsIfdId, iopIfdId, ifd1Id, ifd0Id, exifIfdId, gpsIfdId, iopIfdId, ifd1Id,
canonIfdId, canonCs1IfdId, canonCs2IfdId, canonCfIfdId, canonIfdId, canonCs1IfdId, canonCs2IfdId, canonCfIfdId,
fujiIfdId, fujiIfdId, nikon1IfdId, nikon2IfdId, nikon3IfdId,
nikon1IfdId, nikon2IfdId, nikon3IfdId, nikon3ThumbIfdId,
olympusIfdId, sigmaIfdId, sonyIfdId, olympusIfdId, sigmaIfdId, sonyIfdId,
lastIfdId }; lastIfdId };

@ -30,6 +30,7 @@ Options:
-V Show the program version and exit. -V Show the program version and exit.
-v Be verbose during the program run. -v Be verbose during the program run.
-f Do not prompt before overwriting existing files (force). -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 -a time Time adjustment in the format [-]HH[:MM[:SS]]. This option
is only used with the `adjust' action. is only used with the `adjust' action.
-p mode Print mode for the `print' action. Possible modes are: -p mode Print mode for the `print' action. Possible modes are:

Loading…
Cancel
Save