/*
 * Copyright 2023 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/private/SkXmp.h"

#include "include/core/SkColor.h"
#include "include/core/SkData.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/private/SkGainmapInfo.h"
#include "include/utils/SkParse.h"
#include "src/codec/SkCodecPriv.h"
#include "src/xml/SkDOM.h"

#include <cmath>
#include <cstdint>
#include <cstring>
#include <string>
#include <vector>
#include <utility>

////////////////////////////////////////////////////////////////////////////////////////////////////
// XMP parsing helper functions

const char* kXmlnsPrefix = "xmlns:";
const size_t kXmlnsPrefixLength = 6;

static const char* get_namespace_prefix(const char* name) {
    if (strlen(name) <= kXmlnsPrefixLength) {
        return nullptr;
    }
    return name + kXmlnsPrefixLength;
}

/*
 * Given a node, see if that node has only one child with the indicated name. If so, see if that
 * child has only a single child of its own, and that child is text. If all of that is the case
 * then return the text, otherwise return nullptr.
 *
 * In the following example, innerText will be returned.
 *    <node><childName>innerText</childName></node>
 *
 * In the following examples, nullptr will be returned (because there are multiple children with
 * childName in the first case, and because the child has children of its own in the second).
 *    <node><childName>innerTextA</childName><childName>innerTextB</childName></node>
 *    <node><childName>innerText<otherGrandChild/></childName></node>
 */
static const char* get_unique_child_text(const SkDOM& dom,
                                         const SkDOM::Node* node,
                                         const std::string& childName) {
    // Fail if there are multiple children with childName.
    if (dom.countChildren(node, childName.c_str()) != 1) {
        return nullptr;
    }
    const auto* child = dom.getFirstChild(node, childName.c_str());
    if (!child) {
        return nullptr;
    }
    // Fail if the child has any children besides text.
    if (dom.countChildren(child) != 1) {
        return nullptr;
    }
    const auto* grandChild = dom.getFirstChild(child);
    if (dom.getType(grandChild) != SkDOM::kText_Type) {
        return nullptr;
    }
    // Return the text.
    return dom.getName(grandChild);
}

/*
 * Given a node, find a child node of the specified type.
 *
 * If there exists a child node with name |prefix| + ":" + |type|, then return that child.
 *
 * If there exists a child node with name "rdf:type" that has attribute "rdf:resource" with value
 * of |type|, then if there also exists a child node with name "rdf:value" with attribute
 * "rdf:parseType" of "Resource", then return that child node with name "rdf:value". See Example
 * 3 in section 7.9.2.5: RDF Typed Nodes.
 * TODO(ccameron): This should also accept a URI for the type.
 */
static const SkDOM::Node* get_typed_child(const SkDOM* dom,
                                          const SkDOM::Node* node,
                                          const std::string& prefix,
                                          const std::string& type) {
    const auto name = prefix + std::string(":") + type;
    const SkDOM::Node* child = dom->getFirstChild(node, name.c_str());
    if (child) {
        return child;
    }

    const SkDOM::Node* typeChild = dom->getFirstChild(node, "rdf:type");
    if (!typeChild) {
        return nullptr;
    }
    const char* typeChildResource = dom->findAttr(typeChild, "rdf:resource");
    if (!typeChildResource || typeChildResource != type) {
        return nullptr;
    }

    const SkDOM::Node* valueChild = dom->getFirstChild(node, "rdf:value");
    if (!valueChild) {
        return nullptr;
    }
    const char* valueChildParseType = dom->findAttr(valueChild, "rdf:parseType");
    if (!valueChildParseType || strcmp(valueChildParseType, "Resource") != 0) {
        return nullptr;
    }
    return valueChild;
}

/*
 * Given a node, return its value for the specified attribute.
 *
 * This will first look for an attribute with the name |prefix| + ":" + |key|, and return the value
 * for that attribute.
 *
 * This will then look for a child node of name |prefix| + ":" + |key|, and return the field value
 * for that child.
 */
static const char* get_attr(const SkDOM* dom,
                            const SkDOM::Node* node,
                            const std::string& prefix,
                            const std::string& key) {
    const auto name = prefix + ":" + key;
    const char* attr = dom->findAttr(node, name.c_str());
    if (attr) {
        return attr;
    }
    return get_unique_child_text(*dom, node, name);
}

