1 /*
2 * Copyright (c) 2019-2021 Kevin Townsend (KTOWN)
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdlib.h>
8 #include <ctype.h>
9 #include <zephyr/shell/shell.h>
10 #include <zsl/colorimetry.h>
11
12 #if CONFIG_ZSL_SHELL_CLR
13
14 static int
zsl_clr_shell_invalid_arg(const struct shell * shell,char * arg_name)15 zsl_clr_shell_invalid_arg(const struct shell *shell, char *arg_name)
16 {
17 shell_print(shell, "Error: invalid argument \"%s\"\n", arg_name);
18
19 return -EINVAL;
20 }
21
22 static int
zsl_clr_shell_cmd_ct2rgb(const struct shell * shell,size_t argc,char ** argv)23 zsl_clr_shell_cmd_ct2rgb(const struct shell *shell, size_t argc, char **argv)
24 {
25 ARG_UNUSED(argc);
26 zsl_real_t ct = 0.0;
27 struct zsl_clr_rgb8 rgb;
28 struct zsl_mtx *srgb_ccm;
29
30 /* sRGB D65 correlation matrix. */
31 zsl_clr_rgbccm_get(ZSL_CLR_RGB_CCM_SRGB_D65, &srgb_ccm);
32
33 memset(&rgb, 0, sizeof rgb);
34
35 if ((strcmp(argv[1], "help") == 0)) {
36 shell_print(shell, "Color temperature to sRGB (D65)\n");
37 shell_print(shell, "$ %s %s 5600.0", argv[-1], argv[0]);
38 shell_print(shell, "5600 K to sRGB (D65) = 255 248 224");
39 shell_print(shell, "Gamut Warning: R..\n");
40 shell_print(shell, "'R..' indicates red is out of gamut.");
41 return 0;
42 }
43
44 /* Invalid color temperature. */
45 ct = strtof(argv[1], NULL);
46 if (ct <= 0.0) {
47 return zsl_clr_shell_invalid_arg(shell, argv[1]);
48 }
49
50 /* Convert ct to sRGB and display 8-bit component values. */
51 zsl_clr_conv_ct_rgb8(ct, ZSL_CLR_OBS_2_DEG, srgb_ccm, &rgb);
52 shell_print(shell, "%d K to sRGB (D65) = %d %d %d",
53 (unsigned int)ct, rgb.r, rgb.g, rgb.b);
54
55 /* Display an out of gamut warning. */
56 if ((rgb.r_invalid) || (rgb.g_invalid) || (rgb.b_invalid)) {
57 shell_print(shell, "Gamut Warning: %c%c%c",
58 rgb.r_invalid ? 'R' : '.',
59 rgb.g_invalid ? 'G' : '.',
60 rgb.b_invalid ? 'B' : '.');
61 }
62
63 return 0;
64 }
65
66 static int
zsl_clr_shell_cmd_ct2rgbf(const struct shell * shell,size_t argc,char ** argv)67 zsl_clr_shell_cmd_ct2rgbf(const struct shell *shell, size_t argc, char **argv)
68 {
69 ARG_UNUSED(argc);
70 zsl_real_t ct = 0.0;
71 struct zsl_clr_rgbf rgb;
72 struct zsl_mtx *srgb_ccm;
73
74 /* sRGB D65 correlation matrix. */
75 zsl_clr_rgbccm_get(ZSL_CLR_RGB_CCM_SRGB_D65, &srgb_ccm);
76
77 memset(&rgb, 0, sizeof rgb);
78
79 if ((strcmp(argv[1], "help") == 0)) {
80 shell_print(shell, "Color temperature to sRGB float (D65)\n");
81 shell_print(shell, "$ %s %s 5600.0", argv[-1], argv[0]);
82 shell_print(shell, "5600 K to sRGB (D65) = TODOO");
83 shell_print(shell, "Gamut Warning: R..\n");
84 shell_print(shell, "'R..' indicates red is out of gamut.");
85 return 0;
86 }
87
88 /* Invalid color temperature. */
89 ct = strtof(argv[1], NULL);
90 if (ct <= 0.0) {
91 return zsl_clr_shell_invalid_arg(shell, argv[1]);
92 }
93
94 /* Convert ct to sRGB and display floating point component values. */
95 zsl_clr_conv_ct_rgbf(ct, ZSL_CLR_OBS_2_DEG, srgb_ccm, &rgb);
96 shell_print(shell, "%d K to sRGB (D65) = %f %f %f\n",
97 (unsigned int)ct, rgb.r, rgb.g, rgb.b);
98
99 /* Display an out of gamut warning. */
100 if ((rgb.r_invalid) || (rgb.g_invalid) || (rgb.b_invalid)) {
101 shell_print(shell, "Gamut Warning: %c%c%c",
102 rgb.r_invalid ? 'R' : '.',
103 rgb.g_invalid ? 'G' : '.',
104 rgb.b_invalid ? 'B' : '.');
105 }
106
107 return 0;
108 }
109
110 /* Subcommand array for "color" (level 1). */
111 SHELL_STATIC_SUBCMD_SET_CREATE(
112 sub_color,
113 /* 'rgb' command handler. */
114 SHELL_CMD_ARG(ct2rgb, NULL, "ct to sRGB (D65)",
115 zsl_clr_shell_cmd_ct2rgb, 2, 0),
116 /* 'rgbf' command handler. */
117 SHELL_CMD_ARG(ct2rgbf, NULL, "ct to sRGB float (D65)",
118 zsl_clr_shell_cmd_ct2rgbf, 2, 0),
119
120 /* Array terminator. */
121 SHELL_SUBCMD_SET_END
122 );
123
124 /* Root command "color" (level 0). */
125 SHELL_CMD_REGISTER(color, &sub_color, "Colorimetry commands", NULL);
126
127 #endif
128