Blender V5.0
BLI_math_color_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
7#include "BLI_math_color.h"
9
10TEST(math_color, RGBToHSVRoundtrip)
11{
12 const float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
13 float hsv[3], rgb[3];
14 rgb_to_hsv_v(orig_rgb, hsv);
15 hsv_to_rgb_v(hsv, rgb);
16 EXPECT_V3_NEAR(orig_rgb, rgb, 1e-5);
17}
18
19TEST(math_color, RGBToHSLRoundtrip)
20{
21 const float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
22 float hsl[3], rgb[3];
23 rgb_to_hsl_v(orig_rgb, hsl);
24 hsl_to_rgb_v(hsl, rgb);
25 EXPECT_V3_NEAR(orig_rgb, rgb, 1e-5);
26}
27
28TEST(math_color, RGBToYUVRoundtrip)
29{
30 const float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
31 float yuv[3], rgb[3];
32 rgb_to_yuv(orig_rgb[0], orig_rgb[1], orig_rgb[2], &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709);
33 yuv_to_rgb(yuv[0], yuv[1], yuv[2], &rgb[0], &rgb[1], &rgb[2], BLI_YUV_ITU_BT709);
34 EXPECT_V3_NEAR(orig_rgb, rgb, 1e-4);
35}
36
37TEST(math_color, RGBToYCCRoundtrip)
38{
39 const float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
40 float ycc[3], rgb[3];
41
42 rgb_to_ycc(orig_rgb[0], orig_rgb[1], orig_rgb[2], &ycc[0], &ycc[1], &ycc[2], BLI_YCC_ITU_BT601);
43 ycc_to_rgb(ycc[0], ycc[1], ycc[2], &rgb[0], &rgb[1], &rgb[2], BLI_YCC_ITU_BT601);
44 EXPECT_V3_NEAR(orig_rgb, rgb, 1e-3);
45
46 rgb_to_ycc(orig_rgb[0], orig_rgb[1], orig_rgb[2], &ycc[0], &ycc[1], &ycc[2], BLI_YCC_ITU_BT709);
47 ycc_to_rgb(ycc[0], ycc[1], ycc[2], &rgb[0], &rgb[1], &rgb[2], BLI_YCC_ITU_BT709);
48 EXPECT_V3_NEAR(orig_rgb, rgb, 1e-3);
49
50 rgb_to_ycc(orig_rgb[0], orig_rgb[1], orig_rgb[2], &ycc[0], &ycc[1], &ycc[2], BLI_YCC_JFIF_0_255);
51 ycc_to_rgb(ycc[0], ycc[1], ycc[2], &rgb[0], &rgb[1], &rgb[2], BLI_YCC_JFIF_0_255);
52 EXPECT_V3_NEAR(orig_rgb, rgb, 1e-3);
53}
54
55TEST(math_color, LinearRGBTosRGBNearZero)
56{
57 float linear_color = 0.002f;
58 float srgb_color = linearrgb_to_srgb(linear_color);
59 EXPECT_NEAR(0.02584f, srgb_color, 1e-5);
60}
61
62TEST(math_color, LinearRGBTosRGB)
63{
64 float linear_color = 0.75f;
65 float srgb_color = linearrgb_to_srgb(linear_color);
66 EXPECT_NEAR(0.880824f, srgb_color, 1e-5);
67}
68
69TEST(math_color, LinearRGBTosRGBRoundtrip)
70{
71 const int N = 50;
72 int i;
73 for (i = 0; i < N; ++i) {
74 float orig_linear_color = float(i) / N;
75 float srgb_color = linearrgb_to_srgb(orig_linear_color);
76 float linear_color = srgb_to_linearrgb(srgb_color);
77 EXPECT_NEAR(orig_linear_color, linear_color, 1e-5);
78 }
79}
80
82{
83 float srgb_color[3];
84 {
85 const float kTolerance = 1.0e-8f;
86 const float linear_color[3] = {0.0023f, 0.0024f, 0.0025f};
87 linearrgb_to_srgb_v3_v3(srgb_color, linear_color);
88 EXPECT_NEAR(0.029716f, srgb_color[0], kTolerance);
89 EXPECT_NEAR(0.031008f, srgb_color[1], kTolerance);
90 EXPECT_NEAR(0.032300f, srgb_color[2], kTolerance);
91 }
92
93 {
94 const float kTolerance = 5.0e-7f;
95 const float linear_color[3] = {0.71f, 0.75f, 0.78f};
96 linearrgb_to_srgb_v3_v3(srgb_color, linear_color);
97 EXPECT_NEAR(0.859662f, srgb_color[0], kTolerance);
98 EXPECT_NEAR(0.880790f, srgb_color[1], kTolerance);
99 EXPECT_NEAR(0.896209f, srgb_color[2], kTolerance);
100 }
101
102 {
103 /* Not a common, but possible case: values beyond 1.0 range. */
104 const float kTolerance = 1.3e-7f;
105 const float linear_color[3] = {1.5f, 2.8f, 5.6f};
106 linearrgb_to_srgb_v3_v3(srgb_color, linear_color);
107 EXPECT_NEAR(1.1942182f, srgb_color[0], kTolerance);
108 EXPECT_NEAR(1.5654286f, srgb_color[1], kTolerance);
109 EXPECT_NEAR(2.1076257f, srgb_color[2], kTolerance);
110 }
111}
112
114{
115 const float kTolerance = 1.0e-12f;
116 float linear_color[3];
117 {
118 const float srgb_color[3] = {0.0023f, 0.0024f, 0.0025f};
119 srgb_to_linearrgb_v3_v3(linear_color, srgb_color);
120 EXPECT_NEAR(0.00017801858f, linear_color[0], kTolerance);
121 EXPECT_NEAR(0.00018575852f, linear_color[1], kTolerance);
122 EXPECT_NEAR(0.00019349845f, linear_color[2], kTolerance);
123 }
124
125 {
126 const float srgb_color[3] = {0.71f, 0.72f, 0.73f};
127 srgb_to_linearrgb_v3_v3(linear_color, srgb_color);
128 EXPECT_NEAR(0.46236148477f, linear_color[0], kTolerance);
129 EXPECT_NEAR(0.47699990869f, linear_color[1], kTolerance);
130 EXPECT_NEAR(0.49190518260f, linear_color[2], kTolerance);
131 }
132
133 {
134 /* Not a common, but possible case: values beyond 1.0 range. */
135 const float srgb_color[3] = {1.1f, 2.5f, 5.6f};
136 srgb_to_linearrgb_v3_v3(linear_color, srgb_color);
137 EXPECT_NEAR(1.24277031422f, linear_color[0], kTolerance);
138 EXPECT_NEAR(8.35472869873f, linear_color[1], kTolerance);
139 EXPECT_NEAR(56.2383270264f, linear_color[2], kTolerance);
140 }
141}
142
143TEST(math_color, BlendModeConsistency_SoftLight)
144{
145 float fdst[4];
146 float fcolora[4] = {0.0f, 0.0f, 0.0f, 1.0f};
147 float fcolorb[4] = {1.0f, 1.0f, 1.0f, 1.0f};
148 float fcolorc[4] = {1.0f, 1.0f, 1.0f, 0.5f};
149 float fcolord[4] = {0.5f, 0.5f, 0.5f, 0.5f};
150 uchar bdst[4];
151 uchar bcolora[4] = {0, 0, 0, 255};
152 uchar bcolorb[4] = {255, 255, 255, 255};
153 uchar bcolorc[4] = {255, 255, 255, 128};
154 uchar bcolord[4] = {128, 128, 128, 128};
155
156 blend_color_softlight_float(fdst, fcolora, fcolorb);
157 blend_color_softlight_byte(bdst, bcolora, bcolorb);
158 EXPECT_NEAR(fdst[0] * 255.0f, bdst[0], 1.0f);
159 EXPECT_NEAR(fdst[1] * 255.0f, bdst[1], 1.0f);
160 EXPECT_NEAR(fdst[2] * 255.0f, bdst[2], 1.0f);
161
162 blend_color_softlight_float(fdst, fcolorb, fcolora);
163 blend_color_softlight_byte(bdst, bcolorb, bcolora);
164 EXPECT_NEAR(fdst[0] * 255.0f, bdst[0], 1.0f);
165 EXPECT_NEAR(fdst[1] * 255.0f, bdst[1], 1.0f);
166 EXPECT_NEAR(fdst[2] * 255.0f, bdst[2], 1.0f);
167
168 blend_color_softlight_float(fdst, fcolorc, fcolora);
169 blend_color_softlight_byte(bdst, bcolorc, bcolora);
170 EXPECT_NEAR(fdst[0] * 255.0f, bdst[0], 1.0f);
171 EXPECT_NEAR(fdst[1] * 255.0f, bdst[1], 1.0f);
172 EXPECT_NEAR(fdst[2] * 255.0f, bdst[2], 1.0f);
173
174 blend_color_softlight_float(fdst, fcolorc, fcolord);
175 blend_color_softlight_byte(bdst, bcolorc, bcolord);
176 EXPECT_NEAR(fdst[0] * 255.0f, bdst[0], 1.0f);
177 EXPECT_NEAR(fdst[1] * 255.0f, bdst[1], 1.0f);
178 EXPECT_NEAR(fdst[2] * 255.0f, bdst[2], 1.0f);
179}
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
Definition math_color.cc:57
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
#define BLI_YUV_ITU_BT709
#define BLI_YCC_JFIF_0_255
void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
void hsl_to_rgb_v(const float hsl[3], float r_rgb[3])
Definition math_color.cc:62
void ycc_to_rgb(float y, float cb, float cr, float *r_r, float *r_g, float *r_b, int colorspace)
#define BLI_YCC_ITU_BT601
void rgb_to_ycc(float r, float g, float b, float *r_y, float *r_cb, float *r_cr, int colorspace)
void rgb_to_yuv(float r, float g, float b, float *r_y, float *r_u, float *r_v, int colorspace)
Definition math_color.cc:67
float srgb_to_linearrgb(float c)
void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
float linearrgb_to_srgb(float c)
void yuv_to_rgb(float y, float u, float v, float *r_r, float *r_g, float *r_b, int colorspace)
Definition math_color.cc:91
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
#define BLI_YCC_ITU_BT709
MINLINE void blend_color_softlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_softlight_float(float dst[4], const float src1[4], const float src2[4])
TEST(math_color, RGBToHSVRoundtrip)
unsigned char uchar
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
nullptr float
#define N
i
Definition text_draw.cc:230