// Perform get_attr and parse the result as a bool.
static bool get_attr_bool(const SkDOM* dom,
                          const SkDOM::Node* node,
                          const std::string& prefix,
                          const std::string& key,
                          bool* outValue) {
    const char* attr = get_attr(dom, node, prefix, key);
    if (!attr) {
        return false;
    }
    switch (SkParse::FindList(attr, "False,True")) {
        case 0:
            *outValue = false;
            return true;
        case 1:
            *outValue = true;
            return true;
        default:
            break;
    }
    return false;
}

// Perform get_attr and parse the result as an int32_t.
static bool get_attr_int32(const SkDOM* dom,
                           const SkDOM::Node* node,
                           const std::string& prefix,
                           const std::string& key,
                           int32_t* value) {
    const char* attr = get_attr(dom, node, prefix, key);
    if (!attr) {
        return false;
    }
    if (!SkParse::FindS32(attr, value)) {
        return false;
    }
    return true;
}

// Perform get_attr and parse the result as a float.
static bool get_attr_float(const SkDOM* dom,
                           const SkDOM::Node* node,
                           const std::string& prefix,
                           const std::string& key,
                           float* outValue) {
    const char* attr = get_attr(dom, node, prefix, key);
    if (!attr) {
        return false;
    }
    SkScalar value = 0.f;
    if (SkParse::FindScalar(attr, &value)) {
        *outValue = value;
        return true;
    }
    return false;
}

// Perform get_attr and parse the result as three comma-separated floats. Return the result as an
// SkColor4f with the alpha component set to 1.
static bool get_attr_float3_as_list(const SkDOM* dom,
                                    const SkDOM::Node* node,
                                    const std::string& prefix,
                                    const std::string& key,
                                    SkColor4f* outValue) {
    const auto name = prefix + ":" + key;

    // Fail if there are multiple children with childName.
    if (dom->countChildren(node, name.c_str()) != 1) {
        return false;
    }
    // Find the child.
    const auto* child = dom->getFirstChild(node, name.c_str());
    if (!child) {
        return false;
    }

    // Search for the rdf:Seq child.
    const auto* seq = dom->getFirstChild(child, "rdf:Seq");
    if (!seq) {
        return false;
    }

    size_t count = 0;
    SkScalar values[3] = {0.f, 0.f, 0.f};
    for (const auto* liNode = dom->getFirstChild(seq, "rdf:li"); liNode;
         liNode = dom->getNextSibling(liNode, "rdf:li")) {
        if (count > 2) {
            SkCodecPrintf("Too many items in list.\n");
            return false;
        }
        if (dom->countChildren(liNode) != 1) {
            SkCodecPrintf("Item can only have one child.\n");
            return false;
        }
        const auto* liTextNode = dom->getFirstChild(liNode);
        if (dom->getType(liTextNode) != SkDOM::kText_Type) {
            SkCodecPrintf("Item's only child must be text.\n");
            return false;
        }
        const char* liText = dom->getName(liTextNode);
        if (!liText) {
            SkCodecPrintf("Failed to get item's text.\n");
            return false;
        }
        if (!SkParse::FindScalar(liText, values + count)) {
            SkCodecPrintf("Failed to parse item's text to float.\n");
            return false;
        }
        count += 1;
    }
    if (count < 3) {
        SkCodecPrintf("List didn't have enough items.\n");
        return false;
    }
    *outValue = {values[0], values[1], values[2], 1.f};
    return true;
}

static bool get_attr_float3(const SkDOM* dom,
                            const SkDOM::Node* node,
                            const std::string& prefix,
                            const std::string& key,
                            SkColor4f* outValue) {
    if (get_attr_float3_as_list(dom, node, prefix, key, outValue)) {
        return true;
    }
    SkScalar value = -1.0;
    if (get_attr_float(dom, node, prefix, key, &value)) {
        *outValue = {value, value, value, 1.f};
        return true;
    }
    return false;
}

