Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | List of all members
SkXmpImpl Class Referencefinal
Inheritance diagram for SkXmpImpl:
SkXmp

Public Member Functions

 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
 
bool parseDom (sk_sp< SkData > xmpData, bool extended)
 
- Public Member Functions inherited from SkXmp
 SkXmp ()=default
 
virtual ~SkXmp ()=default
 
 SkXmp (const SkXmp &)=delete
 
SkXmpoperator= (const SkXmp &)=delete
 

Additional Inherited Members

- Static Public Member Functions inherited from SkXmp
static std::unique_ptr< SkXmpMake (sk_sp< SkData > xmpData)
 
static std::unique_ptr< SkXmpMake (sk_sp< SkData > xmpStandard, sk_sp< SkData > xmpExtended)
 

Detailed Description

Definition at line 353 of file SkXmp.cpp.

Constructor & Destructor Documentation

◆ SkXmpImpl()

SkXmpImpl::SkXmpImpl ( )
default

Member Function Documentation

◆ getContainerGainmapLocation()

bool SkXmpImpl::getContainerGainmapLocation ( size_t *  offset,
size_t *  size 
) const
overridevirtual

Implements SkXmp.

Definition at line 412 of file SkXmp.cpp.

412 {
413 // Find a node that matches the requested namespaces and URIs.
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/"};
417 const SkDOM* dom = nullptr;
418 const SkDOM::Node* node = nullptr;
419 if (!findUriNamespaces(2, uris, namespaces, &dom, &node)) {
420 return false;
421 }
422 const char* containerPrefix = get_namespace_prefix(namespaces[0]);
423 const char* itemPrefix = get_namespace_prefix(namespaces[1]);
424
425 // The node must have a Container:Directory child.
426 const auto* directory = get_typed_child(dom, node, containerPrefix, "Directory");
427 if (!directory) {
428 SkCodecPrintf("Missing Container Directory");
429 return false;
430 }
431
432 // That Container:Directory must have a sequence of items.
433 const auto* seq = dom->getFirstChild(directory, "rdf:Seq");
434 if (!seq) {
435 SkCodecPrintf("Missing rdf:Seq");
436 return false;
437 }
438
439 // Iterate through the items in the Container:Directory's sequence. Keep a running sum of the
440 // Item:Length of all items that appear before the GainMap.
441 bool isFirstItem = true;
442 size_t offset = 0;
443 for (const auto* li = dom->getFirstChild(seq, "rdf:li"); li;
444 li = dom->getNextSibling(li, "rdf:li")) {
445 // Each list item must contain a Container:Item.
446 const auto* item = get_typed_child(dom, li, containerPrefix, "Item");
447 if (!item) {
448 SkCodecPrintf("List item does not have container Item.\n");
449 return false;
450 }
451 // A Semantic is required for every item.
452 const char* itemSemantic = get_attr(dom, item, itemPrefix, "Semantic");
453 if (!itemSemantic) {
454 SkCodecPrintf("Item is missing Semantic.\n");
455 return false;
456 }
457 // A Mime is required for every item.
458 const char* itemMime = get_attr(dom, item, itemPrefix, "Mime");
459 if (!itemMime) {
460 SkCodecPrintf("Item is missing Mime.\n");
461 return false;
462 }
463
464 if (isFirstItem) {
465 isFirstItem = false;
466 // The first item must be Primary.
467 if (strcmp(itemSemantic, "Primary") != 0) {
468 SkCodecPrintf("First item is not Primary.\n");
469 return false;
470 }
471 // The first item has mime type image/jpeg (we are decoding a jpeg).
472 if (strcmp(itemMime, "image/jpeg") != 0) {
473 SkCodecPrintf("Primary does not report that it is image/jpeg.\n");
474 return false;
475 }
476 // The first media item can contain a Padding attribute, which specifies additional
477 // padding between the end of the encoded primary image and the beginning of the next
478 // media item. Only the first media item can contain a Padding attribute.
479 int32_t padding = 0;
480 if (get_attr_int32(dom, item, itemPrefix, "Padding", &padding)) {
481 if (padding < 0) {
482 SkCodecPrintf("Item padding must be non-negative.");
483 return false;
484 }
485 offset += padding;
486 }
487 } else {
488 // A Length is required for all non-Primary items.
489 int32_t length = 0;
490 if (!get_attr_int32(dom, item, itemPrefix, "Length", &length)) {
491 SkCodecPrintf("Item length is absent.");
492 return false;
493 }
494 if (length < 0) {
495 SkCodecPrintf("Item length must be non-negative.");
496 return false;
497 }
498 // If this is not the recovery map, then read past it.
499 if (strcmp(itemSemantic, "GainMap") != 0) {
500 offset += length;
501 continue;
502 }
503 // The recovery map must have mime type image/jpeg in this implementation.
504 if (strcmp(itemMime, "image/jpeg") != 0) {
505 SkCodecPrintf("GainMap does not report that it is image/jpeg.\n");
506 return false;
507 }
508
509 // Populate the location in the file at which to find the gainmap image.
510 *outOffset = offset;
511 *outSize = length;
512 return true;
513 }
514 }
515 return false;
516}
#define SkCodecPrintf(...)
Definition SkCodecPriv.h:23
static const char * get_attr(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &key)
Definition SkXmp.cpp:125
static const char * get_namespace_prefix(const char *name)
Definition SkXmp.cpp:32
static bool get_attr_int32(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &key, int32_t *value)
Definition SkXmp.cpp:161
static const SkDOM::Node * get_typed_child(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &type)
Definition SkXmp.cpp:86
Definition SkDOM.h:24
size_t length
Definition dom.py:1
Point offset

