Lumitronix_Iflex_Pro_Workshop
Library to interact with the iFlexPro
Rgbw64Color.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2 Rgbw64Color provides a color object that can be directly consumed by LumitronixIFlexBus
3 
4 Written by Michael C. Miller.
5 
6 I invest time and resources providing this open source code,
7 please support me by dontating (see https://github.com/Makuna)
8 
9 -------------------------------------------------------------------------
10 This file is part of the LUMITRONIX_iFlex_Workshop library.
11 
12 LumitronixIFlexBus is free software: you can redistribute it and/or modify
13 it under the terms of the GNU Lesser General Public License as
14 published by the Free Software Foundation, either version 3 of
15 the License, or (at your option) any later version.
16 
17 LumitronixIFlexBus is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU Lesser General Public License for more details.
21 
22 You should have received a copy of the GNU Lesser General Public
23 License along with LumitronixIFlex. If not, see
24 <http://www.gnu.org/licenses/>.
25 -------------------------------------------------------------------------*/
26 #pragma once
27 
28 struct RgbColor;
29 struct HslColor;
30 struct HsbColor;
31 
32 // ------------------------------------------------------------------------
33 // Rgbw64Color represents a color object that is represented by Red, Green, Blue
34 // component values and an extra White component. It contains helpful color
35 // routines to manipulate the color.
36 // ------------------------------------------------------------------------
38 {
40 
41  // ------------------------------------------------------------------------
42  // Construct a Rgbw64Color using R, G, B, W values (0-65535)
43  // ------------------------------------------------------------------------
44  Rgbw64Color(uint16_t r, uint16_t g, uint16_t b, uint16_t w = 0) :
45  R(r), G(g), B(b), W(w)
46  {
47  };
48 
49  // ------------------------------------------------------------------------
50  // Construct a RgbColor using a single brightness value (0-65535)
51  // This works well for creating gray tone colors
52  // (0) = black, (65535) = white, (32768) = gray
53  // ------------------------------------------------------------------------
54  Rgbw64Color(uint16_t brightness) :
55  R(0), G(0), B(0), W(brightness)
56  {
57  };
58 
59  // ------------------------------------------------------------------------
60  // Construct a Rgbw64Color using RgbColor
61  // ------------------------------------------------------------------------
62  Rgbw64Color(const RgbColor& color)
63  {
64  *this = Rgb48Color(color);
65  };
66 
67  // ------------------------------------------------------------------------
68  // Construct a Rgbw64Color using Rgb48Color
69  // ------------------------------------------------------------------------
70  Rgbw64Color(const Rgb48Color& color) :
71  R(color.R),
72  G(color.G),
73  B(color.B),
74  W(0)
75  {
76  };
77 
78  // ------------------------------------------------------------------------
79  // Construct a Rgbw64Color using RgbwColor
80  // ------------------------------------------------------------------------
81  Rgbw64Color(const RgbwColor& color)
82  {
83  // x16 = map(x8, 0, 255, 0, 65535); // refactors to just * 257
84  R = (uint16_t)color.R * 257; // 257 = MAXUINT16/MAXUINT8 = 65535/255
85  G = (uint16_t)color.G * 257;
86  B = (uint16_t)color.B * 257;
87  W = (uint16_t)color.W * 257;
88  };
89 
90 
91  // ------------------------------------------------------------------------
92  // Construct a Rgbw64Color using HtmlColor
93  // ------------------------------------------------------------------------
94  Rgbw64Color(const HtmlColor& color)
95  {
96  *this = RgbwColor(color);
97  }
98 
99  // ------------------------------------------------------------------------
100  // Construct a Rgbw64Color using HslColor
101  // ------------------------------------------------------------------------
102  Rgbw64Color(const HslColor& color);
103 
104  // ------------------------------------------------------------------------
105  // Construct a Rgbw64Color using HsbColor
106  // ------------------------------------------------------------------------
107  Rgbw64Color(const HsbColor& color);
108 
109  // ------------------------------------------------------------------------
110  // Construct a Rgbw64Color that will have its values set in latter operations
111  // CAUTION: The R,G,B, W members are not initialized and may not be consistent
112  // ------------------------------------------------------------------------
114  {
115  };
116 
117  // ------------------------------------------------------------------------
118  // Comparison operators
119  // ------------------------------------------------------------------------
120  bool operator==(const Rgbw64Color& other) const
121  {
122  return (R == other.R && G == other.G && B == other.B && W == other.W);
123  };
124 
125  bool operator!=(const Rgbw64Color& other) const
126  {
127  return !(*this == other);
128  };
129 
130  // ------------------------------------------------------------------------
131  // CompareTo method
132  // compares against another color with the given epsilon (delta allowed)
133  // returns the greatest difference of a set of elements,
134  // 0 = equal within epsilon delta
135  // negative - this is less than other
136  // positive - this is greater than other
137  // ------------------------------------------------------------------------
138  int32_t CompareTo(const Rgbw64Color& other, uint16_t epsilon = 256)
139  {
140  return _Compare<Rgbw64Color, int32_t>(*this, other, epsilon);
141  }
142 
143  // ------------------------------------------------------------------------
144  // Compare method
145  // compares two colors with the given epsilon (delta allowed)
146  // returns the greatest difference of a set of elements,
147  // 0 = equal within epsilon delta
148  // negative - left is less than right
149  // positive - left is greater than right
150  // ------------------------------------------------------------------------
151  static int32_t Compare(const Rgbw64Color& left, const Rgbw64Color& right, uint16_t epsilon = 256)
152  {
153  return _Compare<Rgbw64Color, int32_t>(left, right, epsilon);
154  }
155 
156  // ------------------------------------------------------------------------
157  // operator [] - readonly
158  // access elements in order by index rather than R,G,B
159  // see static Count for the number of elements
160  // ------------------------------------------------------------------------
161  uint16_t operator[](size_t idx) const
162  {
163  switch (idx)
164  {
165  case 0:
166  return R;
167  case 1:
168  return G;
169  case 2:
170  return B;
171  default:
172  return W;
173  }
174  }
175 
176  // ------------------------------------------------------------------------
177  // operator [] - read write
178  // access elements in order by index rather than R,G,B
179  // see static Count for the number of elements
180  // ------------------------------------------------------------------------
181  uint16_t& operator[](size_t idx)
182  {
183  switch (idx)
184  {
185  case 0:
186  return R;
187  case 1:
188  return G;
189  case 2:
190  return B;
191  default:
192  return W;
193  }
194  }
195 
196  // ------------------------------------------------------------------------
197  // Returns if the color is grey, all values are equal other than white
198  // ------------------------------------------------------------------------
199  bool IsMonotone() const
200  {
201  return (R == B && R == G);
202  };
203 
204  // ------------------------------------------------------------------------
205  // Returns if the color components are all zero, the white component maybe
206  // anything
207  // ------------------------------------------------------------------------
208  bool IsColorLess() const
209  {
210  return (R == 0 && B == 0 && G == 0);
211  };
212 
213  // ------------------------------------------------------------------------
214  // CalculateBrightness will calculate the overall brightness
215  // NOTE: This is a simple linear brightness
216  // ------------------------------------------------------------------------
217  uint16_t CalculateBrightness() const;
218 
219  // ------------------------------------------------------------------------
220  // Dim will return a new color that is blended to black with the given ratio
221  // ratio - (0-65535) where 65535 will return the original color and 0 will return black
222  //
223  // NOTE: This is a simple linear blend
224  // ------------------------------------------------------------------------
225  Rgbw64Color Dim(uint16_t ratio) const;
226 
227  // ------------------------------------------------------------------------
228  // Dim will return a new color that is blended to black with the given ratio
229  // ratio - (0-255) where 255 will return the original color and 0 will return black
230  //
231  // NOTE: This is a simple linear blend
232  // ------------------------------------------------------------------------
233  Rgbw64Color Dim(uint8_t ratio) const
234  {
235  uint16_t expanded = ratio << 8;
236  return Dim(expanded);
237  }
238 
239  // ------------------------------------------------------------------------
240  // Brighten will return a new color that is blended to white with the given ratio
241  // ratio - (0-65535) where 65535 will return the original color and 0 will return white
242  //
243  // NOTE: This is a simple linear blend
244  // ------------------------------------------------------------------------
245  Rgbw64Color Brighten(uint16_t ratio) const;
246 
247  // ------------------------------------------------------------------------
248  // Brighten will return a new color that is blended to white with the given ratio
249  // ratio - (0-255) where 255 will return the original color and 0 will return white
250  //
251  // NOTE: This is a simple linear blend
252  // ------------------------------------------------------------------------
253  Rgbw64Color Brighten(uint8_t ratio) const
254  {
255  uint16_t expanded = ratio << 8;
256  return Brighten(expanded);
257  }
258 
259  // ------------------------------------------------------------------------
260  // Darken will adjust the color by the given delta toward black
261  // NOTE: This is a simple linear change
262  // delta - (0-65535) the amount to dim the color
263  // ------------------------------------------------------------------------
264  void Darken(uint16_t delta);
265 
266  // ------------------------------------------------------------------------
267  // Lighten will adjust the color by the given delta toward white
268  // NOTE: This is a simple linear change
269  // delta - (0-65535) the amount to lighten the color
270  // ------------------------------------------------------------------------
271  void Lighten(uint16_t delta);
272 
273  // ------------------------------------------------------------------------
274  // LinearBlend between two colors by the amount defined by progress variable
275  // left - the color to start the blend at
276  // right - the color to end the blend at
277  // progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
278  // and a value between will blend the color weighted linearly between them
279  // ------------------------------------------------------------------------
280  static Rgbw64Color LinearBlend(const Rgbw64Color& left, const Rgbw64Color& right, float progress);
281  // progress - (0 - 255) value where 0 will return left and 255 will return right
282  // and a value between will blend the color weighted linearly between them
283  // ------------------------------------------------------------------------
284  static Rgbw64Color LinearBlend(const Rgbw64Color& left, const Rgbw64Color& right, uint8_t progress);
285 
286  // ------------------------------------------------------------------------
287  // BilinearBlend between four colors by the amount defined by 2d variable
288  // c00 - upper left quadrant color
289  // c01 - upper right quadrant color
290  // c10 - lower left quadrant color
291  // c11 - lower right quadrant color
292  // x - unit value (0.0 - 1.0) that defines the blend progress in horizontal space
293  // y - unit value (0.0 - 1.0) that defines the blend progress in vertical space
294  // ------------------------------------------------------------------------
295  static Rgbw64Color BilinearBlend(const Rgbw64Color& c00,
296  const Rgbw64Color& c01,
297  const Rgbw64Color& c10,
298  const Rgbw64Color& c11,
299  float x,
300  float y);
301 
302  uint16_t CalcTotalTenthMilliAmpere(const SettingsObject& settings)
303  {
304  auto total = 0;
305 
306  total += R * settings.RedTenthMilliAmpere / Max;
307  total += G * settings.GreenTenthMilliAmpere / Max;
308  total += B * settings.BlueTenthMilliAmpere / Max;
309  total += W * settings.WhiteTenthMilliAmpere / Max;
310 
311  return total;
312  }
313 
314  // ------------------------------------------------------------------------
315  // Red, Green, Blue, White color members (0-65535) where
316  // (0,0,0,0) is black and (65535,65535,65535, 0) and (0,0,0,65535) is white
317  // Note (65535,65535,65535,65535) is extreme bright white
318  // ------------------------------------------------------------------------
319  uint16_t R;
320  uint16_t G;
321  uint16_t B;
322  uint16_t W;
323 
324  const static uint16_t Max = 65535;
325  const static size_t Count = 4; // four elements in []
326 
327 private:
328  inline static uint16_t _elementDim(uint16_t value, uint16_t ratio)
329  {
330  return (static_cast<uint32_t>(value) * (static_cast<uint32_t>(ratio) + 1)) >> 16;
331  }
332 
333  inline static uint16_t _elementBrighten(uint16_t value, uint16_t ratio)
334  {
335  uint32_t element = ((static_cast<uint32_t>(value) + 1) << 16) / (static_cast<uint32_t>(ratio) + 1);
336 
337  if (element > Max)
338  {
339  element = Max;
340  }
341  else
342  {
343  element -= 1;
344  }
345  return element;
346  }
347 };
348 
Definition: NeoSettings.h:65
const uint16_t RedTenthMilliAmpere
Definition: NeoSettings.h:94
const uint16_t GreenTenthMilliAmpere
Definition: NeoSettings.h:95
const uint16_t BlueTenthMilliAmpere
Definition: NeoSettings.h:96
const uint16_t WhiteTenthMilliAmpere
Definition: NeoSettings.h:97
Definition: HsbColor.h:35
Definition: HslColor.h:34
Definition: HtmlColor.h:70
Definition: Rgb48Color.h:36
Definition: RgbColorBase.h:34
Definition: RgbColor.h:36
Definition: Rgbw64Color.h:38
uint16_t B
Definition: Rgbw64Color.h:321
static Rgbw64Color LinearBlend(const Rgbw64Color &left, const Rgbw64Color &right, float progress)
Definition: Rgbw64Color.cpp:158
Rgbw64Color(const HtmlColor &color)
Definition: Rgbw64Color.h:94
void Darken(uint16_t delta)
Definition: Rgbw64Color.cpp:75
uint16_t G
Definition: Rgbw64Color.h:320
uint16_t & operator[](size_t idx)
Definition: Rgbw64Color.h:181
Rgbw64Color()
Definition: Rgbw64Color.h:113
static const size_t Count
Definition: Rgbw64Color.h:325
Rgbw64Color Brighten(uint16_t ratio) const
Definition: Rgbw64Color.cpp:69
Rgbw64Color(const Rgb48Color &color)
Definition: Rgbw64Color.h:70
uint16_t CalculateBrightness() const
Definition: Rgbw64Color.cpp:50
Rgbw64Color(const RgbwColor &color)
Definition: Rgbw64Color.h:81
static int32_t Compare(const Rgbw64Color &left, const Rgbw64Color &right, uint16_t epsilon=256)
Definition: Rgbw64Color.h:151
uint16_t CalcTotalTenthMilliAmpere(const SettingsObject &settings)
Definition: Rgbw64Color.h:302
uint16_t W
Definition: Rgbw64Color.h:322
int32_t CompareTo(const Rgbw64Color &other, uint16_t epsilon=256)
Definition: Rgbw64Color.h:138
bool operator==(const Rgbw64Color &other) const
Definition: Rgbw64Color.h:120
uint16_t R
Definition: Rgbw64Color.h:319
Rgbw64Color(uint16_t r, uint16_t g, uint16_t b, uint16_t w=0)
Definition: Rgbw64Color.h:44
bool IsMonotone() const
Definition: Rgbw64Color.h:199
static const uint16_t Max
Definition: Rgbw64Color.h:324
NeoRgbwCurrentSettings SettingsObject
Definition: Rgbw64Color.h:39
bool IsColorLess() const
Definition: Rgbw64Color.h:208
uint16_t operator[](size_t idx) const
Definition: Rgbw64Color.h:161
Rgbw64Color(const RgbColor &color)
Definition: Rgbw64Color.h:62
bool operator!=(const Rgbw64Color &other) const
Definition: Rgbw64Color.h:125
static Rgbw64Color BilinearBlend(const Rgbw64Color &c00, const Rgbw64Color &c01, const Rgbw64Color &c10, const Rgbw64Color &c11, float x, float y)
Definition: Rgbw64Color.cpp:173
Rgbw64Color Dim(uint16_t ratio) const
Definition: Rgbw64Color.cpp:63
Rgbw64Color Brighten(uint8_t ratio) const
Definition: Rgbw64Color.h:253
void Lighten(uint16_t delta)
Definition: Rgbw64Color.cpp:114
Rgbw64Color Dim(uint8_t ratio) const
Definition: Rgbw64Color.h:233
Rgbw64Color(uint16_t brightness)
Definition: Rgbw64Color.h:54
Definition: RgbwColor.h:38
uint8_t R
Definition: RgbwColor.h:271
uint8_t W
Definition: RgbwColor.h:274
uint8_t B
Definition: RgbwColor.h:273
uint8_t G
Definition: RgbwColor.h:272