Allow format options for XmpParser::encode (Vladimir Nadvornik), write XMP sidecar files without xpacket.

v0.27.3
Andreas Huggel 18 years ago
parent e4c96433d4
commit 38b1a0fa2c

@ -74,7 +74,7 @@ namespace {
Exiv2::XmpValue::XmpStruct xmpStruct(const XMP_OptionBits& opt); Exiv2::XmpValue::XmpStruct xmpStruct(const XMP_OptionBits& opt);
//! Convert Value::XmpStruct to XMP Toolkit array option bits //! Convert Value::XmpStruct to XMP Toolkit array option bits
XMP_OptionBits xmpOptionBits(Exiv2::XmpValue::XmpStruct xs); XMP_OptionBits xmpArrayOptionBits(Exiv2::XmpValue::XmpStruct xs);
//! Convert XMP Toolkit array option bits to array TypeId //! Convert XMP Toolkit array option bits to array TypeId
Exiv2::TypeId arrayValueTypeId(const XMP_OptionBits& opt); Exiv2::TypeId arrayValueTypeId(const XMP_OptionBits& opt);
@ -83,7 +83,10 @@ namespace {
Exiv2::XmpValue::XmpArrayType xmpArrayType(const XMP_OptionBits& opt); Exiv2::XmpValue::XmpArrayType xmpArrayType(const XMP_OptionBits& opt);
//! Convert Value::XmpArrayType to XMP Toolkit array option bits //! Convert Value::XmpArrayType to XMP Toolkit array option bits
XMP_OptionBits xmpOptionBits(Exiv2::XmpValue::XmpArrayType xat); XMP_OptionBits xmpArrayOptionBits(Exiv2::XmpValue::XmpArrayType xat);
//! Convert XmpFormatFlags to XMP Toolkit format option bits
XMP_OptionBits xmpFormatOptionBits(Exiv2::XmpParser::XmpFormatFlags flags);
# ifdef DEBUG # ifdef DEBUG
//! Print information about a parsed XMP node //! Print information about a parsed XMP node
@ -564,7 +567,9 @@ namespace Exiv2 {
#ifdef EXV_HAVE_XMP_TOOLKIT #ifdef EXV_HAVE_XMP_TOOLKIT
int XmpParser::encode( std::string& xmpPacket, int XmpParser::encode( std::string& xmpPacket,
const XmpData& xmpData) const XmpData& xmpData,
uint16_t formatFlags,
uint32_t padding)
{ try { { try {
if (xmpData.empty()) return 0; if (xmpData.empty()) return 0;
@ -609,8 +614,8 @@ namespace Exiv2 {
// Todo: Xmpdatum should have an XmpValue, not a Value // Todo: Xmpdatum should have an XmpValue, not a Value
const XmpValue* val = dynamic_cast<const XmpValue*>(&i->value()); const XmpValue* val = dynamic_cast<const XmpValue*>(&i->value());
assert(val); assert(val);
options = xmpOptionBits(val->xmpArrayType()) options = xmpArrayOptionBits(val->xmpArrayType())
| xmpOptionBits(val->xmpStruct()); | xmpArrayOptionBits(val->xmpStruct());
if ( i->typeId() == xmpBag if ( i->typeId() == xmpBag
|| i->typeId() == xmpSeq || i->typeId() == xmpSeq
|| i->typeId() == xmpAlt) { || i->typeId() == xmpAlt) {
@ -646,7 +651,7 @@ namespace Exiv2 {
throw Error(38, i->tagName(), TypeInfo::typeName(i->typeId())); throw Error(38, i->tagName(), TypeInfo::typeName(i->typeId()));
} }
std::string tmpPacket; std::string tmpPacket;
meta.SerializeToBuffer(&tmpPacket, kXMP_UseCompactFormat); // throws meta.SerializeToBuffer(&tmpPacket, xmpFormatOptionBits(static_cast<XmpFormatFlags>(formatFlags)), padding); // throws
xmpPacket = tmpPacket; xmpPacket = tmpPacket;
return 0; return 0;
@ -686,7 +691,7 @@ namespace {
return var; return var;
} }
XMP_OptionBits xmpOptionBits(Exiv2::XmpValue::XmpStruct xs) XMP_OptionBits xmpArrayOptionBits(Exiv2::XmpValue::XmpStruct xs)
{ {
XMP_OptionBits var(0); XMP_OptionBits var(0);
switch (xs) { switch (xs) {
@ -715,7 +720,7 @@ namespace {
return Exiv2::XmpValue::xmpArrayType(arrayValueTypeId(opt)); return Exiv2::XmpValue::xmpArrayType(arrayValueTypeId(opt));
} }
XMP_OptionBits xmpOptionBits(Exiv2::XmpValue::XmpArrayType xat) XMP_OptionBits xmpArrayOptionBits(Exiv2::XmpValue::XmpArrayType xat)
{ {
XMP_OptionBits var(0); XMP_OptionBits var(0);
switch (xat) { switch (xat) {
@ -736,6 +741,19 @@ namespace {
return var; return var;
} }
XMP_OptionBits xmpFormatOptionBits(Exiv2::XmpParser::XmpFormatFlags flags)
{
XMP_OptionBits var(0);
if (flags & Exiv2::XmpParser::omitPacketWrapper) var |= kXMP_OmitPacketWrapper;
if (flags & Exiv2::XmpParser::readOnlyPacket) var |= kXMP_ReadOnlyPacket;
if (flags & Exiv2::XmpParser::useCompactFormat) var |= kXMP_UseCompactFormat;
if (flags & Exiv2::XmpParser::includeThumbnailPad) var |= kXMP_IncludeThumbnailPad;
if (flags & Exiv2::XmpParser::exactPacketLength) var |= kXMP_ExactPacketLength;
if (flags & Exiv2::XmpParser::writeAliasComments) var |= kXMP_WriteAliasComments;
if (flags & Exiv2::XmpParser::omitAllFormatting) var |= kXMP_OmitAllFormatting;
return var;
}
#ifdef DEBUG #ifdef DEBUG
void printNode(const std::string& schemaNs, void printNode(const std::string& schemaNs,
const std::string& propPath, const std::string& propPath,

@ -254,6 +254,16 @@ namespace Exiv2 {
friend void XmpProperties::registerNs(const std::string&, const std::string&); friend void XmpProperties::registerNs(const std::string&, const std::string&);
friend void XmpProperties::unregisterNs(const std::string&); friend void XmpProperties::unregisterNs(const std::string&);
public: public:
//! Options to control the format of the serialized XMP packet.
enum XmpFormatFlags {
omitPacketWrapper = 0x0010UL, //!< Omit the XML packet wrapper.
readOnlyPacket = 0x0020UL, //!< Default is a writeable packet.
useCompactFormat = 0x0040UL, //!< Use a compact form of RDF.
includeThumbnailPad = 0x0100UL, //!< Include a padding allowance for a thumbnail image.
exactPacketLength = 0x0200UL, //!< The padding parameter is the overall packet length.
writeAliasComments = 0x0400UL, //!< Show aliases as XML comments.
omitAllFormatting = 0x0800UL //!< Omit all formatting whitespace.
};
/*! /*!
@brief Decode XMP metadata from an XMP packet \em xmpPacket into @brief Decode XMP metadata from an XMP packet \em xmpPacket into
\em xmpData. The format of the XMP packet must follow the \em xmpData. The format of the XMP packet must follow the
@ -275,16 +285,21 @@ namespace Exiv2 {
follows the XMP specification. This method only modifies follows the XMP specification. This method only modifies
\em xmpPacket if the operations succeeds (return code 0). \em xmpPacket if the operations succeeds (return code 0).
@param xmpPacket Reference to a string to hold the encoded XMP @param xmpPacket Reference to a string to hold the encoded XMP
packet. packet.
@param xmpData XMP properties to encode. @param xmpData XMP properties to encode.
@param formatFlags Flags that control the format of the XMP packet,
see enum XmpFormatFlags.
@param padding Padding length.
@return 0 if successful;<BR> @return 0 if successful;<BR>
1 if XMP support has not been compiled-in;<BR> 1 if XMP support has not been compiled-in;<BR>
2 if the XMP toolkit failed to initialize;<BR> 2 if the XMP toolkit failed to initialize;<BR>
3 if the XMP toolkit failed and raised an XMP_Error 3 if the XMP toolkit failed and raised an XMP_Error
*/ */
static int encode( std::string& xmpPacket, static int encode( std::string& xmpPacket,
const XmpData& xmpData); const XmpData& xmpData,
uint16_t formatFlags =useCompactFormat,
uint32_t padding =0);
/*! /*!
@brief Initialize the XMP Toolkit. @brief Initialize the XMP Toolkit.

@ -116,13 +116,16 @@ namespace Exiv2 {
IoCloser closer(*io_); IoCloser closer(*io_);
if (writeXmpFromPacket() == false) { if (writeXmpFromPacket() == false) {
if (XmpParser::encode(xmpPacket_, xmpData_)) { if (XmpParser::encode(xmpPacket_, xmpData_, XmpParser::omitPacketWrapper|XmpParser::useCompactFormat)) {
#ifndef SUPPRESS_WARNINGS #ifndef SUPPRESS_WARNINGS
std::cerr << "Error: Failed to encode XMP metadata.\n"; std::cerr << "Error: Failed to encode XMP metadata.\n";
#endif #endif
} }
} }
if (xmpPacket_.size() > 0) { if (xmpPacket_.size() > 0) {
if (xmpPacket_.substr(0, 5) != "<?xml") {
xmpPacket_ = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + xmpPacket_;
}
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
assert(tempIo.get() != 0); assert(tempIo.get() != 0);
// Write XMP packet // Write XMP packet

Loading…
Cancel
Save