545 {
547
548 std::vector<std::pair<uint32_t, sk_sp<SkData>>> tags;
549
550
553 tags.emplace_back(
kTAG_rXYZ, write_xyz_tag(
m.vals[0][0],
m.vals[1][0],
m.vals[2][0]));
554 tags.emplace_back(
kTAG_gXYZ, write_xyz_tag(
m.vals[0][1],
m.vals[1][1],
m.vals[2][1]));
555 tags.emplace_back(
kTAG_bXYZ, write_xyz_tag(
m.vals[0][2],
m.vals[1][2],
m.vals[2][2]));
556 }
557
558
559 tags.emplace_back(
kTAG_wtpt, write_xyz_tag(kD50_x, kD50_y, kD50_z));
560
561
564
565
566
569 } else {
571 }
572
575 } else {
577 }
578 }
579
580
582
585 }
586
587
589 const auto& a2b =
profile->A2B;
590 SkASSERT(a2b.output_channels == kNumChannels);
592 a2b.output_curves,
593 a2b.input_channels ? a2b.input_curves : nullptr,
594 a2b.input_channels ? a2b.grid_points : nullptr,
595 a2b.input_channels ? a2b.grid_16 : nullptr,
596 a2b.matrix_channels ? a2b.matrix_curves : nullptr,
597 a2b.matrix_channels ? &a2b.matrix : nullptr);
598 tags.emplace_back(
kTAG_A2B0, std::move(a2b_data));
599 }
600
601
603 const auto& b2a =
profile->B2A;
604 SkASSERT(b2a.input_channels == kNumChannels);
606 b2a.input_curves,
607 b2a.output_channels ? b2a.input_curves : nullptr,
608 b2a.output_channels ? b2a.grid_points : nullptr,
609 b2a.output_channels ? b2a.grid_16 : nullptr,
610 b2a.matrix_channels ? b2a.matrix_curves : nullptr,
611 b2a.matrix_channels ? &b2a.matrix : nullptr);
612 tags.emplace_back(
kTAG_B2A0, std::move(b2a_data));
613 }
614
615
616 tags.emplace_back(
kTAG_cprt, write_text_tag(
"Google Inc. 2016"));
617
618
619 std::string generatedDesc;
622 for (const auto& tag : tags) {
623 md5.write(&tag.first,
sizeof(tag.first));
624 md5.write(tag.second->bytes(), tag.second->size());
625 }
628 desc = generatedDesc.c_str();
629 }
630
632
633
634 size_t tag_data_size = 0;
635 for (const auto& tag : tags) {
636 tag_data_size += tag.second->size();
637 }
639 size_t profile_size =
kICCHeaderSize + tag_table_size + tag_data_size;
640
641
646
648 uint8_t* ptr = (uint8_t*)profile_data.get();
651
652
653
654
655 size_t last_tag_offset =
sizeof(
header) + tag_table_size;
656 size_t last_tag_size = 0;
657 for (const auto& tag : tags) {
658 if (!tag.second->isEmpty()) {
659 last_tag_offset = last_tag_offset + last_tag_size;
660 last_tag_size = tag.second->size();
661 }
662 uint32_t tag_table_entry[3] = {
666 };
667 memcpy(ptr, tag_table_entry, sizeof(tag_table_entry));
668 ptr += sizeof(tag_table_entry);
669 }
670
671
672 for (const auto& tag : tags) {
673 if (tag.second->isEmpty()) continue;
674 memcpy(ptr, tag.second->data(), tag.second->size());
675 ptr += tag.second->size();
676 }
677
678 SkASSERT(profile_size ==
static_cast<size_t>(ptr - (uint8_t*)profile_data.get()));
680}
static SkMD5::Digest md5(const SkBitmap &bm)
#define SkEndian_SwapBE32(n)
static constexpr uint32_t kTAG_mBAType
static constexpr uint32_t kTAG_desc
static constexpr uint32_t kTAG_gTRC
static constexpr uint32_t kTAG_cprt
static constexpr uint32_t kTAG_bTRC
static constexpr size_t kICCHeaderSize
static constexpr uint32_t kTAG_gXYZ
static constexpr uint32_t kTAG_wtpt
static constexpr uint32_t kTAG_A2B0
static constexpr uint32_t kTAG_B2A0
static constexpr size_t kICCTagTableEntrySize
static constexpr uint32_t kTAG_mABType
static constexpr uint32_t kTAG_bXYZ
static constexpr uint32_t kTAG_rXYZ
static constexpr uint32_t kTAG_rTRC
static constexpr uint32_t kTAG_cicp
static sk_sp< SkData > MakeFromMalloc(const void *data, size_t length)
static sk_sp< SkData > MakeEmpty()
const char * c_str() const
static const char header[]
SkString toHexString() const