#include <exiv2/xmp.hpp>
#include <exiv2/error.hpp>
#include <string>
#include <iostream>
#include <iomanip>
#include <cassert>
#include <cmath>
bool isEqual(float a, float b)
{
double d = std::fabs(a - b);
return d < 0.00001;
}
int main()
try {
Exiv2::XmpData xmpData;
xmpData["Xmp.dc.source"] = "xmpsample.cpp";
xmpData["Xmp.dc.subject"] = "Palmtree";
xmpData["Xmp.dc.subject"] = "Rubbertree";
xmpData["Xmp.dc.title"] = "lang=de-DE Sonnenuntergang am Strand";
xmpData["Xmp.dc.title"] = "lang=en-US Sunset on the beach";
xmpData["Xmp.dc.one"] = -1;
xmpData["Xmp.dc.two"] = 3.1415;
xmpData["Xmp.dc.three"] = Exiv2::Rational(5, 7);
xmpData["Xmp.dc.four"] = uint16_t(255);
xmpData["Xmp.dc.five"] = int32_t(256);
xmpData["Xmp.dc.six"] = false;
Exiv2::XmpTextValue val("Seven");
xmpData["Xmp.dc.seven"] = val;
xmpData["Xmp.dc.eight"] = true;
assert(xmpData["Xmp.dc.one"].toLong() == -1);
assert(xmpData["Xmp.dc.one"].value().ok());
const Exiv2::Value &getv1 = xmpData["Xmp.dc.one"].value();
assert(isEqual(getv1.toFloat(), -1));
assert(getv1.ok());
assert(getv1.toRational() == Exiv2::Rational(-1, 1));
assert(getv1.ok());
const Exiv2::Value &getv2 = xmpData["Xmp.dc.two"].value();
assert(isEqual(getv2.toFloat(), 3.1415f));
assert(getv2.ok());
assert(getv2.toLong() == 3);
assert(getv2.ok());
Exiv2::Rational R = getv2.toRational();
assert(getv2.ok());
assert(isEqual(static_cast<float>(R.first) / R.second, 3.1415f ));
const Exiv2::Value &getv3 = xmpData["Xmp.dc.three"].value();
assert(isEqual(getv3.toFloat(), 5.0f/7.0f));
assert(getv3.ok());
assert(getv3.toLong() == 0);
assert(getv3.ok());
assert(getv3.toRational() == Exiv2::Rational(5, 7));
assert(getv3.ok());
const Exiv2::Value &getv6 = xmpData["Xmp.dc.six"].value();
assert(getv6.toLong() == 0);
assert(getv6.ok());
assert(getv6.toFloat() == 0.0);
assert(getv6.ok());
assert(getv6.toRational() == Exiv2::Rational(0, 1));
assert(getv6.ok());
const Exiv2::Value &getv7 = xmpData["Xmp.dc.seven"].value();
getv7.toLong();
assert(!getv7.ok());
const Exiv2::Value &getv8 = xmpData["Xmp.dc.eight"].value();
assert(getv8.toLong() == 1);
assert(getv8.ok());
assert(getv8.toFloat() == 1.0);
assert(getv8.ok());
assert(getv8.toRational() == Exiv2::Rational(1, 1));
assert(getv8.ok());
Exiv2::XmpData::iterator pos = xmpData.findKey(Exiv2::XmpKey("Xmp.dc.eight"));
if (pos == xmpData.end()) throw Exiv2::Error(1, "Key not found");
xmpData.erase(pos);
Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::xmpText);
v->read("image/jpeg");
xmpData.add(Exiv2::XmpKey("Xmp.dc.format"), v.get());
v = Exiv2::Value::create(Exiv2::xmpSeq);
v->read("1) The first creator");
v->read("2) The second creator");
v->read("3) And another one");
xmpData.add(Exiv2::XmpKey("Xmp.dc.creator"), v.get());
v = Exiv2::Value::create(Exiv2::langAlt);
v->read("lang=de-DE Hallo, Welt");
v->read("Hello, World");
xmpData.add(Exiv2::XmpKey("Xmp.dc.description"), v.get());
xmpData["Xmp.tiff.ImageDescription"] = "TIFF image description";
xmpData["Xmp.tiff.ImageDescription"] = "lang=de-DE TIFF Bildbeschreibung";
Exiv2::XmpProperties::registerNs("myNamespace/", "ns");
xmpData["Xmp.ns.myProperty"] = "myValue";
Exiv2::XmpTextValue tv("16");
xmpData.add(Exiv2::XmpKey("Xmp.xmpDM.videoFrameSize/stDim:w"), &tv);
tv.read("9");
xmpData.add(Exiv2::XmpKey("Xmp.xmpDM.videoFrameSize/stDim:h"), &tv);
tv.read("inch");
xmpData.add(Exiv2::XmpKey("Xmp.xmpDM.videoFrameSize/stDim:unit"), &tv);
xmpData["Xmp.dc.publisher"] = "James Bond";
xmpData["Xmp.dc.publisher[1]/?ns:role"] = "secret agent";
tv.read("programmer");
xmpData.add(Exiv2::XmpKey("Xmp.dc.creator[2]/?ns:role"), &tv);
tv.read("");
tv.setXmpArrayType(Exiv2::XmpValue::xaBag);
xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef"), &tv);
tv.setXmpArrayType(Exiv2::XmpValue::xaNone);
tv.read("Birthday party");
xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[1]/stJob:name"), &tv);
tv.read("Photographer");
xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[1]/stJob:role"), &tv);
tv.read("Wedding ceremony");
xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[2]/stJob:name"), &tv);
tv.read("Best man");
xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[2]/stJob:role"), &tv);
for (Exiv2::XmpData::const_iterator md = xmpData.begin();
md != xmpData.end(); ++md) {
std::cout << std::setfill(' ') << std::left
<< std::setw(44)
<< md->key() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< md->typeName() << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< md->count() << " "
<< std::dec << md->value()
<< std::endl;
}
std::string xmpPacket;
if (0 != Exiv2::XmpParser::encode(xmpPacket, xmpData)) {
throw Exiv2::Error(1, "Failed to serialize XMP data");
}
std::cout << xmpPacket << "\n";
Exiv2::XmpParser::terminate();
return 0;
}
catch (Exiv2::AnyError& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}