You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
7.8 KiB
C++
236 lines
7.8 KiB
C++
18 years ago
|
// ***************************************************************** -*- C++ -*-
|
||
|
/*
|
||
|
* Copyright (C) 2004-2008 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., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||
|
*/
|
||
|
/*
|
||
|
File: convert.cpp
|
||
|
Version: $Rev$
|
||
|
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||
|
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_[]; //<! Conversion rules
|
||
|
bool erase_;
|
||
|
ExifData& exifData_; // use pointers?
|
||
|
XmpData& xmpData_;
|
||
|
|
||
|
}; // class Converter
|
||
|
|
||
|
const Converter::Conversion Converter::conversion_[] = {
|
||
|
{ mdExif, "Exif.Image.ImageWidth", "Xmp.tiff.ImageWidth", &Converter::cnvExifValue, &Converter::cnvXmpValue },
|
||
|
{ mdExif, "Exif.Image.ImageLength", "Xmp.tiff.ImageLength", &Converter::cnvExifValue, &Converter::cnvXmpValue },
|
||
|
{ mdExif, "Exif.Image.BitsPerSample", "Xmp.tiff.BitsPerSample", &Converter::cnvExifValue, &Converter::cnvXmpValue },
|
||
|
{ mdExif, "Exif.Image.Compression", "Xmp.tiff.Compression", &Converter::cnvExifValue, &Converter::cnvXmpValue }
|
||
|
// ...
|
||
|
};
|
||
|
|
||
|
Converter::Converter(ExifData& exifData, XmpData& xmpData)
|
||
|
: erase_(false), exifData_(exifData), xmpData_(xmpData)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void Converter::cnvExifToXmp()
|
||
|
{
|
||
|
for (unsigned int i = 0; i < EXV_COUNTOF(conversion_); ++i) {
|
||
|
const Conversion& c = conversion_[i];
|
||
|
if (c.metadataId == mdExif) {
|
||
|
EXV_CALL_MEMBER_FN(*this, c.key1ToKey2)(c.key1, c.key2);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Converter::cnvXmpToExif()
|
||
|
{
|
||
|
for (unsigned int i = 0; i < EXV_COUNTOF(conversion_); ++i) {
|
||
|
const Conversion& c = conversion_[i];
|
||
|
if (c.metadataId == mdExif) {
|
||
|
EXV_CALL_MEMBER_FN(*this, c.key2ToKey1)(c.key2, c.key1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Converter::cnvExifValue(const char* from, const char* to)
|
||
|
{
|
||
|
Exiv2::ExifData::iterator pos = exifData_.findKey(ExifKey(from));
|
||
|
if (pos == exifData_.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;
|
||
|
}
|
||
|
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&>(exifData), xmpData);
|
||
|
converter.cnvExifToXmp();
|
||
|
}
|
||
|
|
||
|
void moveExifToXmp(ExifData& exifData, XmpData& xmpData)
|
||
|
{
|
||
|
Converter converter(const_cast<ExifData&>(exifData), xmpData);
|
||
|
converter.setErase();
|
||
|
converter.cnvExifToXmp();
|
||
|
}
|
||
|
|
||
|
void copyXmpToExif(const XmpData& xmpData, ExifData& exifData)
|
||
|
{
|
||
|
Converter converter(exifData, const_cast<XmpData&>(xmpData));
|
||
|
converter.cnvXmpToExif();
|
||
|
}
|
||
|
|
||
|
void moveXmpToExif(XmpData& xmpData, ExifData& exifData)
|
||
|
{
|
||
|
Converter converter(exifData, const_cast<XmpData&>(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 {
|
||
|
|
||
|
|
||
|
}
|