1 /**
2 * @file lv_color.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_color.h"
10 #include "lv_math.h"
11
12 /*********************
13 * DEFINES
14 *********************/
15
16 /**********************
17 * TYPEDEFS
18 **********************/
19
20 /**********************
21 * STATIC PROTOTYPES
22 **********************/
23
24 /**********************
25 * STATIC VARIABLES
26 **********************/
27
28 /**********************
29 * MACROS
30 **********************/
31
32 /**********************
33 * GLOBAL FUNCTIONS
34 **********************/
35
36 /**********************
37 * STATIC FUNCTIONS
38 **********************/
39
lv_color_fill(lv_color_t * buf,lv_color_t color,uint32_t px_num)40 LV_ATTRIBUTE_FAST_MEM void lv_color_fill(lv_color_t * buf, lv_color_t color, uint32_t px_num)
41 {
42 #if LV_COLOR_DEPTH == 16
43 uintptr_t buf_int = (uintptr_t) buf;
44 if(buf_int & 0x3) {
45 *buf = color;
46 buf++;
47 px_num--;
48 }
49
50 uint32_t c32 = color.full + (color.full << 16);
51 uint32_t * buf32 = (uint32_t *)buf;
52
53 while(px_num > 16) {
54 *buf32 = c32;
55 buf32++;
56 *buf32 = c32;
57 buf32++;
58 *buf32 = c32;
59 buf32++;
60 *buf32 = c32;
61 buf32++;
62
63 *buf32 = c32;
64 buf32++;
65 *buf32 = c32;
66 buf32++;
67 *buf32 = c32;
68 buf32++;
69 *buf32 = c32;
70 buf32++;
71
72 px_num -= 16;
73 }
74
75 buf = (lv_color_t *)buf32;
76
77 while(px_num) {
78 *buf = color;
79 buf++;
80 px_num --;
81 }
82 #else
83 while(px_num > 16) {
84 *buf = color;
85 buf++;
86 *buf = color;
87 buf++;
88 *buf = color;
89 buf++;
90 *buf = color;
91 buf++;
92
93 *buf = color;
94 buf++;
95 *buf = color;
96 buf++;
97 *buf = color;
98 buf++;
99 *buf = color;
100 buf++;
101
102 *buf = color;
103 buf++;
104 *buf = color;
105 buf++;
106 *buf = color;
107 buf++;
108 *buf = color;
109 buf++;
110
111 *buf = color;
112 buf++;
113 *buf = color;
114 buf++;
115 *buf = color;
116 buf++;
117 *buf = color;
118 buf++;
119
120 px_num -= 16;
121 }
122 while(px_num) {
123 *buf = color;
124 buf++;
125 px_num --;
126 }
127 #endif
128 }
129
130
lv_color_lighten(lv_color_t c,lv_opa_t lvl)131 lv_color_t lv_color_lighten(lv_color_t c, lv_opa_t lvl)
132 {
133 return lv_color_mix(LV_COLOR_WHITE, c, lvl);
134 }
135
136
lv_color_darken(lv_color_t c,lv_opa_t lvl)137 lv_color_t lv_color_darken(lv_color_t c, lv_opa_t lvl)
138 {
139 return lv_color_mix(LV_COLOR_BLACK, c, lvl);
140 }
141
142 /**
143 * Convert a HSV color to RGB
144 * @param h hue [0..359]
145 * @param s saturation [0..100]
146 * @param v value [0..100]
147 * @return the given RGB color in RGB (with LV_COLOR_DEPTH depth)
148 */
lv_color_hsv_to_rgb(uint16_t h,uint8_t s,uint8_t v)149 lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v)
150 {
151 h = (uint32_t)((uint32_t)h * 255) / 360;
152 s = (uint16_t)((uint16_t)s * 255) / 100;
153 v = (uint16_t)((uint16_t)v * 255) / 100;
154
155 uint8_t r, g, b;
156
157 uint8_t region, remainder, p, q, t;
158
159 if(s == 0) {
160 return lv_color_make(v, v, v);
161 }
162
163 region = h / 43;
164 remainder = (h - (region * 43)) * 6;
165
166 p = (v * (255 - s)) >> 8;
167 q = (v * (255 - ((s * remainder) >> 8))) >> 8;
168 t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
169
170 switch(region) {
171 case 0:
172 r = v;
173 g = t;
174 b = p;
175 break;
176 case 1:
177 r = q;
178 g = v;
179 b = p;
180 break;
181 case 2:
182 r = p;
183 g = v;
184 b = t;
185 break;
186 case 3:
187 r = p;
188 g = q;
189 b = v;
190 break;
191 case 4:
192 r = t;
193 g = p;
194 b = v;
195 break;
196 default:
197 r = v;
198 g = p;
199 b = q;
200 break;
201 }
202
203 lv_color_t result = lv_color_make(r, g, b);
204 return result;
205 }
206
207 /**
208 * Convert a 32-bit RGB color to HSV
209 * @param r8 8-bit red
210 * @param g8 8-bit green
211 * @param b8 8-bit blue
212 * @return the given RGB color in HSV
213 */
lv_color_rgb_to_hsv(uint8_t r8,uint8_t g8,uint8_t b8)214 lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8)
215 {
216 uint16_t r = ((uint32_t)r8 << 10) / 255;
217 uint16_t g = ((uint32_t)g8 << 10) / 255;
218 uint16_t b = ((uint32_t)b8 << 10) / 255;
219
220 uint16_t rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b);
221 uint16_t rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b);
222
223 lv_color_hsv_t hsv;
224
225 // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
226 hsv.v = (100 * rgbMax) >> 10;
227
228 int32_t delta = rgbMax - rgbMin;
229 if(LV_MATH_ABS(delta) < 3) {
230 hsv.h = 0;
231 hsv.s = 0;
232 return hsv;
233 }
234
235 // https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation
236 hsv.s = 100 * delta / rgbMax;
237 if(hsv.s < 3) {
238 hsv.h = 0;
239 return hsv;
240 }
241
242 // https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma
243 int32_t h;
244 if(rgbMax == r)
245 h = (((g - b) << 10) / delta) + (g < b ? (6 << 10) : 0); // between yellow & magenta
246 else if(rgbMax == g)
247 h = (((b - r) << 10) / delta) + (2 << 10); // between cyan & yellow
248 else if(rgbMax == b)
249 h = (((r - g) << 10) / delta) + (4 << 10); // between magenta & cyan
250 else
251 h = 0;
252 h *= 60;
253 h >>= 10;
254 if(h < 0) h += 360;
255
256 hsv.h = h;
257 return hsv;
258 }
259
260 /**
261 * Convert a color to HSV
262 * @param color color
263 * @return the given color in HSV
264 */
lv_color_to_hsv(lv_color_t color)265 lv_color_hsv_t lv_color_to_hsv(lv_color_t color)
266 {
267 lv_color32_t color32;
268 color32.full = lv_color_to32(color);
269 return lv_color_rgb_to_hsv(color32.ch.red, color32.ch.green, color32.ch.blue);
270 }
271