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