◆ getExtendedXmpGuid()

const char * SkXmpImpl::getExtendedXmpGuid ( ) const
overridevirtual

Implements SkXmp.

Definition at line 376 of file SkXmp.cpp.

376 {
377 const char* namespaces[1] = {nullptr};
378 const char* uris[1] = {"http://ns.adobe.com/xmp/note/"};
379 const auto* extendedNode = find_uri_namespaces(fStandardDOM, 1, uris, namespaces);
380 if (!extendedNode) {
381 return nullptr;
382 }
383 const auto xmpNotePrefix = get_namespace_prefix(namespaces[0]);
384 // Extract the GUID (the MD5 hash) of the extended metadata.
385 return get_attr(&fStandardDOM, extendedNode, xmpNotePrefix, "HasExtendedXMP");
386}
static void find_uri_namespaces(const SkDOM &dom, const SkDOM::Node *node, size_t count, const char *uris[], const char *outNamespaces[])
Definition SkXmp.cpp:271

◆ getGainmapInfoHDRGainMap()

bool SkXmpImpl::getGainmapInfoHDRGainMap ( SkGainmapInfo info) const
overridevirtual

Implements SkXmp.

Definition at line 519 of file SkXmp.cpp.

519 {
520 // Find a node that matches the requested namespaces and URIs.
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/"};
524 const SkDOM* dom = nullptr;
525 const SkDOM::Node* node = nullptr;
526 if (!findUriNamespaces(2, uris, namespaces, &dom, &node)) {
527 return false;
528 }
529 const char* adpiPrefix = get_namespace_prefix(namespaces[0]);
530 const char* hdrGainMapPrefix = get_namespace_prefix(namespaces[1]);
531
532 const char* auxiliaryImageType = get_attr(dom, node, adpiPrefix, "AuxiliaryImageType");
533 if (!auxiliaryImageType) {
534 SkCodecPrintf("Did not find AuxiliaryImageType.\n");
535 return false;
536 }
537 if (strcmp(auxiliaryImageType, "urn:com:apple:photo:2020:aux:hdrgainmap") != 0) {
538 SkCodecPrintf("AuxiliaryImageType was not HDR gain map.\n");
539 return false;
540 }
541
542 int32_t version = 0;
543 if (!get_attr_int32(dom, node, hdrGainMapPrefix, "HDRGainMapVersion", &version)) {
544 SkCodecPrintf("Did not find HDRGainMapVersion.\n");
545 return false;
546 }
547 if (version != 65536) {
548 SkCodecPrintf("HDRGainMapVersion was not 65536.\n");
549 return false;
550 }
551
552 // This node will often have StoredFormat and NativeFormat children that have inner text that
553 // specifies the integer 'L008' (also known as kCVPixelFormatType_OneComponent8).
554 const float kRatioMax = std::exp(1.f);
555 info->fGainmapRatioMin = {1.f, 1.f, 1.f, 1.f};
556 info->fGainmapRatioMax = {kRatioMax, kRatioMax, kRatioMax, 1.f};
557 info->fGainmapGamma = {1.f, 1.f, 1.f, 1.f};
558 info->fEpsilonSdr = {0.f, 0.f, 0.f, 1.f};
559 info->fEpsilonHdr = {0.f, 0.f, 0.f, 1.f};
560 info->fDisplayRatioSdr = 1.f;
561 info->fDisplayRatioHdr = kRatioMax;
563 return true;
564}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213

◆ getGainmapInfoHDRGM()

bool SkXmpImpl::getGainmapInfoHDRGM ( SkGainmapInfo info) const
overridevirtual

Implements SkXmp.

Definition at line 566 of file SkXmp.cpp.

