msarett | 6a73821 | 2016-03-04 13:27:35 -0800 | [diff] [blame] | 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 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 8 | #include "include/codec/SkCodec.h" |
| 9 | #include "include/core/SkColorSpace.h" |
| 10 | #include "include/core/SkData.h" |
| 11 | #include "include/core/SkImageInfo.h" |
| 12 | #include "include/core/SkRefCnt.h" |
| 13 | #include "include/core/SkStream.h" |
| 14 | #include "include/core/SkTypes.h" |
Brian Osman | ea236bf | 2019-04-29 10:28:22 -0400 | [diff] [blame] | 15 | #include "include/third_party/skcms/skcms.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 16 | #include "src/core/SkColorSpacePriv.h" |
| 17 | #include "tests/Test.h" |
| 18 | #include "tools/Resources.h" |
Hal Canary | 8a00144 | 2018-09-19 11:31:27 -0400 | [diff] [blame] | 19 | |
Hal Canary | 8a00144 | 2018-09-19 11:31:27 -0400 | [diff] [blame] | 20 | #include "png.h" |
Brian Osman | 12e4e84 | 2018-04-27 12:03:51 -0400 | [diff] [blame] | 21 | |
Ben Wagner | 9707a7e | 2019-05-06 17:17:19 -0400 | [diff] [blame] | 22 | #include <string.h> |
Ben Wagner | eed6128 | 2018-04-17 14:14:51 -0400 | [diff] [blame] | 23 | #include <memory> |
| 24 | #include <utility> |
| 25 | |
reed | 50d3b57 | 2016-05-03 12:13:21 -0700 | [diff] [blame] | 26 | static bool almost_equal(float a, float b) { |
| 27 | return SkTAbs(a - b) < 0.001f; |
| 28 | } |
| 29 | |
| 30 | static void test_space(skiatest::Reporter* r, SkColorSpace* space, |
| 31 | const float red[], const float green[], const float blue[], |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 32 | bool expectSRGB = false) { |
msarett | bb9f774 | 2016-05-17 09:31:20 -0700 | [diff] [blame] | 33 | |
msarett | 9d15dab | 2016-08-24 07:36:06 -0700 | [diff] [blame] | 34 | REPORTER_ASSERT(r, nullptr != space); |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 35 | REPORTER_ASSERT(r, expectSRGB == space->gammaCloseToSRGB()); |
msarett | bb9f774 | 2016-05-17 09:31:20 -0700 | [diff] [blame] | 36 | |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 37 | skcms_Matrix3x3 mat; |
Mike Klein | ae5e864 | 2018-10-03 17:00:41 -0400 | [diff] [blame] | 38 | space->toXYZD50(&mat); |
brianosman | de68d6c | 2016-09-09 10:36:17 -0700 | [diff] [blame] | 39 | const float* ref[3] = { red, green, blue }; |
reed | 50d3b57 | 2016-05-03 12:13:21 -0700 | [diff] [blame] | 40 | for (int i = 0; i < 3; ++i) { |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 41 | REPORTER_ASSERT(r, almost_equal(ref[i][0], mat.vals[0][i])); |
| 42 | REPORTER_ASSERT(r, almost_equal(ref[i][1], mat.vals[1][i])); |
| 43 | REPORTER_ASSERT(r, almost_equal(ref[i][2], mat.vals[2][i])); |
reed | 50d3b57 | 2016-05-03 12:13:21 -0700 | [diff] [blame] | 44 | } |
| 45 | } |
| 46 | |
msarett | 9d15dab | 2016-08-24 07:36:06 -0700 | [diff] [blame] | 47 | static void test_path(skiatest::Reporter* r, const char* path, |
| 48 | const float red[], const float green[], const float blue[], |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 49 | bool expectSRGB = false) { |
Ben Wagner | 145dbcd | 2016-11-03 14:40:50 -0400 | [diff] [blame] | 50 | std::unique_ptr<SkStream> stream(GetResourceAsStream(path)); |
msarett | 0e6274f | 2016-03-21 08:04:40 -0700 | [diff] [blame] | 51 | REPORTER_ASSERT(r, nullptr != stream); |
Brian Salomon | d2100f2 | 2016-03-25 17:02:20 -0400 | [diff] [blame] | 52 | if (!stream) { |
| 53 | return; |
| 54 | } |
msarett | 0e6274f | 2016-03-21 08:04:40 -0700 | [diff] [blame] | 55 | |
Mike Reed | ede7bac | 2017-07-23 15:30:02 -0400 | [diff] [blame] | 56 | std::unique_ptr<SkCodec> codec(SkCodec::MakeFromStream(std::move(stream))); |
msarett | 0e6274f | 2016-03-21 08:04:40 -0700 | [diff] [blame] | 57 | REPORTER_ASSERT(r, nullptr != codec); |
Brian Salomon | d2100f2 | 2016-03-25 17:02:20 -0400 | [diff] [blame] | 58 | if (!codec) { |
| 59 | return; |
| 60 | } |
msarett | 0e6274f | 2016-03-21 08:04:40 -0700 | [diff] [blame] | 61 | |
Leon Scroggins III | 712476e | 2018-10-03 15:47:00 -0400 | [diff] [blame] | 62 | auto colorSpace = codec->getInfo().refColorSpace(); |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 63 | test_space(r, colorSpace.get(), red, green, blue, expectSRGB); |
msarett | 9d15dab | 2016-08-24 07:36:06 -0700 | [diff] [blame] | 64 | } |
| 65 | |
brianosman | de68d6c | 2016-09-09 10:36:17 -0700 | [diff] [blame] | 66 | static constexpr float g_sRGB_R[]{ 0.4358f, 0.2224f, 0.0139f }; |
| 67 | static constexpr float g_sRGB_G[]{ 0.3853f, 0.7170f, 0.0971f }; |
| 68 | static constexpr float g_sRGB_B[]{ 0.1430f, 0.0606f, 0.7139f }; |
msarett | 9d15dab | 2016-08-24 07:36:06 -0700 | [diff] [blame] | 69 | |
| 70 | DEF_TEST(ColorSpace_sRGB, r) { |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 71 | test_space(r, sk_srgb_singleton(), g_sRGB_R, g_sRGB_G, g_sRGB_B, true); |
msarett | 9d15dab | 2016-08-24 07:36:06 -0700 | [diff] [blame] | 72 | |
| 73 | } |
| 74 | |
| 75 | DEF_TEST(ColorSpaceParseICCProfiles, r) { |
| 76 | |
| 77 | #if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 6) |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 78 | test_path(r, "images/color_wheel_with_profile.png", g_sRGB_R, g_sRGB_G, g_sRGB_B, true); |
msarett | 9d15dab | 2016-08-24 07:36:06 -0700 | [diff] [blame] | 79 | #endif |
msarett | 0e6274f | 2016-03-21 08:04:40 -0700 | [diff] [blame] | 80 | |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 81 | const float red[] = { 0.385117f, 0.716904f, 0.0970612f }; |
reed | 50d3b57 | 2016-05-03 12:13:21 -0700 | [diff] [blame] | 82 | const float green[] = { 0.143051f, 0.0606079f, 0.713913f }; |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 83 | const float blue[] = { 0.436035f, 0.222488f, 0.013916f }; |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 84 | test_path(r, "images/icc-v2-gbr.jpg", red, green, blue); |
msarett | 9d15dab | 2016-08-24 07:36:06 -0700 | [diff] [blame] | 85 | |
Hal Canary | c465d13 | 2017-12-08 10:21:31 -0500 | [diff] [blame] | 86 | test_path(r, "images/webp-color-profile-crash.webp", |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 87 | red, green, blue); |
Hal Canary | c465d13 | 2017-12-08 10:21:31 -0500 | [diff] [blame] | 88 | test_path(r, "images/webp-color-profile-lossless.webp", |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 89 | red, green, blue); |
Hal Canary | c465d13 | 2017-12-08 10:21:31 -0500 | [diff] [blame] | 90 | test_path(r, "images/webp-color-profile-lossy.webp", |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 91 | red, green, blue); |
Hal Canary | c465d13 | 2017-12-08 10:21:31 -0500 | [diff] [blame] | 92 | test_path(r, "images/webp-color-profile-lossy-alpha.webp", |
Brian Osman | 0251880 | 2019-01-22 10:03:29 -0500 | [diff] [blame] | 93 | red, green, blue); |
msarett | 0e6274f | 2016-03-21 08:04:40 -0700 | [diff] [blame] | 94 | } |
msarett | 02125d1 | 2016-05-03 14:24:47 -0700 | [diff] [blame] | 95 | |
Mike Klein | 8fcfcc5 | 2018-05-23 12:43:42 -0400 | [diff] [blame] | 96 | static void test_serialize(skiatest::Reporter* r, sk_sp<SkColorSpace> space, bool isNamed) { |
msarett | a0605bf | 2016-07-28 10:47:50 -0700 | [diff] [blame] | 97 | sk_sp<SkData> data1 = space->serialize(); |
| 98 | |
| 99 | size_t bytes = space->writeToMemory(nullptr); |
| 100 | sk_sp<SkData> data2 = SkData::MakeUninitialized(bytes); |
| 101 | space->writeToMemory(data2->writable_data()); |
| 102 | |
| 103 | sk_sp<SkColorSpace> newSpace1 = SkColorSpace::Deserialize(data1->data(), data1->size()); |
| 104 | sk_sp<SkColorSpace> newSpace2 = SkColorSpace::Deserialize(data2->data(), data2->size()); |
msarett | 111a42d | 2016-06-22 08:18:54 -0700 | [diff] [blame] | 105 | |
Mike Klein | 63c4d35 | 2019-02-21 21:13:05 +0000 | [diff] [blame] | 106 | if (isNamed) { |
| 107 | REPORTER_ASSERT(r, space.get() == newSpace1.get()); |
| 108 | REPORTER_ASSERT(r, space.get() == newSpace2.get()); |
| 109 | } else { |
| 110 | REPORTER_ASSERT(r, SkColorSpace::Equals(space.get(), newSpace1.get())); |
| 111 | REPORTER_ASSERT(r, SkColorSpace::Equals(space.get(), newSpace2.get())); |
| 112 | } |
msarett | 111a42d | 2016-06-22 08:18:54 -0700 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | DEF_TEST(ColorSpace_Serialize, r) { |
Mike Klein | 8fcfcc5 | 2018-05-23 12:43:42 -0400 | [diff] [blame] | 116 | test_serialize(r, SkColorSpace::MakeSRGB(), true); |
| 117 | test_serialize(r, SkColorSpace::MakeSRGBLinear(), true); |
msarett | 111a42d | 2016-06-22 08:18:54 -0700 | [diff] [blame] | 118 | |
Mike Klein | 8fcfcc5 | 2018-05-23 12:43:42 -0400 | [diff] [blame] | 119 | auto test = [&](const char* path) { |
| 120 | sk_sp<SkData> data = GetResourceAsData(path); |
| 121 | |
| 122 | skcms_ICCProfile profile; |
| 123 | REPORTER_ASSERT(r, skcms_Parse(data->data(), data->size(), &profile)); |
| 124 | |
| 125 | sk_sp<SkColorSpace> space = SkColorSpace::Make(profile); |
| 126 | REPORTER_ASSERT(r, space); |
| 127 | |
| 128 | test_serialize(r, space, false); |
| 129 | }; |
| 130 | test("icc_profiles/HP_ZR30w.icc"); |
| 131 | test("icc_profiles/HP_Z32x.icc"); |
msarett | d9015a4 | 2016-08-22 12:29:31 -0700 | [diff] [blame] | 132 | |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 133 | skcms_TransferFunction fn; |
| 134 | fn.a = 1.0f; |
| 135 | fn.b = 0.0f; |
| 136 | fn.c = 1.0f; |
| 137 | fn.d = 0.5f; |
| 138 | fn.e = 0.0f; |
| 139 | fn.f = 0.0f; |
| 140 | fn.g = 1.0f; |
| 141 | skcms_Matrix3x3 toXYZ = {{ |
| 142 | { 1, 0, 0 }, |
| 143 | { 0, 1, 0 }, |
| 144 | { 0, 0, 1 }, |
| 145 | }}; |
Mike Klein | 8fcfcc5 | 2018-05-23 12:43:42 -0400 | [diff] [blame] | 146 | test_serialize(r, SkColorSpace::MakeRGB(fn, toXYZ), false); |
msarett | 111a42d | 2016-06-22 08:18:54 -0700 | [diff] [blame] | 147 | } |
| 148 | |
msarett | abbd6d5 | 2016-08-01 09:43:08 -0700 | [diff] [blame] | 149 | DEF_TEST(ColorSpace_Equals, r) { |
Matt Sarett | 77a7a1b | 2017-02-07 13:56:11 -0500 | [diff] [blame] | 150 | sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB(); |
Mike Klein | 8fcfcc5 | 2018-05-23 12:43:42 -0400 | [diff] [blame] | 151 | |
Mike Klein | 8fcfcc5 | 2018-05-23 12:43:42 -0400 | [diff] [blame] | 152 | auto parse = [&](const char* path) { |
| 153 | sk_sp<SkData> data = GetResourceAsData(path); |
| 154 | |
| 155 | skcms_ICCProfile profile; |
| 156 | REPORTER_ASSERT(r, skcms_Parse(data->data(), data->size(), &profile)); |
| 157 | |
| 158 | sk_sp<SkColorSpace> space = SkColorSpace::Make(profile); |
| 159 | REPORTER_ASSERT(r, space); |
| 160 | |
| 161 | return space; |
| 162 | }; |
| 163 | sk_sp<SkColorSpace> z30 = parse("icc_profiles/HP_ZR30w.icc"); |
| 164 | sk_sp<SkColorSpace> z32 = parse("icc_profiles/HP_Z32x.icc"); |
msarett | abbd6d5 | 2016-08-01 09:43:08 -0700 | [diff] [blame] | 165 | |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 166 | skcms_TransferFunction fn; |
| 167 | fn.a = 1.0f; |
| 168 | fn.b = 0.0f; |
| 169 | fn.c = 1.0f; |
| 170 | fn.d = 0.5f; |
| 171 | fn.e = 0.0f; |
| 172 | fn.f = 0.0f; |
| 173 | fn.g = 1.0f; |
| 174 | skcms_Matrix3x3 toXYZ = {{ |
| 175 | { 1, 0, 0 }, |
| 176 | { 0, 1, 0 }, |
| 177 | { 0, 0, 1 }, |
| 178 | }}; |
Brian Osman | 526972e | 2016-10-24 09:24:02 -0400 | [diff] [blame] | 179 | sk_sp<SkColorSpace> rgb4 = SkColorSpace::MakeRGB(fn, toXYZ); |
Matt Sarett | df44fc5 | 2016-10-11 16:57:50 -0400 | [diff] [blame] | 180 | |
msarett | abbd6d5 | 2016-08-01 09:43:08 -0700 | [diff] [blame] | 181 | REPORTER_ASSERT(r, SkColorSpace::Equals(nullptr, nullptr)); |
| 182 | REPORTER_ASSERT(r, SkColorSpace::Equals(srgb.get(), srgb.get())); |
msarett | abbd6d5 | 2016-08-01 09:43:08 -0700 | [diff] [blame] | 183 | REPORTER_ASSERT(r, SkColorSpace::Equals(z30.get(), z30.get())); |
| 184 | REPORTER_ASSERT(r, SkColorSpace::Equals(z32.get(), z32.get())); |
Matt Sarett | df44fc5 | 2016-10-11 16:57:50 -0400 | [diff] [blame] | 185 | REPORTER_ASSERT(r, SkColorSpace::Equals(rgb4.get(), rgb4.get())); |
msarett | abbd6d5 | 2016-08-01 09:43:08 -0700 | [diff] [blame] | 186 | |
| 187 | REPORTER_ASSERT(r, !SkColorSpace::Equals(nullptr, srgb.get())); |
| 188 | REPORTER_ASSERT(r, !SkColorSpace::Equals(srgb.get(), nullptr)); |
msarett | abbd6d5 | 2016-08-01 09:43:08 -0700 | [diff] [blame] | 189 | REPORTER_ASSERT(r, !SkColorSpace::Equals(z30.get(), srgb.get())); |
| 190 | REPORTER_ASSERT(r, !SkColorSpace::Equals(z32.get(), z30.get())); |
Matt Sarett | 99e3f7d | 2016-10-28 12:51:08 -0400 | [diff] [blame] | 191 | REPORTER_ASSERT(r, !SkColorSpace::Equals(z30.get(), rgb4.get())); |
| 192 | REPORTER_ASSERT(r, !SkColorSpace::Equals(srgb.get(), rgb4.get())); |
msarett | abbd6d5 | 2016-08-01 09:43:08 -0700 | [diff] [blame] | 193 | } |
msarett | a5a31dd | 2016-10-11 09:41:16 -0700 | [diff] [blame] | 194 | |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 195 | static inline bool matrix_almost_equal(const skcms_Matrix3x3& a, const skcms_Matrix3x3& b) { |
| 196 | for (int r = 0; r < 3; ++r) { |
| 197 | for (int c = 0; c < 3; ++c) { |
| 198 | if (!almost_equal(a.vals[r][c], b.vals[r][c])) { |
| 199 | return false; |
| 200 | } |
| 201 | } |
| 202 | } |
| 203 | return true; |
Matt Sarett | 8c05b45 | 2016-10-28 14:45:03 -0400 | [diff] [blame] | 204 | } |
msarett | a5a31dd | 2016-10-11 09:41:16 -0700 | [diff] [blame] | 205 | |
Matt Sarett | 8c05b45 | 2016-10-28 14:45:03 -0400 | [diff] [blame] | 206 | static inline void check_primaries(skiatest::Reporter* r, const SkColorSpacePrimaries& primaries, |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 207 | const skcms_Matrix3x3& reference) { |
| 208 | skcms_Matrix3x3 toXYZ; |
msarett | a5a31dd | 2016-10-11 09:41:16 -0700 | [diff] [blame] | 209 | bool result = primaries.toXYZD50(&toXYZ); |
| 210 | REPORTER_ASSERT(r, result); |
Matt Sarett | 8c05b45 | 2016-10-28 14:45:03 -0400 | [diff] [blame] | 211 | REPORTER_ASSERT(r, matrix_almost_equal(toXYZ, reference)); |
| 212 | } |
msarett | a5a31dd | 2016-10-11 09:41:16 -0700 | [diff] [blame] | 213 | |
Matt Sarett | 8c05b45 | 2016-10-28 14:45:03 -0400 | [diff] [blame] | 214 | DEF_TEST(ColorSpace_Primaries, r) { |
| 215 | // sRGB primaries (D65) |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 216 | skcms_Matrix3x3 srgbToXYZ; |
| 217 | bool result = skcms_PrimariesToXYZD50( |
| 218 | 0.64f, 0.33f, |
| 219 | 0.30f, 0.60f, |
| 220 | 0.15f, 0.06f, |
| 221 | 0.3127f, 0.3290f, |
| 222 | &srgbToXYZ); |
Matt Sarett | 8c05b45 | 2016-10-28 14:45:03 -0400 | [diff] [blame] | 223 | REPORTER_ASSERT(r, result); |
| 224 | |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 225 | sk_sp<SkColorSpace> space = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, srgbToXYZ); |
Matt Sarett | 77a7a1b | 2017-02-07 13:56:11 -0500 | [diff] [blame] | 226 | REPORTER_ASSERT(r, SkColorSpace::MakeSRGB() == space); |
Matt Sarett | 8c05b45 | 2016-10-28 14:45:03 -0400 | [diff] [blame] | 227 | |
Matt Sarett | 8c05b45 | 2016-10-28 14:45:03 -0400 | [diff] [blame] | 228 | // ProPhoto (D50) |
| 229 | SkColorSpacePrimaries proPhoto; |
| 230 | proPhoto.fRX = 0.7347f; |
| 231 | proPhoto.fRY = 0.2653f; |
| 232 | proPhoto.fGX = 0.1596f; |
| 233 | proPhoto.fGY = 0.8404f; |
| 234 | proPhoto.fBX = 0.0366f; |
| 235 | proPhoto.fBY = 0.0001f; |
| 236 | proPhoto.fWX = 0.34567f; |
| 237 | proPhoto.fWY = 0.35850f; |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 238 | skcms_Matrix3x3 proToXYZ = {{ |
| 239 | { 0.7976749f, 0.1351917f, 0.0313534f }, |
| 240 | { 0.2880402f, 0.7118741f, 0.0000857f }, |
| 241 | { 0.0000000f, 0.0000000f, 0.8252100f }, |
| 242 | }}; |
Matt Sarett | 8c05b45 | 2016-10-28 14:45:03 -0400 | [diff] [blame] | 243 | check_primaries(r, proPhoto, proToXYZ); |
| 244 | |
| 245 | // NTSC (C) |
| 246 | SkColorSpacePrimaries ntsc; |
| 247 | ntsc.fRX = 0.67f; |
| 248 | ntsc.fRY = 0.33f; |
| 249 | ntsc.fGX = 0.21f; |
| 250 | ntsc.fGY = 0.71f; |
| 251 | ntsc.fBX = 0.14f; |
| 252 | ntsc.fBY = 0.08f; |
| 253 | ntsc.fWX = 0.31006f; |
| 254 | ntsc.fWY = 0.31616f; |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 255 | skcms_Matrix3x3 ntscToXYZ = {{ |
| 256 | { 0.6343706f, 0.1852204f, 0.1446290f }, |
| 257 | { 0.3109496f, 0.5915984f, 0.0974520f }, |
| 258 | { -0.0011817f, 0.0555518f, 0.7708399f } |
| 259 | }}; |
Matt Sarett | 8c05b45 | 2016-10-28 14:45:03 -0400 | [diff] [blame] | 260 | check_primaries(r, ntsc, ntscToXYZ); |
Matt Sarett | 77a7a1b | 2017-02-07 13:56:11 -0500 | [diff] [blame] | 261 | |
| 262 | // DCI P3 (D65) |
| 263 | SkColorSpacePrimaries p3; |
| 264 | p3.fRX = 0.680f; |
| 265 | p3.fRY = 0.320f; |
| 266 | p3.fGX = 0.265f; |
| 267 | p3.fGY = 0.690f; |
| 268 | p3.fBX = 0.150f; |
| 269 | p3.fBY = 0.060f; |
| 270 | p3.fWX = 0.3127f; |
| 271 | p3.fWY = 0.3290f; |
Mike Klein | b147ace | 2020-01-16 11:11:06 -0600 | [diff] [blame] | 272 | space = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3); |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 273 | skcms_Matrix3x3 reference; |
Matt Sarett | 77a7a1b | 2017-02-07 13:56:11 -0500 | [diff] [blame] | 274 | SkAssertResult(space->toXYZD50(&reference)); |
| 275 | check_primaries(r, p3, reference); |
| 276 | |
| 277 | // Rec 2020 (D65) |
| 278 | SkColorSpacePrimaries rec2020; |
| 279 | rec2020.fRX = 0.708f; |
| 280 | rec2020.fRY = 0.292f; |
| 281 | rec2020.fGX = 0.170f; |
| 282 | rec2020.fGY = 0.797f; |
| 283 | rec2020.fBX = 0.131f; |
| 284 | rec2020.fBY = 0.046f; |
| 285 | rec2020.fWX = 0.3127f; |
| 286 | rec2020.fWY = 0.3290f; |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 287 | space = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kRec2020); |
Matt Sarett | 77a7a1b | 2017-02-07 13:56:11 -0500 | [diff] [blame] | 288 | SkAssertResult(space->toXYZD50(&reference)); |
| 289 | check_primaries(r, rec2020, reference); |
msarett | a5a31dd | 2016-10-11 09:41:16 -0700 | [diff] [blame] | 290 | } |
Matt Sarett | 0186661 | 2016-10-31 13:41:57 -0400 | [diff] [blame] | 291 | |
Matt Sarett | e151bdb | 2017-01-04 11:05:05 -0500 | [diff] [blame] | 292 | DEF_TEST(ColorSpace_MatrixHash, r) { |
Matt Sarett | 77a7a1b | 2017-02-07 13:56:11 -0500 | [diff] [blame] | 293 | sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB(); |
Matt Sarett | e151bdb | 2017-01-04 11:05:05 -0500 | [diff] [blame] | 294 | |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 295 | skcms_TransferFunction fn; |
| 296 | fn.a = 1.0f; |
| 297 | fn.b = 0.0f; |
| 298 | fn.c = 0.0f; |
| 299 | fn.d = 0.0f; |
| 300 | fn.e = 0.0f; |
| 301 | fn.f = 0.0f; |
| 302 | fn.g = 3.0f; |
Matt Sarett | e151bdb | 2017-01-04 11:05:05 -0500 | [diff] [blame] | 303 | |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 304 | sk_sp<SkColorSpace> strange = SkColorSpace::MakeRGB(fn, SkNamedGamut::kSRGB); |
Matt Sarett | e151bdb | 2017-01-04 11:05:05 -0500 | [diff] [blame] | 305 | |
Brian Osman | 36703d9 | 2017-12-12 14:09:31 -0500 | [diff] [blame] | 306 | REPORTER_ASSERT(r, srgb->toXYZD50Hash() == strange->toXYZD50Hash()); |
Matt Sarett | e151bdb | 2017-01-04 11:05:05 -0500 | [diff] [blame] | 307 | } |
Matt Sarett | d83545e | 2017-03-06 11:11:23 -0500 | [diff] [blame] | 308 | |
| 309 | DEF_TEST(ColorSpace_IsSRGB, r) { |
| 310 | sk_sp<SkColorSpace> srgb0 = SkColorSpace::MakeSRGB(); |
Matt Sarett | d83545e | 2017-03-06 11:11:23 -0500 | [diff] [blame] | 311 | |
Brian Osman | 82ebe04 | 2019-01-04 17:03:00 -0500 | [diff] [blame] | 312 | skcms_TransferFunction fn; |
| 313 | fn.a = 1.0f; |
| 314 | fn.b = 0.0f; |
| 315 | fn.c = 0.0f; |
| 316 | fn.d = 0.0f; |
| 317 | fn.e = 0.0f; |
| 318 | fn.f = 0.0f; |
| 319 | fn.g = 2.2f; |
| 320 | sk_sp<SkColorSpace> twoDotTwo = SkColorSpace::MakeRGB(fn, SkNamedGamut::kSRGB); |
Matt Sarett | d83545e | 2017-03-06 11:11:23 -0500 | [diff] [blame] | 321 | |
| 322 | REPORTER_ASSERT(r, srgb0->isSRGB()); |
Matt Sarett | d83545e | 2017-03-06 11:11:23 -0500 | [diff] [blame] | 323 | REPORTER_ASSERT(r, !twoDotTwo->isSRGB()); |
| 324 | } |
Brian Osman | 12e4e84 | 2018-04-27 12:03:51 -0400 | [diff] [blame] | 325 | |
Brian Osman | 12e4e84 | 2018-04-27 12:03:51 -0400 | [diff] [blame] | 326 | DEF_TEST(ColorSpace_skcms_IsSRGB, r) { |
Mike Klein | e61b969 | 2018-05-09 15:00:25 -0400 | [diff] [blame] | 327 | sk_sp<SkColorSpace> srgb = SkColorSpace::Make(*skcms_sRGB_profile()); |
Brian Osman | 12e4e84 | 2018-04-27 12:03:51 -0400 | [diff] [blame] | 328 | REPORTER_ASSERT(r, srgb->isSRGB()); |
| 329 | } |
Mike Klein | 273b74a | 2018-08-29 11:24:43 -0400 | [diff] [blame] | 330 | |
| 331 | DEF_TEST(ColorSpace_skcms_sRGB_exact, r) { |
| 332 | skcms_ICCProfile profile; |
| 333 | sk_srgb_singleton()->toProfile(&profile); |
| 334 | |
| 335 | REPORTER_ASSERT(r, 0 == memcmp(&profile, skcms_sRGB_profile(), sizeof(skcms_ICCProfile))); |
| 336 | } |
Brian Osman | 9ead6c7 | 2019-10-28 15:50:44 -0400 | [diff] [blame] | 337 | |
| 338 | DEF_TEST(ColorSpace_classifyUnderflow, r) { |
| 339 | // crbug.com/1016183 |
| 340 | skcms_TransferFunction fn; |
| 341 | fn.a = 1.0f; |
| 342 | fn.b = 0.0f; |
| 343 | fn.c = 0.0f; |
| 344 | fn.d = 0.0f; |
| 345 | fn.e = 0.0f; |
| 346 | fn.f = 0.0f; |
| 347 | fn.g = INT_MIN; |
| 348 | sk_sp<SkColorSpace> bad = SkColorSpace::MakeRGB(fn, SkNamedGamut::kSRGB); |
| 349 | REPORTER_ASSERT(r, bad == nullptr); |
| 350 | } |
Mike Klein | 9e77f20 | 2020-08-13 13:08:29 -0500 | [diff] [blame] | 351 | |
| 352 | DEF_TEST(ColorSpace_equiv, r) { |
| 353 | skcms_TransferFunction tf = SkNamedTransferFn::kSRGB; |
| 354 | skcms_Matrix3x3 gamut = SkNamedGamut::kSRGB; |
| 355 | |
| 356 | // Previously a NaN anywhere in the tf or gamut would trip up Equals(), |
| 357 | // making us think we'd hit a hash collision where we hadn't. |
| 358 | gamut.vals[1][1] = SK_FloatNaN; |
| 359 | |
| 360 | // There's a quick pointer comparison in SkColorSpace::Equals() we want to get past. |
| 361 | sk_sp<SkColorSpace> x = SkColorSpace::MakeRGB(tf, gamut), |
| 362 | y = SkColorSpace::MakeRGB(tf, gamut); |
| 363 | REPORTER_ASSERT(r, x && y); |
| 364 | REPORTER_ASSERT(r, x.get() != y.get()); |
| 365 | |
| 366 | // Most important to test in debug mode that we don't SkASSERT(). |
| 367 | REPORTER_ASSERT(r, SkColorSpace::Equals(x.get(), y.get())); |
| 368 | } |