color_encoding_internal_test.cc (4894B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #include "lib/jxl/color_encoding_internal.h" 7 8 #include <jxl/color_encoding.h> 9 10 #include <cstdlib> // rand 11 12 #include "lib/jxl/cms/color_encoding_cms.h" 13 #include "lib/jxl/test_utils.h" 14 #include "lib/jxl/testing.h" 15 16 namespace jxl { 17 namespace { 18 19 using jxl::cms::ColorEncoding; 20 21 TEST(ColorEncodingTest, RoundTripAll) { 22 for (const test::ColorEncodingDescriptor& cdesc : test::AllEncodings()) { 23 ColorEncoding c_original = test::ColorEncodingFromDescriptor(cdesc).View(); 24 // Verify Set(Get) yields the same white point/primaries/gamma. 25 { 26 ColorEncoding c; 27 EXPECT_TRUE(c.SetWhitePoint(c_original.GetWhitePoint())); 28 EXPECT_EQ(c_original.white_point, c.white_point); 29 } 30 { 31 ColorEncoding c; 32 EXPECT_TRUE(c.SetPrimaries(c_original.GetPrimaries())); 33 EXPECT_EQ(c_original.primaries, c.primaries); 34 } 35 if (c_original.tf.have_gamma) { 36 ColorEncoding c; 37 EXPECT_TRUE(c.tf.SetGamma(c_original.tf.GetGamma())); 38 EXPECT_TRUE(c_original.tf.IsSame(c.tf)); 39 } 40 } 41 } 42 43 TEST(ColorEncodingTest, CustomWhitePoint) { 44 ColorEncoding c; 45 // Nonsensical values 46 CIExy xy_in; 47 xy_in.x = 0.8; 48 xy_in.y = 0.01; 49 EXPECT_TRUE(c.SetWhitePoint(xy_in)); 50 const CIExy xy = c.GetWhitePoint(); 51 52 ColorEncoding c2; 53 EXPECT_TRUE(c2.SetWhitePoint(xy)); 54 EXPECT_TRUE(c.SameColorSpace(c2)); 55 } 56 57 TEST(ColorEncodingTest, CustomPrimaries) { 58 ColorEncoding c; 59 PrimariesCIExy xy_in; 60 // Nonsensical values 61 xy_in.r.x = -0.01; 62 xy_in.r.y = 0.2; 63 xy_in.g.x = 0.4; 64 xy_in.g.y = 0.401; 65 xy_in.b.x = 1.1; 66 xy_in.b.y = -1.2; 67 EXPECT_TRUE(c.SetPrimaries(xy_in)); 68 const PrimariesCIExy xy = c.GetPrimaries(); 69 70 ColorEncoding c2; 71 EXPECT_TRUE(c2.SetPrimaries(xy)); 72 EXPECT_TRUE(c.SameColorSpace(c2)); 73 } 74 75 TEST(ColorEncodingTest, CustomGamma) { 76 ColorEncoding c; 77 #ifndef JXL_CRASH_ON_ERROR 78 EXPECT_FALSE(c.tf.SetGamma(0.0)); 79 EXPECT_FALSE(c.tf.SetGamma(-1E-6)); 80 EXPECT_FALSE(c.tf.SetGamma(1.001)); 81 #endif 82 EXPECT_TRUE(c.tf.SetGamma(1.0)); 83 EXPECT_FALSE(c.tf.have_gamma); 84 EXPECT_TRUE(c.tf.IsLinear()); 85 86 EXPECT_TRUE(c.tf.SetGamma(0.123)); 87 EXPECT_TRUE(c.tf.have_gamma); 88 const double gamma = c.tf.GetGamma(); 89 90 ColorEncoding c2; 91 EXPECT_TRUE(c2.tf.SetGamma(gamma)); 92 EXPECT_TRUE(c.SameColorEncoding(c2)); 93 EXPECT_TRUE(c2.tf.have_gamma); 94 } 95 96 TEST(ColorEncodingTest, InternalExternalConversion) { 97 ColorEncoding source_internal; 98 ColorEncoding destination_internal; 99 100 const auto rand_float = []() { 101 return (static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * 0.5) + 102 0.25; 103 }; 104 105 for (int i = 0; i < 100; i++) { 106 source_internal.color_space = static_cast<ColorSpace>(rand() % 4); 107 CIExy wp; 108 wp.x = rand_float(); 109 wp.y = rand_float(); 110 EXPECT_TRUE(source_internal.SetWhitePoint(wp)); 111 if (source_internal.HasPrimaries()) { 112 PrimariesCIExy primaries; 113 primaries.r.x = rand_float(); 114 primaries.r.y = rand_float(); 115 primaries.g.x = rand_float(); 116 primaries.g.y = rand_float(); 117 primaries.b.x = rand_float(); 118 primaries.b.y = rand_float(); 119 EXPECT_TRUE(source_internal.SetPrimaries(primaries)); 120 } 121 jxl::cms::CustomTransferFunction tf; 122 EXPECT_TRUE(tf.SetGamma(rand_float())); 123 source_internal.tf = tf; 124 source_internal.rendering_intent = static_cast<RenderingIntent>(rand() % 4); 125 126 JxlColorEncoding external = source_internal.ToExternal(); 127 EXPECT_TRUE(destination_internal.FromExternal(external)); 128 129 EXPECT_EQ(source_internal.color_space, destination_internal.color_space); 130 EXPECT_EQ(source_internal.white_point, destination_internal.white_point); 131 CIExy src_wp = source_internal.GetWhitePoint(); 132 CIExy dst_wp = destination_internal.GetWhitePoint(); 133 EXPECT_EQ(src_wp.x, dst_wp.x); 134 EXPECT_EQ(src_wp.y, dst_wp.y); 135 if (source_internal.HasPrimaries()) { 136 PrimariesCIExy src_p = source_internal.GetPrimaries(); 137 PrimariesCIExy dst_p = destination_internal.GetPrimaries(); 138 EXPECT_EQ(src_p.r.x, dst_p.r.x); 139 EXPECT_EQ(src_p.r.y, dst_p.r.y); 140 EXPECT_EQ(src_p.g.x, dst_p.g.x); 141 EXPECT_EQ(src_p.g.y, dst_p.g.y); 142 EXPECT_EQ(src_p.b.x, dst_p.b.x); 143 EXPECT_EQ(src_p.b.y, dst_p.b.y); 144 } 145 EXPECT_EQ(source_internal.tf.have_gamma, 146 destination_internal.tf.have_gamma); 147 if (source_internal.tf.have_gamma) { 148 EXPECT_EQ(source_internal.tf.GetGamma(), 149 destination_internal.tf.GetGamma()); 150 } else { 151 EXPECT_EQ(source_internal.tf.GetTransferFunction(), 152 destination_internal.tf.GetTransferFunction()); 153 } 154 EXPECT_EQ(source_internal.rendering_intent, 155 destination_internal.rendering_intent); 156 } 157 } 158 159 } // namespace 160 } // namespace jxl