Flutter Engine
The Flutter Engine
ICCTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
13#include "modules/skcms/skcms.h"
14#include "tests/Test.h"
15#include "tools/Resources.h"
16
17#include <cmath>
18#include <cstdint>
19#include <cstdlib>
20
21DEF_TEST(AdobeRGB, r) {
22 if (sk_sp<SkData> profile = GetResourceAsData("icc_profiles/AdobeRGB1998.icc")) {
23 skcms_ICCProfile parsed;
24 REPORTER_ASSERT(r, skcms_Parse(profile->data(), profile->size(), &parsed));
25 REPORTER_ASSERT(r, !parsed.has_CICP);
26
27 auto got = SkColorSpace::Make(parsed);
29 REPORTER_ASSERT(r, SkColorSpace::Equals(got.get(), want.get()));
30 }
31}
32
33DEF_TEST(HDR_ICC, r) {
34 constexpr size_t kTestCount = 3;
35 sk_sp<SkData> profile[kTestCount] = {
39 };
40
41 sk_sp<SkData> dst_profile[kTestCount] = {
45 };
46
47 constexpr size_t kPixelCount = 7;
48
49 // clang-format off
50 float pixels[kPixelCount][3] = {
51 { 0.00f, 0.00f, 0.00f, },
52 { 0.50f, 0.50f, 0.50f, },
53 { 0.50f, 0.00f, 0.00f, },
54 { 0.00f, 0.50f, 0.00f, },
55 { 0.00f, 0.00f, 0.50f, },
56 { 0.25f, 0.50f, 0.00f, },
57 { 0.75f, 0.75f, 0.75f, },
58 };
59
60 // The tone mapped value of PQ 0.5 and 0.75.
61 constexpr float kPQ_05 = 0.3182877451f;
62 constexpr float kPQ_075 = 0.9943588777f;
63
64 // The tone mapped value of PQ 0.25, when maxRGB is 0.5.
65 constexpr float kPQ_025 = 0.020679904f;
66
67 // The tone mapped value of HLG 0.5 and 0.75 (when all channels are equal).
68 constexpr float kHLG_05 = 0.20188954163f;
69 constexpr float kHLG_075 = 0.5208149688f;
70
71 // The linearized values of sRGB 0.25, 0.5, and 0.75.
72 constexpr float kSRGB_025 = 0.05087607f;
73 constexpr float kSRGB_05 = 0.21404112f;
74 constexpr float kSRGB_075 = 0.52252153f;
75
76 float dst_pixels_expected[kTestCount][kPixelCount][3] = {
77 {
78 { 0.f, 0.f, 0.f, },
79 { kPQ_05, kPQ_05, kPQ_05, },
80 { kPQ_05, 0.f, 0.f, },
81 { 0.f, kPQ_05, 0.f, },
82 { 0.f, 0.f, kPQ_05, },
83 { kPQ_025, kPQ_05, 0.f, },
84 { kPQ_075, kPQ_075, kPQ_075, }, // PQ maps 0.75 ~ 1000 nits to 1.0
85 },
86 {
87 { 0.f, 0.f, 0.f, },
88 { kHLG_05, kHLG_05, kHLG_05, },
89 { 0.1618f, 0.f, 0.f, }, // HLG will map 0.5 to different values
90 { 0.f, 0.1895f, 0.f, }, // if it is the R, G, or B channel, because
91 { 0.f, 0.f, 0.1251f, }, // of the OOTF.
92 { 0.0513f, 0.1924f, 0.f, },
93 { kHLG_075, kHLG_075, kHLG_075, },
94 },
95 {
96 { 0.f, 0.f, 0.f, },
97 { kSRGB_05, kSRGB_05, kSRGB_05, }, // This is just the sRGB transfer function
98 { kSRGB_05, 0.f, 0.f, },
99 { 0.f, kSRGB_05, 0.f, },
100 { 0.f, 0.f, kSRGB_05, },
101 { kSRGB_025, kSRGB_05, 0.f, },
102 { kSRGB_075, kSRGB_075, kSRGB_075, },
103 },
104 };
105 // clang-format on
106 bool cicp_expected[kTestCount] = {true, true, false};
107 bool a2b_expected[kTestCount] = {true, true, false};
108 uint32_t cicp_primaries_expected[kTestCount] = {9, 12, 0};
109 uint32_t cicp_trfn_expected[kTestCount] = {16, 18, 0};
110
111 for (size_t test = 0; test < kTestCount; ++test) {
112 skcms_ICCProfile parsed;
114
115 REPORTER_ASSERT(r, parsed.has_A2B == a2b_expected[test]);
116 REPORTER_ASSERT(r, parsed.has_CICP == cicp_expected[test]);
117 if (cicp_expected[test]) {
118 REPORTER_ASSERT(r, parsed.CICP.color_primaries == cicp_primaries_expected[test]);
119 REPORTER_ASSERT(r, parsed.CICP.transfer_characteristics == cicp_trfn_expected[test]);
122 }
123
124 skcms_ICCProfile dst_parsed;
126 r, skcms_Parse(dst_profile[test]->data(), dst_profile[test]->size(), &dst_parsed));
127
128 for (size_t pixel = 0; pixel < kPixelCount; ++pixel) {
129 float dst_pixel_actual[3]{0.f, 0.f, 0.f};
130 bool xform_result = skcms_Transform(pixels[pixel],
133 &parsed,
134 dst_pixel_actual,
137 &dst_parsed,
138 1);
139 REPORTER_ASSERT(r, xform_result);
140
141 auto approx_equal = [=](float x, float y) { return std::abs(x - y) < 1.f / 64.f; };
142 for (size_t i = 0; i < 3; ++i) {
144 r, approx_equal(dst_pixel_actual[i], dst_pixels_expected[test][pixel][i]));
145 }
146 }
147 }
148}
#define test(name)
static bool approx_equal(const SkColor4f &a, const SkColor4f &b)
DEF_TEST(AdobeRGB, r)
Definition: ICCTest.cpp:21
sk_sp< SkData > GetResourceAsData(const char *resource)
Definition: Resources.cpp:42
SK_API sk_sp< SkData > SkWriteICCProfile(const skcms_TransferFunction &, const skcms_Matrix3x3 &toXYZD50)
Definition: SkICC.cpp:682
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
static bool Equals(const SkColorSpace *, const SkColorSpace *)
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
static sk_sp< SkColorSpace > Make(const skcms_ICCProfile &)
double y
double x
static constexpr skcms_Matrix3x3 kSRGB
Definition: SkColorSpace.h:67
static constexpr skcms_Matrix3x3 kAdobeRGB
Definition: SkColorSpace.h:77
static constexpr skcms_Matrix3x3 kRec2020
Definition: SkColorSpace.h:93
static constexpr skcms_Matrix3x3 kDisplayP3
Definition: SkColorSpace.h:87
static constexpr skcms_TransferFunction k2Dot2
Definition: SkColorSpace.h:48
static constexpr skcms_TransferFunction kSRGB
Definition: SkColorSpace.h:45
static constexpr skcms_TransferFunction kHLG
Definition: SkColorSpace.h:60
static constexpr skcms_TransferFunction kPQ
Definition: SkColorSpace.h:57
static constexpr skcms_TransferFunction kLinear
Definition: SkColorSpace.h:51
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
Definition: switches.h:259
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition: SkVx.h:707
bool skcms_Transform(const void *src, skcms_PixelFormat srcFmt, skcms_AlphaFormat srcAlpha, const skcms_ICCProfile *srcProfile, void *dst, skcms_PixelFormat dstFmt, skcms_AlphaFormat dstAlpha, const skcms_ICCProfile *dstProfile, size_t nz)
Definition: skcms.cc:2495
@ skcms_PixelFormat_RGB_fff
Definition: skcms_public.h:315
static bool skcms_Parse(const void *buf, size_t len, skcms_ICCProfile *profile)
Definition: skcms_public.h:245
@ skcms_AlphaFormat_Opaque
Definition: skcms_public.h:337
uint8_t color_primaries
Definition: skcms_public.h:167
uint8_t matrix_coefficients
Definition: skcms_public.h:169
uint8_t video_full_range_flag
Definition: skcms_public.h:170
uint8_t transfer_characteristics
Definition: skcms_public.h:168
skcms_CICP CICP
Definition: skcms_public.h:208
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63