blob: 597bec20248d0dc0f00852dd49e9cb1632534b58 [file] [log] [blame]
Avi Drissman3e1a26c2022-09-15 20:26:031// Copyright 2016 The Chromium Authors
ccameron87b65e9b62016-12-27 10:19:072// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Elly Fong-Jonesa8ea66f12024-07-24 18:37:105#ifdef UNSAFE_BUFFERS_BUILD
6// TODO(crbug.com/354829279): Remove this and convert code to safer constructs.
7#pragma allow_unsafe_buffers
8#endif
9
ccameron290a91a2017-05-13 19:22:3310#include "ui/gfx/icc_profile.h"
ccameron87b65e9b62016-12-27 10:19:0711#include "testing/gtest/include/gtest/gtest.h"
12#include "ui/gfx/color_space.h"
ccameron290a91a2017-05-13 19:22:3313#include "ui/gfx/skia_color_space_util.h"
ccameron83e8e9a2017-01-04 01:31:2014#include "ui/gfx/test/icc_profiles.h"
ccameron87b65e9b62016-12-27 10:19:0715
16namespace gfx {
17
ccameron87b65e9b62016-12-27 10:19:0718TEST(ICCProfile, Conversions) {
19 ICCProfile icc_profile = ICCProfileForTestingColorSpin();
20 ColorSpace color_space_from_icc_profile = icc_profile.GetColorSpace();
21
Christopher Cameron3bc3d5e2017-11-23 03:48:1122 ICCProfile icc_profile_from_color_space =
Christopher Cameron20eeb0c2019-04-05 23:40:0023 ICCProfile::FromColorSpace(color_space_from_icc_profile);
Christopher Cameron3bc3d5e2017-11-23 03:48:1124 EXPECT_TRUE(icc_profile_from_color_space.IsValid());
25 EXPECT_NE(icc_profile, icc_profile_from_color_space);
ccameron87b65e9b62016-12-27 10:19:0726}
27
28TEST(ICCProfile, SRGB) {
ccameronfa21c642017-05-10 19:38:3629 ICCProfile icc_profile = ICCProfileForTestingSRGB();
ccameron87b65e9b62016-12-27 10:19:0730 ColorSpace color_space = ColorSpace::CreateSRGB();
msarett29c85572017-02-10 22:16:5531 sk_sp<SkColorSpace> sk_color_space = SkColorSpace::MakeSRGB();
ccameron87b65e9b62016-12-27 10:19:0732
ccameronfa21c642017-05-10 19:38:3633 // The ICC profile parser should note that this is SRGB.
Christopher Camerona4adb41b2017-07-13 06:44:2534 EXPECT_EQ(icc_profile.GetColorSpace(), ColorSpace::CreateSRGB());
ccameronfa21c642017-05-10 19:38:3635 EXPECT_EQ(icc_profile.GetColorSpace().ToSkColorSpace().get(),
36 sk_color_space.get());
ccameronfa21c642017-05-10 19:38:3637 // The generated color space should recognize that this is SRGB.
ccameron628896ee2017-02-03 09:29:1238 EXPECT_EQ(color_space.ToSkColorSpace().get(), sk_color_space.get());
ccameron87b65e9b62016-12-27 10:19:0739}
40
ccameron549738b2017-01-28 17:39:3241TEST(ICCProfile, Equality) {
42 ICCProfile spin_profile = ICCProfileForTestingColorSpin();
43 ICCProfile adobe_profile = ICCProfileForTestingAdobeRGB();
44 EXPECT_TRUE(spin_profile == spin_profile);
45 EXPECT_FALSE(spin_profile != spin_profile);
46 EXPECT_FALSE(spin_profile == adobe_profile);
47 EXPECT_TRUE(spin_profile != adobe_profile);
48
49 gfx::ColorSpace spin_space = spin_profile.GetColorSpace();
50 gfx::ColorSpace adobe_space = adobe_profile.GetColorSpace();
51 EXPECT_TRUE(spin_space == spin_space);
52 EXPECT_FALSE(spin_space != spin_space);
53 EXPECT_FALSE(spin_space == adobe_space);
54 EXPECT_TRUE(spin_space != adobe_space);
55
ccameron628896ee2017-02-03 09:29:1256 EXPECT_TRUE(!!spin_space.ToSkColorSpace());
57 EXPECT_TRUE(!!adobe_space.ToSkColorSpace());
58 EXPECT_FALSE(SkColorSpace::Equals(
59 spin_space.ToSkColorSpace().get(),
60 adobe_space.ToSkColorSpace().get()));
ccameron549738b2017-01-28 17:39:3261}
62
Christopher Cameron3bc3d5e2017-11-23 03:48:1163TEST(ICCProfile, ParametricVersusExactInaccurate) {
Brian Osman37233e32018-05-17 16:53:1764 // This ICC profile has three transfer functions that differ significantly,
65 // but ICCProfiles are always either invalid or considered accurate (and in
66 // this case, each curve is approximated, so the profile is "accurate").
67 // See comments in ICCProfile::Internals::Analyze.
ccameron95f83c512017-03-31 20:16:1268 ICCProfile multi_tr_fn = ICCProfileForTestingNoAnalyticTrFn();
Christopher Cameron20eeb0c2019-04-05 23:40:0069 EXPECT_TRUE(multi_tr_fn.IsColorSpaceAccurate());
ccameron24c87c32017-03-14 21:50:4270
Christopher Cameron3bc3d5e2017-11-23 03:48:1171 // We are capable of generating a parametric approximation.
Christopher Cameron79358bd2018-08-02 04:31:4472 ICCProfile profile;
Christopher Cameron20eeb0c2019-04-05 23:40:0073 profile = ICCProfile::FromColorSpace(multi_tr_fn.GetColorSpace());
Christopher Cameron3bc3d5e2017-11-23 03:48:1174 EXPECT_TRUE(profile.IsValid());
75 EXPECT_NE(profile, multi_tr_fn);
76}
77
78TEST(ICCProfile, ParametricVersusExactOvershoot) {
ccameron95f83c512017-03-31 20:16:1279 // This ICC profile has a transfer function with T(1) that is greater than 1
80 // in the approximation, but is still close enough to be considered accurate.
81 ICCProfile overshoot = ICCProfileForTestingOvershoot();
Christopher Cameron20eeb0c2019-04-05 23:40:0082 EXPECT_TRUE(overshoot.IsColorSpaceAccurate());
ccameron95f83c512017-03-31 20:16:1283
Christopher Cameron3bc3d5e2017-11-23 03:48:1184 ICCProfile profile;
Christopher Cameron20eeb0c2019-04-05 23:40:0085 profile = ICCProfile::FromColorSpace(overshoot.GetColorSpace());
Christopher Cameron3bc3d5e2017-11-23 03:48:1186 EXPECT_TRUE(profile.IsValid());
87 EXPECT_NE(profile, overshoot);
88}
ccameron24c87c32017-03-14 21:50:4289
Christopher Cameron3bc3d5e2017-11-23 03:48:1190TEST(ICCProfile, ParametricVersusExactAdobe) {
ccameron24c87c32017-03-14 21:50:4291 // This ICC profile is precisely represented by the parametric color space.
92 ICCProfile accurate = ICCProfileForTestingAdobeRGB();
Christopher Cameron20eeb0c2019-04-05 23:40:0093 EXPECT_TRUE(accurate.IsColorSpaceAccurate());
ccameron24c87c32017-03-14 21:50:4294
Christopher Cameron3bc3d5e2017-11-23 03:48:1195 ICCProfile profile;
Christopher Cameron20eeb0c2019-04-05 23:40:0096 profile = ICCProfile::FromColorSpace(accurate.GetColorSpace());
Christopher Cameron3bc3d5e2017-11-23 03:48:1197 EXPECT_TRUE(profile.IsValid());
98 EXPECT_NE(profile, accurate);
99}
ccameron24c87c32017-03-14 21:50:42100
Christopher Cameron3bc3d5e2017-11-23 03:48:11101TEST(ICCProfile, ParametricVersusExactA2B) {
Brian Osman37233e32018-05-17 16:53:17102 // This ICC profile has only an A2B representation. We cannot transform to
103 // A2B only ICC profiles, so this should be marked as invalid.
ccameron24c87c32017-03-14 21:50:42104 ICCProfile a2b = ICCProfileForTestingA2BOnly();
ccameronb3206e22017-03-25 02:09:12105 EXPECT_FALSE(a2b.GetColorSpace().IsValid());
Christopher Cameron64a55ad2017-09-21 05:31:22106
Brian Osman37233e32018-05-17 16:53:17107 // Even though it is invalid, it should not be equal to the empty constructor
Christopher Cameron64a55ad2017-09-21 05:31:22108 EXPECT_NE(a2b, gfx::ICCProfile());
ccameron24c87c32017-03-14 21:50:42109}
110
111TEST(ICCProfile, GarbageData) {
112 std::vector<char> bad_data(10 * 1024);
113 const char* bad_data_string = "deadbeef";
114 for (size_t i = 0; i < bad_data.size(); ++i)
115 bad_data[i] = bad_data_string[i % 8];
116 ICCProfile garbage_profile =
117 ICCProfile::FromData(bad_data.data(), bad_data.size());
118 EXPECT_FALSE(garbage_profile.IsValid());
119 EXPECT_FALSE(garbage_profile.GetColorSpace().IsValid());
ccameron24c87c32017-03-14 21:50:42120
121 ICCProfile default_ctor_profile;
122 EXPECT_FALSE(default_ctor_profile.IsValid());
123 EXPECT_FALSE(default_ctor_profile.GetColorSpace().IsValid());
ccameron24c87c32017-03-14 21:50:42124}
125
ccameron290a91a2017-05-13 19:22:33126TEST(ICCProfile, GenericRGB) {
127 ColorSpace icc_profile = ICCProfileForTestingGenericRGB().GetColorSpace();
128 ColorSpace color_space(ColorSpace::PrimaryID::APPLE_GENERIC_RGB,
129 ColorSpace::TransferID::GAMMA18);
130
Xianzhu Wang239702f2022-02-18 08:02:38131 SkM44 icc_profile_matrix = icc_profile.GetPrimaryMatrix();
132 SkM44 color_space_matrix = color_space.GetPrimaryMatrix();
ccameron290a91a2017-05-13 19:22:33133
Xianzhu Wang239702f2022-02-18 08:02:38134 SkM44 eye;
135 EXPECT_TRUE(icc_profile_matrix.invert(&eye));
ccameron290a91a2017-05-13 19:22:33136 eye.postConcat(color_space_matrix);
Xianzhu Wang239702f2022-02-18 08:02:38137 EXPECT_TRUE(SkM44IsApproximatelyIdentity(eye));
ccameron290a91a2017-05-13 19:22:33138}
139
ccameron87b65e9b62016-12-27 10:19:07140} // namespace gfx