Skip to content

Commit e729b2d

Browse files
Material Engcopybara-github
authored andcommitted
Port Dynamic Color to C++.
PiperOrigin-RevId: 527822851
1 parent df5e198 commit e729b2d

16 files changed

+1669
-10
lines changed

cpp/cam/cam.cc

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818

1919
#include <assert.h>
2020
#include <math.h>
21-
#include <stdio.h>
22-
#include <stdlib.h>
2321

2422
#include "cpp/cam/hct_solver.h"
2523
#include "cpp/cam/viewing_conditions.h"
@@ -206,4 +204,60 @@ Argb IntFromHcl(double hue, double chroma, double lstar) {
206204
return SolveToInt(hue, chroma, lstar);
207205
}
208206

207+
Cam CamFromXyzAndViewingConditions(
208+
double x, double y, double z, const ViewingConditions &viewing_conditions) {
209+
// Convert XYZ to 'cone'/'rgb' responses
210+
double r_c = 0.401288 * x + 0.650173 * y - 0.051461 * z;
211+
double g_c = -0.250268 * x + 1.204414 * y + 0.045854 * z;
212+
double b_c = -0.002079 * x + 0.048952 * y + 0.953127 * z;
213+
214+
// Discount illuminant.
215+
double r_d = viewing_conditions.rgb_d[0] * r_c;
216+
double g_d = viewing_conditions.rgb_d[1] * g_c;
217+
double b_d = viewing_conditions.rgb_d[2] * b_c;
218+
219+
// Chromatic adaptation.
220+
double r_af = pow(viewing_conditions.fl * fabs(r_d) / 100.0, 0.42);
221+
double g_af = pow(viewing_conditions.fl * fabs(g_d) / 100.0, 0.42);
222+
double b_af = pow(viewing_conditions.fl * fabs(b_d) / 100.0, 0.42);
223+
double r_a = Signum(r_d) * 400.0 * r_af / (r_af + 27.13);
224+
double g_a = Signum(g_d) * 400.0 * g_af / (g_af + 27.13);
225+
double b_a = Signum(b_d) * 400.0 * b_af / (b_af + 27.13);
226+
227+
// Redness-greenness
228+
double a = (11.0 * r_a + -12.0 * g_a + b_a) / 11.0;
229+
double b = (r_a + g_a - 2.0 * b_a) / 9.0;
230+
double u = (20.0 * r_a + 20.0 * g_a + 21.0 * b_a) / 20.0;
231+
double p2 = (40.0 * r_a + 20.0 * g_a + b_a) / 20.0;
232+
233+
double radians = atan2(b, a);
234+
double degrees = radians * 180.0 / kPi;
235+
double hue = SanitizeDegreesDouble(degrees);
236+
double hue_radians = hue * kPi / 180.0;
237+
double ac = p2 * viewing_conditions.nbb;
238+
239+
double j = 100.0 * pow(ac / viewing_conditions.aw,
240+
viewing_conditions.c * viewing_conditions.z);
241+
double q = (4.0 / viewing_conditions.c) * sqrt(j / 100.0) *
242+
(viewing_conditions.aw + 4.0) * viewing_conditions.fl_root;
243+
double hue_prime = hue < 20.14 ? hue + 360 : hue;
244+
double e_hue = 0.25 * (cos(hue_prime * kPi / 180.0 + 2.0) + 3.8);
245+
double p1 =
246+
50000.0 / 13.0 * e_hue * viewing_conditions.n_c * viewing_conditions.ncb;
247+
double t = p1 * sqrt(a * a + b * b) / (u + 0.305);
248+
double alpha =
249+
pow(t, 0.9) *
250+
pow(1.64 - pow(0.29, viewing_conditions.background_y_to_white_point_y),
251+
0.73);
252+
double c = alpha * sqrt(j / 100.0);
253+
double m = c * viewing_conditions.fl_root;
254+
double s = 50.0 * sqrt((alpha * viewing_conditions.c) /
255+
(viewing_conditions.aw + 4.0));
256+
double jstar = (1.0 + 100.0 * 0.007) * j / (1.0 + 0.007 * j);
257+
double mstar = 1.0 / 0.0228 * log(1.0 + 0.0228 * m);
258+
double astar = mstar * cos(hue_radians);
259+
double bstar = mstar * sin(hue_radians);
260+
return {hue, c, j, q, m, s, jstar, astar, bstar};
261+
}
262+
209263
} // namespace material_color_utilities

cpp/cam/cam.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ Argb IntFromHcl(double hue, double chroma, double lstar);
4242
Argb IntFromCam(Cam cam);
4343
Cam CamFromUcsAndViewingConditions(double jstar, double astar, double bstar,
4444
const ViewingConditions &viewing_conditions);
45+
/**
46+
* Given color expressed in the XYZ color space and viewed
47+
* in [viewingConditions], converts the color to CAM16.
48+
*/
49+
Cam CamFromXyzAndViewingConditions(double x, double y, double z,
50+
const ViewingConditions &viewing_conditions);
4551

4652
} // namespace material_color_utilities
4753
#endif // CPP_CAM_CAM_H_

cpp/cam/hct.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ Hct::Hct(double hue, double chroma, double tone) {
2626

2727
Hct::Hct(Argb argb) { SetInternalState(argb); }
2828

29-
double Hct::get_hue() { return hue_; }
29+
double Hct::get_hue() const { return hue_; }
3030

31-
double Hct::get_chroma() { return chroma_; }
31+
double Hct::get_chroma() const { return chroma_; }
3232

33-
double Hct::get_tone() { return tone_; }
33+
double Hct::get_tone() const { return tone_; }
3434

35-
Argb Hct::ToInt() { return argb_; }
35+
Argb Hct::ToInt() const { return argb_; }
3636

3737
void Hct::set_hue(double new_hue) {
3838
SetInternalState(SolveToInt(new_hue, chroma_, tone_));

cpp/cam/hct.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,28 +66,28 @@ class Hct {
6666
*
6767
* @return hue of the color, in degrees.
6868
*/
69-
double get_hue();
69+
double get_hue() const;
7070

7171
/**
7272
* Returns the chroma of the color.
7373
*
7474
* @return chroma of the color.
7575
*/
76-
double get_chroma();
76+
double get_chroma() const;
7777

7878
/**
7979
* Returns the tone of the color.
8080
*
8181
* @return tone of the color, satisfying 0 <= tone <= 100.
8282
*/
83-
double get_tone();
83+
double get_tone() const;
8484

8585
/**
8686
* Returns the color in ARGB format.
8787
*
8888
* @return an integer, representing the color in ARGB format.
8989
*/
90-
Argb ToInt();
90+
Argb ToInt() const;
9191

9292
/**
9393
* Sets the hue of this color. Chroma may decrease because chroma has a

0 commit comments

Comments
 (0)