54 const std::string& childName) {
56 if (
dom.countChildren(node, childName.c_str()) != 1) {
59 const auto* child =
dom.getFirstChild(node, childName.c_str());
64 if (
dom.countChildren(child) != 1) {
67 const auto* grandChild =
dom.getFirstChild(child);
72 return dom.getName(grandChild);
89 const std::string&
type) {
96 const SkDOM::Node* typeChild =
dom->getFirstChild(node,
"rdf:type");
100 const char* typeChildResource =
dom->findAttr(typeChild,
"rdf:resource");
101 if (!typeChildResource || typeChildResource !=
type) {
105 const SkDOM::Node* valueChild =
dom->getFirstChild(node,
"rdf:value");
109 const char* valueChildParseType =
dom->findAttr(valueChild,
"rdf:parseType");
110 if (!valueChildParseType || strcmp(valueChildParseType,
"Resource") != 0) {
127 const std::string&
prefix,
128 const std::string&
key) {
130 const char* attr =
dom->findAttr(node,
name.c_str());
140 const std::string&
prefix,
141 const std::string&
key,
163 const std::string&
prefix,
164 const std::string&
key,
179 const std::string&
prefix,
180 const std::string&
key,
198 const std::string&
prefix,
199 const std::string&
key,
204 if (
dom->countChildren(node,
name.c_str()) != 1) {
208 const auto* child =
dom->getFirstChild(node,
name.c_str());
214 const auto* seq =
dom->getFirstChild(child,
"rdf:Seq");
221 for (
const auto* liNode =
dom->getFirstChild(seq,
"rdf:li"); liNode;
222 liNode =
dom->getNextSibling(liNode,
"rdf:li")) {
227 if (
dom->countChildren(liNode) != 1) {
231 const auto* liTextNode =
dom->getFirstChild(liNode);
236 const char* liText =
dom->getName(liTextNode);
257 const std::string&
prefix,
258 const std::string&
key,
275 const char* outNamespaces[]) {
277 for (
const auto* attr =
dom.getFirstAttr(node); attr; attr =
dom.getNextAttr(node, attr)) {
278 const char* attrName =
dom.getAttrName(node, attr);
279 const char* attrValue =
dom.getAttrValue(node, attr);
280 if (!attrName || !attrValue) {
291 for (
size_t i = 0;
i <
count; ++
i) {
292 if (strcmp(attrValue, uris[
i]) != 0) {
295 outNamespaces[
i] = attrName;
305 const char* outNamespaces[]) {
312 const char* rootName =
dom.getName(
root);
313 if (!rootName || strcmp(rootName,
"x:xmpmeta") != 0) {
318 const char* kRdf =
"rdf:RDF";
319 for (
const auto* rdf =
dom.getFirstChild(
root, kRdf); rdf;
320 rdf =
dom.getNextSibling(rdf, kRdf)) {
321 std::vector<const char*> rdfNamespaces(
count,
nullptr);
325 const char* kDesc =
"rdf:Description";
326 for (
const auto*
desc =
dom.getFirstChild(rdf, kDesc);
desc;
328 std::vector<const char*> descNamespaces = rdfNamespaces;
332 bool foundAllUris =
true;
333 for (
size_t i = 0;
i <
count; ++
i) {
334 if (!descNamespaces[
i]) {
335 foundAllUris =
false;
340 for (
size_t i = 0;
i <
count; ++
i) {
341 outNamespaces[
i] = descNamespaces[
i];
366 bool findUriNamespaces(
size_t count,
368 const char* outNamespaces[],
369 const SkDOM** outDom,
377 const char* namespaces[1] = {
nullptr};
378 const char* uris[1] = {
"http://ns.adobe.com/xmp/note/"};
385 return get_attr(&fStandardDOM, extendedNode, xmpNotePrefix,
"HasExtendedXMP");
388bool SkXmpImpl::findUriNamespaces(
size_t count,
390 const char* outNamespaces[],
391 const SkDOM** outDom,
400 *outDom = &fStandardDOM;
405 *outDom = &fExtendedDOM;
414 const char* namespaces[2] = {
nullptr,
nullptr};
415 const char* uris[2] = {
"http://ns.google.com/photos/1.0/container/",
416 "http://ns.google.com/photos/1.0/container/item/"};
419 if (!findUriNamespaces(2, uris, namespaces, &
dom, &node)) {
433 const auto* seq =
dom->getFirstChild(directory,
"rdf:Seq");
441 bool isFirstItem =
true;
443 for (
const auto* li =
dom->getFirstChild(seq,
"rdf:li"); li;
444 li =
dom->getNextSibling(li,
"rdf:li")) {
452 const char* itemSemantic =
get_attr(
dom, item, itemPrefix,
"Semantic");
458 const char* itemMime =
get_attr(
dom, item, itemPrefix,
"Mime");
467 if (strcmp(itemSemantic,
"Primary") != 0) {
472 if (strcmp(itemMime,
"image/jpeg") != 0) {
473 SkCodecPrintf(
"Primary does not report that it is image/jpeg.\n");
499 if (strcmp(itemSemantic,
"GainMap") != 0) {
504 if (strcmp(itemMime,
"image/jpeg") != 0) {
505 SkCodecPrintf(
"GainMap does not report that it is image/jpeg.\n");
521 const char* namespaces[2] = {
nullptr,
nullptr};
522 const char* uris[2] = {
"http://ns.apple.com/pixeldatainfo/1.0/",
523 "http://ns.apple.com/HDRGainMap/1.0/"};
526 if (!findUriNamespaces(2, uris, namespaces, &
dom, &node)) {
532 const char* auxiliaryImageType =
get_attr(
dom, node, adpiPrefix,
"AuxiliaryImageType");
533 if (!auxiliaryImageType) {
537 if (strcmp(auxiliaryImageType,
"urn:com:apple:photo:2020:aux:hdrgainmap") != 0) {
551 float hdrHeadroom = exifHdrHeadroom;
552 float xmpHdrHeadroom = 0.f;
553 if (
get_attr_float(
dom, node, hdrGainMapPrefix,
"HDRGainMapHeadroom", &xmpHdrHeadroom)) {
554 hdrHeadroom = xmpHdrHeadroom;
559 info->fGainmapRatioMin = {1.f, 1.f, 1.f, 1.f};
560 info->fGainmapRatioMax = {hdrHeadroom, hdrHeadroom, hdrHeadroom, 1.f};
561 info->fGainmapGamma = {1.f, 1.f, 1.f, 1.f};
562 info->fEpsilonSdr = {0.f, 0.f, 0.f, 1.f};
563 info->fEpsilonHdr = {0.f, 0.f, 0.f, 1.f};
564 info->fDisplayRatioSdr = 1.f;
565 info->fDisplayRatioHdr = hdrHeadroom;
573 const char* namespaces[1] = {
nullptr};
574 const char* uris[1] = {
"http://ns.adobe.com/hdr-gain-map/1.0/"};
577 if (!findUriNamespaces(1, uris, namespaces, &
dom, &node)) {
588 if (strcmp(
version,
"1.0") != 0) {
594 bool baseRenditionIsHDR =
false;
595 SkColor4f gainMapMin = {0.f, 0.f, 0.f, 1.f};
596 SkColor4f gainMapMax = {1.f, 1.f, 1.f, 1.f};
598 SkColor4f offsetSdr = {1.f / 64.f, 1.f / 64.f, 1.f / 64.f, 0.f};
599 SkColor4f offsetHdr = {1.f / 64.f, 1.f / 64.f, 1.f / 64.f, 0.f};
604 get_attr_bool(
dom, node, hdrgmPrefix,
"BaseRenditionIsHDR", &baseRenditionIsHDR);
614 if (!outGainmapInfo) {
619 std::exp(gainMapMin.fG * kLog2),
620 std::exp(gainMapMin.fB * kLog2),
623 std::exp(gainMapMax.fG * kLog2),
624 std::exp(gainMapMax.fB * kLog2),
626 outGainmapInfo->
fGainmapGamma = {1.f / gamma.fR, 1.f / gamma.fG, 1.f / gamma.fB, 1.f};
631 if (baseRenditionIsHDR) {
642 if (!
dom->build(*xmpdStream)) {
653 std::unique_ptr<SkXmpImpl> xmp(
new SkXmpImpl);
654 if (!xmp->parseDom(std::move(xmpData),
false)) {
661 std::unique_ptr<SkXmpImpl> xmp(
new SkXmpImpl);
662 if (!xmp->parseDom(std::move(xmpStandard),
false)) {
667 (void)xmp->parseDom(std::move(xmpExtended),
true);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
#define SkCodecPrintf(...)
static void find_uri_namespaces(const SkDOM &dom, const SkDOM::Node *node, size_t count, const char *uris[], const char *outNamespaces[])
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 size_t kXmlnsPrefixLength
static const char * get_unique_child_text(const SkDOM &dom, const SkDOM::Node *node, const std::string &childName)
static const char * get_attr(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &key)
static bool get_attr_bool(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &key, bool *outValue)
static bool get_attr_float3(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &key, SkColor4f *outValue)
static const char * get_namespace_prefix(const char *name)
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 * kXmlnsPrefix
static const SkDOM::Node * get_typed_child(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &type)
static bool get_attr_float(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &key, float *outValue)
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
static const char * FindScalar(const char str[], SkScalar *value)
static const char * FindS32(const char str[], int32_t *value)
static int FindList(const char str[], const char list[])
const char * getExtendedXmpGuid() const override
bool parseDom(sk_sp< SkData > xmpData, bool extended)
bool getGainmapInfoApple(float exifHdrHeadroom, SkGainmapInfo *info) const override
bool getContainerGainmapLocation(size_t *offset, size_t *size) const override
bool getGainmapInfoAdobe(SkGainmapInfo *info) const override
static std::unique_ptr< SkXmp > Make(sk_sp< SkData > xmpData)
DEF_SWITCHES_START aot vmservice shared library name
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
SkColor4f fGainmapRatioMax
SkColor4f fGainmapRatioMin
BaseImageType fBaseImageType