diff --git a/samples/Makefile b/samples/Makefile index b36b2c10..58c6a495 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -55,6 +55,7 @@ include $(top_srcdir)/config/config.mk # Add source files of sample programs to this list BINSRC = addmoddel.cpp \ + convert-test.cpp \ crwedit.cpp \ crwparse.cpp \ dataarea-test.cpp \ diff --git a/samples/convert-test.cpp b/samples/convert-test.cpp new file mode 100644 index 00000000..75143069 --- /dev/null +++ b/samples/convert-test.cpp @@ -0,0 +1,37 @@ +// ***************************************************************** -*- C++ -*- +// convert-test.cpp, $Rev$ +// Conversion test driver - make sure you have a copy of the input file around! + +#include +#include +#include +#include +#include + +int main(int argc, char* const 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::XmpData xmpData; + Exiv2::copyExifToXmp(image->exifData(), xmpData); + + Exiv2::ExifData exifData; + Exiv2::copyXmpToExif(xmpData, exifData); + + image->setXmpData(xmpData); + image->setExifData(exifData); + image->writeMetadata(); + + return 0; +} +catch (Exiv2::AnyError& e) { + std::cout << "Caught Exiv2 exception '" << e << "'\n"; + return -1; +} diff --git a/src/Makefile b/src/Makefile index 68370e62..fa6d928d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -69,6 +69,7 @@ CCHDR = exv_conf.h \ # Add library C++ source files to this list CCSRC = basicio.cpp \ canonmn.cpp \ + convert.cpp \ cr2image.cpp \ crwimage.cpp \ datasets.cpp \ diff --git a/src/convert.cpp b/src/convert.cpp new file mode 100644 index 00000000..1d6ab508 --- /dev/null +++ b/src/convert.cpp @@ -0,0 +1,235 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2004-2008 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: convert.cpp + Version: $Rev$ + Author(s): Andreas Huggel (ahu) + History: 17-Mar-07, ahu: created + */ +// ***************************************************************************** +#include "rcsid.hpp" +EXIV2_RCSID("@(#) $Id$") + +// ***************************************************************************** +// included header files +#include "types.hpp" +#include "exif.hpp" +#include "iptc.hpp" +#include "xmp.hpp" +#include "convert.hpp" + +// + standard includes + +// ***************************************************************************** +namespace { + +} + +// ***************************************************************************** +// class member definitions +namespace Exiv2 { + + //! Metadata conversions. + class Converter { + public: + /*! + @brief Type for metadata converter functions, taking two key strings, + \em from and \em to. + + These functions have access to both the source and destination metadata + containers and store the result directly in the destination container. + */ + typedef void (Converter::*ConvertFct)(const char* from, const char* to); + //! Structure to define conversions between two keys. + struct Conversion { + MetadataId metadataId; //!< Type of metadata for the first key. + const char* key1; //!< First metadata key. + const char* key2; //!< Second metadata key (always an XMP key for now). + ConvertFct key1ToKey2; //!< Conversion from first to second key. + ConvertFct key2ToKey1; //!< Conversion from second to first key. + }; + public: + //! @name Creators + //@{ + //! Constructor for Exif tags and XMP properties. + Converter(ExifData& exifData, XmpData& xmpData); + //@} + //! @name Manipulators + //@{ + //! Convert Exif tags to XMP properties according to the conversion table. + void cnvExifToXmp(); + //! Convert XMP properties to Exif tags according to the conversion table. + void cnvXmpToExif(); + /*! + @brief Set the erase flag. + + This flag indicates whether successfully converted source records are erased. + */ + void setErase(bool onoff =true) { erase_ = onoff; } + //@} + //! @name Conversion functions (manipulators) + //@{ + /*! + @brief Simple Exif to XMP conversion function. + + Sets the XMP property to an XmpText value containing the Exif value string. + */ + void cnvExifValue(const char* from, const char* to); + /*! + @brief Simple XMP to Exif conversion function. + + Sets the Exif tag according to the XMP property. + */ + void cnvXmpValue(const char* from, const char* to); + //@} + //! @name Accessors + //@{ + //! Get the value of the erase flag, see also setErase(bool on). + bool erase() const { return erase_; } + //@} + private: + // DATA + static const Conversion conversion_[]; //value().toString(); + if (!pos->value().ok()) { +#ifndef SUPPRESS_WARNINGS + std::cerr << "Warning: Failed to convert " << from << " to " << to << "\n"; +#endif + return; + } + xmpData_[to] = value; + if (erase_) exifData_.erase(pos); + } + + void Converter::cnvXmpValue(const char* from, const char* to) + { + Exiv2::XmpData::iterator pos = xmpData_.findKey(XmpKey(from)); + if (pos == xmpData_.end()) return; + std::string value = pos->value().toString(); + if (!pos->value().ok()) { +#ifndef SUPPRESS_WARNINGS + std::cerr << "Warning: Failed to convert " << from << " to " << to << "\n"; +#endif + return; + } + exifData_[to] = value; + if (erase_) xmpData_.erase(pos); + } + + // ************************************************************************* + // free functions + void copyExifToXmp(const ExifData& exifData, XmpData& xmpData) + { + Converter converter(const_cast(exifData), xmpData); + converter.cnvExifToXmp(); + } + + void moveExifToXmp(ExifData& exifData, XmpData& xmpData) + { + Converter converter(const_cast(exifData), xmpData); + converter.setErase(); + converter.cnvExifToXmp(); + } + + void copyXmpToExif(const XmpData& xmpData, ExifData& exifData) + { + Converter converter(exifData, const_cast(xmpData)); + converter.cnvXmpToExif(); + } + + void moveXmpToExif(XmpData& xmpData, ExifData& exifData) + { + Converter converter(exifData, const_cast(xmpData)); + converter.setErase(); + converter.cnvXmpToExif(); + } + + void copyIptcToXmp(const IptcData& iptcData, XmpData& xmpData) + { + // Todo: implement me! + } + + void moveIptcToXmp(IptcData& iptcData, XmpData& xmpData) + { + // Todo: implement me! + } + + void copyXmpToIptc(const XmpData& xmpData, IptcData& iptcData) + { + // Todo: implement me! + } + + void moveXmpToIptc(XmpData& xmpData, IptcData& iptcData) + { + // Todo: implement me! + } + +} // namespace Exiv2 + +// ***************************************************************************** +// local definitions +namespace { + + +} diff --git a/src/convert.hpp b/src/convert.hpp new file mode 100644 index 00000000..b0264199 --- /dev/null +++ b/src/convert.hpp @@ -0,0 +1,72 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (C) 2004-2008 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 convert.hpp + @brief Exif and IPTC conversions to and from XMP + @version $Rev$ + @author Andreas Huggel (ahu) + ahuggel@gmx.net + @date 17-Mar-08, ahu: created + */ +#ifndef CONVERT_HPP_ +#define CONVERT_HPP_ + +// ***************************************************************************** +// included header files + +// + standard includes + +// ***************************************************************************** +// namespace extensions +namespace Exiv2 { + +// ***************************************************************************** +// class declarations + class ExifData; + class IptcData; + class XmpData; + +// ***************************************************************************** +// free functions, template and inline definitions + + //! Convert (copy) Exif tags to XMP properties. + void copyExifToXmp(const ExifData& exifData, XmpData& xmpData); + //! Convert (move) Exif tags to XMP properties, remove converted properties. + void moveExifToXmp(ExifData& exifData, XmpData& xmpData); + + //! Convert (copy) XMP properties to Exif tags. + void copyXmpToExif(const XmpData& xmpData, ExifData& exifData); + //! Convert (move) XMP properties to Exif tags, remove converted properties. + void moveXmpToExif(XmpData& xmpData, ExifData& exifData); + + //! Convert (copy) IPTC datasets to XMP properties. + void copyIptcToXmp(const IptcData& iptcData, XmpData& xmpData); + //! Convert (move) IPTC datasets to XMP properties, remove converted properties. + void moveIptcToXmp(IptcData& iptcData, XmpData& xmpData); + + //! Convert (copy) XMP properties to IPTC datasets. + void copyXmpToIptc(const XmpData& xmpData, IptcData& iptcData); + //! Convert (move) XMP properties to IPTC tags, remove converted properties. + void moveXmpToIptc(XmpData& xmpData, IptcData& iptcData); + +} // namespace Exiv2 + +#endif // #ifndef CONVERT_HPP_