566 {
567 // Find a node that matches the requested namespace and URI.
568 const char* namespaces[1] = {nullptr};
569 const char* uris[1] = {"http://ns.adobe.com/hdr-gain-map/1.0/"};
570 const SkDOM* dom = nullptr;
571 const SkDOM::Node* node = nullptr;
572 if (!findUriNamespaces(1, uris, namespaces, &dom, &node)) {
573 return false;
574 }
575 const char* hdrgmPrefix = get_namespace_prefix(namespaces[0]);
576
577 // Require that hdrgm:Version="1.0" be present.
578 const char* version = get_attr(dom, node, hdrgmPrefix, "Version");
579 if (!version) {
580 SkCodecPrintf("Version attribute is absent.\n");
581 return false;
582 }
583 if (strcmp(version, "1.0") != 0) {
584 SkCodecPrintf("Version is \"%s\", not \"1.0\".\n", version);
585 return false;
586 }
587
588 // Initialize the parameters to their defaults.
589 bool baseRenditionIsHDR = false;
590 SkColor4f gainMapMin = {0.f, 0.f, 0.f, 1.f}; // log2 value
591 SkColor4f gainMapMax = {1.f, 1.f, 1.f, 1.f}; // log2 value
592 SkColor4f gamma = {1.f, 1.f, 1.f, 1.f};
593 SkColor4f offsetSdr = {1.f / 64.f, 1.f / 64.f, 1.f / 64.f, 0.f};
594 SkColor4f offsetHdr = {1.f / 64.f, 1.f / 64.f, 1.f / 64.f, 0.f};
595 SkScalar hdrCapacityMin = 0.f; // log2 value
596 SkScalar hdrCapacityMax = 1.f; // log2 value
597
598 // Read all parameters that are present.
599 get_attr_bool(dom, node, hdrgmPrefix, "BaseRenditionIsHDR", &baseRenditionIsHDR);
600 get_attr_float3(dom, node, hdrgmPrefix, "GainMapMin", &gainMapMin);
601 get_attr_float3(dom, node, hdrgmPrefix, "GainMapMax", &gainMapMax);
602 get_attr_float3(dom, node, hdrgmPrefix, "Gamma", &gamma);
603 get_attr_float3(dom, node, hdrgmPrefix, "OffsetSDR", &offsetSdr);
604 get_attr_float3(dom, node, hdrgmPrefix, "OffsetHDR", &offsetHdr);
605 get_attr_float(dom, node, hdrgmPrefix, "HDRCapacityMin", &hdrCapacityMin);
606 get_attr_float(dom, node, hdrgmPrefix, "HDRCapacityMax", &hdrCapacityMax);
607
608 // Translate all parameters to SkGainmapInfo's expected format.
609 const float kLog2 = std::log(2.f);
610 outGainmapInfo->fGainmapRatioMin = {std::exp(gainMapMin.fR * kLog2),
611 std::exp(gainMapMin.fG * kLog2),
612 std::exp(gainMapMin.fB * kLog2),
613 1.f};
614 outGainmapInfo->fGainmapRatioMax = {std::exp(gainMapMax.fR * kLog2),
615 std::exp(gainMapMax.fG * kLog2),
616 std::exp(gainMapMax.fB * kLog2),
617 1.f};
618 outGainmapInfo->fGainmapGamma = {1.f / gamma.fR, 1.f / gamma.fG, 1.f / gamma.fB, 1.f};
619 outGainmapInfo->fEpsilonSdr = offsetSdr;
620 outGainmapInfo->fEpsilonHdr = offsetHdr;
621 outGainmapInfo->fDisplayRatioSdr = std::exp(hdrCapacityMin * kLog2);
622 outGainmapInfo->fDisplayRatioHdr = std::exp(hdrCapacityMax * kLog2);
623 if (baseRenditionIsHDR) {
624 outGainmapInfo->fBaseImageType = SkGainmapInfo::BaseImageType::kHDR;
625 } else {
626 outGainmapInfo->fBaseImageType = SkGainmapInfo::BaseImageType::kSDR;
627 }
628 return true;
629}
static bool get_attr_bool(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &key, bool *outValue)
Definition SkXmp.cpp:138
static bool get_attr_float3(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &key, SkColor4f *outValue)
Definition SkXmp.cpp:255
static bool get_attr_float(const SkDOM *dom, const SkDOM::Node *node, const std::string &prefix, const std::string &key, float *outValue)
Definition SkXmp.cpp:177
float SkScalar
Definition extension.cpp:12

◆ parseDom()

bool SkXmpImpl::parseDom ( sk_sp< SkData xmpData,
bool  extended 
)

Definition at line 631 of file SkXmp.cpp.

631 {
632 SkDOM* dom = extended ? &fExtendedDOM : &fStandardDOM;
633 auto xmpdStream = SkMemoryStream::Make(std::move(xmpData));
634 if (!dom->build(*xmpdStream)) {
635 SkCodecPrintf("Failed to parse XMP %s metadata.\n", extended ? "extended" : "standard");
636 return false;
637 }
638 return true;
639}
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
Definition SkStream.cpp:314

The documentation for this class was generated from the following file: