[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a
Maximiliano Curia
maxy at moszumanska.debian.org
Thu Jul 13 17:38:45 UTC 2017
Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=16c95f0
The following commit has been merged in the master branch:
commit 16c95f0fab5efe24f428bbc0a1a32cff394b92aa
Author: Andreas Huggel <ahuggel at gmx.net>
Date: Sun Sep 23 16:15:49 2007 +0000
Extended xmpsample.cpp, related bugfixes and tweaks.
---
README-XMP | 27 +++++++-------
src/doxygen.hpp.in | 4 +++
src/error.cpp | 5 ++-
src/properties.cpp | 22 ++++++------
src/properties.hpp | 27 ++++++--------
src/value.hpp | 2 +-
src/xmp.cpp | 26 +++++++++-----
src/xmp.hpp | 16 +++++++--
src/xmpsample.cpp | 75 ++++++++++++++++++++++++++++++++-------
test/data/xmpparser-test.out | 84 ++++++++++++++++++++++++++++++++++++++++++++
test/xmpparser-test.sh | 4 +++
11 files changed, 224 insertions(+), 68 deletions(-)
diff --git a/README-XMP b/README-XMP
index 6496832..9abb5cb 100644
--- a/README-XMP
+++ b/README-XMP
@@ -6,17 +6,6 @@ Exif and IPTC classes. The property-repository is XmpProperties.
In addition to the expected new members, class Image also
has a new interface to access the raw XMP packet.
-Todo: XMP support is controlled with the ENABLE_XMP directive
-in config/config.mk.in. This will be a configure option
-eventually. For now, comment the line "ENABLE_XMP = 1" either
-in config.mk.in before running ./configure or in config.mk to
-build without XMP support.
-
-Exiv2 uses the Adobe XMP toolkit (XMP SDK) to parse
-and serialize XMP packets (only the XMPCore component).
-
-Supported XMP value types
--------------------------
All XMP value types are supported: Simple types, structures,
arrays, property qualifiers and language alternatives.
@@ -35,16 +24,28 @@ namespaces can be registered.
The specialized Exiv2 values XmpArrayValue and LangAltValue are
provided to simplify the use of XMP properties.
+See xmpsample.cpp for examples of how to set various types of
+XMP properties.
+
Note: Unlike Exif and IPTC tags, XMP properties do not have
a tag number.
Todo: Conversion between XMP and Exif/IPTC metadata.
-XMP toolkit installation
+Todo: XMP support is controlled with the ENABLE_XMP directive
+in config/config.mk.in. This will be a configure option
+eventually. For now, comment the line "ENABLE_XMP = 1" either
+in config.mk.in before running ./configure or in config.mk to
+build without XMP support.
+
+Exiv2 uses the Adobe XMP Toolkit (XMP SDK) to parse
+and serialize XMP packets (only the XMPCore component).
+
+XMP Toolkit installation
========================
This is what worked for me on a Debian GNU/Linux (testing)
system. Your mileage may vary. Please check with Adobe if
-you encounter problems with the XMP toolkit installation.
+you encounter problems with the XMP Toolkit installation.
Installation directory
----------------------
diff --git a/src/doxygen.hpp.in b/src/doxygen.hpp.in
index bacadeb..e3c97e7 100644
--- a/src/doxygen.hpp.in
+++ b/src/doxygen.hpp.in
@@ -133,3 +133,7 @@ bug tracking system</a>.</p>
@example iptceasy.cpp
The quickest way to access, set or modify IPTC metadata
*/
+/*!
+ @example xmpsample.cpp
+ Sample usage of high-level XMP classes.
+ */
diff --git a/src/error.cpp b/src/error.cpp
index a6b701c..83d7d21 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -78,9 +78,9 @@ namespace Exiv2 {
ErrMsg( 33, N_("This does not look like a CRW image")),
ErrMsg( 34, N_("%1: Not supported")), // %1=function
ErrMsg( 35, N_("No namespace info available for XMP prefix `%1'")), // %1=prefix
- ErrMsg( 36, N_("No XMP property list for prefix `%1'")), // %1=prefix
+ ErrMsg( 36, N_("No prefix registered for namespace `%1'")), // %1=namespace
ErrMsg( 37, N_("Size of %1 JPEG segment is larger than 65535 bytes")), // %1=type of metadata (Exif, IPTC, JPEG comment)
- ErrMsg( 38, N_("Unknown XMP property `%1:%2'")), // %1=prefix, %2=property name
+ ErrMsg( 38, N_("Unhandled Xmpdatum %1 of type %2")), // %1=key, %2=value type
ErrMsg( 39, N_("Unhandled XMP node %1 with opt=%2")), // %1=key, %2=XMP Toolkit option flags
ErrMsg( 40, N_("XMP Toolkit error %1: %2")), // %1=XMP_Error::GetID(), %2=XMP_Error::GetErrMsg()
ErrMsg( 41, N_("Failed to decode Lang Alt property %1 with opt=%2")), // %1=property path, %3=XMP Toolkit option flags
@@ -89,7 +89,6 @@ namespace Exiv2 {
ErrMsg( 44, N_("Failed to determine property name from path %1, namespace %2")), // %1=property path, %2=namespace
ErrMsg( 45, N_("Schema namespace %1 is not registered with the XMP Toolkit")), // %1=namespace
ErrMsg( 46, N_("No namespace registered for prefix `%1'")), // %1=prefix
- ErrMsg( 47, N_("No prefix registered for namespace `%1'")), // %1=namespace
// Last error message (message is not used)
ErrMsg( -2, N_("(Unknown Error)"))
diff --git a/src/properties.cpp b/src/properties.cpp
index e16bd77..424ad67 100644
--- a/src/properties.cpp
+++ b/src/properties.cpp
@@ -37,6 +37,7 @@ EXIV2_RCSID("@(#) $Id$")
#include "value.hpp"
#include "metadatum.hpp"
#include "i18n.h" // NLS support.
+#include "xmp.hpp"
#include <iostream>
#include <iomanip>
@@ -793,8 +794,10 @@ namespace Exiv2 {
const std::string& prefix)
{
std::string ns2 = ns;
- if (ns2.substr(ns2.size() - 1, 1) != "/") ns2 += "/";
+ if ( ns2.substr(ns2.size() - 1, 1) != "/"
+ && ns2.substr(ns2.size() - 1, 1) != "#") ns2 += "/";
nsRegistry_[ns2] = prefix;
+ XmpParser::registerNs(ns2, prefix);
}
std::string XmpProperties::prefix(const std::string& ns)
@@ -827,28 +830,26 @@ namespace Exiv2 {
const char* XmpProperties::propertyTitle(const XmpKey& key)
{
- return propertyInfo(key)->title_;
+ const XmpPropertyInfo* pi = propertyInfo(key);
+ return pi ? pi->title_ : 0;
}
const char* XmpProperties::propertyDesc(const XmpKey& key)
{
- return propertyInfo(key)->desc_;
+ const XmpPropertyInfo* pi = propertyInfo(key);
+ return pi ? pi->desc_ : 0;
}
TypeId XmpProperties::propertyType(const XmpKey& key)
{
- const XmpPropertyInfo* pi = propertyInfo(key, false);
+ const XmpPropertyInfo* pi = propertyInfo(key);
return pi ? pi->typeId_ : xmpText;
}
- const XmpPropertyInfo* XmpProperties::propertyInfo(const XmpKey& key,
- bool doThrow)
+ const XmpPropertyInfo* XmpProperties::propertyInfo(const XmpKey& key)
{
const XmpPropertyInfo* pl = propertyList(key.groupName());
- if (!pl) {
- if (doThrow) throw Error(36, key.groupName());
- else return 0;
- }
+ if (!pl) return 0;
const XmpPropertyInfo* pi = 0;
for (int i = 0; pl[i].name_ != 0; ++i) {
if (std::string(pl[i].name_) == key.tagName()) {
@@ -856,7 +857,6 @@ namespace Exiv2 {
break;
}
}
- if (!pi && doThrow) throw Error(38, key.groupName(), key.tagName());
return pi;
}
diff --git a/src/properties.hpp b/src/properties.hpp
index 1260fbd..ba533ec 100644
--- a/src/properties.hpp
+++ b/src/properties.hpp
@@ -108,15 +108,15 @@ namespace Exiv2 {
/*!
@brief Return the title (label) of the property.
@param key The property key
- @return The title (label) of the property
- @throw Error if the key is invalid.
+ @return The title (label) of the property, 0 if the
+ key is of an unknown property.
*/
static const char* propertyTitle(const XmpKey& key);
/*!
@brief Return the description of the property.
@param key The property key
- @return The description of the property
- @throw Error if the key is invalid.
+ @return The description of the property, 0 if the
+ key is of an unknown property.
*/
static const char* propertyDesc(const XmpKey& key);
/*!
@@ -128,21 +128,16 @@ namespace Exiv2 {
static TypeId propertyType(const XmpKey& key);
/*!
@brief Return information for the property for key.
- Always returns a valid pointer.
@param key The property key
- @param doThrow Flag indicating whether to throw an Error or
- return 0 if the key is not valid or unknown.
- @return a pointer to the property information
- @throw Error if the key is unknown and the \em doThrow
- flag is true.
+ @return A pointer to the property information, 0 if the
+ key is of an unknown property.
*/
- static const XmpPropertyInfo* propertyInfo(const XmpKey& key,
- bool doThrow =true);
+ static const XmpPropertyInfo* propertyInfo(const XmpKey& key);
/*!
@brief Return the namespace name for the schema associated
with \em prefix.
@param prefix Prefix
- @return the namespace name
+ @return The namespace name
@throw Error if no namespace is registered with \em prefix.
*/
static std::string ns(const std::string& prefix);
@@ -150,7 +145,7 @@ namespace Exiv2 {
@brief Return the namespace description for the schema associated
with \em prefix.
@param prefix Prefix
- @return the namespace description
+ @return The namespace description
@throw Error if no namespace is registered with \em prefix.
*/
static const char* nsDesc(const std::string& prefix);
@@ -166,14 +161,14 @@ namespace Exiv2 {
@brief Return information about a schema namespace for \em prefix.
Always returns a valid pointer.
@param prefix The prefix
- @return a pointer to the related information
+ @return A pointer to the related information
@throw Error if no namespace is registered with \em prefix.
*/
static const XmpNsInfo* nsInfo(const std::string& prefix);
/*!
@brief Return the (preferred) prefix for schema namespace \em ns.
@param ns Schema namespace
- @return the prefix or an empty string if namespace \em ns is not
+ @return The prefix or an empty string if namespace \em ns is not
registered.
*/
static std::string prefix(const std::string& ns);
diff --git a/src/value.hpp b/src/value.hpp
index e4db4aa..70e0d02 100644
--- a/src/value.hpp
+++ b/src/value.hpp
@@ -652,7 +652,7 @@ namespace Exiv2 {
//! Set the XMP array type to indicate that an XMP value is an array.
void setXmpArrayType(XmpArrayType xmpArrayType);
//! Set the XMP struct type to indicate that an XMP value is a structure.
- void setXmpStruct(XmpStruct xmpStruct);
+ void setXmpStruct(XmpStruct xmpStruct =xsStruct);
/*!
@brief Read the value from a character buffer.
diff --git a/src/xmp.cpp b/src/xmp.cpp
index bfa7dfc..9242755 100644
--- a/src/xmp.cpp
+++ b/src/xmp.cpp
@@ -387,6 +387,17 @@ namespace Exiv2 {
}
}
+ bool XmpParser::registerNs(const std::string& ns,
+ const std::string& prefix)
+ {
+ initialize();
+#ifdef EXV_HAVE_XMP_TOOLKIT
+ return SXMPMeta::RegisterNamespace(ns.c_str(), prefix.c_str(), 0);
+#else
+ return true;
+#endif
+ }
+
#ifdef EXV_HAVE_XMP_TOOLKIT
int XmpParser::decode( XmpData& xmpData,
const std::string& xmpPacket)
@@ -549,15 +560,8 @@ namespace Exiv2 {
}
SXMPMeta meta;
-
for (XmpData::const_iterator i = xmpData.begin(); i != xmpData.end(); ++i) {
-
- std::string ns = XmpProperties::ns(i->groupName());
-
- // Todo: Make sure the namespace is registered with XMP-SDK
-
- // Todo: What about structure namespaces?
-
+ const std::string ns = XmpProperties::ns(i->groupName());
XMP_OptionBits options = 0;
if (i->typeId() == langAlt) {
@@ -605,6 +609,7 @@ namespace Exiv2 {
#endif
meta.SetProperty(ns.c_str(), item.c_str(), i->toString(idx).c_str());
}
+ continue;
}
if (i->typeId() == xmpText) {
if (i->count() == 0) {
@@ -619,7 +624,10 @@ namespace Exiv2 {
#endif
meta.SetProperty(ns.c_str(), i->tagName().c_str(), i->toString(0).c_str(), options);
}
+ continue;
}
+ // Don't let any Xmpdatum go by unnoticed
+ throw Error(38, i->tagName(), TypeInfo::typeName(i->typeId()));
}
meta.SerializeToBuffer(&xmpPacket, kXMP_UseCompactFormat);
@@ -771,7 +779,7 @@ namespace {
property = propPath.substr(idx + 1);
std::string prefix = Exiv2::XmpProperties::prefix(schemaNs);
if (prefix.empty()) {
- throw Exiv2::Error(47, propPath, schemaNs);
+ throw Exiv2::Error(36, propPath, schemaNs);
}
return Exiv2::XmpKey::AutoPtr(new Exiv2::XmpKey(prefix, property));
} // makeXmpKey
diff --git a/src/xmp.hpp b/src/xmp.hpp
index bc9e498..b61aece 100644
--- a/src/xmp.hpp
+++ b/src/xmp.hpp
@@ -32,9 +32,9 @@
// *****************************************************************************
// included header files
#include "metadatum.hpp"
-#include "types.hpp"
-#include "value.hpp"
#include "properties.hpp"
+#include "value.hpp"
+#include "types.hpp"
// + standard includes
#include <string>
@@ -245,6 +245,7 @@ namespace Exiv2 {
the XMP toolkit to do the job.
*/
class XmpParser {
+ friend void XmpProperties::registerNs(const std::string&, const std::string&);
public:
/*!
@brief Decode XMP metadata from an XMP packet \em xmpPacket into
@@ -295,6 +296,17 @@ namespace Exiv2 {
static void terminate();
private:
+ /*!
+ @brief Register a namespace with the XMP Toolkit.
+
+ XmpProperties::registerNs calls this to synchronize namespaces.
+
+ @return \em true if the registered prefix matches the suggested prefix.
+ */
+ static bool registerNs(const std::string& ns,
+ const std::string& prefix);
+
+ // DATA
static bool initialized_; //! Indicates if the XMP Toolkit has been initialized
}; // class XmpParser
diff --git a/src/xmpsample.cpp b/src/xmpsample.cpp
index 4dc1adf..7e193be 100644
--- a/src/xmpsample.cpp
+++ b/src/xmpsample.cpp
@@ -1,8 +1,7 @@
// ***************************************************************** -*- C++ -*-
// xmpsample.cpp, $Rev$
-// Sample/test for high level XMP classes
+// Sample/test for high level XMP classes. See also addmoddel.cpp
-#include "value.hpp"
#include "xmp.hpp"
#include "error.hpp"
@@ -10,31 +9,79 @@
#include <iostream>
#include <iomanip>
-using namespace Exiv2;
-
int main()
try {
// The XMP property container
Exiv2::XmpData xmpData;
+ // -------------------------------------------------------------------------
+ // Exiv2 has specialized values for simple XMP properties, arrays of simple
+ // properties and language alternatives.
+
// Add a simple XMP property in a known namespace
- Exiv2::Value::AutoPtr v = Exiv2::Value::create(xmpText);
+ Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::xmpText);
v->read("image/jpeg");
xmpData.add(Exiv2::XmpKey("Xmp.dc.format"), v.get());
- // Add an ordered array of text values
- v = Exiv2::Value::create(xmpSeq);
- v->read("1) The first creator"); // the sequence in which the array elements
- v->read("2) The second creator"); // are added is relevant
- v->read("3) And another one");
+ // Add an ordered array of text values.
+ v = Exiv2::Value::create(Exiv2::xmpSeq); // or xmpBag or xmpAlt.
+ v->read("1) The first creator"); // The sequence in which the array
+ v->read("2) The second creator"); // elements are added is their
+ v->read("3) And another one"); // order in the array.
xmpData.add(Exiv2::XmpKey("Xmp.dc.creator"), v.get());
// Add a language alternative property
- v = Exiv2::Value::create(langAlt);
- v->read("lang=de-DE Hallo, Welt"); // the default doesn't need a qualifier
- v->read("Hello, World"); // and it will become the first element
+ v = Exiv2::Value::create(Exiv2::langAlt);
+ v->read("lang=de-DE Hallo, Welt"); // The default doesn't need a
+ v->read("Hello, World"); // qualifier
xmpData.add(Exiv2::XmpKey("Xmp.dc.description"), v.get());
+ // -------------------------------------------------------------------------
+ // Register a namespace which Exiv2 doesn't know yet. This is only needed
+ // when properties are added manually. If the XMP metadata is read from an
+ // image, namespaces are decoded and registered at the same time.
+ Exiv2::XmpProperties::registerNs("myNamespace/", "ns");
+
+ // -------------------------------------------------------------------------
+ // There are no specialized values for structures, qualifiers and nested
+ // types. However, these can be added by using a XmpTextValue and a path as
+ // the key.
+
+ // Add a structure
+ 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);
+
+ // Add an element with a qualifier (using the namespace registered earlier)
+ tv.read("James Bond");
+ xmpData.add(Exiv2::XmpKey("Xmp.dc.publisher"), &tv);
+ tv.read("secret agent");
+ xmpData.add(Exiv2::XmpKey("Xmp.dc.publisher/?ns:role"), &tv);
+
+ // Add a qualifer to an array element of Xmp.dc.creator (added above)
+ tv.read("programmer");
+ xmpData.add(Exiv2::XmpKey("Xmp.dc.creator[2]/?ns:role"), &tv);
+
+ // Add an array of structures
+ tv.read("");
+ tv.setXmpArrayType(Exiv2::XmpValue::xaBag);
+ xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef"), &tv); // Set the array type.
+ tv.setXmpArrayType(Exiv2::XmpValue::xaNone);
+
+ tv.read("Birtday 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);
+
+ // -------------------------------------------------------------------------
// Output XMP properties
for (Exiv2::XmpData::const_iterator md = xmpData.begin();
md != xmpData.end(); ++md) {
@@ -50,6 +97,7 @@ try {
<< std::endl;
}
+ // -------------------------------------------------------------------------
// Serialize the XMP data and output the XMP packet
std::string xmpPacket;
if (0 != Exiv2::XmpParser::encode(xmpPacket, xmpData)) {
@@ -59,6 +107,7 @@ try {
// Cleanup
Exiv2::XmpParser::terminate();
+
return 0;
}
catch (Exiv2::AnyError& e) {
diff --git a/test/data/xmpparser-test.out b/test/data/xmpparser-test.out
index 330b9a0..dc84e59 100644
--- a/test/data/xmpparser-test.out
+++ b/test/data/xmpparser-test.out
@@ -279,3 +279,87 @@ Xmp.ns1.NestedStructProp/ns2:Outer/ns2:Middle/ns2:Inner/ns2:Field2 XmpText 12
>
> <?xpacket end="w"?>
\ No newline at end of file
+Xmp.dc.format XmpText 10 image/jpeg
+Xmp.dc.creator XmpSeq 3 1) The first creator, 2) The second creator, 3) And another one
+Xmp.dc.description LangAlt 2 lang="de-DE" Hallo, Welt, lang="x-default" Hello, World
+Xmp.xmpDM.videoFrameSize/stDim:w XmpText 2 16
+Xmp.xmpDM.videoFrameSize/stDim:h XmpText 1 9
+Xmp.xmpDM.videoFrameSize/stDim:unit XmpText 4 inch
+Xmp.dc.publisher XmpText 10 James Bond
+Xmp.dc.publisher/?ns:role XmpText 12 secret agent
+Xmp.dc.creator[2]/?ns:role XmpText 10 programmer
+Xmp.xmpBJ.JobRef XmpText 0
+Xmp.xmpBJ.JobRef[1]/stJob:name XmpText 13 Birtday party
+Xmp.xmpBJ.JobRef[1]/stJob:role XmpText 12 Photographer
+Xmp.xmpBJ.JobRef[2]/stJob:name XmpText 16 Wedding ceremony
+Xmp.xmpBJ.JobRef[2]/stJob:role XmpText 8 Best man
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.1.1">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:ns="myNamespace/"
+ xmlns:xmpDM="http://ns.adobe.com/xmp/1.0/DynamicMedia/"
+ xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+ xmlns:xapBJ="http://ns.adobe.com/xap/1.0/bj/"
+ xmlns:stJob="http://ns.adobe.com/xap/1.0/sType/Job#"
+ dc:format="image/jpeg">
+ <dc:creator>
+ <rdf:Seq>
+ <rdf:li>1) The first creator</rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <rdf:value>2) The second creator</rdf:value>
+ <ns:role>programmer</ns:role>
+ </rdf:li>
+ <rdf:li>3) And another one</rdf:li>
+ </rdf:Seq>
+ </dc:creator>
+ <dc:description>
+ <rdf:Alt>
+ <rdf:li xml:lang="x-default">Hello, World</rdf:li>
+ <rdf:li xml:lang="de-DE">Hallo, Welt</rdf:li>
+ </rdf:Alt>
+ </dc:description>
+ <dc:publisher rdf:parseType="Resource">
+ <rdf:value>James Bond</rdf:value>
+ <ns:role>secret agent</ns:role>
+ </dc:publisher>
+ <xmpDM:videoFrameSize
+ stDim:w="16"
+ stDim:h="9"
+ stDim:unit="inch"/>
+ <xapBJ:JobRef>
+ <rdf:Bag>
+ <rdf:li
+ stJob:name="Birtday party"
+ stJob:role="Photographer"/>
+ <rdf:li
+ stJob:name="Wedding ceremony"
+ stJob:role="Best man"/>
+ </rdf:Bag>
+ </xapBJ:JobRef>
+ </rdf:Description>
+ </rdf:RDF>
+</x:xmpmeta>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end="w"?>
diff --git a/test/xmpparser-test.sh b/test/xmpparser-test.sh
index 705d4ce..9ddba93 100755
--- a/test/xmpparser-test.sh
+++ b/test/xmpparser-test.sh
@@ -52,6 +52,10 @@ $binpath/xmpparse ${testfile} > t1 2>&1
$binpath/xmpparse ${testfile}-new > t2 2>&1
diff t1 t2
+# ----------------------------------------------------------------------
+# xmpsample
+$binpath/xmpsample
+
) > $results 2>&1
# ----------------------------------------------------------------------
--
exiv2 packaging
More information about the pkg-kde-commits
mailing list