static void find_uri_namespaces(const SkDOM& dom,
                                const SkDOM::Node* node,
                                size_t count,
                                const char* uris[],
                                const char* outNamespaces[]) {
    // Search all attributes for xmlns:NAMESPACEi="URIi".
    for (const auto* attr = dom.getFirstAttr(node); attr; attr = dom.getNextAttr(node, attr)) {
        const char* attrName = dom.getAttrName(node, attr);
        const char* attrValue = dom.getAttrValue(node, attr);
        if (!attrName || !attrValue) {
            continue;
        }
        // Make sure the name starts with "xmlns:".
        if (strlen(attrName) <= kXmlnsPrefixLength) {
            continue;
        }
        if (memcmp(attrName, kXmlnsPrefix, kXmlnsPrefixLength) != 0) {
            continue;
        }
        // Search for a requested URI that matches.
        for (size_t i = 0; i < count; ++i) {
            if (strcmp(attrValue, uris[i]) != 0) {
                continue;
            }
            outNamespaces[i] = attrName;
        }
    }
}

// See SkXmp::findUriNamespaces. This function has the same behavior, but only searches
// a single SkDOM.
static const SkDOM::Node* find_uri_namespaces(const SkDOM& dom,
                                              size_t count,
                                              const char* uris[],
                                              const char* outNamespaces[]) {
    const SkDOM::Node* root = dom.getRootNode();
    if (!root) {
        return nullptr;
    }

    // Ensure that the root node identifies itself as XMP metadata.
    const char* rootName = dom.getName(root);
    if (!rootName || strcmp(rootName, "x:xmpmeta") != 0) {
        return nullptr;
    }

    //  Iterate the children with name rdf:RDF.
    const char* kRdf = "rdf:RDF";
    for (const auto* rdf = dom.getFirstChild(root, kRdf); rdf;
         rdf = dom.getNextSibling(rdf, kRdf)) {
        std::vector<const char*> rdfNamespaces(count, nullptr);
        find_uri_namespaces(dom, rdf, count, uris, rdfNamespaces.data());

        // Iterate the children with name rdf::Description.
        const char* kDesc = "rdf:Description";
        for (const auto* desc = dom.getFirstChild(rdf, kDesc); desc;
             desc = dom.getNextSibling(desc, kDesc)) {
            std::vector<const char*> descNamespaces = rdfNamespaces;
            find_uri_namespaces(dom, desc, count, uris, descNamespaces.data());

            // If we have a match for all the requested URIs, return.
            bool foundAllUris = true;
            for (size_t i = 0; i < count; ++i) {
                if (!descNamespaces[i]) {
                    foundAllUris = false;
                    break;
                }
            }
            if (foundAllUris) {
                for (size_t i = 0; i < count; ++i) {
                    outNamespaces[i] = descNamespaces[i];
                }
                return desc;
            }
        }
    }
    return nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// SkXmpImpl

class SkXmpImpl final : public SkXmp {
public:
    SkXmpImpl() = default;

    bool getGainmapInfoHDRGM(SkGainmapInfo* info) const override;
    bool getGainmapInfoHDRGainMap(SkGainmapInfo* info) const override;
    bool getContainerGainmapLocation(size_t* offset, size_t* size) const override;
    const char* getExtendedXmpGuid() const override;
    // Parse the given xmp data and store it into either the standard (main) DOM or the extended
    // DOM. Returns true on successful parsing.
    bool parseDom(sk_sp<SkData> xmpData, bool extended);

private:
    bool findUriNamespaces(size_t count,
                           const char* uris[],
                           const char* outNamespaces[],
                           const SkDOM** outDom,
                           const SkDOM::Node** outNode) const;

    SkDOM fStandardDOM;
    SkDOM fExtendedDOM;
};

const char* SkXmpImpl::getExtendedXmpGuid() const {
    const char* namespaces[1] = {nullptr};
    const char* uris[1] = {"http://ns.adobe.com/xmp/note/"};
    const auto* extendedNode = find_uri_namespaces(fStandardDOM, 1, uris, namespaces);
    if (!extendedNode) {
        return nullptr;
    }
    const auto xmpNotePrefix = get_namespace_prefix(namespaces[0]);
    // Extract the GUID (the MD5 hash) of the extended metadata.
    return get_attr(&fStandardDOM, extendedNode, xmpNotePrefix, "HasExtendedXMP");
}

bool SkXmpImpl::findUriNamespaces(size_t count,
                                  const char* uris[],
                                  const char* outNamespaces[],
                                  const SkDOM** outDom,
                                  const SkDOM::Node** outNode) const {
    // See XMP Specification Part 3: Storage in files, Section 1.1.3.1: Extended XMP in JPEG:
    // A JPEG reader must recompose the StandardXMP and ExtendedXMP into a single data model tree
    // containing all of the XMP for the JPEG file, and remove the xmpNote:HasExtendedXMP property.
    // This code does not do that. Instead, it maintains the two separate trees and searches them
    // sequentially.
    *outNode = find_uri_namespaces(fStandardDOM, count, uris, outNamespaces);
    if (*outNode) {
        *outDom = &fStandardDOM;
        return true;
    }
    *outNode = find_uri_namespaces(fExtendedDOM, count, uris, outNamespaces);
    if (*outNode) {
        *outDom = &fExtendedDOM;
        return true;
    }
    *outDom = nullptr;
    return false;
}

bool SkXmpImpl::getContainerGainmapLocation(size_t* outOffset, size_t* outSize) const {
    // Find a node that matches the requested namespaces and URIs.
    const char* namespaces[2] = {nullptr, nullptr};
    const char* uris[2] = {"http://ns.google.com/photos/1.0/container/",
                           "http://ns.google.com/photos/1.0/container/item/"};
    const SkDOM* dom = nullptr;
    const SkDOM::Node* node = nullptr;
    if (!findUriNamespaces(2, uris, namespaces, &dom, &node)) {
        return false;
    }
    const char* containerPrefix = get_namespace_prefix(namespaces[0]);
    const char* itemPrefix = get_namespace_prefix(namespaces[1]);

    // The node must have a Container:Directory child.
    const auto* directory = get_typed_child(dom, node, containerPrefix, "Directory");
    if (!directory) {
        SkCodecPrintf("Missing Container Directory");
        return false;
    }

    // That Container:Directory must have a sequence of  items.
    const auto* seq = dom->getFirstChild(directory, "rdf:Seq");
    if (!seq) {
        SkCodecPrintf("Missing rdf:Seq");
        return false;
    }

    // Iterate through the items in the Container:Directory's sequence. Keep a running sum of the
    // Item:Length of all items that appear before the GainMap.
    bool isFirstItem = true;
    size_t offset = 0;
    for (const auto* li = dom->getFirstChild(seq, "rdf:li"); li;
         li = dom->getNextSibling(li, "rdf:li")) {
        // Each list item must contain a Container:Item.
        const auto* item = get_typed_child(dom, li, containerPrefix, "Item");
        if (!item) {
            SkCodecPrintf("List item does not have container Item.\n");
            return false;
        }
        // A Semantic is required for every item.
        const char* itemSemantic = get_attr(dom, item, itemPrefix, "Semantic");
        if (!itemSemantic) {
            SkCodecPrintf("Item is missing Semantic.\n");
            return false;
        }
        // A Mime is required for every item.
        const char* itemMime = get_attr(dom, item, itemPrefix, "Mime");
        if (!itemMime) {
            SkCodecPrintf("Item is missing Mime.\n");
            return false;
        }

        if (isFirstItem) {
            isFirstItem = false;
            // The first item must be Primary.
            if (strcmp(itemSemantic, "Primary") != 0) {
                SkCodecPrintf("First item is not Primary.\n");
                return false;
            }
            // The first item has mime type image/jpeg (we are decoding a jpeg).
            if (strcmp(itemMime, "image/jpeg") != 0) {
                SkCodecPrintf("Primary does not report that it is image/jpeg.\n");
                return false;
            }
            // The first media item can contain a Padding attribute, which specifies additional
            // padding between the end of the encoded primary image and the beginning of the next
            // media item. Only the first media item can contain a Padding attribute.
            int32_t padding = 0;
            if (get_attr_int32(dom, item, itemPrefix, "Padding", &padding)) {
                if (padding < 0) {
                    SkCodecPrintf("Item padding must be non-negative.");
                    return false;
                }
                offset += padding;
            }
        } else {
            // A Length is required for all non-Primary items.
            int32_t length = 0;
            if (!get_attr_int32(dom, item, itemPrefix, "Length", &length)) {
                SkCodecPrintf("Item length is absent.");
                return false;
            }
            if (length < 0) {
                SkCodecPrintf("Item length must be non-negative.");
                return false;
            }
            // If this is not the recovery map, then read past it.
            if (strcmp(itemSemantic, "GainMap") != 0) {
                offset += length;
                continue;
            }
            // The recovery map must have mime type image/jpeg in this implementation.
            if (strcmp(itemMime, "image/jpeg") != 0) {
                SkCodecPrintf("GainMap does not report that it is image/jpeg.\n");
                return false;
            }

            // Populate the location in the file at which to find the gainmap image.
            *outOffset = offset;
            *outSize = length;
            return true;
        }
    }
    return false;
}

// Return true if the specified XMP metadata identifies this image as an HDR gainmap.
bool SkXmpImpl::getGainmapInfoHDRGainMap(SkGainmapInfo* info) const {
    // Find a node that matches the requested namespaces and URIs.
    const char* namespaces[2] = {nullptr, nullptr};
    const char* uris[2] = {"http://ns.apple.com/pixeldatainfo/1.0/",
                           "http://ns.apple.com/HDRGainMap/1.0/"};
    const SkDOM* dom = nullptr;
    const SkDOM::Node* node = nullptr;
    if (!findUriNamespaces(2, uris, namespaces, &dom, &node)) {
        return false;
    }
    const char* adpiPrefix = get_namespace_prefix(namespaces[0]);
    const char* hdrGainMapPrefix = get_namespace_prefix(namespaces[1]);

    const char* auxiliaryImageType = get_attr(dom, node, adpiPrefix, "AuxiliaryImageType");
    if (!auxiliaryImageType) {
        SkCodecPrintf("Did not find AuxiliaryImageType.\n");
        return false;
    }
    if (strcmp(auxiliaryImageType, "urn:com:apple:photo:2020:aux:hdrgainmap") != 0) {
        SkCodecPrintf("AuxiliaryImageType was not HDR gain map.\n");
        return false;
    }

    int32_t version = 0;
    if (!get_attr_int32(dom, node, hdrGainMapPrefix, "HDRGainMapVersion", &version)) {
        SkCodecPrintf("Did not find HDRGainMapVersion.\n");
        return false;
    }
    if (version != 65536) {
        SkCodecPrintf("HDRGainMapVersion was not 65536.\n");
        return false;
    }

    // This node will often have StoredFormat and NativeFormat children that have inner text that
    // specifies the integer 'L008' (also known as kCVPixelFormatType_OneComponent8).
    const float kRatioMax = std::exp(1.f);
    info->fGainmapRatioMin = {1.f, 1.f, 1.f, 1.f};
    info->fGainmapRatioMax = {kRatioMax, kRatioMax, kRatioMax, 1.f};
    info->fGainmapGamma = {1.f, 1.f, 1.f, 1.f};
    info->fEpsilonSdr = {0.f, 0.f, 0.f, 1.f};
    info->fEpsilonHdr = {0.f, 0.f, 0.f, 1.f};
    info->fDisplayRatioSdr = 1.f;
    info->fDisplayRatioHdr = kRatioMax;
    info->fBaseImageType = SkGainmapInfo::BaseImageType::kSDR;
    return true;
}

bool SkXmpImpl::getGainmapInfoHDRGM(SkGainmapInfo* outGainmapInfo) const {
    // Find a node that matches the requested namespace and URI.
    const char* namespaces[1] = {nullptr};
    const char* uris[1] = {"http://ns.adobe.com/hdr-gain-map/1.0/"};
    const SkDOM* dom = nullptr;
    const SkDOM::Node* node = nullptr;
    if (!findUriNamespaces(1, uris, namespaces, &dom, &node)) {
        return false;
    }
    const char* hdrgmPrefix = get_namespace_prefix(namespaces[0]);

    // Require that hdrgm:Version="1.0" be present.
    const char* version = get_attr(dom, node, hdrgmPrefix, "Version");
    if (!version) {
        SkCodecPrintf("Version attribute is absent.\n");
        return false;
    }
    if (strcmp(version, "1.0") != 0) {
        SkCodecPrintf("Version is \"%s\", not \"1.0\".\n", version);
        return false;
    }

    // Initialize the parameters to their defaults.
    bool baseRenditionIsHDR = false;
    SkColor4f gainMapMin = {0.f, 0.f, 0.f, 1.f};  // log2 value
    SkColor4f gainMapMax = {1.f, 1.f, 1.f, 1.f};  // log2 value
    SkColor4f gamma = {1.f, 1.f, 1.f, 1.f};
    SkColor4f offsetSdr = {1.f / 64.f, 1.f / 64.f, 1.f / 64.f, 0.f};
    SkColor4f offsetHdr = {1.f / 64.f, 1.f / 64.f, 1.f / 64.f, 0.f};
    SkScalar hdrCapacityMin = 0.f;  // log2 value
    SkScalar hdrCapacityMax = 1.f;  // log2 value

    // Read all parameters that are present.
    get_attr_bool(dom, node, hdrgmPrefix, "BaseRenditionIsHDR", &baseRenditionIsHDR);
    get_attr_float3(dom, node, hdrgmPrefix, "GainMapMin", &gainMapMin);
    get_attr_float3(dom, node, hdrgmPrefix, "GainMapMax", &gainMapMax);
    get_attr_float3(dom, node, hdrgmPrefix, "Gamma", &gamma);
    get_attr_float3(dom, node, hdrgmPrefix, "OffsetSDR", &offsetSdr);
    get_attr_float3(dom, node, hdrgmPrefix, "OffsetHDR", &offsetHdr);
    get_attr_float(dom, node, hdrgmPrefix, "HDRCapacityMin", &hdrCapacityMin);
    get_attr_float(dom, node, hdrgmPrefix, "HDRCapacityMax", &hdrCapacityMax);

    // Translate all parameters to SkGainmapInfo's expected format.
    const float kLog2 = std::log(2.f);
    outGainmapInfo->fGainmapRatioMin = {std::exp(gainMapMin.fR * kLog2),
                                        std::exp(gainMapMin.fG * kLog2),
                                        std::exp(gainMapMin.fB * kLog2),
                                        1.f};
    outGainmapInfo->fGainmapRatioMax = {std::exp(gainMapMax.fR * kLog2),
                                        std::exp(gainMapMax.fG * kLog2),
                                        std::exp(gainMapMax.fB * kLog2),
                                        1.f};
    outGainmapInfo->fGainmapGamma = {1.f / gamma.fR, 1.f / gamma.fG, 1.f / gamma.fB, 1.f};
    outGainmapInfo->fEpsilonSdr = offsetSdr;
    outGainmapInfo->fEpsilonHdr = offsetHdr;
    outGainmapInfo->fDisplayRatioSdr = std::exp(hdrCapacityMin * kLog2);
    outGainmapInfo->fDisplayRatioHdr = std::exp(hdrCapacityMax * kLog2);
    if (baseRenditionIsHDR) {
        outGainmapInfo->fBaseImageType = SkGainmapInfo::BaseImageType::kHDR;
    } else {
        outGainmapInfo->fBaseImageType = SkGainmapInfo::BaseImageType::kSDR;
    }
    return true;
}

bool SkXmpImpl::parseDom(sk_sp<SkData> xmpData, bool extended) {
    SkDOM* dom = extended ? &fExtendedDOM : &fStandardDOM;
    auto xmpdStream = SkMemoryStream::Make(std::move(xmpData));
    if (!dom->build(*xmpdStream)) {
        SkCodecPrintf("Failed to parse XMP %s metadata.\n", extended ? "extended" : "standard");
        return false;
    }
    return true;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// SkXmp

std::unique_ptr<SkXmp> SkXmp::Make(sk_sp<SkData> xmpData) {
    std::unique_ptr<SkXmpImpl> xmp(new SkXmpImpl);
    if (!xmp->parseDom(std::move(xmpData), /*extended=*/false)) {
        return nullptr;
    }
    return xmp;
}

std::unique_ptr<SkXmp> SkXmp::Make(sk_sp<SkData> xmpStandard, sk_sp<SkData> xmpExtended) {
    std::unique_ptr<SkXmpImpl> xmp(new SkXmpImpl);
    if (!xmp->parseDom(std::move(xmpStandard), /*extended=*/false)) {
        return nullptr;
    }
    // Try to parse extended xmp but ignore the return value: if parsing fails, we'll still return
    // the standard xmp.
    (void)xmp->parseDom(std::move(xmpExtended), /*extended=*/true);
    return xmp;
}
