diff --git a/samples/Makefile b/samples/Makefile index 733e1ff0..7c8b6fe3 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -56,6 +56,7 @@ include $(top_srcdir)/config/config.mk # Add source files of sample programs to this list BINSRC = addmoddel.cpp \ convert-test.cpp \ + easyaccess-test.cpp \ exifcomment.cpp \ exifdata-test.cpp \ exifprint.cpp \ diff --git a/samples/easyaccess-test.cpp b/samples/easyaccess-test.cpp new file mode 100644 index 00000000..c046f58b --- /dev/null +++ b/samples/easyaccess-test.cpp @@ -0,0 +1,58 @@ +// ***************************************************************** -*- C++ -*- +// easyaccess-test.cpp, $Rev$ +// Sample program using high-level metadata access functions + +// included header files +#include +#include +#include +#include +#include +#include + +typedef Exiv2::ExifData::const_iterator (*EasyAccessFct)(const Exiv2::ExifData& ed); + +struct EasyAccess { + const char* label_; + EasyAccessFct findFct_; +}; + +static const EasyAccess easyAccess[] = { + { "Orientation", Exiv2::orientation }, + { "ISO speed", Exiv2::isoSpeed }, + { "Flash bias", Exiv2::flashBias }, + { "Exposure mode", Exiv2::exposureMode }, + { "Scene mode", Exiv2::sceneMode }, + { "Macro mode", Exiv2::macroMode }, + { "Image quality", Exiv2::imageQuality }, + { "White balance", Exiv2::whiteBalance }, + { "Lens name", Exiv2::lensName } +}; + +int main(int argc, char **argv) +try { + if (argc != 2) { + std::cout << "Usage: " << argv[0] << " file\n"; + return 1; + } + + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]); + assert (image.get() != 0); + image->readMetadata(); + Exiv2::ExifData& ed = image->exifData(); + + for (unsigned int i = 0; i < EXV_COUNTOF(easyAccess); ++i) { + Exiv2::ExifData::const_iterator pos = easyAccess[i].findFct_(ed); + if (pos != ed.end()) { + std::cout << std::setw(13) << std::left << easyAccess[i].label_ << " (" + << std::setw(30) << pos->key() << ") : " + << pos->print(&ed) << "\n"; + } + } + + return 0; +} +catch (Exiv2::AnyError& e) { + std::cout << "Caught Exiv2 exception '" << e << "'\n"; + return -1; +} diff --git a/src/Makefile b/src/Makefile index 65d412d0..173ec269 100644 --- a/src/Makefile +++ b/src/Makefile @@ -73,6 +73,7 @@ CCSRC = basicio.cpp \ cr2image.cpp \ crwimage.cpp \ datasets.cpp \ + easyaccess.cpp \ error.cpp \ exif.cpp \ futils.cpp \ diff --git a/src/actions.cpp b/src/actions.cpp index 7b0febaa..a315ec3e 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -48,6 +48,7 @@ EXIV2_RCSID("@(#) $Id$") #include "utils.hpp" #include "types.hpp" #include "exif.hpp" +#include "easyaccess.hpp" #include "canonmn.hpp" #include "iptc.hpp" #include "xmp.hpp" @@ -324,23 +325,8 @@ namespace Action { // Flash printTag(exifData, "Exif.Photo.Flash", _("Flash")); - // Todo: Flash bias, flash energy - // Todo: Implement this for other cameras - done = false; - printLabel(_("Flash bias")); - if (!done) { - done = 0 != printTag(exifData, "Exif.CanonSi.FlashBias"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Panasonic.FlashBias"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Olympus.FlashBias"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.OlympusCs.FlashExposureComp"); - } - std::cout << std::endl; + // Flash bias + printTag(exifData, Exiv2::flashBias, _("Flash bias")); // Actual focal length and 35 mm equivalent // Todo: Calculate 35 mm equivalent a la jhead @@ -371,139 +357,19 @@ namespace Action { std::cout << std::endl; // ISO speed - // from ISOSpeedRatings or the Makernote - printLabel(_("ISO speed")); - done = false; - if (!done) { - done = 0 != printTag(exifData, "Exif.Photo.ISOSpeedRatings"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.CanonSi.ISOSpeed"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Nikon1.ISOSpeed"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Nikon2.ISOSpeed"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Nikon3.ISOSpeed"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCsNew.ISOSpeed"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCsOld.ISOSpeed"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCs5D.ISOSpeed"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCs7D.ISOSpeed"); - } - std::cout << std::endl; + printTag(exifData, Exiv2::isoSpeed, _("ISO speed")); // Exposure mode - // From ExposureProgram or Canon Makernote - printLabel(_("Exposure mode")); - done = false; - if (!done) { - done = 0 != printTag(exifData, "Exif.Photo.ExposureProgram"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.CanonCs.ExposureProgram"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCs7D.ExposureMode"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCs5D.ExposureMode"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCsNew.ExposureMode"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCsOld.ExposureMode"); - } - std::cout << std::endl; + printTag(exifData, Exiv2::exposureMode, _("Exposure mode")); // Metering mode printTag(exifData, "Exif.Photo.MeteringMode", _("Metering mode")); // Macro mode - // Todo: Implement this for other cameras - printLabel(_("Macro mode")); - done = false; - if (!done) { - done = 0 != printTag(exifData, "Exif.CanonCs.Macro"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Fujifilm.Macro"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Olympus.Macro"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.OlympusCs.MacroMode"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Panasonic.Macro"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCsNew.MacroMode"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCsOld.MacroMode"); - } - std::cout << std::endl; + printTag(exifData, Exiv2::macroMode, _("Macro mode")); // Image quality setting (compression) - // Todo: Implement this for other cameras - printLabel(_("Image quality")); - done = false; - if (!done) { - done = 0 != printTag(exifData, "Exif.CanonCs.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Fujifilm.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Sigma.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Nikon1.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Nikon2.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Nikon3.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Olympus.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.OlympusCs.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Panasonic.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Minolta.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCsNew.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCsOld.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCs5D.Quality"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCs7D.Quality"); - } - std::cout << std::endl; + printTag(exifData, Exiv2::imageQuality, _("Image quality")); // Exif Resolution printLabel(_("Exif Resolution")); @@ -529,52 +395,7 @@ namespace Action { std::cout << std::endl; // White balance - // Todo: Implement this for other cameras - printLabel(_("White balance")); - done = false; - if (!done) { - done = 0 != printTag(exifData, "Exif.CanonSi.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Fujifilm.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Sigma.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Nikon1.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Nikon2.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Nikon3.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Olympus.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.OlympusCs.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Panasonic.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCs5D.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCs7D.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCsNew.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.MinoltaCsOld.WhiteBalance"); - } - if (!done) { - done = 0 != printTag(exifData, "Exif.Photo.WhiteBalance"); - } - std::cout << std::endl; + printTag(exifData, Exiv2::whiteBalance, _("White balance")); // Thumbnail printLabel(_("Thumbnail")); @@ -633,6 +454,23 @@ namespace Action { return rc; } // Print::printTag + int Print::printTag(const Exiv2::ExifData& exifData, + EasyAccessFct easyAccessFct, + const std::string& label) const + { + int rc = 0; + if (!label.empty()) { + printLabel(label); + } + Exiv2::ExifData::const_iterator md = easyAccessFct(exifData); + if (md != exifData.end()) { + md->write(std::cout, &exifData); + rc = 1; + } + if (!label.empty()) std::cout << std::endl; + return rc; + } // Print::printTag + int Print::printList() { int rc = 0; diff --git a/src/actions.hpp b/src/actions.hpp index fe113311..5590cb71 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -184,6 +184,16 @@ namespace Action { int printTag(const Exiv2::ExifData& exifData, const std::string& key, const std::string& label ="") const; + //! Type for an Exiv2 Easy access function + typedef Exiv2::ExifData::const_iterator (*EasyAccessFct)(const Exiv2::ExifData& ed); + /*! + @brief Print one summary line with a label (if provided) and requested + data. A line break is printed only if a label is provided. + @return 1 if a line was written, 0 if the information was not found. + */ + int printTag(const Exiv2::ExifData& exifData, + EasyAccessFct easyAccessFct, + const std::string& label) const; private: virtual Print* clone_() const; diff --git a/src/easyaccess.cpp b/src/easyaccess.cpp new file mode 100644 index 00000000..beeb9d4b --- /dev/null +++ b/src/easyaccess.cpp @@ -0,0 +1,203 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2004-2009 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., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/* + File: easyaccess.cpp + Version: $Rev$ + Author(s): Carsten Pfeiffer + Andreas Huggel (ahu) + History: 28-Feb-09, gis: created + */ +// ***************************************************************************** +#include "rcsid.hpp" +EXIV2_RCSID("@(#) $Id$") + +// ***************************************************************************** +// included header files +#include "easyaccess.hpp" + +// ***************************************************************************** +namespace { + + using namespace Exiv2; + + /*! + @brief Search \em ed for a Metadatum specified by the \em keys. + The \em keys are searched in the order of their appearance, the + first available Metadatum is returned. + + @param ed The %Exif metadata container to search + @param keys Array of keys to look for + @param count Number of elements in the array + */ + ExifData::const_iterator findMetadatum(const ExifData& ed, + const char* keys[], + int count) + { + for (int i = 0; i < count; ++i) { + ExifData::const_iterator pos = ed.findKey(ExifKey(keys[i])); + if (pos != ed.end()) return pos; + } + return ed.end(); + } // findMetadatum + +} // anonymous namespace + +// ***************************************************************************** +// class member definitions +namespace Exiv2 { + + ExifData::const_iterator orientation(const ExifData& ed) + { + static const char* keys[] = { + "Exif.Image.Orientation", + "Exif.Panasonic.Rotation", + "Exif.MinoltaCs5D.Rotation", + "Exif.MinoltaCs7D.Rotation" + }; + return findMetadatum(ed, keys, EXV_COUNTOF(keys)); + } + + ExifData::const_iterator isoSpeed(const ExifData& ed) + { + static const char* keys[] = { + "Exif.Photo.ISOSpeedRatings", + "Exif.CanonSi.ISOSpeed", + "Exif.CanonCs.ISOSpeed", + "Exif.Nikon1.ISOSpeed", + "Exif.Nikon2.ISOSpeed", + "Exif.Nikon3.ISOSpeed", + "Exif.MinoltaCsNew.ISOSpeed", + "Exif.MinoltaCsOld.ISOSpeed", + "Exif.MinoltaCs5D.ISOSpeed", + "Exif.MinoltaCs7D.ISOSpeed", + "Exif.Pentax.ISO", + "Exif.Olympus.ISOSpeed" + }; + return findMetadatum(ed, keys, EXV_COUNTOF(keys)); + } + + ExifData::const_iterator flashBias(const ExifData& ed) + { + static const char* keys[] = { + "Exif.CanonSi.FlashBias", + "Exif.Panasonic.FlashBias", + "Exif.Olympus.FlashBias", + "Exif.OlympusCs.FlashExposureComp" + }; + return findMetadatum(ed, keys, EXV_COUNTOF(keys)); + } + + ExifData::const_iterator exposureMode(const ExifData& ed) + { + static const char* keys[] = { + "Exif.Photo.ExposureProgram", + "Exif.CanonCs.ExposureProgram", + "Exif.MinoltaCs7D.ExposureMode", + "Exif.MinoltaCs5D.ExposureMode", + "Exif.MinoltaCsNew.ExposureMode", + "Exif.MinoltaCsOld.ExposureMode", + "Exif.Sigma.ExposureMode" + }; + return findMetadatum(ed, keys, EXV_COUNTOF(keys)); + } + + ExifData::const_iterator sceneMode(const ExifData& ed) + { + static const char* keys[] = { + "Exif.CanonCs.EasyMode", + "Exif.Fujifilm.PictureMode", + "Exif.MinoltaCsNew.SubjectProgram", + "Exif.OlympusCs.SceneMode", + "Exif.Panasonic.ShootingMode", + "Exif.Panasonic.SceneMode", + "Exif.Pentax.PictureMode" + }; + return findMetadatum(ed, keys, EXV_COUNTOF(keys)); + } + + ExifData::const_iterator macroMode(const ExifData& ed) + { + static const char* keys[] = { + "Exif.CanonCs.Macro", + "Exif.Fujifilm.Macro", + "Exif.Olympus.Macro", + "Exif.OlympusCs.MacroMode", + "Exif.Panasonic.Macro", + "Exif.MinoltaCsNew.MacroMode", + "Exif.MinoltaCsOld.MacroMode" + }; + return findMetadatum(ed, keys, EXV_COUNTOF(keys)); + } + + ExifData::const_iterator imageQuality(const ExifData& ed) + { + static const char* keys[] = { + "Exif.CanonCs.Quality", + "Exif.Fujifilm.Quality", + "Exif.Sigma.Quality", + "Exif.Nikon1.Quality", + "Exif.Nikon2.Quality", + "Exif.Nikon3.Quality", + "Exif.Olympus.Quality", + "Exif.OlympusCs.Quality", + "Exif.Panasonic.Quality", + "Exif.Minolta.Quality", + "Exif.MinoltaCsNew.Quality", + "Exif.MinoltaCsOld.Quality", + "Exif.MinoltaCs5D.Quality", + "Exif.MinoltaCs7D.Quality" + }; + return findMetadatum(ed, keys, EXV_COUNTOF(keys)); + } + + ExifData::const_iterator whiteBalance(const ExifData& ed) + { + static const char* keys[] = { + "Exif.CanonSi.WhiteBalance", + "Exif.Fujifilm.WhiteBalance", + "Exif.Sigma.WhiteBalance", + "Exif.Nikon1.WhiteBalance", + "Exif.Nikon2.WhiteBalance", + "Exif.Nikon3.WhiteBalance", + "Exif.Olympus.WhiteBalance", + "Exif.OlympusCs.WhiteBalance", + "Exif.Panasonic.WhiteBalance", + "Exif.MinoltaCs5D.WhiteBalance", + "Exif.MinoltaCs7D.WhiteBalance", + "Exif.MinoltaCsNew.WhiteBalance", + "Exif.MinoltaCsOld.WhiteBalance", + "Exif.Photo.WhiteBalance" + }; + return findMetadatum(ed, keys, EXV_COUNTOF(keys)); + } + + ExifData::const_iterator lensName(const ExifData& ed) + { + static const char* keys[] = { + "Exif.CanonCs.LensType", + "Exif.Nikon3.LensData", + "Exif.Minolta.LensID", + "Exif.Pentax.LensType" + }; + return findMetadatum(ed, keys, EXV_COUNTOF(keys)); + } + +} // namespace Exiv2 diff --git a/src/easyaccess.hpp b/src/easyaccess.hpp new file mode 100644 index 00000000..22ced470 --- /dev/null +++ b/src/easyaccess.hpp @@ -0,0 +1,62 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2004-2009 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., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. + */ +/*! + @file easyaccess.hpp + @brief Provides easy (high-level) access to some Exif meta data. + @version $Rev$ + @author Carsten Pfeiffer + @date 28-Feb-09, gis: created + */ +#ifndef EASYACCESS_HPP_ +#define EASYACCESS_HPP_ + +// ***************************************************************************** +// included header files +#include "exif.hpp" + +namespace Exiv2 { + +// ***************************************************************************** +// class declarations + class ExifData; + + //! Return the orientation of the image + EXIV2API ExifData::const_iterator orientation(const ExifData& ed); + //! Return the ISO speed used to shoot the image + EXIV2API ExifData::const_iterator isoSpeed(const ExifData& ed); + //! Return the flash bias value + EXIV2API ExifData::const_iterator flashBias(const ExifData& ed); + //! Return the exposure mode setting + EXIV2API ExifData::const_iterator exposureMode(const ExifData& ed); + //! Return the scene mode setting + EXIV2API ExifData::const_iterator sceneMode(const ExifData& ed); + //! Return the macro mode setting + EXIV2API ExifData::const_iterator macroMode(const ExifData& ed); + //! Return the image quality setting + EXIV2API ExifData::const_iterator imageQuality(const ExifData& ed); + //! Return the white balance setting + EXIV2API ExifData::const_iterator whiteBalance(const ExifData& ed); + //! Return the name of the lens used + EXIV2API ExifData::const_iterator lensName(const ExifData& ed); + +} // namespace Exiv2 + +#endif // EASYACCESS_HPP_