MRaster lib 22.0.0.0
Image Processing Library
Loading...
Searching...
No Matches
MRcolorTpl.hpp
Go to the documentation of this file.
1// -*- Mode:C++; Coding:us-ascii-unix; fill-column:158 -*-
2/*******************************************************************************************************************************************************.H.S.**/
3/**
4 @file MRcolorTpl.hpp
5 @author Mitch Richling <https://www.mitchr.me>
6 @brief Header for the ramColor class@EOL
7 @copyright
8 @parblock
9 Copyright (c) 1988-2015, Mitchell Jay Richling <https://www.mitchr.me> All rights reserved.
10
11 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
12
13 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.
14
15 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation
16 and/or other materials provided with the distribution.
17
18 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software
19 without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 DAMAGE.
27 @endparblock
28*/
29/*******************************************************************************************************************************************************.H.E.**/
30
31////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32#ifndef MJR_INCLUDE_MRcolorTpl
33
34#include "MRMathFC.hpp"
35#include "MRMathIVL.hpp"
36#include "MRMathLINM.hpp"
37#include "MRMathODR.hpp"
38
39////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
40#include <algorithm> /* STL algorithm C++11 */
41#include <array> /* array template C++11 */
42#include <bit> /* STL bit manipulation C++20 */
43#include <climits> /* std:: C limits.h C++11 */
44#include <cmath> /* std:: C math.h C++11 */
45#include <complex> /* Complex Numbers C++11 */
46#include <concepts> /* Concepts library C++20 */
47#include <cstring> /* std:: C string.h C++11 */
48#include <iomanip> /* C++ stream formatting C++11 */
49#include <iostream> /* C++ iostream C++11 */
50#include <limits> /* C++ Numeric limits C++11 */
51#include <span> /* STL spans C++20 */
52#include <sstream> /* C++ string stream C++ */
53#include <string> /* C++ strings C++11 */
54#include <tuple> /* STL tuples C++11 */
55#include <type_traits> /* C++ metaprogramming C++11 */
56#include <utility> /* STL Misc Utilities C++11 */
57#include <vector> /* STL vector C++11 */
58
59////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60/** Set to 1 to look for 128-bit integer types, and 0 to not look for them.
61 Right now this only works on GCC & Clang! */
62#ifndef MJR_LOOK_FOR_128_BIT_TYPES
63#define MJR_LOOK_FOR_128_BIT_TYPES MRASTER_OPT_128_INT
64#endif
65
66////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
67#if MJR_LOOK_FOR_128_BIT_TYPES
68#ifdef __GNUC__
69#ifdef __SIZEOF_INT128__
70#if __SIZEOF_INT128__ == 16
71typedef unsigned __int128 mjr_uint128_t;
72typedef __int128 mjr_int128_t;
73#define MJR_HAVE_128_BIT_TYPES
74#endif
75#endif
76#endif
77#endif
78
79////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
80#ifdef MJR_HAVE_128_BIT_TYPES
81typedef mjr_uint128_t mjr_uintBiggest_t; //!< The largest unsigned integer supported on the platform
82typedef mjr_int128_t mjr_intBiggest_t; //!< The largest signed integer supported on the platform
83#else
84typedef uint64_t mjr_uintBiggest_t; //!< The largest unsigned integer supported on the platform
85typedef int64_t mjr_intBiggest_t; //!< The largest signed integer supported on the platform
86#endif
87
88////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
89// Put everything in the mjr namespace
90namespace mjr {
91
92////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93
94/** @brief Template Class used to house colors for ramCanvas objects.@EOL
95
96 This template provides a rich API for color management, and may be used to store colors with a wide range of channel depth and count. This class is
97 intended to be a "small concrete" class (as defined by Bjarne Stroustrup in "The C++ Programming Language"). That is to say, it is intended for use as a
98 "fundamental" type for tools requiring a space efficient and high performance set of concrete objects representing colors. The canonical example is
99 representing an image as a very large, rectangular array of colors.
100
101 @par Size efficiency
102
103 While this class supports large channel counts and very deep channels, it is best optimized for colors that take require no more RAM space than the
104 largest hardware supported integer. This is because the library uses an integer to cover color channel array in RAM to make memory operations faster.
105 With a compiler supporting ISO C++, this object should take no more than the maximum of sizeof(clrChanT)*numChan or the mask used to cover the data. More
106 detail on the "mask" is provided later in the section "Memory Layout and Performance".
107
108 @par Passing colors as function arguments
109
110 The most common use cases are 24-bit RGB, 32-bit RGBA, and greyscale up to 64-bits deep. All of these types are smaller than a 64-bit pointer, so it is
111 almost always better to pass these values around by value. That said, some types are quite large -- an RGBA image with 64-bit floating point channels
112 requires 256 bits of RAM. For these larger color objects, it is more efficient to pass them by reference. Within the library, some care is taken to
113 adapt to the size of the color object, and pass objects to functions by the most efficient means (value or const reference). The class provides a type
114 the end user can employ to use this same strategy: colorArgType.
115
116 @par Memory Layout and Performance
117
118 Within this object an integer mask and an array of numChan clrCompT are placed into a union -- and thus are stacked upon each other in memory. When an
119 integer type exists that can cover the entire channel array without wasting too much space, we can achieve serious performance gains. The trick is
120 finding an integer big enough, but not so big it wastes space. Big enough means it is at least sizeof(clrChanT)*numChan chars long. The "not too big"
121 constraint is more flexible, and I have elected to make a covering mask only if we waste no more than 1/4 of the RAM for the mask value. Examples:
122
123 - An RGBA color with 8-bit channels (32-bits total) is covered by a uint32_t with no lost space.
124 - An RGB color with 8-bit canonical (24-bits total) is also covered with a single uint32_t. One byte per pixel is wasted -- i.e. 25% of the space.
125 - A 5 channel color with 8-bit channels (40-bits total) is *NOT* covered by a uint64_t as it would lead to almost 50% wasted space.
126 - A 6 channel color with 8-bit channels (48-bits total) is would be covered by a uint64_t -- a 25% waste of space.
127
128 When we can't cover the channel array, the mask type will be set to a uint8_t to avoid any alignment issues with the union.
129
130 Some common diagrams of common cases might help:
131
132 2222222222222222 Cover: 16-bits
133 11111111 1x8 Waste 1/2 => No Cover
134 1111111122222222 2x8 Waste 0/2 => Cover with 16-bits
135
136 44444444444444444444444444444444 Cover: 32-bits
137 111111112222222233333333 3x8 Waste 1/4 => Cover with 32-bits
138 11111111222222223333333344444444 4x8 Waste 0/4 => Cover with 32-bits
139
140 8888888888888888888888888888888888888888888888888888888888888888
141 1111111122222222333333334444444455555555 5x8 Waste 3/8 => No cover
142 111111112222222233333333444444445555555566666666 6x8 Waste 2/8 => Cover with 64-bits
143 111111111111111122222222222222223333333333333333 3x16 Waste 2/8 => Cover with 64-bits
144
145 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
146 1111111122222222333333334444444455555555666666667777777788888888999999990000000011111111 11x8 Waste 5/16 => No Cover
147 111111112222222233333333444444445555555566666666777777778888888899999999000000001111111122222222 12x8 Waste 4/16 => Cover with uint128_t
148 11111111111111112222222222222222333333333333333344444444444444445555555555555555 5x16 Waste 6/16 == No Cover
149 111111111111111122222222222222223333333333333333444444444444444455555555555555556666666666666666 6x16 Waste 4/16 => Cover with uint128_t
150 111111111111111111111111111111112222222222222222222222222222222233333333333333333333333333333333 3x32 Waste 4/16 => Cover with uint128_t
151
152 @par Usage
153
154 Several methods are provided that access and modify the internal color represented by a color object. In most cases, methods that modify the color object
155 state return a reference to the object after the change. This provides the ability to use the value returned by such a function in the expression in
156 which it appears. So, for example, it is not necessary to use two statements to change a color object's value and then use it in a drawing function. As
157 another example, this provides the ability to do "method chaining" like so: aColor.setToRed().setToBlack() -- which will lead to aColor being black. The
158 obvious potential performance impact of returning unused references is generally optimized away by modern compilers.
159
160 Several methods are provided that transform the color object as a whole. For example, methods are provided to compute component-wise linear histogram
161 transformations. Note that transformation methods are not provided to transform just one component of an object or a range of components. The philosophy
162 is that the class provides methods that treat the color object as a whole and not methods that operate on single components. Just as we don't have a
163 function to add the second half of two integers together -- integers are one "thingy" and so are colors. :)
164
165 @par Construction
166
167 Several constructors are provided. All in all, the goal is to make it easy to construct color objects with a specified color.
168
169 |--------------------------------+---------------------+----------------------------------------|
170 | Type | Member Helper | Cast Application |
171 |--------------------------------+---------------------+----------------------------------------|
172 | colorT | copy | |
173 | four clrChanT | setChans | |
174 | three clrChanT | setChans | |
175 | two clrChanT | setChans | |
176 | one clrChanT | setChans | drawPoint(x, y, 128); |
177 | Named Corner Colors via string | setColorFromString | drawPoint(x, y, "Red"); |
178 | Web hex string | setColorFromString | drawPoint(x, y, "#FF0000"); |
179 | Extended web hex string | setColorFromString | drawPoint(x, y, "##FFFF00000000"); |
180 | Single character string | setColorFromString | drawPoint(x, y, "R"); |
181 | Named Corner Colors via ENUM | setToCorner | drawPoint(x, y, cornerColorEnum::RED); |
182 |--------------------------------+---------------------+----------------------------------------|
183
184 @tparam clrChanT Type to contain the channel information. This type should be a unsigned integral type, a float, or double.
185 @tparam numChan The number of channels this color will have. Common choices are 1 for greyscale, 3 for RGB, and 4 for RGBA.
186 @tparam redChanIdx Index for the Red channel. -1 indicates no Red chan.
187 @tparam blueChanIdx Index for the Blue channel. -1 indicates no Red channel.
188 @tparam greenChanIdx Index for the Green channel. -1 indicates no Red channel.
189 @tparam alphaChanIdx Index for the Alpha channel. -1 indicates no Red channel.
190 If redChanIdx, blueChanIdx, greenChanIdx, & alphaChanIdx are *all* -1, then they will be assigned to channels 0, 1, 2, & 3 when numChan is >= 4. If they
191 are all negative and numChan == 3, then alphaChanIdx won't be assigned, but red, blue, and green will be. */
192 template <class clrChanT, int numChan, int redChanIdx = -1, int greenChanIdx = -1, int blueChanIdx = -1, int alphaChanIdx = -1>
193 requires ((numChan>0) && // Must have at least 1 chan
194 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
195 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
196 (redChanIdx < numChan) &&
197 (blueChanIdx < numChan) &&
198 (greenChanIdx < numChan) &&
199 (alphaChanIdx < numChan) &&
200 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
201 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
202 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
203 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
204 (redChanIdx != blueChanIdx) &&
205 (redChanIdx != alphaChanIdx) &&
206 (greenChanIdx != blueChanIdx) &&
207 (greenChanIdx != alphaChanIdx) &&
208 (blueChanIdx != alphaChanIdx)))) // Chans can't be teh same if non-negative
209 class colorTpl {
210
211 public:
212
213 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
214 /** @name Public type related types -- meta-types? ;) */
215 //@{
216 /** This object type */
218 /** Pointer to colorTpl */
220 /** Reference to colorTpl) */
222 /** Reference to const colorTpl */
223 typedef colorType const& colorCRefType;
224 /** Type for the channels (clrChanT) */
225 typedef clrChanT channelType;
226 //@}
227
228 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
229 /** @name Public types for std::tuple & std::vector containing clrChanT values */
230 //@{
231 typedef std::tuple<clrChanT, clrChanT, clrChanT, clrChanT> clrChanTup6;
232 typedef std::tuple<clrChanT, clrChanT, clrChanT, clrChanT> clrChanTup5;
233 typedef std::tuple<clrChanT, clrChanT, clrChanT, clrChanT> clrChanTup4;
234 typedef std::tuple<clrChanT, clrChanT, clrChanT> clrChanTup3;
235 typedef std::tuple<clrChanT, clrChanT> clrChanTup2;
236 typedef std::tuple<clrChanT> clrChanTup1;
237
238 typedef std::vector<clrChanT> clrChanVec;
239 //@}
240
241 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
242 /** @name Public types for for packed integers. */
243 //@{
244 typedef uint32_t packed4Cint; //!< Used for passing & returning integers with packed 8-bit channels
245 //@}
246
247 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
248 /** @name Public color types related to colorT.
249 These types are used for things like color space computations and sources for setting channels, etc...*/
250 //@{
251 typedef colorTpl<double, 3> colConDbl3; //!< Used for color space computations. Type identical to colConRGBdbl, but might not be RGB.
252 typedef colorTpl<double, 3> colConRGBdbl; //!< RGB with double channels.
253 typedef colorTpl<double, 4> colConRGBAdbl; //!< RGBA with double channels.
254 typedef colorTpl<uint8_t, 3> colConRGBbyte; //!< RGB with uint8_t channels.
255 typedef colorTpl<uint8_t, 4> colConRGBAbyte; //!< RGBA with uint8_t channels.
256 typedef colorTpl<double, numChan> colConALLdbl; //!< Color with the same number of challens as colorT, but with double channels
257 typedef colorTpl<uint8_t, numChan> colConALLbyte; //!< Color with the same number of challens as colorT, but with uint8_t channels
258 //@}
259
260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
261 /** @cond pat */
262 /** @name Public arithmetic types */
263 //@{
264 /** @typedef maskType
265 Unsigned integer mask to cover the channel array without wasting too much space.
266 This type is the the smallest unsigned integer that can cover clrChanT[numChan] such that it is no larger than 1/4 the total size of
267 clrChanT[numChan]. Ex: 3*uint8_t is covered by uint32_t, but 5*uint8_t would not be covered by uint64_t because it would waste almost half the
268 64 bits. When a cover can't be found, this type is set to uint8_t -- to avoid any alignment issues in RAM.
269
270 The constant goodMask can be used to tell if maskType is large enough to cover.
271 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
272 typedef typename std::conditional<std::cmp_greater_equal(sizeof(uint8_t), sizeof(clrChanT)*numChan), uint8_t,
273 typename std::conditional<std::cmp_greater_equal(sizeof(uint16_t), sizeof(clrChanT)*numChan), uint16_t,
274 typename std::conditional<std::cmp_greater_equal(sizeof(uint32_t), sizeof(clrChanT)*numChan), uint32_t,
275 typename std::conditional<std::cmp_greater_equal(sizeof(uint64_t), sizeof(clrChanT)*numChan),
276 typename std::conditional<std::cmp_less_equal(3*sizeof(uint64_t), sizeof(clrChanT)*numChan*4), uint64_t,
277 uint8_t
278 >::type,
279 typename std::conditional<std::cmp_greater_equal(sizeof(mjr_uintBiggest_t), sizeof(clrChanT)*numChan),
280 typename std::conditional<std::cmp_less_equal(3*sizeof(mjr_uintBiggest_t), sizeof(clrChanT)*numChan*4), mjr_uintBiggest_t,
281 uint8_t
282 >::type,
283 uint8_t
284 >::type>::type>::type>::type>::type maskType;
285
286 /** @typedef channelArithDType
287 Arithmetic type for differences of clrChanT values.
288 When clrChanT is a float, this type will be clrChanT. When it's an integer, we attempt to find a signed integer 2x the size.
289
290 The constant goodArithD can be used to tell if channelArithDType is large enough.
291 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
292 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
293 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)*2), int8_t,
294 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)*2), int16_t,
295 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)*2), int32_t,
296 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)*2), int64_t,
298 >::type>::type>::type>::type>::type channelArithDType;
299
300 /** @typedef channelArithSPType
301 Arithmetic type for sums and products of clrChanT values.
302 When clrChanT is a float, this type will be clrChanT. When it's an integer, we attempt to find an unsigned integer 2x the size.
303
304 The constant goodArithSP can be used to tell if channelArithSPType is large enough.
305 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
306 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
307 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)*2), uint8_t,
308 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)*2), uint16_t,
309 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)*2), uint32_t,
310 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)*2), uint64_t,
312 >::type>::type>::type>::type>::type channelArithSPType;
313
314 /** @typedef channelArithSDPType
315 Arithmetic type for sums, differences, and products of clrChanT values.
316 When clrChanT is a float, this type will be clrChanT. When it's an integer, we attempt to find an signed integer 4x the size.
317
318 The constant goodArithSDP can be used to tell if channelArithSDPType is large enough.
319 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
320 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
321 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)*4), int8_t,
322 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)*4), int16_t,
323 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)*4), int32_t,
324 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)*4), int64_t,
326 >::type>::type>::type>::type>::type channelArithSDPType;
327
328 /** @typedef channelArithFltType
329 Floating point type suitable for arithmetic of clrChanT values.
330 When clrChanT is a float, this type will be clrChanT. When it's an integer, we attempt to find a float at least as big as clrChanT.
331
332 The constant goodArithFlt can be used to tell if channelArithFltType is large enough.
333 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
334 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
335 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)), float,
336 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)), float,
337 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)), double,
338 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)), long double,
339 long double
340 >::type>::type>::type>::type>::type channelArithFltType;
341
342 /** @typedef channelArithLogType
343 Arithmetic type suitable for for logical operations of clrChanT values.
344
345 When clrChanT is an integer, this type will be clrChanT. When it's a floating point type, we attempt to find an unsigned integer exactly the same
346 size as clrChanT. Note that on x86 hardware, a quad float (long double or extended double) is 80-bits in the processor but 128-bits in RAM. In
347 general the size of quad floats can vary a bit across hardware platforms, so I suggest not using them for channel types.
348
349 The constant goodArithLog can be used to tell if channelArithLogType the same size as clrChanT.
350 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
351 typedef typename std::conditional<std::is_integral<clrChanT>::value, clrChanT,
352 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)), uint32_t,
353 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)), uint64_t,
354 typename std::conditional<std::cmp_greater_equal(sizeof(mjr_uintBiggest_t), sizeof(clrChanT)), mjr_uintBiggest_t,
355 uint64_t
356 >::type>::type>::type>::type channelArithLogType;
357 //@}
358 /** @endcond */
359
360 private:
361
362 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
363 /** @name Private Object Data */
364 //@{
365 /** Holds the color channel data.
366 The union is used to overlay a mask integer leading to dramatic performance improvements for common color types.
367
368 Technically we are not allowed to use a union the way we do in colorTpl with modern C++; however, every compiler I use allows us to access
369 "non-active" union members the same way we did with good old C. At some point C++ compilers will have bit_cast, and I can try doing this the
370 "correct" way with modern C++; however, I'll need to do quite a bit of performance testing first... */
371 union {
372 maskType theInt;
373 clrChanT thePartsA[numChan];
374 } theColor;
375 //@}
376
377 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
378 /** @name Private utility functions */
379 //@{
380 //--------------------------------------------------------------------------------------------------------------------------------------------------------
381 /** This is a helper function for setRGBfromColorSpace. */
382 inline double hslHelperVal(double n1, double n2, double hue) {
383 hue = mjr::math::ivl::wrapCO(hue, 360.0);
384 if(hue<60)
385 return n1+(n2-n1)*hue/60.0;
386 else if(hue<180)
387 return n2;
388 else if (hue < 240)
389 return n1+(n2-n1)*(240-hue)/60.0;
390 else
391 return n1;
392 }
393 //--------------------------------------------------------------------------------------------------------------------------------------------------------
394 /** Set all channels to meanChanVal. */
395 inline void setChansToMean() { std::fill_n(theColor.thePartsA, numChan, meanChanVal); }
396 //--------------------------------------------------------------------------------------------------------------------------------------------------------
397 /** Set all channels to minChanVal. */
398 inline void setChansToMin() {
399 if constexpr (goodMask)
400 setMaskNC(maskAllZero);
401 else
402 std::fill_n(theColor.thePartsA, numChan, minChanVal);
403 }
404 //--------------------------------------------------------------------------------------------------------------------------------------------------------
405 /** Set all channels to maxChanVal. */
406 inline void setChansToMax() {
407 if(chanIsInt && goodMask)
408 setMaskNC(~static_cast<maskType>(0));
409 else
410 std::fill_n(theColor.thePartsA, numChan, maxChanVal);
411 }
412 //--------------------------------------------------------------------------------------------------------------------------------------------------------
413 /** Sets the current color based upon the contents of the given std::string.
414 This is the guts of the magic constructor taking a string. If colorString starts with a "#", then setChans() will be used.
415 Otherwise setToCorner() will be used */
416 inline colorTpl& setColorFromString(std::string colorString) {
417 if ( !(colorString.empty())) {
418 if(colorString[0] == '#') {
419 setChans(colorString, true);
420 } else {
421 if(((colorString[0] == 'b') || (colorString[0] == 'B')) && (colorString.size() > 1)) {
422 if( (colorString[2]=='u') || (colorString[2]=='U') )
423 setToBlue();
424 else
425 setToBlack();
426 } else {
427 setToCorner(colorString[0]);
428 }
429 }
430 }
431 return *this;
432 }
433 //--------------------------------------------------------------------------------------------------------------------------------------------------------
434 /** Convert a uint8_t to a clrChanT (for integral clrChanT) */
435 inline clrChanT convertByteToChan(uint8_t cVal) const requires (std::integral<clrChanT>) {
436 if(chanIsByte)
437 return cVal;
438 else
439 return static_cast<clrChanT>(static_cast<channelArithSPType>(cVal) * static_cast<channelArithSPType>(maxChanVal) / static_cast<channelArithSPType>(255));
440 }
441 //--------------------------------------------------------------------------------------------------------------------------------------------------------
442 /** Convert a uint8_t to a clrChanT (for floating point clrChanT)*/
443 inline clrChanT convertByteToChan(uint8_t cVal) const requires (std::floating_point<clrChanT>) {
444 return (static_cast<clrChanT>(cVal) / static_cast<clrChanT>(255));
445 }
446 //--------------------------------------------------------------------------------------------------------------------------------------------------------
447 /** Convert hex CString to clrChanT (for integral clrChanT) */
448 inline clrChanT convertHexStringToChan(std::string hexString) const requires (std::integral<clrChanT>) {
449 if (sizeof(unsigned long) >= sizeof(clrChanT))
450 return static_cast<clrChanT>( std::stoul(hexString, nullptr, 16));
451 else
452 return static_cast<clrChanT>(std::stoull(hexString, nullptr, 16));
453 }
454 //--------------------------------------------------------------------------------------------------------------------------------------------------------
455 /** Convert hex CString to clrChanT (for floating point clrChanT)*/
456 inline clrChanT convertHexStringToChan(std::string hexString) const requires (std::floating_point<clrChanT>) {
457 if (sizeof(unsigned long) >= sizeof(clrChanT))
458 return static_cast<clrChanT>( std::stoul(hexString, nullptr, 16)) / static_cast<clrChanT>((chanIsInt ? 1 : std::pow(2, bitsPerChan)));
459 else
460 return static_cast<clrChanT>(std::stoull(hexString, nullptr, 16)) / static_cast<clrChanT>((chanIsInt ? 1 : std::pow(2, bitsPerChan)));
461 }
462 //--------------------------------------------------------------------------------------------------------------------------------------------------------
463 /** Convert a clrChanT to a uint8_t (for floating point clrChanT) */
464 inline uint8_t convertChanToByte(clrChanT cVal) const requires (std::floating_point<clrChanT>) {
465 return static_cast<uint8_t>(cVal * static_cast<clrChanT>(255) / maxChanVal);
466 }
467 //--------------------------------------------------------------------------------------------------------------------------------------------------------
468 /** Convert a clrChanT to a uint8_t (for integral clrChanT) */
469 inline uint8_t convertChanToByte(clrChanT cVal) const requires (std::integral<clrChanT>) {
470 /* Performance: A good compiler *should* recgonize the case when bitsPerChan-8==0, and render this function an NOOP. Some don't. Hence the if-then
471 below. */
472 if constexpr (chanIsByte)
473 return static_cast<uint8_t>(cVal); // Cast is unnessary because we only get uint8_t cVal in this branch, but some compilers issue a warning.
474 else
475 return static_cast<uint8_t>(static_cast<channelArithSPType>(cVal) * static_cast<channelArithSPType>(255) / static_cast<channelArithSPType>(maxChanVal));
476 }
477 //--------------------------------------------------------------------------------------------------------------------------------------------------------
478 /** Convert a double to a clrChanT */
479 inline clrChanT convertDoubleToChan(double cVal) const {
480 /* Performance: Not all compilers recognize multiplication by 1.0 as a NOOP. Hence the if-then below. */
481 if constexpr (chanIsInt)
482 return static_cast<clrChanT>(cVal * maxChanVal);
483 else
484 return static_cast<clrChanT>(cVal);
485 }
486 //--------------------------------------------------------------------------------------------------------------------------------------------------------
487 /** Convert a clrChanT to a double */
488 inline double convertChanToDouble(clrChanT cVal) const {
489 if constexpr (chanIsInt)
490 return static_cast<double>(cVal) / static_cast<double>(maxChanVal);
491 else
492 return static_cast<double>(cVal);
493 }
494 //--------------------------------------------------------------------------------------------------------------------------------------------------------
495 /** Return the mask value */
496 inline maskType getMaskNC() const {
497#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
498#pragma GCC diagnostic push
499#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
500#endif
501 return theColor.theInt;
502#if __GNUC__
503#pragma GCC diagnostic pop
504#endif
505 }
506 //--------------------------------------------------------------------------------------------------------------------------------------------------------
507 /** Set the mask value */
508 inline void setMaskNC(maskType aMask) { theColor.theInt = aMask; }
509 //@}
510
511 public:
512
513 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
514 /** @name Public Constants Related to RGBA channels */
515 //@{
516 constexpr static int noRGBchanIdx = (redChanIdx < 0) && (greenChanIdx < 0) && (blueChanIdx < 0) && (alphaChanIdx < 0);
517 constexpr static int redChan = (noRGBchanIdx && numChan > 0 ? 0 : redChanIdx);
518 constexpr static int greenChan = (noRGBchanIdx && numChan > 1 ? 1 : greenChanIdx);
519 constexpr static int blueChan = (noRGBchanIdx && numChan > 2 ? 2 : blueChanIdx);
520 constexpr static int alphaChan = (noRGBchanIdx && numChan > 3 ? 3 : alphaChanIdx);
521 //@}
522
523 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
524 /** @name Public Constants Related to template paramaters */
525 //@{
526 constexpr static int bitsPerChan = (int)(sizeof(clrChanT)*CHAR_BIT); //!< Number of bits in clrChanT
527 constexpr static int bitsPerPixel = numChan*bitsPerChan; //!< Number of color data bits
528 constexpr static bool chanIsInt = std::is_integral<clrChanT>::value; //!< clrChanT is an integral type
529 constexpr static bool chanIsFloat = std::is_floating_point<clrChanT>::value; //!< clrChanT is a floating pint type
530 constexpr static bool chanIsUnsigned = std::is_unsigned<clrChanT>::value; //!< clrChanT is an unsigned integral type
531 constexpr static bool chanIsByte = std::is_same<clrChanT, uint8_t>::value; //!< is clrChanT an 8-bit unsigned int?
532 constexpr static bool chanIsDouble = std::is_same<clrChanT, double>::value; //!< is clrChanT a double?
533 constexpr static bool goodMask = (sizeof(maskType) >= sizeof(clrChanT)*numChan); //!< maskType is big enough
534 constexpr static bool perfectMask = (sizeof(maskType) == sizeof(clrChanT)*numChan); //!< maskType is perfectly sized
535 constexpr static bool goodArithD = (chanIsFloat || (sizeof(channelArithDType) >= sizeof(clrChanT)*2)); //!< channelArithDType is big enough
536 constexpr static bool goodArithSP = (chanIsFloat || (sizeof(channelArithSPType) >= sizeof(clrChanT)*2)); //!< channelArithSPType is big enough
537 constexpr static bool goodArithSDP = (chanIsFloat || (sizeof(channelArithSDPType) >= sizeof(clrChanT)*4)); //!< channelArithSDPType is big enough
538 constexpr static bool goodArithFlt = (chanIsFloat || (sizeof(channelArithFltType) > sizeof(clrChanT))); //!< channelArithFltType is big enough
539 constexpr static bool goodArithLog = (sizeof(channelArithLogType) == sizeof(clrChanT)); //!< channelArithLogType is the right size
540 constexpr static int sizeOfColor = (int)(goodMask ? sizeof(maskType) : sizeof(clrChanT)*numChan); //!< Size of this object
541 constexpr static bool ptrIsSmaller = sizeOfColor > (int)sizeof(colorPtrType); //!< This object smaller than a pointer
542 constexpr static clrChanT maxChanVal = (chanIsInt ? std::numeric_limits<clrChanT>::max() : 1); //!< maximum value for a channel
543 constexpr static clrChanT minChanVal = (chanIsInt ? std::numeric_limits<clrChanT>::min() : 0); //!< maximum value for a channel
544 constexpr static clrChanT meanChanVal = (maxChanVal-minChanVal)/2; //!< middle value for a channel
545 constexpr static maskType maskAllOne = ~(static_cast<maskType>(0)); //!< mask value all ones
546 constexpr static maskType maskAllZero = static_cast<maskType>(0); //!< mask value all zeros
547 constexpr static int channelCount = numChan; //!< Number of channels
548 //@}
549
550 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
551 /** @name Public type for argument passing */
552 //@{
553 /** A type for passing colorTpl objects to functions.
554
555 WHen the size of a colorTpl object is smaller than a pointer, this type is colorTpl -- resulting in pass by value. Otherwise, this type is
556 colorType const& -- resulting in pass by refrence. */
557 typedef typename std::conditional<ptrIsSmaller, colorCRefType, colorType>::type colorArgType;
558 //@}
559
560 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
561 /** @cond cst */
562 /** @name Color Scheme Related Types */
563 //@{
564 /** A type used for discreet color scheme indexes.
565 This will be uint64_t for floating point clrChanT, and the larger of uint32_t and colorChanArithSPType for integral clrChanT.
566 We use cmp_less because < confuses Doxygen.*/
567 typedef typename std::conditional<std::cmp_less(sizeof(channelArithSPType), sizeof(uint32_t)), uint32_t,
568 typename std::conditional<std::is_floating_point<clrChanT>::value, uint64_t,
569 channelArithSPType
570 >::type>::type csIntType;
571
572 /** A type used for continous color scheme indexes. */
573 typedef double csFltType;
574 /** A type used for 2D continous color scheme indexes. */
575 typedef std::complex<csFltType> csCplxType;
576 /** A clrChanT-similar type color scheme indexes. */
577 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, csFltType, csIntType>::type csNatType;
578 //@}
579 /** @endcond */
580
581 /** @name Color Scheme Constants */
582 //@{
583 /* The cast to csIntType is required to prevent std::numeric_limits<uint32_t>::max from being cast to a float when maxChanVal is a float. */
584 constexpr static csIntType chanStepMax = (chanIsInt ? static_cast<csIntType>(maxChanVal) : std::numeric_limits<uint32_t>::max()); //!< Finite "steps" for a color scheme: [0, chanStepMax]
585 constexpr static int minWavelength = 360; //!< Minimum wavelength for wavelength conversion
586 constexpr static int maxWavelength = 830; //!< Maximum wavelength for wavelength conversion
587 //@}
588
589 /** @name Default RGB Luminescence Weights */
590 //@{
591 constexpr static double RGBluminanceWeightR = 0.2126;
592 constexpr static double RGBluminanceWeightG = 0.7152;
593 constexpr static double RGBluminanceWeightB = 0.0722;
594 //@}
595
596 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
597 /** @name Public Enums Constants */
598 //@{
599 /** Colors at the corners of the RGB color cube. */
600 enum class cornerColorEnum { BLACK, //!< Color cube corner color with RGB=000
601 RED, //!< Color cube corner color with RGB=100
602 GREEN, //!< Color cube corner color with RGB=010
603 BLUE, //!< Color cube corner color with RGB=001
604 YELLOW, //!< Color cube corner color with RGB=110
605 CYAN, //!< Color cube corner color with RGB=011
606 MAGENTA, //!< Color cube corner color with RGB=101
607 WHITE //!< Color cube corner color with RGB=111
608 };
609 /** Color spaces.
610 This ENUM is used by setRGBfromColorSpace(), interplColorSpace(), and rgb2colorSpace(). In this context these color spaces use double values for each
611 channel. Angles (the H of HSV, HSL, & LCH) are in degrees, and will always be normalized to [0, 360). */
612 enum class colorSpaceEnum { RGB, //!< RGB color space. R in [0, 1]. G in [0, 1]. B in [0, 1].
613 HSL, //!< HSL color space. H in [0, 360]. S in [0, 1]. L in [0, 1].
614 HSV, //!< HSV color space. H in [0, 360]. S in [0, 1]. V in [0, 1].
615 LAB, //!< CIE-L*ab color space. L in [0, 100]. A in REALS. B in REALS.
616 XYZ, //!< XYZ color space. X in [0, 1]. Y in [0, 1]. Z in [0, 1].
617 LCH, //!< CIE-L*ch color space. L in [0, 100]. C in [0, 100]. H in [0, 360]
618 NONE //!< Used when the color channels don't have an assocaited color space
619 };
620 /** Interpolation methods for emperical color matching functions. */
621 enum class cmfInterpolationEnum { FLOOR, //!< closest lower
622 CEILING, //!< closest upper
623 NEAREST, //!< closest
624 LINEAR, //!< linear interpolation
625 BUMP //!< exponential bump map interpolation
626 // MJR TODO NOTE cmfInterpolationEnum: Add Chebychev and cubic spline options.
627 };
628 //@}
629
630 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
631 /** @name Constructors: C++ Utility */
632 //@{
633 //--------------------------------------------------------------------------------------------------------------------------------------------------------
634 /** The no arg constructor is a noop so we don't needlessly initialize millions of pixels -- compiler warnings are expected. */
636 //--------------------------------------------------------------------------------------------------------------------------------------------------------
637 /** Copy constructor (heavily used for assignment in the ramCanvas library). */
638 colorTpl(const colorType& aColor) {
639 /* Saftey: Yep. Sometimes the compiler might not be able to tell if we have initalized the color object -- some of the color set code is too complex.
640 Sometimes we might even want to copy an unitilzied color -- sometimes it makes the code easier to write.*/
641 if constexpr (goodMask)
642 setMaskNC(aColor.getMaskNC());
643 else
644 std::copy_n(aColor.theColor.thePartsA, numChan, theColor.thePartsA);
645 }
646 //--------------------------------------------------------------------------------------------------------------------------------------------------------
647 /** Initializer list. Unspecified channels are set ot minChanVal, and extra channel values are ignored. */
648 colorTpl(std::initializer_list<clrChanT> cVals) {
649 int numChanGiven = static_cast<int>(cVals.size());
650 auto p = cVals.begin();
651 for(int i=0; i<std::min(numChanGiven, numChan); i++) {
652 setChanNC(i, *p);
653 ++p;
654 }
655 if (numChanGiven < numChan)
656 for(int i=numChanGiven; i<numChan; i++)
657 setChanToMin(i);
658 }
659 //@}
660
661 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
662 /** @name Constructors: RGB
663 These all use setChansRGB or setChansRGBA internally; however, these constructors will set any unspecified channels to min. */
664 //@{
665 colorTpl(clrChanT r, clrChanT g, clrChanT b, clrChanT a) {
666 if constexpr (numChan > 4)
667 setChansToMin();
668 setChansRGBA(r, g, b, a);
669 }
670 colorTpl(clrChanT r, clrChanT g, clrChanT b) {
671 if constexpr (numChan > 3)
672 setChansToMin();
673 setChansRGB(r, g, b);
674 }
675 //@}
676
677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
678 /** @name Constructors: Conversions
679 These are all guarnteed to set all channels of the object. */
680 //@{
681 //--------------------------------------------------------------------------------------------------------------------------------------------------------
682 /** Uses setChans() to set all channels to the given value
683 @param cVal The value to set the channels to */
684 colorTpl(clrChanT cVal) { setChans(cVal); }
685 //--------------------------------------------------------------------------------------------------------------------------------------------------------
686 /** Uses the setToCorner() method to set the initialize the object.
687 Note that no constructor exists taking a character to provide to setToCorner(). Why? Because character literals are integers in C++, and they might
688 be the same as clrChanT -- rendering ambiguous overload cases.*/
689 colorTpl(cornerColorEnum cornerColor) { setToCorner(cornerColor); }
690 //--------------------------------------------------------------------------------------------------------------------------------------------------------
691 /** Uses the setColorFromString() method to set the initialize the object. */
692 colorTpl(std::string colorString) { setColorFromString(colorString); }
693 //--------------------------------------------------------------------------------------------------------------------------------------------------------
694 /** Uses the setColorFromString() method to set the initialize the object. */
695 colorTpl(const char* colorCString) { setColorFromString(std::string(colorCString)); }
696 //@}
697
698 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
699 /** @name Destructor */
700 //@{
701 /** The destructor for this class is a no-op. */
703 //@}
704
705 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
706 /** @name Utility Methods */
707 //@{
708 /** Copy the contents of the given color object into the current object.
709 When sizeof(colorTpl)<=sizeof(maskType), this function consists of a single assignment statement. Otherwise it is O(numChan).
710 @return Returns a reference to the current color object.*/
711 inline colorTpl& copy(colorArgType aCol) {
712 if constexpr (goodMask)
713 setMaskNC(aCol.getMaskNC());
714 else
715 for(int i=0; i<numChan; i++)
716 setChanNC(i, aCol.getChanNC(i));
717 return *this;
718 }
719 //@}
720
721 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
722 /** @name Named Channel Access
723 Provides access to the specified color channel value with compile time index check.
724 - _dbl versions work with double values scaled to [0, 1].
725 - _byte versions work with uint8_t values scaled to [0, 255]
726 - Numbered channel names are 0 indexed. */
727 //@{
728 inline clrChanT getRed() const requires ((redChan>=0) && (numChan>redChan)) { return getChanNC(redChan); }
729 inline clrChanT getBlue() const requires ((blueChan>=0) && (numChan>blueChan)) { return getChanNC(blueChan); }
730 inline clrChanT getGreen() const requires ((greenChan>=0) && (numChan>greenChan)) { return getChanNC(greenChan); }
731 inline clrChanT getAlpha() const requires ((alphaChan>=0) && (numChan>alphaChan)) { return getChanNC(alphaChan); }
732
733 inline double getRed_dbl() const { return convertChanToDouble(getRed()); }
734 inline double getGreen_dbl() const { return convertChanToDouble(getGreen()); }
735 inline double getBlue_dbl() const { return convertChanToDouble(getBlue()); }
736 inline double getAlpha_dbl() const { return convertChanToDouble(getAlpha()); }
737
738 inline uint8_t getRed_byte() const { return convertChanToByte(getRed()); }
739 inline uint8_t getGreen_byte() const { return convertChanToByte(getGreen()); }
740 inline uint8_t getBlue_byte() const { return convertChanToByte(getBlue()); }
741 inline uint8_t getAlpha_byte() const { return convertChanToByte(getAlpha()); }
742
743 inline clrChanT getC0() const { return getChanNC(0); }
744 inline clrChanT getC1() const requires (numChan>1) { return getChanNC(1); }
745 inline clrChanT getC2() const requires (numChan>2) { return getChanNC(2); }
746 inline clrChanT getC3() const requires (numChan>3) { return getChanNC(3); }
747
748 inline double getC0_dbl() const { return convertChanToDouble(getC0()); }
749 inline double getC1_dbl() const { return convertChanToDouble(getC1()); }
750 inline double getC2_dbl() const { return convertChanToDouble(getC2()); }
751 inline double getC3_dbl() const { return convertChanToDouble(getC3()); }
752
753 inline uint8_t getC0_byte() const { return convertChanToByte(getC0()); }
754 inline uint8_t getC1_byte() const { return convertChanToByte(getC1()); }
755 inline uint8_t getC2_byte() const { return convertChanToByte(getC2()); }
756 inline uint8_t getC3_byte() const { return convertChanToByte(getC3()); }
757 //@}
758
759 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
760 /** @name Indexed Channel Access
761 Provides access to an indexed color channel value with run time index check.
762 The channels are 0 indexed.
763 - _dbl versions work with double values scaled to [0, 1].
764 - _byte versions work with uint8_t values scaled to [0, 255] */
765 //--------------------------------------------------------------------------------------------------------------------------------------------------------
766 inline clrChanT getChan(int chan) const {
767 if((chan >= 0) && (chan < numChan)) [[likely]]
768 return getChanNC(chan);
769 else
770 return minChanVal;
771 }
772 //--------------------------------------------------------------------------------------------------------------------------------------------------------
773 inline double getChan_dbl(int chan) const {
774 if((chan >= 0) && (chan < numChan)) [[likely]]
775 return convertChanToDouble(getChanNC(chan));
776 else
777 return 0.0;
778 }
779 //--------------------------------------------------------------------------------------------------------------------------------------------------------
780 inline uint8_t getChan_byte(int chan) const {
781 if((chan >= 0) && (chan < numChan)) [[likely]]
782 return convertChanToByte(getChanNC(chan));
783 else
784 return 0;
785 }
786 //@}
787
788 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
789 /** @name Set Named Channel Value
790 Provides access to the specified color channel value with compile time index check.
791 - _dbl versions work with double values scaled to [0, 1].
792 - _byte versions work with uint8_t values scaled to [0, 255]
793 - Numbered channel names are 0 indexed. */
794 //@{
795 /* Performance: The array assignment here gets optimized because the index is known at compile time. It's just as fast as accessing a member of a union
796 for example. */
797 /* Useablity: We could do this with a template, but that means we need ".template set" syntax in some cases. That's just too uguly. */
798
799 inline colorTpl& setC0(clrChanT cVal) { return setChanNC(0, cVal); }
800 inline colorTpl& setC1(clrChanT cVal) requires (numChan>1) { return setChanNC(1, cVal); }
801 inline colorTpl& setC2(clrChanT cVal) requires (numChan>2) { return setChanNC(2, cVal); }
802 inline colorTpl& setC3(clrChanT cVal) requires (numChan>3) { return setChanNC(3, cVal); }
803
804 inline colorTpl& setC0_dbl(double cVal) { return setC0(convertDoubleToChan(cVal)); }
805 inline colorTpl& setC1_dbl(double cVal) { return setC1(convertDoubleToChan(cVal)); }
806 inline colorTpl& setC2_dbl(double cVal) { return setC2(convertDoubleToChan(cVal)); }
807 inline colorTpl& setC3_dbl(double cVal) { return setC3(convertDoubleToChan(cVal)); }
808
809 inline colorTpl& setC0_byte(uint8_t cVal) { return setC0(convertByteToChan(cVal)); }
810 inline colorTpl& setC1_byte(uint8_t cVal) { return setC1(convertByteToChan(cVal)); }
811 inline colorTpl& setC2_byte(uint8_t cVal) { return setC2(convertByteToChan(cVal)); }
812 inline colorTpl& setC3_byte(uint8_t cVal) { return setC3(convertByteToChan(cVal)); }
813
814 inline colorTpl& setRed(clrChanT cVal) requires ((redChan>=0) && (numChan>redChan)) { return setChanNC(redChan, cVal); }
815 inline colorTpl& setBlue(clrChanT cVal) requires ((blueChan>=0) && (numChan>blueChan)) { return setChanNC(blueChan, cVal); }
816 inline colorTpl& setGreen(clrChanT cVal) requires ((greenChan>=0) && (numChan>greenChan)) { return setChanNC(greenChan, cVal); }
817 inline colorTpl& setAlpha(clrChanT cVal) requires ((alphaChan>=0) && (numChan>alphaChan)) { return setChanNC(alphaChan, cVal); }
818
819 inline colorTpl& setRed_dbl(double cVal) { return setRed(convertDoubleToChan(cVal)); }
820 inline colorTpl& setGreen_dbl(double cVal) { return setGreen(convertDoubleToChan(cVal)); }
821 inline colorTpl& setBlue_dbl(double cVal) { return setBlue(convertDoubleToChan(cVal)); }
822 inline colorTpl& setAlpha_dbl(double cVal) { return setAlpha(convertDoubleToChan(cVal)); }
823
824 inline colorTpl& setRed_byte(uint8_t cVal) { return setRed(convertByteToChan(cVal)); }
825 inline colorTpl& setGreen_byte(uint8_t cVal) { return setGreen(convertByteToChan(cVal)); }
826 inline colorTpl& setBlue_byte(uint8_t cVal) { return setBlue(convertByteToChan(cVal)); }
827 inline colorTpl& setAlpha_byte(uint8_t cVal) { return setAlpha(convertByteToChan(cVal)); }
828
829 inline colorTpl& setChansRGBA(clrChanT r, clrChanT g, clrChanT b, clrChanT a) { setRed(r); setGreen(g); setBlue(b); setAlpha(a); return *this; }
830 inline colorTpl& setChansRGB(clrChanT r, clrChanT g, clrChanT b) { setRed(r); setGreen(g); setBlue(b); return *this; }
831
832 inline colorTpl& setChansRGBA_dbl(double r, double g, double b, double a) { return setChansRGBA(convertDoubleToChan(r), convertDoubleToChan(g), convertDoubleToChan(b), convertDoubleToChan(a)); }
833 inline colorTpl& setChansRGB_dbl(double r, double g, double b) { return setChansRGB(convertDoubleToChan(r), convertDoubleToChan(g), convertDoubleToChan(b)); }
834
835 inline colorTpl& setChansRGBA_byte(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { return setChansRGBA(convertByteToChan(r), convertByteToChan(g), convertByteToChan(b), convertByteToChan(a)); }
836 inline colorTpl& setChansRGB_byte(uint8_t r, uint8_t g, uint8_t b) { return setChansRGB(convertByteToChan(r), convertByteToChan(g), convertByteToChan(b)); }
837
838 inline colorTpl& setChansRGBA(clrChanTup4 chanValues) { setRed(std::get<0>(chanValues)); setGreen(std::get<1>(chanValues)); setBlue(std::get<2>(chanValues)); setAlpha(std::get<3>(chanValues)); return *this; }
839 inline colorTpl& setChansRGB(clrChanTup3 chanValues) { setRed(std::get<0>(chanValues)); setGreen(std::get<1>(chanValues)); setBlue(std::get<2>(chanValues)); return *this; }
840 //@}
841
842 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
843 /** @name Canonical Color Types.
844 Provide conversions to/from canonical color types. */
845 //@{
846 inline colorTpl& setChans_dbl(colConALLdbl dblColor) { for(int i=0; i<numChan; i++) setChanNC(i, convertDoubleToChan(dblColor.getChanNC(i))); return *this; }
847 inline colorTpl& setChans_byte(colConALLbyte byteColor) { for(int i=0; i<numChan; i++) setChanNC(i, convertByteToChan(byteColor.getChanNC(i))); return *this; }
848 inline colorTpl& setChansRGBA_dbl(colConRGBAdbl dblColor) { return setChansRGBA(convertDoubleToChan(dblColor.getRed()), convertDoubleToChan(dblColor.getGreen()), convertDoubleToChan(dblColor.getBlue()), convertDoubleToChan(dblColor.getAlpha())); }
849 inline colorTpl& setChansRGB_dbl(colConRGBdbl dblColor) { return setChansRGB( convertDoubleToChan(dblColor.getRed()), convertDoubleToChan(dblColor.getGreen()), convertDoubleToChan(dblColor.getBlue())); }
850 inline colorTpl& setChansRGBA_byte(colConRGBAbyte byteColor) { return setChansRGBA(convertByteToChan(byteColor.getRed()), convertByteToChan(byteColor.getGreen()), convertByteToChan(byteColor.getBlue()), convertByteToChan(byteColor.getAlpha())); }
851 inline colorTpl& setChansRGB_byte(colConRGBbyte byteColor) { return setChansRGB( convertByteToChan(byteColor.getRed()), convertByteToChan(byteColor.getGreen()), convertByteToChan(byteColor.getBlue())); }
852
853 inline colConALLdbl getColCon_dbl() { colConALLdbl rCol; for(int i=0; i<numChan; i++) rCol.setChanNC(i, convertChanToDouble(getChanNC(i))); return rCol; }
854 inline colConALLbyte getColCon_byte() { colConALLbyte rCol; for(int i=0; i<numChan; i++) rCol.setChanNC(i, convertChanToByte( getChanNC(i))); return rCol; }
855 inline colConRGBAdbl getColConRGBA_dbl() { return colConRGBAdbl( getChan_dbl(bestRedChan()), getChan_dbl(bestGreenChan()), getChan_dbl(bestBlueChan()), getChan_dbl(bestAlphaChan())); }
856 inline colConRGBdbl getColConRGB_dbl() { return colConRGBdbl( getChan_dbl(bestRedChan()), getChan_dbl(bestGreenChan()), getChan_dbl(bestBlueChan())); }
857 inline colConRGBAbyte getColConRGBA_byte() { return colConRGBAbyte(getChan_byte(bestRedChan()), getChan_byte(bestGreenChan()), getChan_byte(bestBlueChan()), getChan_byte(bestAlphaChan())); }
858 inline colConRGBbyte getColConRGB_byte() { return colConRGBbyte( getChan_byte(bestRedChan()), getChan_byte(bestGreenChan()), getChan_byte(bestBlueChan())); }
859 //@}
860
861 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
862 /** @name Best guess for named channel index.
863 These are used when we wish to get the named channel index, but the current color might not have specified an approprate value. */
864 //--------------------------------------------------------------------------------------------------------------------------------------------------------
865 /* Returns redChan if non-negative and 0 otherwise */
866 inline int bestRedChan() {
867 if constexpr (redChan >= 0)
868 return redChan; // If we have an identical red, then return it.
869 else
870 return 0; // Otherwise return 0 -- we are guarnteed at least one channel.
871 }
872 //--------------------------------------------------------------------------------------------------------------------------------------------------------
873 /* Returns blueChan if it is non-negative. If we only have one channel, then returns 0. If we have more than one channel, then returns 1. */
874 inline int bestGreenChan() {
875 if constexpr (greenChan >= 0)
876 return greenChan; // If we have an identified green, then return it.
877 else if constexpr (numChan == 1)
878 return 0; // for greyscale, return chan 0
879 else
880 return 1; // If we have more than 1 channel, then return 1
881 }
882 //--------------------------------------------------------------------------------------------------------------------------------------------------------
883 /* Returns blueChan if it is non-negative. If we only have one channel, then returns 0. If we have two channels, then returns -1. Otherwise returns 2. */
884 inline int bestBlueChan() {
885 if constexpr (blueChan >= 0)
886 return blueChan; // If we have an identified blue, then return it.
887 else if constexpr (numChan == 1)
888 return 0; // for greyscale, return chan 0
889 else if constexpr (numChan == 2)
890 return -1; // No sensible value for blue channel with 2 channel images
891 else
892 return 2; // If we have at least three channels, then return chan 2
893 }
894 //--------------------------------------------------------------------------------------------------------------------------------------------------------
895 /* Returns alphaChan if it is non-negative. If we only have four or more channels, then returns 3. Otherwise returns -1. */
896 inline int bestAlphaChan() {
897 if constexpr (alphaChan >= 0)
898 return alphaChan; // If we have an identified alpha, then return it.
899 else if constexpr (numChan >= 4)
900 return 3; // If we have at least four channels, then return chan 3
901 else
902 return -1; // No sensible value for alpha channel
903 }
904 //@}
905
906 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
907 /** @name Setting a single Channel by Index
908 Provides access to an indexed color channel value with run time index check.
909 The channels are 0 indexed.
910 - _dbl versions work with double values scaled to [0, 1].
911 - _byte versions work with uint8_t values scaled to [0, 255] */
912 //--------------------------------------------------------------------------------------------------------------------------------------------------------
913 inline colorTpl& setChanToMax(int chan) {
914 if((chan >= 0) && (chan < numChan)) [[likely]]
915 setChanNC(chan, maxChanVal);
916 return *this;
917 }
918 //--------------------------------------------------------------------------------------------------------------------------------------------------------
919 inline colorTpl& setChanToMin(int chan) {
920 if((chan >= 0) && (chan < numChan)) [[likely]]
921 setChanNC(chan, minChanVal);
922 return *this;
923 }
924 //--------------------------------------------------------------------------------------------------------------------------------------------------------
925 inline colorTpl& setChan(int chan, clrChanT cVal) {
926 if((chan >= 0) && (chan < numChan)) [[likely]]
927 setChanNC(chan, cVal);
928 return *this;
929 }
930 //--------------------------------------------------------------------------------------------------------------------------------------------------------
931 inline colorTpl& setChan_dbl(int chan, double cVal) {
932 /* Performance: We expect chan to be in range most of the time. If it is not, we waste time here computing the channel value.. */
933 return setChan(chan, convertDoubleToChan(cVal));
934 }
935 //--------------------------------------------------------------------------------------------------------------------------------------------------------
936 inline colorTpl& setChan_byte(int chan, uint8_t cVal) {
937 /* Performance: We expect chan to be in range most of the time. If it is not, we waste time here computing the channel value.. */
938 /* Performance: When chanIsByte, convertByteToChan is a NOOP. As it's inline, this leads to zero overhead for the chanIsByte case. */
939 return setChan(chan, convertByteToChan(cVal));
940 }
941 //@}
942
943 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
944 /** @name Set/Get Single Channel values with no index checks.
945 @warning These functions are fast, but have no error checking. Use them wrong, and get a segfault! */
946 //@{
947 //--------------------------------------------------------------------------------------------------------------------------------------------------------
948 /** Sets the specified color channel value with no index check. */
949 inline colorTpl& setChanNC(int chan, clrChanT cVal) { theColor.thePartsA[chan] = cVal; return *this; }
950 //--------------------------------------------------------------------------------------------------------------------------------------------------------
951 /** Provides access to an specified color channel value with no index check. */
952 inline clrChanT getChanNC(int chan) const {
953#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
954#pragma GCC diagnostic push
955#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
956#endif
957 return theColor.thePartsA[chan];
958#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
959#pragma GCC diagnostic pop
960#endif
961 }
962 //@}
963
964 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
965 /** @name Set All Channel Values To One Value
966 Sets all components of the current object from to \a cVal.
967 - _dbl versions work with double values scaled to [0, 1].
968 - _byte versions work with uint8_t values scaled to [0, 255] */
969 //@{
970 //--------------------------------------------------------------------------------------------------------------------------------------------------------
971 inline colorTpl& setChans(clrChanT cVal) {
972 for(int i=0; i<numChan; i++)
973 setChanNC(i, cVal);
974 return *this;
975 }
976 //--------------------------------------------------------------------------------------------------------------------------------------------------------
977 inline colorTpl& setChans_dbl(double cVal) { return setChans(convertDoubleToChan(cVal)); }
978 inline colorTpl& setChans_byte(uint8_t cVal) { return setChans(convertByteToChan(cVal)); }
979 //@}
980
981 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
982 /** @name Set Channel Value(s) with clrChanT values */
983 //@{
984 //--------------------------------------------------------------------------------------------------------------------------------------------------------
985 /** Sets the first four channels current object.
986 @param chanValues The values for the components
987 @return Returns a reference to the current color object.*/
988 inline colorTpl& setChans(clrChanTup4 chanValues) { /* Requires: Inherits numChan>3 from getC3. */
989 setC0(std::get<0>(chanValues));
990 setC1(std::get<1>(chanValues));
991 setC2(std::get<2>(chanValues));
992 return setC3(std::get<3>(chanValues));
993 }
994 //--------------------------------------------------------------------------------------------------------------------------------------------------------
995 /** Sets the first three channels current object.
996 @param chanValues The values for the components
997 @return Returns a reference to the current color object.*/
998 inline colorTpl& setChans(clrChanTup3 chanValues) { /* Requires: Inherits numChan>2 from getC2. */
999 setC0(std::get<0>(chanValues));
1000 setC1(std::get<1>(chanValues));
1001 return setC2(std::get<2>(chanValues));
1002 }
1003 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1004 /** This function sets color channels from the data in a std::vector.
1005 @warning input vector must have at least #channelCount elements! This is *not* checked!
1006
1007 @param chanValues A std::vector containing the color channels.
1008 @return Returns a reference to the current color object.*/
1009 inline colorTpl& setChans(clrChanVec& chanValues) {
1010 for(int i=0; i<numChan; i++)
1011 setChanNC(i, chanValues[i]);
1012 return *this;
1013 }
1014 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1015 /** Sets the current color based upon the contents of the given color hex string.
1016 A color hex string is similar to the hash hex strings used in HTML, but extended to larger depths and higher channel counts.
1017
1018 #FF0000 -- Red for an RGB color with 8-bit per channels
1019 #FFFF00000000 -- Red for an RGB color with 16-bit per channels
1020 #FF0000EE -- Red for an RGBA color with 8-bit per channels (with alpha set to EE)
1021 #FFFFFFFFFF -- White for a 5 channel color with 8-bit per channels
1022 Fewer channel specifiers may be provided than channels in the current color, then the value of clearUndefinedChannels defines the behavior: NOOP or
1023 set them to #minChanVal. If the colorHexString is somehow invalid, then all channels are considered undefined, and the action is defined by the
1024 value of clearUndefinedChannels.
1025 @param colorHexString Hex string specifying a color.
1026 @param clearUndefinedChannels Specify error action and what to do with unspecified channels.
1027 @return Returns a reference to the current color object.*/
1028 inline colorTpl& setChans(std::string colorHexString, bool clearUndefinedChannels = false) {
1029 std::string::size_type sizeOfString = colorHexString.size();
1030 std::string::size_type digitsPerChan = bitsPerChan / 4;
1031 if (sizeOfString > 0) { // Not empty
1032 if (colorHexString[0] == '#') { // Starts with hash
1033 if (0 == ((sizeOfString-1) % digitsPerChan)) { // Has correct number of digits
1034 if (std::string::npos == colorHexString.find_first_not_of("0123456789abcdefABCDEF", 1)) { // All hex digits after the pound
1035 std::string::size_type numChanGiven = (sizeOfString-1) / digitsPerChan;
1036 if (numChan < numChanGiven)
1037 numChanGiven = numChan;
1038 std::string curHexStr(digitsPerChan, 1);
1039 for(std::string::size_type i=0; i<numChanGiven; i++) {
1040 for(std::string::size_type j=0; j<digitsPerChan; j++)
1041 curHexStr[j] = colorHexString[1+j+digitsPerChan*i];
1042 setChan(static_cast<int>(i), convertHexStringToChan(curHexStr));
1043 }
1044 if (clearUndefinedChannels && (numChanGiven < numChan))
1045 for(std::string::size_type i=numChanGiven; i<numChan; i++)
1046 setChanToMin(static_cast<int>(i));
1047 return *this;
1048 }
1049 }
1050 }
1051 }
1052 if (clearUndefinedChannels)
1053 return setToBlack();
1054 else
1055 return *this;
1056 }
1057 //@}
1058
1059 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1060 /** @name Set To Special Colors (RGB Corners)
1061 While the assumed color model is RGB, these functions are generalized beyond RGB in that non-RGB channels are uniformly, and usefully, manipulated.
1062 For example, setToBlack and setToWhite functions set all channels to minimum and maximum respectively -- both reasonable definitions for "black" and
1063 "white" in many situations. The "primary" colors (red, blue, and green) set all non-RGB channels to minimum, and the "secondary" colors (cyan,
1064 yellow, and magenta) set all non-RGB channels to max. The reason for this difference in behavior on non-RGB channels between primary and secondary
1065 colors is two fold: 1) It allows the setTo*() functions to complete their work using no more than two assignment statements for channel objects with
1066 integer channels and good masks. 2) It makes each secondary an inverse (a logical NOT for integer colors) color from a primary across all
1067 channels. Note that the other functions in this group end with a call to one of the setTo*() functions. */
1068 //@{
1069 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1070 inline colorTpl& setToBlack() { setChansToMin(); return *this; }
1071 inline colorTpl& setToWhite() { setChansToMax(); return *this; }
1072 inline colorTpl& setToRed() { setChansToMin(); setChanToMax(0); return *this; }
1073 inline colorTpl& setToBlue() { setChansToMin(); setChanToMax(2); return *this; }
1074 inline colorTpl& setToGreen() { setChansToMin(); setChanToMax(1); return *this; }
1075 inline colorTpl& setToCyan() { setChansToMax(); setChanToMin(0); return *this; }
1076 inline colorTpl& setToYellow() { setChansToMax(); setChanToMin(2); return *this; }
1077 inline colorTpl& setToMagenta() { setChansToMax(); setChanToMin(1); return *this; }
1078 inline colorTpl& setToHalf() { setChansToMean(); return *this; }
1079 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1080 /** Set the current color based upon the single character given -- 0==black, R, G, B, M, C, Y, W/1==white).
1081 The color is acutally set using one of the setTo*() functions. If \a cornerColor is invalid, then setToBlack().
1082 @param cornerColor Character specifying the color
1083 @return Returns a reference to the current color object.*/
1084 inline colorTpl& setToCorner(char cornerColor) {
1085 /* This case is ordered by the frequency in which colors are generally encountered. This will vary for different applications. */
1086 switch(cornerColor) {
1087 case '0': return setToBlack(); break;
1088 case '1': [[fallthrough]];
1089 case 'w': [[fallthrough]];
1090 case 'W': return setToWhite(); break;
1091 case 'r': [[fallthrough]];
1092 case 'R': return setToRed(); break;
1093 case 'g': [[fallthrough]];
1094 case 'G': return setToGreen(); break;
1095 case 'b': [[fallthrough]];
1096 case 'B': return setToBlue(); break;
1097 case 'y': [[fallthrough]];
1098 case 'Y': return setToYellow(); break;
1099 case 'c': [[fallthrough]];
1100 case 'C': return setToCyan(); break;
1101 case 'm': [[fallthrough]];
1102 case 'M': return setToMagenta(); break;
1103 default: return setToBlack(); break;
1104 }
1105 }
1106 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1107 /** Set the color to the given corner color.
1108 The color is acutally set using one of the setTo*() functions. If \a cornerColor is invalid, then setToBlack().
1109 @param cornerColor Enum value specifying the color
1110 @return Returns a reference to the current color object.*/
1111 inline colorTpl& setToCorner(cornerColorEnum cornerColor) {
1112 /* This case is ordered by the frequency in which colors are generally encountered. This will vary for different applications. */
1113 switch(cornerColor) {
1114 case cornerColorEnum::BLACK: return setToBlack(); break;
1115 case cornerColorEnum::WHITE: return setToWhite(); break;
1116 case cornerColorEnum::RED: return setToRed(); break;
1117 case cornerColorEnum::GREEN: return setToGreen(); break;
1118 case cornerColorEnum::BLUE: return setToBlue(); break;
1119 case cornerColorEnum::YELLOW: return setToYellow(); break;
1120 case cornerColorEnum::CYAN: return setToCyan(); break;
1121 case cornerColorEnum::MAGENTA: return setToMagenta(); break;
1122 default: return setToBlack(); break; // Some compilers don't realize all cases are covered above...
1123 }
1124 return *this;
1125 }
1126 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1127 /** Set the color to the named corner color.
1128 If cornerColor is one character long, then the call is equivalent to setToCorner(cornerColor[0]). Otherwise a valid corner color name string is
1129 expected: red, blue, green, cyan, yellow, magenta, black, or white. If \a cornerColor is invalid, then setToBlack(). The color is actually set
1130 using one of the setTo*() functions.
1131 @param cornerColor String value specifying the color
1132 @return Returns a reference to the current color object.*/
1133 inline colorTpl& setToCorner(std::string cornerColor) {
1134 std::string::size_type sizeOfString = cornerColor.size();
1135 if (sizeOfString > 0) {
1136 if(((cornerColor[0] == 'b') || (cornerColor[0] == 'B')) && (sizeOfString > 0)) {
1137 if( (cornerColor[2]=='u') || (cornerColor[2]=='U') )
1138 return setToBlue();
1139 else
1140 return setToBlack();
1141 } else {
1142 return setToCorner(cornerColor[0]);
1143 }
1144 }
1145 return setToBlack();
1146 }
1147 //@}
1148
1149 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1150 /** @name Color Setting Methods via Logically Packed Integers.
1151 By "logically" we mean as if the integers were written on paper left to right with MSB on the left -- the same way they are "written" in C++ source code.
1152 ex: 0x11223344u has 11 as the most significant byte, but it might be placed in memory differently. These functions are very usefully for unpacking integers
1153 derived from integer literals in C++ code. setRGBfromLogPackIntARGB() is heavily used for color schemes. */
1154 //@{
1155 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1156 /** Set the color based upon the bytes of the given integer ordered from LSB to MSB.
1157 The *Idx arguments select which byte of the int is used for each channel -- with LSB equal to index 0 and MSB equal to index 3. The extracted bytes
1158 are interpreted as by setChans_byte. Any channels beyond four are left untouched.
1159 @param anInt The integer from which to extract bytes to set color
1160 @param rIdx Location of red byte in \a anInt
1161 @param gIdx Location of green byte in \a anInt
1162 @param bIdx Location of blue byte in \a anInt
1163 @param aIdx Location of alpha byte in \a anInt
1164 @return Returns a reference to the current color object.*/
1165 inline colorTpl& setRGBAfromLogPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx, uint8_t aIdx) {
1166 /* Requires: Inherits numChan>3 from setAlpha. */
1167 uint8_t bytes[4];
1168 bytes[0] = (0xFF & anInt); anInt = anInt >> 8;
1169 bytes[1] = (0xFF & anInt); anInt = anInt >> 8;
1170 bytes[2] = (0xFF & anInt); anInt = anInt >> 8;
1171 bytes[3] = (0xFF & anInt);
1172 setRed_byte( bytes[rIdx]);
1173 setGreen_byte(bytes[gIdx]);
1174 setBlue_byte( bytes[bIdx]);
1175 setAlpha_byte(bytes[aIdx]);
1176 return *this;
1177 }
1178 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1179 /** Just like setRGBAfromLogPackIntGen, but no A */
1180 inline colorTpl& setRGBfromLogPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx) {
1181 uint8_t bytes[4];
1182 /* Requires: Inherits numChan>2 from setBlue. */
1183 bytes[0] = (0xFF & anInt); anInt = anInt >> 8;
1184 bytes[1] = (0xFF & anInt); anInt = anInt >> 8;
1185 bytes[2] = (0xFF & anInt); anInt = anInt >> 8;
1186 bytes[3] = (0xFF & anInt);
1187 setRed_byte( bytes[rIdx]);
1188 setGreen_byte(bytes[gIdx]);
1189 setBlue_byte( bytes[bIdx]);
1190 return *this;
1191 }
1192 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1193 /* These four pixel formats (ARGB, RGBA, ABGR, & BGRA) are commonly used (SDL, OpenGL, ImageJ, etc...). Note we have two methods per pixel format --
1194 one for RGB & one for RGBA */
1195 inline colorTpl& setRGBAfromLogPackIntARGB(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 2, 1, 0, 3); } /* Requires: Inherits numChan>3 from setAlpha. */
1196 inline colorTpl& setRGBfromLogPackIntARGB( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 2, 1, 0); } /* Requires: Inherits numChan>2 from setBlue. */
1197 inline colorTpl& setRGBAfromLogPackIntRGBA(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 3, 2, 1, 0); } /* Requires: Inherits numChan>3 from setAlpha. */
1198 inline colorTpl& setRGBfromLogPackIntRGBA( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 3, 2, 1); } /* Requires: Inherits numChan>2 from setBlue. */
1199 inline colorTpl& setRGBAfromLogPackIntABGR(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 0, 1, 2, 3); } /* Requires: Inherits numChan>3 from setAlpha. */
1200 inline colorTpl& setRGBfromLogPackIntABGR( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 0, 1, 2); } /* Requires: Inherits numChan>2 from setBlue. */
1201 inline colorTpl& setRGBAfromLogPackIntBGRA(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 1, 2, 3, 0); } /* Requires: Inherits numChan>3 from setAlpha. */
1202 inline colorTpl& setRGBfromLogPackIntBGRA( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 1, 2, 3); } /* Requires: Inherits numChan>2 from setBlue. */
1203 /* This pixel format (ABRG) is used by POV-Ray for height fields */
1204 inline colorTpl& setRGBAfromLogPackIntABRG(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 1, 0, 2, 3); } /* Requires: Inherits numChan>3 from setAlpha. */
1205 inline colorTpl& setRGBfromLogPackIntABRG( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 1, 0, 2); } /* Requires: Inherits numChan>2 from setBlue. */
1206 //@}
1207
1208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1209 /** @name TGA Height Maps for POVray */
1210 //@{
1211 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1212 /** Computes a 24-bit truecolor value intended for use in producing 16-bit greyscale TGA.
1213 This is the color scheme that should be used for POVray 16-bit height files
1214 @param tga16val An integer
1215 @return Returns a reference to the current color object. */
1216 inline colorTpl& setRGBcmpGreyTGA16bit(uint32_t tga16val) requires(chanIsByte) {
1217 /* Requires: Inherits numChan>1 from setGreen. */
1218 tga16val = mjr::math::ivl::wrapCC(tga16val, 0x0000FFFFu);
1219 return setRGBfromLogPackIntABRG(tga16val);
1220 // setChansToMin();
1221 // setGreen_byte(static_cast<clrChanT>( tga16val & 0xff)); // 0
1222 // setRed_byte( static_cast<clrChanT>((tga16val >> 8) & 0xff)); // 1
1223 // return *this;
1224 }
1225 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1226 /** Computes a 24-bit truecolor value intended for use in producing 24-bit greyscale TGA.
1227 @param tga24val An integer
1228 @return Returns a reference to the current color object. */
1229 inline colorTpl& setRGBcmpGreyTGA24bit(uint32_t tga24val) requires(chanIsByte) {
1230 /* Requires: Inherits numChan>2 from setBlue. */
1231 tga24val = mjr::math::ivl::wrapCC(tga24val, 0x00FFFFFFu);
1232 return setRGBfromLogPackIntABRG(tga24val);
1233 // setGreen_byte( tga24val & 0xff); // 0
1234 // setRed_byte( (tga24val >> 8) & 0xff); // 1
1235 // setBlue_byte( (tga24val >> 16) & 0xff); // 2
1236 // return *this;
1237 } //BRG
1238 //@}
1239
1240 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1241 /** @name Color Setting Methods via Physically Packed Integers.
1242 By "physically" we mean as the bytes are physically ordered in RAM -- which may differ from how we write them on paper or in C++ code. */
1243 //@{
1244 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1245 /** Set the color based upon the bytes of the given integer ordered as in RAM.
1246 The *Idx arguments select which byte of the int is used for each channel -- with byte[0] being the first in RAM. The extracted bytes are interpreted
1247 as by setChans_byte. Any channels beyond four are left untouched.
1248 @param anInt The integer from which to extract bytes to set color
1249 @param rIdx Location of red byte in \a anInt
1250 @param gIdx Location of green byte in \a anInt
1251 @param bIdx Location of blue byte in \a anInt
1252 @param aIdx Location of alpha byte in \a anInt
1253 @return Returns a reference to the current color object.*/
1254 inline colorTpl& setRGBAfromPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx, uint8_t aIdx) {
1255 /* Requires: Inherits numChan>3 from setAlpha. */
1256 uint8_t *curByte = (uint8_t *)(&anInt);
1257 setRed_byte( curByte[rIdx]);
1258 setGreen_byte(curByte[gIdx]);
1259 setBlue_byte( curByte[bIdx]);
1260 setAlpha_byte(curByte[aIdx]);
1261 return *this;
1262 }
1263 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1264 /** Just like setRGBAfromPackIntGen, but no A */
1265 inline colorTpl& setRGBfromPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx) {
1266 /* Requires: Inherits numChan>2 from setBlue. */
1267 uint8_t *curByte = (uint8_t *)(&anInt);
1268 setRed_byte( curByte[rIdx]);
1269 setGreen_byte(curByte[gIdx]);
1270 setBlue_byte( curByte[bIdx]);
1271 return *this;
1272 }
1273 //@}
1274
1275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1276 /** @name Setting Colors Based Upon Other Color Spaces
1277 Other Colorspaces.
1278 The most common use case is to think of the image as holding RGB color data, and these functions are designed with that idea in mind. Note that
1279 alternate colorspaces computations all take place with double floating point values. Various other tools are also available for manipulating colors
1280 in other colorspaces (see: interplColorSpace() and rgb2colorSpace() for example).. See the #colorSpaceEnum for details regarding supported colorspaces. */
1281 //@{
1282 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1283 /** Set the color indicated by the given HSV values.
1284 The 'unit' in the name indicates that the values for h, s, and v are the unit interval, [0,1].
1285 @param H The Hue.
1286 @param S The Saturation.
1287 @param V The Value
1288 @return Returns a reference to the current color object. */
1289 inline colorTpl& setRGBfromUnitHSV(double H, double S, double V) { return setRGBfromColorSpace(colorSpaceEnum::HSV, H*360.0, S, V); }
1290 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1291 /** Set the color indicated by the given HSL values.
1292 The 'unit' in the name indicates that The ranges for h, s, and v are the the unit interval -- i.e. [0,1].
1293 @param H The Hue.
1294 @param S The Saturation.
1295 @param L The Lightness or Luminescence
1296 @return Returns a reference to the current color object. */
1297 inline colorTpl& setRGBfromUnitHSL(double H, double S, double L) { return setRGBfromColorSpace(colorSpaceEnum::HSL, H*360.0, S, L); }
1298 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1299 /** Set the color indicated by the color space and values.
1300 @param space The colorspace
1301 @param inCh1 Channel one value for given colorspace
1302 @param inCh2 Channel two value for given colorspace
1303 @param inCh3 Channel three value for given colorspace
1304 @return Returns a reference to the current color object. */
1305 inline colorTpl& setRGBfromColorSpace(colorSpaceEnum space, double inCh1, double inCh2, double inCh3) {
1306 // Note: If space==RGB => C0==R, C1=G, C2=B regardless of redChan, blueChan, & greenChan.
1307 double outR = 0.0, outG = 0.0, outB = 0.0;
1308 if (space == colorSpaceEnum::HSL) {
1309 if( (inCh3 >= 0.0) && (inCh3 <= 1.0) && (inCh2 >= 0.0) && (inCh2 <= 1.0) ) {
1310 double H = mjr::math::ivl::wrapCO(inCh1, 360.0);
1311 const double epsilon = 0.000001;
1312 double m1, m2;
1313 if(inCh3 <= 0.5)
1314 m2 = inCh3 * (1.0 + inCh2);
1315 else
1316 m2 = inCh3 + inCh2 - inCh3 * inCh2;
1317 m1 = 2.0 * inCh3 - m2;
1318 if(inCh2 < epsilon) {
1319 outR = inCh3;
1320 outG = inCh3;
1321 outB = inCh3;
1322 } else {
1323 outR = mjr::math::ivl::unit_clamp(hslHelperVal(m1, m2, H+120));
1324 outG = mjr::math::ivl::unit_clamp(hslHelperVal(m1, m2, H));
1325 outB = mjr::math::ivl::unit_clamp(hslHelperVal(m1, m2, H-120));
1326 }
1327 }
1328 } else if ((space == colorSpaceEnum::LAB) || (space == colorSpaceEnum::XYZ) || (space == colorSpaceEnum::LCH)) {
1329 double X, Y, Z;
1330 if (space == colorSpaceEnum::XYZ) {
1331 X = inCh1 / 100.0;
1332 Y = inCh2 / 100.0;
1333 Z = inCh3 / 100.0;
1334 } else {
1335 Y = ( inCh1 + 16.0 ) / 116.0;
1336 if (space == colorSpaceEnum::LCH) {
1337 X = std::cos(inCh3 * std::numbers::pi / 180.0) * inCh2 / 500.0 + Y;
1338 Z = Y - std::sin(inCh3 * std::numbers::pi / 180.0) * inCh2 / 200.0;
1339 } else {
1340 X = inCh2 / 500.0 + Y;
1341 Z = Y - inCh3 / 200.0;
1342 }
1343 X = (X > 0.206893034423 ? std::pow(X, 3) : ( X - 16.0 / 116.0 ) / 7.787) * 95.047 / 100.0;
1344 Y = (Y > 0.206893034423 ? std::pow(Y, 3) : ( Y - 16.0 / 116.0 ) / 7.787) * 100.000 / 100.0;
1345 Z = (Z > 0.206893034423 ? std::pow(Z, 3) : ( Z - 16.0 / 116.0 ) / 7.787) * 108.883 / 100.0;
1346 }
1347 outR = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
1348 outG = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
1349 outB = X * 0.0557 + Y * -0.2040 + Z * 1.0570;
1350 outR = mjr::math::ivl::unit_clamp((outR > 0.0031308 ? 1.055 * std::pow(outR, 1.0 / 2.4) - 0.055 : 12.92 * outR));
1351 outG = mjr::math::ivl::unit_clamp((outG > 0.0031308 ? 1.055 * std::pow(outG, 1.0 / 2.4) - 0.055 : 12.92 * outG));
1352 outB = mjr::math::ivl::unit_clamp((outB > 0.0031308 ? 1.055 * std::pow(outB, 1.0 / 2.4) - 0.055 : 12.92 * outB));
1353 } else if (space == colorSpaceEnum::RGB) {
1354 outR = mjr::math::ivl::unit_clamp(inCh1);
1355 outG = mjr::math::ivl::unit_clamp(inCh2);
1356 outB = mjr::math::ivl::unit_clamp(inCh3);
1357 } else if (space == colorSpaceEnum::HSV) {
1358 double t;
1359 double f = static_cast<double>(std::modf(inCh1 * 6.0 / 360.0, &t));
1360 int i = static_cast<int>(t) % 6;
1361 double p = inCh3 * (1 - inCh2);
1362 double q = inCh3 * (1 - inCh2 * f);
1363 double u = inCh3 * (1 - (inCh2 * (1 - f)));
1364 double w = inCh3;
1365 switch (i) {
1366 case 0: outR = mjr::math::ivl::unit_clamp(w); outG = mjr::math::ivl::unit_clamp(u); outB = mjr::math::ivl::unit_clamp(p); break;
1367 case 1: outR = mjr::math::ivl::unit_clamp(q); outG = mjr::math::ivl::unit_clamp(w); outB = mjr::math::ivl::unit_clamp(p); break;
1368 case 2: outR = mjr::math::ivl::unit_clamp(p); outG = mjr::math::ivl::unit_clamp(w); outB = mjr::math::ivl::unit_clamp(u); break;
1369 case 3: outR = mjr::math::ivl::unit_clamp(p); outG = mjr::math::ivl::unit_clamp(q); outB = mjr::math::ivl::unit_clamp(w); break;
1370 case 4: outR = mjr::math::ivl::unit_clamp(u); outG = mjr::math::ivl::unit_clamp(p); outB = mjr::math::ivl::unit_clamp(w); break;
1371 case 5: outR = mjr::math::ivl::unit_clamp(w); outG = mjr::math::ivl::unit_clamp(p); outB = mjr::math::ivl::unit_clamp(q); break;
1372 default: outR = 0.0 ; outG = 0.0 ; outB = 0.0 ; break;
1373 }
1374 } else {
1375 std::cerr << "ERROR: Unsupported color space used in setRGBfromColorSpace!" << std::endl;
1376 }
1377 setChansRGB(static_cast<clrChanT>(maxChanVal * outR),
1378 static_cast<clrChanT>(maxChanVal * outG),
1379 static_cast<clrChanT>(maxChanVal * outB));
1380 return *this;
1381 }
1382 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1383 /** @overload */
1385 /* Requires: Inherits numChan>2 from getC2. */
1386 /* This use of getC0/getC1/getC2 for RGB is OK -- that is how colConDbl3 objects work */
1387 return setRGBfromColorSpace(space, inColor.getC0(), inColor.getC1(), inColor.getC2());
1388 }
1389 //@}
1390
1391 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1392 /** @name Setting Colors Based Upon Spectral Color */
1393 //@{
1394 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1395 /** Set the color indicated by the given wavelength.
1396 This function uses an algorithm based upon the color matching functions as tabulated in table 3 from Stockman and Sharpe (2000) -- I believe they
1397 are taken from Stiles and Burch 10-degree (1959). Four of the algorithms are based upon simple linear interpolation, while one is based upon
1398 exponential bump functions closely matching the color matching functions. The method of interpolation may be specified via the final argument.
1399
1400 @warning If you are looking for a wavelength color scheme, then see the csRainbowCM class: http://richmit.github.io/mraster/ColorSchemes.html
1401
1402 @param wavelength The wavelength to convert into RGB
1403 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
1404 @return Returns a reference to the current color object. */
1405 inline colorTpl& setRGBfromWavelengthCM(double wavelength, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
1406 // Color matching function table & metadata.
1407 // Tabulated in table 3 from Stockman and Sharpe (2000). I beleive they are taken from Stiles and Burch 10-degree (1959)
1408 const double minWL = 390.0; // Min wavelength in table
1409 const double maxWL = 830.0; // Max wavelength in table
1410 const int numPT = 89; // Number fo points in the table
1411 const double rScl = 3.1673; // Scale factors for color function
1412 const double gScl = 1.0517;
1413 const double bScl = 1.0019;
1414 const static int cmfW[] = { 390, 395, 400, 405, 410, 415, 420, 425, 430,
1415 435, 440, 445, 450, 455, 460, 465, 470, 475,
1416 480, 485, 490, 495, 500, 505, 510, 515, 520,
1417 525, 530, 535, 540, 545, 550, 555, 560, 565,
1418 570, 575, 580, 585, 590, 595, 600, 605, 610,
1419 615, 620, 625, 630, 635, 640, 645, 650, 655,
1420 660, 665, 670, 675, 680, 685, 690, 695, 700,
1421 705, 710, 715, 720, 725, 730, 735, 740, 745,
1422 750, 755, 760, 765, 770, 775, 780, 785, 790,
1423 795, 800, 805, 810, 815, 820, 825, 830 };
1424 const static double cmfR[] = { 1.5000E-03, 3.8000E-03, 8.9000E-03, 1.8800E-02, 3.5000E-02, 5.3100E-02, 7.0200E-02, 7.6300E-02, 7.4500E-02,
1425 5.6100E-02, 3.2300E-02, -4.4000E-03, -4.7800E-02, -9.7000E-02, -1.5860E-01, -2.2350E-01, -2.8480E-01, -3.3460E-01,
1426 -3.7760E-01, -4.1360E-01, -4.3170E-01, -4.4520E-01, -4.3500E-01, -4.1400E-01, -3.6730E-01, -2.8450E-01, -1.8550E-01,
1427 -4.3500E-02, 1.2700E-01, 3.1290E-01, 5.3620E-01, 7.7220E-01, 1.0059E+00, 1.2710E+00, 1.5574E+00, 1.8465E+00,
1428 2.1511E+00, 2.4250E+00, 2.6574E+00, 2.9151E+00, 3.0779E+00, 3.1613E+00, 3.1673E+00, 3.1048E+00, 2.9462E+00,
1429 2.7194E+00, 2.4526E+00, 2.1700E+00, 1.8358E+00, 1.5179E+00, 1.2428E+00, 1.0070E+00, 7.8270E-01, 5.9340E-01,
1430 4.4420E-01, 3.2830E-01, 2.3940E-01, 1.7220E-01, 1.2210E-01, 8.5300E-02, 5.8600E-02, 4.0800E-02, 2.8400E-02,
1431 1.9700E-02, 1.3500E-02, 9.2400E-03, 6.3800E-03, 4.4100E-03, 3.0700E-03, 2.1400E-03, 1.4900E-03, 1.0500E-03,
1432 7.3900E-04, 5.2300E-04, 3.7200E-04, 2.6500E-04, 1.9000E-04, 1.3600E-04, 9.8400E-05, 7.1300E-05, 5.1800E-05,
1433 3.7700E-05, 2.7600E-05, 2.0300E-05, 1.4900E-05, 1.1000E-05, 8.1800E-06, 6.0900E-06, 4.5500E-06 };
1434 const static double cmfG[] = { -4.0000E-04, -1.0000E-03, -2.5000E-03, -5.9000E-03, -1.1900E-02, -2.0100E-02, -2.8900E-02, -3.3800E-02, -3.4900E-02,
1435 -2.7600E-02, -1.6900E-02, 2.4000E-03, 2.8300E-02, 6.3600E-02, 1.0820E-01, 1.6170E-01, 2.2010E-01, 2.7960E-01,
1436 3.4280E-01, 4.0860E-01, 4.7160E-01, 5.4910E-01, 6.2600E-01, 7.0970E-01, 7.9350E-01, 8.7150E-01, 9.4770E-01,
1437 9.9450E-01, 1.0203E+00, 1.0375E+00, 1.0517E+00, 1.0390E+00, 1.0029E+00, 9.6980E-01, 9.1620E-01, 8.5710E-01,
1438 7.8230E-01, 6.9530E-01, 5.9660E-01, 5.0630E-01, 4.2030E-01, 3.3600E-01, 2.5910E-01, 1.9170E-01, 1.3670E-01,
1439 9.3800E-02, 6.1100E-02, 3.7100E-02, 2.1500E-02, 1.1200E-02, 4.4000E-03, 7.8000E-05, -1.3680E-03, -1.9880E-03,
1440 -2.1680E-03, -2.0060E-03, -1.6420E-03, -1.2720E-03, -9.4700E-04, -6.8300E-04, -4.7800E-04, -3.3700E-04, -2.3500E-04,
1441 -1.6300E-04, -1.1100E-04, -7.4800E-05, -5.0800E-05, -3.4400E-05, -2.3400E-05, -1.5900E-05, -1.0700E-05, -7.2300E-06,
1442 -4.8700E-06, -3.2900E-06, -2.2200E-06, -1.5000E-06, -1.0200E-06, -6.8800E-07, -4.6500E-07, -3.1200E-07, -2.0800E-07,
1443 -1.3700E-07, -8.8000E-08, -5.5300E-08, -3.3600E-08, -1.9600E-08, -1.0900E-08, -5.7000E-09, -2.7700E-09 };
1444 const static double cmfB[] = { 6.2000E-03, 1.6100E-02, 4.0000E-02, 9.0600E-02, 1.8020E-01, 3.0880E-01, 4.6700E-01, 6.1520E-01, 7.6380E-01,
1445 8.7780E-01, 9.7550E-01, 1.0019E+00, 9.9960E-01, 9.1390E-01, 8.2970E-01, 7.4170E-01, 6.1340E-01, 4.7200E-01,
1446 3.4950E-01, 2.5640E-01, 1.8190E-01, 1.3070E-01, 9.1000E-02, 5.8000E-02, 3.5700E-02, 2.0000E-02, 9.5000E-03,
1447 7.0000E-04, -4.3000E-03, -6.4000E-03, -8.2000E-03, -9.4000E-03, -9.7000E-03, -9.7000E-03, -9.3000E-03, -8.7000E-03,
1448 8.0000E-03, -7.3000E-03, -6.3000E-03, -5.3700E-03, -4.4500E-03, -3.5700E-03, -2.7700E-03, -2.0800E-03, 1.5000E-03,
1449 1.0300E-03, -6.8000E-04, -4.4200E-04, -2.7200E-04, -1.4100E-04, -5.4900E-05, -2.2000E-06, 2.3700E-05, 2.8600E-05,
1450 2.6100E-05, 2.2500E-05, 1.8200E-05, 1.3900E-05, 1.0300E-05, 7.3800E-06, -5.2200E-06, 3.6700E-06, 2.5600E-06,
1451 1.7600E-06, 1.2000E-06, 8.1700E-07, 5.5500E-07, 3.7500E-07, 2.5400E-07, -1.7100E-07, 1.1600E-07, 7.8500E-08,
1452 5.3100E-08, 3.6000E-08, 2.4400E-08, 1.6500E-08, 1.1200E-08, 7.5300E-09, -5.0700E-09, 3.4000E-09, 2.2700E-09,
1453 1.5000E-09, 9.8600E-10, 6.3900E-10, 4.0700E-10, 2.5300E-10, 1.5200E-10, -8.6400E-11, 4.4200E-11 };
1454
1455 // Clip the wavelength to be in range
1456 wavelength = std::clamp(wavelength, minWL, maxWL);
1457
1458 // Figure out where we are in our color function table
1459 double fIdx = (wavelength-minWL)/(maxWL-minWL)*(numPT-1.0);
1460 int iIdx1 = static_cast<int>(fIdx);
1461 int iIdx2 = iIdx1+1;
1462
1463 // If we fell off the edge, then we set our indexes to the appropriate edge
1464 if(iIdx2>(numPT-1)) { iIdx1 = numPT-2; iIdx2 = numPT-1; fIdx = static_cast<double>(iIdx1); }
1465 if(iIdx1<0) { iIdx1 = 0; iIdx2 = 1; fIdx = static_cast<double>(iIdx1); }
1466
1467 // Interpolate using our tabulated color matching function
1468 double rf, gf, bf;
1469 switch(interpMethod) {
1470 case cmfInterpolationEnum::FLOOR : // Closest with wavelength lower than given value
1471 rf=cmfR[iIdx1];
1472 gf=cmfG[iIdx1];
1473 bf=cmfB[iIdx1];
1474 break;
1475 case cmfInterpolationEnum::CEILING : // Closest with wavelength greater than given value
1476 rf=cmfR[iIdx2];
1477 gf=cmfG[iIdx2];
1478 bf=cmfB[iIdx2];
1479 break;
1480 case cmfInterpolationEnum::NEAREST : // Closest with wavelength to given value
1481 if( std::abs(wavelength-cmfW[iIdx2]) < std::abs(wavelength-cmfW[iIdx1])) {
1482 rf=cmfR[iIdx2];
1483 gf=cmfG[iIdx2];
1484 bf=cmfB[iIdx2];
1485 } else {
1486 rf=cmfR[iIdx1];
1487 gf=cmfG[iIdx1];
1488 bf=cmfB[iIdx1];
1489 }
1490 break;
1491 case cmfInterpolationEnum::LINEAR : // Linear interpolation between data points
1492 rf = (fIdx-static_cast<double>(iIdx1)) * (cmfR[iIdx2] - cmfR[iIdx1]) + cmfR[iIdx1];
1493 gf = (fIdx-static_cast<double>(iIdx1)) * (cmfG[iIdx2] - cmfG[iIdx1]) + cmfG[iIdx1];
1494 bf = (fIdx-static_cast<double>(iIdx1)) * (cmfB[iIdx2] - cmfB[iIdx1]) + cmfB[iIdx1];
1495 break;
1496 case cmfInterpolationEnum::BUMP : // Use exponential hump functions -- MJR developed algorithm 2007
1497 rf = 3.07 / std::exp(0.0005 * (wavelength-600.0)*(wavelength-600.0)) + 0.09 / std::exp(0.005 * (wavelength-425.0)*(wavelength-425.0));
1498 gf = 1.05 / std::exp(0.0004 * (wavelength-540.0)*(wavelength-540.0));
1499 bf = 1.00 / std::exp(0.0010 * (wavelength-450.0)*(wavelength-450.0));
1500 break;
1501 default:
1502 rf = gf = bf = 0.0;
1503 break;
1504 }
1505
1506 // Make them positive and scale to a [0,1] range
1507 rf=(rf>0.0 ? rf : 0.0)/rScl;
1508 gf=(gf>0.0 ? gf : 0.0)/gScl;
1509 bf=(bf>0.0 ? bf : 0.0)/bScl;
1510
1511 // We are done. Set the color and exit.
1512 setChansRGB_dbl(rf, gf, bf);
1513 return *this;
1514 }
1515 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1516 /** Set the color indicated by the given wavelength.
1517 This function uses an algorithm based upon linear approximations to the color match functions. I believe the original algorithm is due to Dan
1518 Bruton, and his FORTRAN version is available (at least as of 1997) at http://www.physics.sfasu.edu/astro/color.html
1519
1520 @warning If you are looking for a wavelength color scheme, then see the csRainbowLA class: http://richmit.github.io/mraster/ColorSchemes.html
1521
1522 @param wavelength to convert
1523 @return Returns a reference to the current color object. */
1524 inline colorTpl& setRGBfromWavelengthLA(double wavelength) {
1525 double rf, gf, bf;
1526
1527 const double minWL = 380.0; // Min wavelength in table
1528 const double maxWL = 780.0; // Max wavelength in table
1529
1530 // Clip the wavelength to be in range
1531 if(wavelength < minWL)
1532 wavelength = minWL;
1533 if(wavelength > maxWL)
1534 wavelength = maxWL;
1535
1536 // Compute color match functions.
1537 rf = gf = bf = 0;
1538 if ( (wavelength >= 380) && (wavelength < 440)) {
1539 rf = (440-wavelength)/(440-380);
1540 gf = 0.0;
1541 bf = 1.0;
1542 } else if( (wavelength >= 440) && (wavelength < 490)) {
1543 rf = 0.0;
1544 gf = (wavelength-440)/(490-440);
1545 bf = 1.0;
1546 } else if( (wavelength >= 490) && (wavelength < 510)) {
1547 rf = 0.0;
1548 gf = 1.0;
1549 bf = (510-wavelength)/(510-490);
1550 } else if( (wavelength >= 510) && (wavelength < 580)) {
1551 rf = (wavelength-510)/(580-510);
1552 gf = 1.0;
1553 bf = 0.0;
1554 } else if( (wavelength >= 580) && (wavelength < 645)) {
1555 rf = 1.0;
1556 gf = (645-wavelength)/(645-580);
1557 bf = 0.0;
1558 } else if( (wavelength >= 645) && (wavelength <= 780)) {
1559 rf = 1.0;
1560 gf = 0.0;
1561 bf = 0.0;
1562 }
1563
1564 /* Lower the intensity near edges of vision. */
1565 double edgeIntensityAdj;
1566 if(wavelength > 700.0) {
1567 edgeIntensityAdj=0.3 + 0.7 * (780-wavelength)/(780-700);
1568 } else if(wavelength < 420.0) {
1569 edgeIntensityAdj=0.3 + 0.7 * (wavelength - 380)/(420-380);
1570 } else {
1571 edgeIntensityAdj=1.0;
1572 }
1573
1574 return setChansRGB_dbl(edgeIntensityAdj*rf, edgeIntensityAdj*gf, edgeIntensityAdj*bf);
1575 }
1576 //@}
1577
1578 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1579 /** @name Color Ramps, Gradients, Interpolation, Binary Thresholds.
1580 Members in this section form the computational foundation for many of the named color schemes found in this class. */
1581 //@{
1582 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1583 /** Convert a double to a color value based upon a color ramp passing through the given sequence of corner colors at the given anchor points.
1584 The value of this function at \a aDouble equal to \a anchor[i] will be \a colors[i]. This is an extremely general function that is capable of
1585 replicating many of the more precise color ramp sequence functions in this library. The only defects are the lack of bit level precision and the
1586 poor performance -- both due to the use of floating point arithmetic. Note this function operates correctly with any channel type and with an
1587 arbitrary number of channels -- it is NOT limited to RGB colors or RGB color corners for anchors.
1588
1589 @warning In many cases it is better to use csFP_tpl, csCC_tpl, or csHSLh_tpl to define a continuous gradient color scheme than to use this function
1590 directly. In fact, the first step might be to see if a suitable gradient color scheme is already are predefined:
1591 http://richmit.github.io/mraster/ColorSchemes.html
1592
1593 @param csX The value to convert
1594 @param anchors Doubles for which color equals the corresponding corner.
1595 @param colors A vector of colors to use
1596 @return A reference to this object */
1597 inline colorTpl& cmpGradiant(csFltType csX, std::vector<csFltType > const& anchors, std::vector<colorType> const& colors) {
1598 typename std::vector<colorType>::size_type numColors = colors.size();
1599 if((numColors >= 2) && (anchors.size() == numColors)) {
1600 for(typename std::vector<colorType>::size_type i=0; i<(numColors-1); i++) {
1601 csFltType lowAnchor = anchors[i];
1602 csFltType highAnchor = anchors[i+1];
1603 if( (csX >= lowAnchor) && (csX <= highAnchor) ) {
1604 return linearInterpolate(std::abs((csX-lowAnchor)/(highAnchor-lowAnchor)), colors[i], colors[i+1]);
1605 }
1606 }
1607 }
1608 return *this;
1609 }
1610 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1611 /** Identical to the other cmpGradiant() function except that equidistant anchors are automatically generated on [0, 1] for the given colors array. */
1612 inline colorTpl& cmpGradiant(csFltType csX, std::vector<colorType> const& colors) {
1613 typename std::vector<colorType>::size_type numColors = colors.size();
1614 if(numColors >= 2) {
1615 for(typename std::vector<colorType>::size_type i=0; i<(numColors-1); i++) {
1616 csFltType lowAnchor = static_cast<csFltType>(i) / static_cast<csFltType>(numColors-1);
1617 csFltType highAnchor = static_cast<csFltType>(i+1)/ static_cast<csFltType>(numColors-1);
1618 if( (csX >= lowAnchor) && (csX <= highAnchor) ) {
1619 return linearInterpolate(std::abs((csX-lowAnchor)/(highAnchor-lowAnchor)), colors[i], colors[i+1]);
1620 }
1621 }
1622 }
1623 return *this;
1624 }
1625 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1626 /** Identical to the other equidistant cmpGradiant() function except that this one works on just the RGB channels and takes an array of packed integers. */
1627 inline colorTpl& cmpGradiant(csFltType csX, csIntType numColors, const packed4Cint* colors) {
1628 if(numColors >= 2) {
1629 for(csIntType i=0; i<(numColors-1); i++) {
1630 csFltType lowAnchor = static_cast<csFltType>(i) / static_cast<csFltType>(numColors-1);
1631 csFltType highAnchor = static_cast<csFltType>(i+1)/ static_cast<csFltType>(numColors-1);
1632 if( (csX >= lowAnchor) && (csX <= highAnchor) ) {
1633 colorTpl c1;
1634 colorTpl c2;
1635 c1.setRGBfromLogPackIntARGB(colors[i]);
1636 c2.setRGBfromLogPackIntARGB(colors[i+1]);
1637 return linearInterpolateRGB(std::abs((csX-lowAnchor)/(highAnchor-lowAnchor)), c1, c2);
1638 }
1639 }
1640 }
1641 return *this;
1642 }
1643 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1644 /** This is simply a version of cmpRGBcornerCGradiant() that computes the length of the final argument as a C-string.
1645 Unlike the version of cmpRGBcornerDGradiant() specifying numColors, this one requires the final argument to be a real C-string -- i.e. it must have a
1646 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1647
1648 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1649
1650 @param csX The value to convert
1651 @param cornerColors Characters specifying color (as used by setColor)
1652 @return A reference to this object */
1653 inline colorTpl& cmpRGBcornerCGradiant(csFltType csX, const char *cornerColors) {
1654 return cmpRGBcornerCGradiant(csX, static_cast<csIntType>(std::strlen(cornerColors)), cornerColors);
1655 }
1656 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1657 /** This is simply a version of cmpRGBcornerDGradiant() that computes the length of the final argument as a C-string.
1658 Unlike the version of cmpRGBcornerDGradiant() specifying numColors, this one requires the final argument to be a real C-string -- i.e. it must have a
1659 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1660
1661 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1662
1663 @param csIdx The value to convert
1664 @param cornerColors Characters specifying color (as used by setColor)
1665 @return A reference to this object */
1666 inline colorTpl& cmpRGBcornerDGradiant(csIntType csIdx, const char *cornerColors) {
1667 return cmpRGBcornerDGradiant(csIdx, static_cast<csIntType>(std::strlen(cornerColors)), cornerColors);
1668 }
1669 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1670 /** Color value based upon a color ramp passing through the given sequence of corner colors at equal intervals along [0, (mjr::colorTpl::chanStepMax *
1671 (numColors - 1) + 1)]. At 0, the color will be the first specified color. At (mjr::colorTpl::chanStepMax * ( numColors - 1) + 1) it will be the
1672 last color specified color. This function uses precise integer arithmetic. cornerColors need not be a real C-string -- i.e. no need for an
1673 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1674
1675 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1676
1677 @param csIdx The value to convert
1678 @param numColors The number of colors
1679 @param cornerColors An array of things that can be passed to setToCorner() -- usually char or cornerColorEnum
1680 @return A reference to this object */
1681 template <typename ccT>
1682 inline colorTpl& cmpRGBcornerDGradiant(csIntType csIdx, csIntType numColors, const ccT* cornerColors) {
1683 csIdx = mjr::math::ivl::wrapCC(csIdx, static_cast<csIntType>(chanStepMax * numColors - chanStepMax)); // First wrap to the total color count
1684 csIntType edgeNum = csIdx / chanStepMax;
1685 if (edgeNum == (numColors-1)) {
1686 edgeNum = edgeNum - 1;
1687 csIdx = chanStepMax;
1688 } else {
1689 csIdx = csIdx % chanStepMax;
1690 }
1691 colorTpl c1;
1692 colorTpl c2;
1693 c1.setToCorner(cornerColors[edgeNum]);
1694 c2.setToCorner(cornerColors[edgeNum+1]);
1695 for (int j : {redChan, greenChan, blueChan}) {
1696 csIntType cVal;
1697 if(c1.getChan(j) > c2.getChan(j)) {
1698 cVal = chanStepMax - csIdx;
1699 } else if(c1.getChan(j) < c2.getChan(j)) {
1700 cVal = csIdx;
1701 } else {
1702 cVal = ( c1.getChan(j) > 0 ? chanStepMax : 0);
1703 }
1704 if constexpr (chanIsFloat)
1705 setChan(j, static_cast<clrChanT>(cVal) / static_cast<clrChanT>(chanStepMax));
1706 else
1707 setChan(j, static_cast<clrChanT>(cVal));
1708 }
1709 return *this;
1710 }
1711 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1712 /** Color value based upon a color ramp passing through the given sequence of corner colors at equal intervals along [0.0, 1.0]. At 0, the color will
1713 be the first specified color. At 1.0 it will be the last color specified color. CornerColors need not be a real C-string -- i.e. no need for an
1714 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1715
1716 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1717
1718 @param csX The value to convert
1719 @param numColors The number of colors
1720 @param cornerColors An array of things that can be passed to setToCorner() -- usually char or cornerColorEnum
1721 @return A reference to this object */
1722 template <typename ccT>
1723 inline colorTpl& cmpRGBcornerCGradiant(csFltType csX, csIntType numColors, const ccT* cornerColors) {
1724 /* performance: I have no idea why this is slower than the linear search loop used in cmpGradiant(). Still, the code is cleaner this way. Perhaps
1725 the optimizer will figure it out someday... The optimizer works in strange ways. */
1726 if(numColors >= 2) {
1727 csX = mjr::math::ivl::wrapCC(csX, static_cast<csFltType>(1));
1728 csFltType mF = csX * static_cast<csFltType>(numColors - 1);
1729 csIntType mI = static_cast<csIntType>(mF);
1730 if (mI >= (numColors-2)) mI=numColors-2;
1731 colorTpl c1;
1732 colorTpl c2;
1733 c1.setToCorner(cornerColors[mI]);
1734 c2.setToCorner(cornerColors[mI+1]);
1735 return linearInterpolate(mF-static_cast<csFltType>(mI), c1, c2);
1736 } else {
1737 return *this;
1738 }
1739 }
1740 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1741 /** Set the current color to a value linearly interpolated between the two given colors.
1742 When \a aDouble is 0, the color is col1. When \a aDouble is 1 the new value is col2. The interpolation is done in HSL space -- i.e. the given colors are
1743 converted to HSL, the interpolation is done, and the result is converted back to RGB and the current color is set. Unlike linearInterpolate, this
1744 function will NOT interpolate every channel. Rather, as this function deals specifically with RGB and HSL space, only the RGB channels will be
1745 interpolated.
1746 @param space The color space to use
1747 @param aDouble The distance from col1
1748 @param col1 The starting color
1749 @param col2 The ending color
1750 @return Returns a reference to the current color object.*/
1751 inline colorTpl& interplColorSpace(colorSpaceEnum space, double aDouble, colorArgType col1, colorArgType col2) {
1752 /* Requires: Inherits numChan>2 from getC2. */
1753 /* This use of getC0/getC1/getC2 for RGB is OK -- that is how colConDbl3 objects work */
1754 if( (aDouble >= 0.0) && (aDouble <= 1.0) ) {
1755 // Convert our given colors into HSL
1756 colConDbl3 acol1 = col1.rgb2colorSpace(space);
1757 colConDbl3 acol2 = col2.rgb2colorSpace(space);
1758
1759 // Interpolate values
1760 double out1, out2, out3;
1761 if ((space == colorSpaceEnum::HSL) || (space == colorSpaceEnum::HSV))
1762 out1 = mjr::math::linm::interpolate_degrees(acol1.getC0(), acol2.getC0(), aDouble);
1763 else
1764 out1 = mjr::math::linm::interpolate(acol1.getC0(), acol2.getC0(), aDouble);
1765 out2 = mjr::math::linm::interpolate(acol1.getC1(), acol2.getC1(), aDouble);
1766 if (space == colorSpaceEnum::LCH)
1767 out3 = mjr::math::linm::interpolate_degrees(acol1.getC2(), acol2.getC2(), aDouble);
1768 else
1769 out3 = mjr::math::linm::interpolate(acol1.getC2(), acol2.getC2(), aDouble);
1770
1771 // Set color
1772 setRGBfromColorSpace(space, out1, out2, out3);
1773 }
1774 // Return
1775 return *this;
1776 }
1777 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1778 /** Convert a channelArithFltType value into a clrChanT value.
1779
1780 This function works hard to return the nearest clrChanT value to a channelArithFltType value, but it is quite slow.
1781
1782 @param flt Value to convert */
1783 inline clrChanT channelArithFlt2clrChan(channelArithFltType flt) {
1784 return static_cast<clrChanT>(std::round(flt)+0.1);
1785 }
1786 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1787 /** Compute the weighted mean of the given colors.
1788
1789 @warning In order to keep the result in range, w1,w2,w3,s4 must be in [0,1] and w1+w2+w3_w5=1. See uMean() for a way to do that automatically.
1790
1791 @warning Floating point arithmetic results vary with hardware, compiler, and even compiler options. These small differences can have an impact on
1792 casts from floating point values to integers when the floating point result is near an whole number. For example, suppose we have a floating point
1793 computation for which the "theoretical" value is exactly 5. If that computation results in 4.999999, then the a cast will result in 4. OTOH if the
1794 computation resulted in 5.000001, then the cast results in 5. In short we *expect* the result of this function to vary by as much as 1. Yes we
1795 could "do it right", but this function is intended to be fast. We are more than happy to have a little slop in the results in exchange for speed.
1796
1797 @param w1 The first weight
1798 @param w2 The second weight
1799 @param w3 The third weight
1800 @param w4 The fourth weight
1801 @param col1 The first color
1802 @param col2 The second color
1803 @param col3 The third color
1804 @param col4 The fourth color
1805 @return Returns a reference to the current color object. */
1806 inline colorTpl& wMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3, channelArithFltType w4,
1807 colorArgType col1, colorArgType col2, colorArgType col3, colorArgType col4) {
1808 for(int i=0; i<numChan; i++)
1809 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithFltType>(col1.getChanNC(i)) * w1) +
1810 (static_cast<channelArithFltType>(col2.getChanNC(i)) * w2) +
1811 (static_cast<channelArithFltType>(col3.getChanNC(i)) * w3) +
1812 (static_cast<channelArithFltType>(col4.getChanNC(i)) * w4)));
1813
1814 return *this;
1815 }
1816 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1817 /** @overload */
1818 inline colorTpl& wMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3,
1819 colorArgType col1, colorArgType col2, colorArgType col3) {
1820 for(int i=0; i<numChan; i++) {
1821 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithFltType>(col1.getChanNC(i)) * w1) +
1822 (static_cast<channelArithFltType>(col2.getChanNC(i)) * w2) +
1823 (static_cast<channelArithFltType>(col3.getChanNC(i)) * w3)));
1824 }
1825 return *this;
1826 }
1827 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1828 /** @overload */
1829 inline colorTpl& wMean(channelArithFltType w1, channelArithFltType w2, colorArgType col1, colorArgType col2) {
1830 for(int i=0; i<numChan; i++)
1831 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithFltType>(col1.getChanNC(i)) * w1) +
1832 (static_cast<channelArithFltType>(col2.getChanNC(i)) * w2)));
1833 return *this;
1834 }
1835 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1836 /** Compute the unit weighted mean of the given colors -- like wMean(), but last weight is computed such that weights sum to 1.0.
1837 @param w1 The first weight in the range [0, 1) -- the range not checked!
1838 @param w2 The second weight in the range [0, 1) -- the range not checked!
1839 @param w3 The third weight in the range [0, 1) -- the range not checked!
1840 @param col1 The first color
1841 @param col2 The second color
1842 @param col3 The third color
1843 @param col4 The fourth color
1844 @return Returns a reference to the current color object. */
1845 inline colorTpl& uMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3,
1846 colorArgType col1, colorArgType col2, colorArgType col3, colorArgType col4) {
1847 return wMean(w1, w2, w3, static_cast<channelArithFltType>(1)-w1-w2-w3, col1, col2, col3, col4);
1848 }
1849 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1850 /** @overload */
1851 inline colorTpl& uMean(channelArithFltType w1, channelArithFltType w2, colorArgType col1, colorArgType col2, colorArgType col3) {
1852 return wMean(w1, w2, static_cast<channelArithFltType>(1)-w1-w2, col1, col2, col3);
1853 }
1854 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1855 /** @overload */
1856 inline colorTpl& uMean(channelArithFltType w1, colorArgType col1, colorArgType col2) {
1857 return wMean(w1, static_cast<channelArithFltType>(1)-w1, col1, col2);
1858 }
1859 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1860 /** Set the current color to a value linearly interpolated between the two given colors.
1861 When \a aDouble is 0, the color is col1. When \a aDouble is 1 the new value is col2. This method interpolates all channels without any color space
1862 conversions and as few type conversions as possible.
1863 @param aDouble The distance from col1
1864 @param col1 The starting color
1865 @param col2 The ending color
1866 @return Returns a reference to the current color object.*/
1867 inline colorTpl& linearInterpolate(double aDouble, colorArgType col1, colorArgType col2) {
1868 if( (aDouble >= 0.0) && (aDouble <= 1.0) )
1869 for(int i=0; i<numChan; i++)
1870 setChanNC(i, static_cast<clrChanT>(mjr::math::linm::interpolate(static_cast<double>(col1.getChanNC(i)), static_cast<double>(col2.getChanNC(i)), aDouble)));
1871 return *this;
1872 }
1873 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1874 /** Set the RGB channels of the current color to a value linearly interpolated between the two given colors.
1875 When \a aDouble is 0, the color is col1. When \a aDouble is 1 the new value is col2. This method interpolates all channels without any color space
1876 conversions and as few type conversions as possible.
1877 @param aDouble The distance from col1
1878 @param col1 The starting color
1879 @param col2 The ending color
1880 @return Returns a reference to the current color object.*/
1881 inline colorTpl& linearInterpolateRGB(double aDouble, colorArgType col1, colorArgType col2) {
1882 if( (aDouble >= 0.0) && (aDouble <= 1.0) )
1883 for (int i : {redChan, blueChan, greenChan})
1884 setChanNC(i, static_cast<clrChanT>(mjr::math::linm::interpolate(static_cast<double>(col1.getChanNC(i)), static_cast<double>(col2.getChanNC(i)), aDouble)));
1885 return *this;
1886 }
1887 //@}
1888
1889 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1890 /** @name Logical Operators */
1891 //@{
1892 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1893 /** Performs a logical OR with the current object and the given object and places the value in the current object.
1894 @param aCol The color to use in the computation.
1895 @return Returns a reference to the current color object.*/
1896 inline colorTpl& tfrmOr(colorArgType aCol) requires (std::integral<clrChanT>) {
1897 if constexpr (goodMask)
1898 setMaskNC(getMaskNC() | aCol.getMaskNC());
1899 else
1900 for(int i=0; i<numChan; i++)
1901 setChanNC(i, getChanNC(i) | aCol.getChanNC(i));
1902 return *this;
1903 }
1904#if !(MISSING_P0476R2)
1905 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1906 /** Template specialization member function differing from the above function only in supported template conditions. */
1907 inline colorTpl& tfrmOr(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1908 /* Performance: Yep. Sometimes floating point colors get a goodMask. */
1909 if constexpr (goodMask)
1910 setMaskNC(getMaskNC() | aCol.getMaskNC());
1911 else
1912 for(int i=0; i<numChan; i++)
1913 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) | std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
1914 return *this;
1915 }
1916#endif
1917 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1918 /** Performs a logical NOR with the current object and the given object and places the value in the current object.
1919 @param aCol The color to use in the computation.
1920 @return Returns a reference to the current color object.*/
1921 inline colorTpl& tfrmNor(colorArgType aCol) requires (std::integral<clrChanT>) {
1922 if constexpr (goodMask)
1923 setMaskNC(~(getMaskNC() | aCol.getMaskNC()));
1924 else
1925 for(int i=0; i<numChan; i++)
1926 setChanNC(i, ~(getChanNC(i) | aCol.getChanNC(i)));
1927 return *this;
1928 }
1929#if !(MISSING_P0476R2)
1930 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1931 /** Template specialization member function differing from the above function only in supported template conditions. */
1932 inline colorTpl& tfrmNor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1933 if constexpr (goodMask)
1934 setMaskNC(~(getMaskNC() | aCol.getMaskNC()));
1935 else
1936 for(int i=0; i<numChan; i++)
1937 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) | std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
1938 return *this;
1939 }
1940#endif
1941 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1942 /** Performs a logical AND with the current object and the given object and places the value in the current object.
1943 @param aCol The color to use in the computation.
1944 @return Returns a reference to the current color object.*/
1945 inline colorTpl& tfrmAnd(colorArgType aCol) requires (std::integral<clrChanT>) {
1946 if constexpr (goodMask)
1947 setMaskNC(getMaskNC() & aCol.getMaskNC());
1948 else
1949 for(int i=0; i<numChan; i++)
1950 setChanNC(i, getChanNC(i) & aCol.getChanNC(i));
1951 return *this;
1952 }
1953#if !(MISSING_P0476R2)
1954 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1955 /** Template specialization member function differing from the above function only in supported template conditions. */
1956 inline colorTpl& tfrmAnd(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1957 if constexpr (goodMask)
1958 setMaskNC(getMaskNC() & aCol.getMaskNC());
1959 else
1960 for(int i=0; i<numChan; i++)
1961 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) & std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
1962 return *this;
1963 }
1964#endif
1965 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1966 /** Performs a logical NAND with the current object and the given object and places the value in the current object.
1967 @param aCol The color to use in the computation.
1968 @return Returns a reference to the current color object.*/
1969 inline colorTpl& tfrmNand(colorArgType aCol) requires (std::integral<clrChanT>) {
1970 if constexpr (goodMask)
1971 setMaskNC(~(getMaskNC() & aCol.getMaskNC()));
1972 else
1973 for(int i=0; i<numChan; i++)
1974 setChanNC(i, ~(getChanNC(i) & aCol.getChanNC(i)));
1975 return *this;
1976 }
1977#if !(MISSING_P0476R2)
1978 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1979 /** Template specialization member function differing from the above function only in supported template conditions. */
1980 inline colorTpl& tfrmNand(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1981 if constexpr (goodMask)
1982 setMaskNC(~(getMaskNC() & aCol.getMaskNC()));
1983 else
1984 for(int i=0; i<numChan; i++)
1985 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) & std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
1986 return *this;
1987 }
1988#endif
1989 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1990 /** Performs a logical EXCLUSIVE OR (XOR) with the current object and the given object and places the value in the current object.
1991 @param aCol The color to use in the computation.
1992 @return Returns a reference to the current color object.*/
1993 inline colorTpl& tfrmXor(colorArgType aCol) requires (std::integral<clrChanT>) {
1994 if constexpr (goodMask)
1995 setMaskNC(getMaskNC() ^ aCol.getMaskNC());
1996 else
1997 for(int i=0; i<numChan; i++)
1998 setChanNC(i, getChanNC(i) ^ aCol.getChanNC(i));
1999 return *this;
2000 }
2001#if !(MISSING_P0476R2)
2002 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2003 /** Template specialization member function differing from the above function only in supported template conditions. */
2004 inline colorTpl& tfrmXor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2005 if constexpr (goodMask)
2006 setMaskNC(getMaskNC() ^ aCol.getMaskNC());
2007 else
2008 for(int i=0; i<numChan; i++)
2009 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) ^ std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
2010 return *this;
2011 }
2012#endif
2013 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2014 /** Performs a logical NOT EXCLUSIVE OR (NXOR) with the current object and the given object and places the value in the current object.
2015 @param aCol The color to use in the computation.
2016 @return Returns a reference to the current color object.*/
2017 inline colorTpl& tfrmNxor(colorArgType aCol) requires (std::integral<clrChanT>) {
2018 if constexpr (goodMask)
2019 setMaskNC(~(getMaskNC() ^ aCol.getMaskNC()));
2020 else
2021 for(int i=0; i<numChan; i++)
2022 setChanNC(i, ~(getChanNC(i) ^ aCol.getChanNC(i)));
2023 return *this;
2024 }
2025#if !(MISSING_P0476R2)
2026 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2027 /** Template specialization member function differing from the above function only in supported template conditions. */
2028 inline colorTpl& tfrmNxor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2029 if constexpr (goodMask)
2030 setMaskNC(~(getMaskNC() ^ aCol.getMaskNC()));
2031 else
2032 for(int i=0; i<numChan; i++)
2033 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) ^ std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
2034 return *this;
2035 }
2036#endif
2037 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2038 /** Performs logical (bit-wise) negation of current object.
2039 @return Returns a reference to the current color object.*/
2040 inline colorTpl& tfrmNot(void) requires (std::integral<clrChanT>) {
2041 if constexpr (goodMask)
2042 setMaskNC(~(getMaskNC()));
2043 else
2044 for(int i=0; i<numChan; i++)
2045 setChanNC(i, ~(getChanNC(i)));
2046 return *this;
2047 }
2048#if !(MISSING_P0476R2)
2049 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2050 /** Template specialization member function differing from the above function only in supported template conditions. */
2051 inline colorTpl& tfrmNot(void) requires (std::floating_point<clrChanT>) {
2052 if constexpr (goodMask)
2053 setMaskNC(~(getMaskNC()));
2054 else
2055 for(int i=0; i<numChan; i++)
2056 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)))));
2057 return *this;
2058 }
2059#endif
2060 //@}
2061
2062 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2063 /** @name Arithmetic Operators */
2064 //@{
2065 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2066 /** Computes the square of the difference for each channel between the given color and the current color object.
2067 @param aCol The color to use in the computation.
2068 @return Returns a reference to the current color object.*/
2070 for(int i=0; i<numChan; i++)
2071 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithSDPType>(getChanNC(i)) - static_cast<channelArithSDPType>(aCol.getChanNC(i))) *
2072 (static_cast<channelArithSDPType>(getChanNC(i)) - static_cast<channelArithSDPType>(aCol.getChanNC(i)))));
2073 return *this;
2074 }
2075 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2076 /** Computes the absolute value of the difference for each channel between the given color and the current color object.
2077 @param aCol The color to use in the computation.
2078 @return Returns the absolute value of the difference for each channel.*/
2080 for(int i=0; i<numChan; i++)
2081 setChanNC(i, static_cast<clrChanT>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i)))));
2082 return *this;
2083 }
2084 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2085 /** Computes the arithmetic sum of the given color and the current one.
2086 @param aCol The color to use in the computation.
2087 @return Returns a reference to the current color object.*/
2089 for(int i=0; i<numChan; i++)
2090 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))));
2091 return *this;
2092 }
2093 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2094 /** Computes the arithmetic division of the current color by the given color.
2095 If a channel of aCol is zero, then the corresponding channel of the current color object will be left untouched.
2096 @param aCol The color to use in the computation.
2097 @return Returns a reference to the current color object.*/
2098 inline colorTpl& tfrmDiv(colorArgType aCol) requires (std::integral<clrChanT>) {
2099 for(int i=0; i<numChan; i++)
2100 if (aCol.getChanNC(i) != 0)
2101 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) / static_cast<channelArithSPType>(aCol.getChanNC(i))));
2102 return *this;
2103 }
2104 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2105 /** Template specialization member function differing from the above function only in supported template conditions. */
2106 inline colorTpl& tfrmDiv(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2107 for(int i=0; i<numChan; i++)
2108 if (mjr::math::fc::not_near_zero(aCol.getChanNC(i), static_cast<clrChanT>(1.0e-8)))
2109 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) / static_cast<channelArithSPType>(aCol.getChanNC(i))));
2110 return *this;
2111 }
2112 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2113 /** Computes the arithmetic product of the given color and the current one.
2114 @param aCol The color to use in the computation.
2115 @return Returns a reference to the current color object.*/
2117 for(int i=0; i<numChan; i++)
2118 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(aCol.getChanNC(i))));
2119 return *this;
2120 }
2121 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2122 /** Computes the product of the given color and the current one.
2123 If the result of a multiplication is too large, it will be set to the maximum component value.
2124 @param aCol The color to use in the computation.
2125 @return Returns a reference to the current color object.*/
2127 for(int i=0; i<numChan; i++)
2128 setChanNC(i, clampTop(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(aCol.getChanNC(i))));
2129 return *this;
2130 }
2131 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2132 /** Computes the component wise scaled sign of the difference between the current color and the given one.
2133 As an example of the computation, the red component of the current color is computed like this:
2134 - R=#minChanVal iff(R<color.R)
2135 - R=#meanChanVal iff(R==color.R)
2136 - R=#maxChanVal iff(R>color.R)
2137 @param aCol The color to use in the computation.
2138 @return Returns a reference to the current color object.*/
2140 for(int i=0; i<numChan; i++) {
2141 if(getChanNC(i) < aCol.getChanNC(i)) {
2142 setChanNC(i, minChanVal);
2143 } else if(getChanNC(i) > aCol.getChanNC(i)) {
2144 setChanNC(i, maxChanVal);
2145 } else {
2146 setChanNC(i, meanChanVal);
2147 }
2148 }
2149 return *this;
2150 }
2151 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2152 /** Computes the arithmetic difference of the given color from the current one.
2153 If the result a differences is negative, then that component will be set to zero.
2154 @param aCol The color to use in the computation.
2155 @return Returns a reference to the current color object.*/
2157 for(int i=0; i<numChan; i++)
2158 setChanNC(i, clampBot(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i))));
2159 return *this;
2160 }
2161 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2162 /** Computes the negative of the arithmetic difference of the given color from the current one.
2163 This is the same as the arithmetic difference of the current color from the given color. If the result a differences is negative, then that
2164 component will be set to zero.
2165 @param aCol The color to use in the computation.
2166 @return Returns a reference to the current color object.*/
2168 for(int i=0; i<numChan; i++)
2169 setChanNC(i, clampBot(static_cast<channelArithDType>(aCol.getChanNC(i)) - static_cast<channelArithDType>(getChanNC(i))));
2170 return *this;
2171 }
2172 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2173 /** Computes the arithmetic sum of the given color from the current one.
2174 If the result of a sum is greater than the maximum value, then that component will be set to the maximum value.
2175 @param aCol The color to use in the computation.
2176 @return Returns a reference to the current color object.*/
2178 for(int i=0; i<numChan; i++)
2179 setChanNC(i, clampTop(static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))));
2180 return *this;
2181 }
2182 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2183 /** Computes the arithmetic sum of the current color and aCol, then divids by dCol.
2184 If the result is greater than the maximum value, then that component will be set to the maximum value.
2185 If a channel of dCol is zero, then the corresponding channel of the current color object will be left untouched.
2186 @param aCol The color to use for initial add.
2187 @param dCol The color to use for final division.
2188 @return Returns a reference to the current color object.*/
2189 inline colorTpl& tfrmAddDivClamp(colorArgType aCol, colorArgType dCol) requires (std::integral<clrChanT>) {
2190 for(int i=0; i<numChan; i++)
2191 if (dCol.getChanNC(i) != 0)
2192 setChanNC(i, clampTop((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) /
2193 static_cast<channelArithSPType>(dCol.getChanNC(i))));
2194 return *this;
2195 }
2196 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2197 /** Template specialization member function differing from the above function only in supported template conditions. */
2198 inline colorTpl& tfrmAddDivClamp(colorArgType aCol, colorArgType dCol) requires (std::floating_point<clrChanT>) {
2199 for(int i=0; i<numChan; i++)
2200 if (mjr::math::fc::not_near_zero(dCol.getChanNC(i), static_cast<clrChanT>(1.0e-8)))
2201 setChanNC(i, clampTop((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) /
2202 static_cast<channelArithSPType>(dCol.getChanNC(i))));
2203 return *this;
2204 }
2205 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2206 /** Computes the arithmetic difference of the given color from the current one.
2207 @param aCol The color to use in the computation.
2208 @return Returns a reference to the current color object.*/
2210 for(int i=0; i<numChan; i++)
2211 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i))));
2212 return *this;
2213 }
2214 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2215 /** Computes the arithmetic modulus of the current by the given one.
2216 If a channel of aCol is zero, then the corresponding channel of the current object is left untouched.
2217 @param aCol The color to use in the computation.
2218 @return Returns a reference to the current color object.*/
2219 inline colorTpl& tfrmMod(colorArgType aCol) requires (std::integral<clrChanT>) {
2220 for(int i=0; i<numChan; i++)
2221 if (aCol.getChanNC(i) != 0)
2222 setChanNC(i, getChanNC(i) % aCol.getChanNC(i));
2223 return *this;
2224 }
2225 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2226 /** Template specialization member function differing from the above function only in supported template conditions. */
2227 inline colorTpl& tfrmMod(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2228 for(int i=0; i<numChan; i++)
2229 if (mjr::math::fc::not_near_zero(aCol.getChanNC(i), static_cast<clrChanT>(1.0e-8)))
2230 setChanNC(i, static_cast<clrChanT>(std::fmod(static_cast<double>(getChanNC(i)), static_cast<double>(aCol.getChanNC(i)))));
2231 return *this;
2232 }
2233 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2234 /** Transforms the color: r=#maxChanVal-r, g=#maxChanVal-r, and b=#maxChanVal-b
2235 @return Returns a reference to the current color object.*/
2237 // MJR TODO NOTE tfrmInvert: This is just as fast as array refs...
2238 // MJR TODO NOTE tfrmInvert: We should use this universally across the library -- to isolate the code from the array specifics...
2239 for(int i=0; i<numChan; i++)
2240 setChanNC(i, maxChanVal - getChanNC(i));
2241 return *this;
2242 }
2243 //@}
2244
2245 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2246 /** @name Named Operators */
2247 //@{
2248 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2249 /** Power: c=maxChanVal*(c/maxChanVal)^p.
2250 Floating point Numbers are used for intermediate values and the result cast to a colorT at the end.
2251 Take care when negative values for p -- this can cause undefined behavior!!
2252 @return Returns a reference to the current color object.*/
2253 inline colorTpl& tfrmPow(double p) {
2254 for(int i=0; i<numChan; i++)
2255 setChanNC(i, static_cast<clrChanT>(static_cast<double>(maxChanVal) * std::pow(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal), p)));
2256 return *this;
2257 }
2258 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2259 /** Adds 1.0 and takes the natural logarithm of each channel.
2260 Floating point Numbers are used for intermediate values and the result cast to a colorT at the end.
2261 If a channel value would result in an undefined result, then the value is left untouched.
2262 @return Returns a reference to the current color object.*/
2263 inline colorTpl& tfrmLn1() requires (std::integral<clrChanT>) {
2264 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2265 for(int i=0; i<numChan; i++)
2266 setChanNC(i, static_cast<clrChanT>(std::log(1.0 + static_cast<double>(getChanNC(i)))));
2267 return *this;
2268 }
2269 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2270 /** Template specialization member function differing from the above function only in supported template conditions. */
2271 inline colorTpl& tfrmLn1() requires (std::floating_point<clrChanT>) {
2272 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2273 for(int i=0; i<numChan; i++) {
2274 clrChanT cVal = getChanNC(i);
2275 if (cVal > static_cast<clrChanT>(-1.0))
2276 setChanNC(i, static_cast<clrChanT>(std::log(1.0 + static_cast<double>(cVal))));
2277 }
2278 return *this;
2279 }
2280 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2281 /** Computes ln(c)*scale for each channel value c. If c==0, then the value is left undisturbed.
2282 Floating point Numbers are used for intermediate values and the result cast to a colorT at the end.
2283 If a channel value would result in an undefined result, then the value is left untouched.
2284 @param scale The scale value to multiply by the final result.
2285 @return Returns a reference to the current color object.*/
2286 inline colorTpl& tfrmLn(double scale) requires (std::integral<clrChanT>) {
2287 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2288 for(int i=0; i<numChan; i++) {
2289 clrChanT cVal = getChanNC(i);
2290 if(cVal != 0)
2291 setChanNC(i, static_cast<clrChanT>(std::log(static_cast<double>(cVal)) * scale));
2292 }
2293 return *this;
2294 }
2295 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2296 /** Template specialization member function differing from the above function only in supported template conditions. */
2297 inline colorTpl& tfrmLn(double scale) requires (std::floating_point<clrChanT>) {
2298 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2299 for(int i=0; i<numChan; i++) {
2300 clrChanT cVal = getChanNC(i);
2301 if (cVal > static_cast<clrChanT>(0.0))
2302 setChanNC(i, static_cast<clrChanT>(std::log(static_cast<double>(cVal)) * scale));
2303 }
2304 return *this;
2305 }
2306 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2307 /** Linearly interpolate between the current color and the given color (at a point scaled the unit interval).
2308 If \a aDouble is 0, then the current color will not change. If \a aDouble is 1, then the current color will be tooCol.
2309 @param aDouble Distance from the current color (on a unit interval)
2310 @param tooCol The color we are interpolating with.
2311 @return Returns a reference to the current color object.*/
2312 inline colorTpl& tfrmMix(double aDouble, colorArgType tooCol) {
2313 if( (aDouble >= 0.0) && (aDouble <= 1.0) )
2314 for(int i=0; i<numChan; i++)
2315 setChanNC(i, static_cast<clrChanT>(mjr::math::linm::interpolate(static_cast<double>(getChanNC(i)), static_cast<double>(tooCol.getChanNC(i)), aDouble)));
2316 return *this;
2317 }
2318 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2319 /** Copies the given argument into the current color object.
2320 Scan as copy() -- just with a name more suited to transformation code.
2321 @return Returns a reference to the current color object.*/
2322 inline colorTpl& tfrmCopy(colorArgType aCol) { return copy(aCol); }
2323 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2324 /** Makes the current color the maximum of the current color or the given color.
2325 Colors are ordered by intensity (thus the 'I' in the name)
2326 @param aCol The color to use in the computation.
2327 @return Returns a reference to the current color object.*/
2329 channelArithSPType thisSum = 0;
2330 channelArithSPType thatSum = 0;
2331 for(int i=0; i<numChan; i++) {
2332 thisSum += static_cast<channelArithSPType>(getChanNC(i));
2333 thatSum += static_cast<channelArithSPType>(aCol.getChanNC(i));
2334 }
2335 if(thisSum < thatSum)
2336 tfrmCopy(aCol);
2337 return *this;
2338 }
2339 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2340 /** Makes the current color the minimum of the current color or the given color.
2341 Colors are ordered by intensity (thus the 'I' in the name)
2342 @param aCol The color to use in the computation.
2343 @return Returns a reference to the current color object.*/
2345 /* Performance: Finding the max of two arrays in parallel with one loop is faster than calling max twice, once for each array. */
2346 channelArithSPType thisSum = 0;
2347 channelArithSPType thatSum = 0;
2348 for(int i=0; i<numChan; i++) {
2349 thisSum += static_cast<channelArithSPType>(getChanNC(i));
2350 thatSum += static_cast<channelArithSPType>(aCol.getChanNC(i));
2351 }
2352 if(thisSum > thatSum)
2353 tfrmCopy(aCol);
2354 return *this;
2355 }
2356 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2357 /** Makes each component of the current color the maximum of that component and the corresponding component of the given color.
2358 @param aCol The color to use in the computation.
2359 @return Returns a reference to the current color object.*/
2361 for(int i=0; i<numChan; i++)
2362 if(getChanNC(i) < aCol.getChanNC(i))
2363 setChanNC(i, aCol.getChanNC(i));
2364 return *this;
2365 }
2366 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2367 /** Makes each component of the current color the minimum of that component and the corresponding component of the given color.
2368 @param aCol The color to use in the computation.
2369 @return Returns a reference to the current color object.*/
2371 for(int i=0; i<numChan; i++)
2372 if(getChanNC(i) > aCol.getChanNC(i))
2373 setChanNC(i, aCol.getChanNC(i));
2374 return *this;
2375 }
2376 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2377 /** The Shift Left Transform modifies the current color.
2378 @param aCol Number of bits to shift left
2379 @return Returns a reference to the current color object.*/
2380 inline colorTpl& tfrmShiftL(colorArgType aCol) requires (std::integral<clrChanT>) {
2381 for(int i=0; i<numChan; i++)
2382 setChanNC(i, getChanNC(i) << aCol.getChanNC(i));
2383 return *this;
2384 }
2385#if !(MISSING_P0476R2)
2386 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2387 /** Template specialization member function differing from the above function only in supported template conditions. */
2388 inline colorTpl& tfrmShiftL(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2389 for(int i=0; i<numChan; i++)
2390 /* tricky: We are casting the color component being shifted bitwise to a big int; however, we are casting the shifting quantity via a static_cast. */
2391 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) << static_cast<uint64_t>(aCol.getChanNC(i))));
2392 return *this;
2393 }
2394#endif
2395 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2396 /** The Shift Right Transform modifies the current color.
2397 @param aCol How many bits to shift.
2398 @return Returns a reference to the current color object.*/
2399 inline colorTpl& tfrmShiftR(colorArgType aCol) requires (std::integral<clrChanT>) {
2400 for(int i=0; i<numChan; i++)
2401 setChanNC(i, getChanNC(i) >> aCol.getChanNC(i));
2402 return *this;
2403 }
2404#if !(MISSING_P0476R2)
2405 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2406 /** Template specialization member function differing from the above function only in supported template conditions. */
2407 inline colorTpl& tfrmShiftR(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2408 for(int i=0; i<numChan; i++)
2409 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) >> static_cast<uint64_t>(aCol.getChanNC(i))));
2410 return *this;
2411 }
2412#endif
2413 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2414 /** The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, C_i, 0)
2415 @param lowCol lower cutoff value
2416 @param highCol upper cutoff value
2417 @return Returns a reference to the current color object.*/
2418 inline colorTpl& tfrmSaw(colorArgType lowCol, colorArgType highCol) {
2419 for(int i=0; i<numChan; i++)
2420 setChanNC(i, ((lowCol.getChanNC(i) <= getChanNC(i)) && (highCol.getChanNC(i) >= getChanNC(i)) ? getChanNC(i) : 0));
2421 return *this;
2422 }
2423 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2424 /** The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, maxChanVal, 0)
2425 @param lowCol lower cutoff value
2426 @param highCol upper cutoff value
2427 @return Returns a reference to the current color object.*/
2428 inline colorTpl& tfrmStep(colorArgType lowCol, colorArgType highCol) {
2429 for(int i=0; i<numChan; i++)
2430 setChanNC(i, ((lowCol.getChanNC(i) <= getChanNC(i)) && (highCol.getChanNC(i) >= getChanNC(i)) ? maxChanVal : 0));
2431 return *this;
2432 }
2433 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2434 /** The DiracTot (total) Transform modifies the current color: Set current color to white if it equals aCol, and black otherwise.
2435 @param aCol Dirac trigger value
2436 @return Returns a reference to the current color object.*/
2438 for(int i=0; i<numChan; i++)
2439 if(aCol.getChanNC(i) != getChanNC(i))
2440 return setToBlack();
2441 return setToWhite();
2442 }
2443 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2444 /** The Dirac Transform modifies the current color: C_i = ifelse(C_i==aCol.C_i, maxChanVal, 0)
2445 @param aCol Dirac trigger value
2446 @return Returns a reference to the current color object.*/
2448 for(int i=0; i<numChan; i++)
2449 setChanNC(i, ((aCol.getChanNC(i) == getChanNC(i)) ? maxChanVal : 0));
2450 return *this;
2451 }
2452 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2453 /** The Fuzzy Dirac Transform modifies the current color: C_i=ifelse(|R-ctrCol.R|<=radCol.R), maxChanVal, 0)
2454 @param ctrCol Center Color
2455 @param radCol Radius Color
2456 @return Returns a reference to the current color object.*/
2458 for(int i=0; i<numChan; i++)
2459 setChanNC(i, ((std::abs(ctrCol.getChanNC(i) - getChanNC(i)) <= radCol.getChanNC(i)) ? maxChanVal : 0));
2460 return *this;
2461 }
2462 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2463 /** Computes the arithmetic mean of the given color and the current one.
2464 @param aCol The color to use in the computation.
2465 @return Returns a reference to the current color object.*/
2467 for(int i=0; i<numChan; i++)
2468 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) / 2));
2469 return *this;
2470 }
2471 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2472 /** Computes the geometric mean of the given color and the current one.
2473 Floating point Numbers re used for intermediate values and the result cast to a colorT at the end.
2474 @param aCol The color to use in the computation.
2475 @return Returns a reference to the current color object.*/
2477 for(int i=0; i<numChan; i++)
2478 setChanNC(i, static_cast<clrChanT>(std::sqrt(static_cast<channelArithFltType>(getChanNC(i)) * static_cast<channelArithFltType>(aCol.getChanNC(i)))));
2479 return *this;
2480 }
2481 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2482 /** Transform the current color by rendering it into a true grey via the same method used by the luminanceRGB() function.
2483 This function only sets the red, blue, and green channels -- all other channels are left untouched.
2484 @return Returns a reference to the current color object.*/
2486 /* Requires: Inherits numChan>2 from getC2. */
2487 double lumU = static_cast<double>(luminanceRGB());
2488 setRed_dbl( lumU);
2489 setGreen_dbl(lumU);
2490 setBlue_dbl( lumU);
2491 return *this;
2492 }
2493 //@}
2494
2495 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2496 /** @name Color Reduction Transformations */
2497 //@{
2498 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2499 /** The 216 Palate Web Safe Transform modifies the current color into the closest web safe color from the 216 color web safe pallet.
2500 This function only sets the red, blue, and green channels -- all other channels are left untouched.
2501 @return Returns a reference to the current color object.*/
2502 inline colorTpl& tfrmWebSafeRGB() requires (redChan>=0) {
2503 for (int c : {redChan, blueChan, greenChan}) {
2504 int charCompVal = convertChanToByte(getChanNC(c));
2505 int minDist = 256;
2506 int minCol;
2507 for(int pv : { 0x0, 0x33, 0x66, 0x99, 0xCC, 0xFF }) {
2508 int curDist = std::abs(charCompVal - pv);
2509 if( curDist < minDist ) {
2510 minDist = curDist;
2511 minCol = pv;
2512 }
2513 }
2514 setChanNC(c, convertByteToChan(static_cast<uint8_t>(minCol)));
2515 }
2516 return *this;
2517 }
2518 //@}
2519
2520 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2521 /** @name Alternate Color Space Stuff */
2522 //@{
2523 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2524 /** Compute channels for given color space coordinates for the current color.
2525 Note RGB returns float RGB normalized to 1.0.
2526 @param space The color space to convert to
2527 @return An RGB color with double channels. */
2529 /* Requires: Inherits numChan>2 from getBlue. */
2530
2531 double redF = getRed_dbl();
2532 double greenF = getGreen_dbl();
2533 double blueF = getBlue_dbl();
2534
2535 if (space == colorSpaceEnum::RGB)
2536 return colConDbl3(redF, greenF, blueF);
2537
2538 if ((space == colorSpaceEnum::HSL) || (space == colorSpaceEnum::HSV)) {
2539 clrChanT rgbMaxI = getMaxRGB();
2540 clrChanT rgbMinI = getMinRGB();
2541
2542 channelArithSDPType rangeI = rgbMaxI - rgbMinI;
2543
2544 double rgbMaxF = static_cast<double>(rgbMaxI) / static_cast<double>(maxChanVal);
2545 double rgbMinF = static_cast<double>(rgbMinI) / static_cast<double>(maxChanVal);
2546
2547 double rangeF = rgbMaxF - rgbMinF;
2548 double sumF = rgbMaxF + rgbMinF;
2549
2550 // Compute L
2551 double L = sumF / 2.0;
2552 double V = rgbMaxF;
2553
2554 // Compute H & S
2555 double S, H;
2556 if((rgbMaxI == 0) || (rangeI == 0)) {
2557 S = 0.0;
2558 H = 0.0;
2559 } else {
2560
2561 if (space == colorSpaceEnum::HSL) {
2562 if(L <= 0.5)
2563 S = rangeF / sumF;
2564 else
2565 S = rangeF / ( 2.0 - sumF);
2566 } else {
2567 S = rangeF / rgbMaxF;
2568 }
2569
2570 H = 0.0;
2571 if(getRed() == rgbMaxI)
2572 H = 0.0 + (greenF - blueF) / rangeF;
2573 else if(getGreen() == rgbMaxI)
2574 H = 2.0 + (blueF - redF) / rangeF;
2575 else if(getBlue() == rgbMaxI)
2576 H = 4.0 + (redF - greenF) / rangeF;
2577 H = mjr::math::ivl::wrapCO(H * 60.0, 360.0);
2578 }
2579 if (space == colorSpaceEnum::HSL)
2580 return colConDbl3(H, S, L);
2581 else
2582 return colConDbl3(H, S, V);
2583 } else {
2584 redF = 100.0 * ((redF > 0.04045) ? std::pow((redF + 0.055) / 1.055, 2.4) : redF / 12.92);
2585 greenF = 100.0 * ((greenF > 0.04045) ? std::pow((greenF + 0.055) / 1.055, 2.4) : greenF / 12.92);
2586 blueF = 100.0 * ((blueF > 0.04045) ? std::pow((blueF + 0.055) / 1.055, 2.4) : blueF / 12.92);
2587
2588 double X = (0.4124 * redF + 0.3576 * greenF + 0.1805 * blueF);
2589 double Y = (0.2126 * redF + 0.7152 * greenF + 0.0722 * blueF); // luminance with weights RGBluminanceWeightR, RGBluminanceWeightG, RGBluminanceWeightB
2590 double Z = (0.0193 * redF + 0.1192 * greenF + 0.9505 * blueF);
2591
2592 if (space == colorSpaceEnum::XYZ)
2593 return colConDbl3(X, Y, Z);
2594
2595 X /= 95.0429;
2596 Y /= 100.0;
2597 Z /= 108.89;
2598
2599 X = (X > 0.008856 ? std::pow(X, 1.0 / 3.0) : (7.787 * X) + (16.0 / 116.0));
2600 Y = (Y > 0.008856 ? std::pow(Y, 1.0 / 3.0) : (7.787 * Y) + (16.0 / 116.0));
2601 Z = (Z > 0.008856 ? std::pow(Z, 1.0 / 3.0) : (7.787 * Z) + (16.0 / 116.0));
2602
2603 double L = (116.0 * Y) - 16.0;
2604 double A = 500.0 * (X - Y);
2605 double B = 200.0 * (Y - Z);
2606
2607 if (space == colorSpaceEnum::LAB)
2608 return colConDbl3(L, A, B);
2609
2610 double C = std::hypot(A, B);
2611
2612 double H = 0.0;
2613 if ( std::abs(A) > 1.0e-5) // Not Grey
2614 H = mjr::math::ivl::wrapCO(atan2(B,A) * 180.0 / std::numbers::pi, 360.0);
2615
2616 if (space == colorSpaceEnum::LCH)
2617 return colConDbl3(L, C, H);
2618 }
2619
2620 return colConDbl3(0.0, 0.0, 0.0);
2621 }
2622 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2623 /** Compute channels for given color space coordinates for the current color.
2624 Note RGB returns float RGB normalized to 1.0.
2625 @param space The color space to stringify
2626 @return A string representing the color space. */
2627 inline std::string colorSpaceToString(colorSpaceEnum space) {
2628 switch (space) {
2629 case colorSpaceEnum::RGB : return std::string("rgb");
2630 case colorSpaceEnum::HSL : return std::string("HSL");
2631 case colorSpaceEnum::HSV : return std::string("HSV");
2632 case colorSpaceEnum::LAB : return std::string("Lab");
2633 case colorSpaceEnum::XYZ : return std::string("XYZ");
2634 case colorSpaceEnum::LCH : return std::string("Lch");
2635 default: return std::string("ERROR");
2636 }
2637 }
2638 //@}
2639
2640 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2641 /** @name Color Transformation Functions */
2642 //@{
2643 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2644 /** The Linear Grey Level Scale transform modifies the current color such that: C_n=c*C_n+b.
2645 This function transforms all channels --- not just RGBA.
2646 @param c The "contrast" value
2647 @param b The "brightness" value
2648 @return Returns a reference to the current color object.*/
2649 inline colorTpl& tfrmLinearGreyLevelScale(double c, double b) {
2650 for(int i=0; i<numChan; i++)
2651 setChanNC(i, static_cast<clrChanT>(c * static_cast<double>(getChanNC(i)) + b));
2652 return *this;
2653 }
2654 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2655 /** The Linear Grey Level Scale transform modifies the current color such that: R=rc*R+rb, G=gc*G+gb, B=bc*B+bb.
2656 This function ONLY transforms the red, green, and blue channels.
2657 @param rc The "contrast" value for red
2658 @param rb The "brightness" value for red
2659 @param gc The "contrast" value for green
2660 @param gb The "brightness" value for green
2661 @param bc The "contrast" value for blue
2662 @param bb The "brightness" value for blue
2663 @return Returns a reference to the current color object.*/
2664 inline colorTpl& tfrmLinearGreyLevelScaleRGB(double rc, double rb, double gc, double gb, double bc, double bb) {
2665 /* Requires: Inherits numChan>3 from setAlpha & getC3. */
2666 setRed( static_cast<clrChanT>(rc * static_cast<double>(getRed()) + rb));
2667 setGreen(static_cast<clrChanT>(gc * static_cast<double>(getGreen()) + gb));
2668 setBlue( static_cast<clrChanT>(bc * static_cast<double>(getBlue()) + bb));
2669 return *this;
2670 }
2671 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2672 /** Perform a tfrmLinearGreyLevelScale based on a complex number.
2673 @param z The complex number
2674 @param cutDepth Range: @f$[1, ~30]@f$ Smaller means more contrast on cuts.
2675 @param argCuts Number of grey cuts for arg
2676 @param absCuts Number of grey cuts for abs
2677 @param logAbs If true, then take the logorithm of abs for cuts. */
2678 inline colorTpl& tfrmComplexCut(std::complex<double> z, double cutDepth, double argCuts, double absCuts, bool logAbs = true) {
2679 double tau = std::numbers::pi * 2; // 2*Pi
2680 double zArg = std::arg(z); // Arg
2681 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
2682 if (argCuts > 0)
2683 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(pzArg*argCuts) - pzArg*argCuts)/cutDepth, 0);
2684 if (absCuts > 0) {
2685 double zAbs = std::abs(z); // Abs
2686 if (logAbs) {
2687 double lzAbs = std::log(zAbs);
2688 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(lzAbs*absCuts) - lzAbs*absCuts)/cutDepth, 0);
2689 } else {
2690 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(zAbs*absCuts) - zAbs*absCuts)/cutDepth, 0);
2691 }
2692 }
2693 return *this;
2694 }
2695 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2696 /** The Standard Power Transform modifies the current color such that: C_i = maxChanVal*(C_i / maxChanVal)**p.
2697 @return Returns a reference to the current color object.*/
2698 inline colorTpl& tfrmStdPow(double p) {
2699 for(int i=0; i<numChan; i++)
2700 setChanNC(i, static_cast<clrChanT>(std::pow(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal), p) * static_cast<double>(maxChanVal)));
2701 return *this;
2702 }
2703 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2704 /** The Standard Power Transform modifies the current color such that:
2705 R=#maxChanVal*(R/#maxChanVal)**rp, B=#maxChanVal*(B/#maxChanVal)**gp, B=#maxChanVal*(B/#maxChanVal)**bp
2706 @return Returns a reference to the current color object.*/
2707 inline colorTpl& tfrmStdPowRGB(double rp, double gp, double bp) {
2708 /* Requires: Inherits numChan>2 from setBlue & getC2. */
2709 setRed( static_cast<clrChanT>(std::pow(static_cast<double>(getRed()) / static_cast<double>(maxChanVal), rp) * static_cast<double>(maxChanVal)));
2710 setGreen(static_cast<clrChanT>(std::pow(static_cast<double>(getGreen()) / static_cast<double>(maxChanVal), gp) * static_cast<double>(maxChanVal)));
2711 setBlue( static_cast<clrChanT>(std::pow(static_cast<double>(getBlue()) / static_cast<double>(maxChanVal), bp) * static_cast<double>(maxChanVal)));
2712 return *this;
2713 }
2714 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2715 /** The Standard Power Transform with p=2. The new color will be: C_i = C_i * C_i / maxChanVal == (C_i/maxChanVal)^2*maxChanVal
2716 This computation is done with integer math if clrChanT is integral.
2717 @return Returns a reference to the current color object.*/
2718 inline colorTpl& tfrmStdPowSqr(void) {
2719 for(int i=0; i<numChan; i++)
2720 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(getChanNC(i)) /
2721 static_cast<channelArithSPType>(maxChanVal)));
2722 return *this;
2723 }
2724 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2725 /** The Standard Power Transform with p=1/2. The new color will be: C_i = sqrt(C_i / maxChanVal) * maxChanVal
2726 @return Returns a reference to the current color object.*/
2727 inline colorTpl& tfrmStdPowSqrt(void) {
2728 for(int i=0; i<numChan; i++)
2729 setChanNC(i, static_cast<clrChanT>(std::sqrt(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal)) * static_cast<double>(maxChanVal)));
2730 return *this;
2731 }
2732 //@}
2733
2734 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2735 /** @name Mathematical Operations On Color(s)
2736 Members in this section produce non-color results. i.e. They consume the current, and possibly other colors and arguments, to produce a non-color
2737 result. */
2738 //@{
2739 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2740 /** Use the R, G, & B channels to compute a floating point value representing a grey scale.
2741 What is returned is the dot product of the given color and the three scalars: R*redWt+G*greenWt+B*blueWt.
2742 @param redWt The red weight
2743 @param greenWt The green weight
2744 @param blueWt The blue weight
2745 @return The integer representing grey value for the given color. */
2746 inline channelArithFltType rgb2GreyDotProd(channelArithFltType redWt = RGBluminanceWeightR,
2747 channelArithFltType greenWt = RGBluminanceWeightG,
2748 channelArithFltType blueWt = RGBluminanceWeightB) const {
2749 /* Requires: Inherits numChan>2 from getC2. */
2750 return (static_cast<channelArithFltType>(getRed()) * static_cast<channelArithFltType>(redWt) +
2751 static_cast<channelArithFltType>(getGreen()) * static_cast<channelArithFltType>(greenWt) +
2752 static_cast<channelArithFltType>(getBlue()) * static_cast<channelArithFltType>(blueWt));
2753 }
2754 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2755 /** Compute the luminance of the current color via the definition given in the ITU-R Recommendation BT.709.
2756 The output value will be between 0 and 1, and is given by: (RGBluminanceWeightR*R+RGBluminanceWeightG*G+RGBluminanceWeightB*B)/#maxChanVal.
2757 @return The luminance for the current object. */
2758 inline channelArithFltType luminanceRGB(void) const {
2759 /* Requires: Inherits numChan>2 from getC2. */
2760 return ((static_cast<channelArithFltType>(getRed()) * static_cast<channelArithFltType>(RGBluminanceWeightR) +
2761 static_cast<channelArithFltType>(getGreen()) * static_cast<channelArithFltType>(RGBluminanceWeightG) +
2762 static_cast<channelArithFltType>(getBlue()) * static_cast<channelArithFltType>(RGBluminanceWeightB)) / static_cast<channelArithFltType>(maxChanVal));
2763 }
2764 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2765 /** Compute the unscaled intensity (sum of the R, G, & B components) of the current color
2766 @return The unscaled intensity for the current object. */
2767 inline channelArithSPType intensityRGB(void) const {
2768 /* Requires: Inherits numChan>2 from getC2. */
2769 return static_cast<channelArithSPType>(static_cast<channelArithSPType>(getRed()) +
2770 static_cast<channelArithSPType>(getGreen()) +
2771 static_cast<channelArithSPType>(getC2()));
2772 }
2773 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2774 /** Compute the sum of the components.
2775 @return Sum of components. */
2776 inline channelArithSPType intensity() const {
2777 channelArithSPType sum = 0;
2778 for(int i=0; i<numChan; i++)
2779 sum += getChan(i);
2780 return (sum);
2781 }
2782 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2783 /** Compute the scaled intensity (sum of the first three components divided by the maximum intensity possible) of the current color
2784 @return The scaled intensity for the current object. */
2785 inline channelArithFltType intensityScaledRGB() const {
2786 return (static_cast<channelArithFltType>(intensityRGB()) / static_cast<channelArithFltType>(3) / static_cast<channelArithFltType>(maxChanVal));
2787 }
2788 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2789 /** Compute the scaled intensity (sum of the components divided by the maximum intensity possible) of the current color
2790 @return Sum of components. */
2791 inline channelArithFltType intensityScaled() const {
2792 return (static_cast<channelArithFltType>(intensity()) / static_cast<channelArithFltType>(numChan) / static_cast<channelArithFltType>(maxChanVal));
2793 }
2794 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2795 /** Returns the value of the largest component.
2796 @return The value of the largest color component currently stored.*/
2797 inline clrChanT getMaxC() const {
2798 /* Performance: I'm manually unrolling the loop and using direct calls to max functions because some compilers can't figure out how to optimize this code.
2799 At some point I expect the C++ reduce or max algorithms to be able to handle this case in an optimal way. Till then, we get this weird bit of
2800 code. */
2801 if constexpr (numChan == 1) { // 1 channel
2802 return getChanNC(0);
2803 } else if constexpr (numChan == 2) { // 2 channels
2804 return std::max(getChanNC(0), getChanNC(1));
2805 } else if constexpr (numChan == 3) { // 3 channels
2806 return mjr::math::odr::max3(getChanNC(0), getChanNC(1), getChanNC(2));
2807 } else if constexpr (numChan == 4) { // 4 channels
2808 return mjr::math::odr::max4(getChanNC(0), getChanNC(1), getChanNC(2), getChanNC(3));
2809 } else { // More than 3 channels
2810 clrChanT theMax = minChanVal;
2811 for(int i=0; i<numChan; i++)
2812 if(theMax < getChanNC(i))
2813 theMax = getChanNC(i);
2814 return theMax;
2815 }
2816 }
2817 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2818 /** Returns the value of the smallest component.
2819 @return The value of the smallest color component currently stored.*/
2820 inline clrChanT getMinC() const {
2821 if constexpr (numChan == 1) { // 1 channel
2822 return getChanNC(0);
2823 } else if constexpr (numChan == 2) { // 2 channels
2824 return std::min(getChanNC(0), getChanNC(1));
2825 } else if constexpr (numChan == 3) { // 3 channels
2826 return mjr::math::odr::min3(getChanNC(0), getChanNC(1), getChanNC(2));
2827 } else if constexpr (numChan == 4) { // 4 channels
2828 return mjr::math::odr::min4(getChanNC(0), getChanNC(1), getChanNC(2), getChanNC(3));
2829 } else {
2830 clrChanT theMin = maxChanVal;
2831 for(int i=0; i<numChan; i++)
2832 if(theMin > getChanNC(i))
2833 theMin = getChanNC(i);
2834 return theMin;
2835 }
2836 }
2837 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2838 /** Returns the value of the largest component from R, G, and B. This function is highly optimized.
2839 @return The value of the largest color component.*/
2840 inline clrChanT getMaxRGB() const { return mjr::math::odr::max3(getRed(), getGreen(), getBlue()); } /* Requires: Inherits numChan>2 from getC2. */
2841 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2842 /** Returns the value of the smallest component from R, G, and B. This function is highly optimized.
2843 @return The value of the smallest color component.*/
2844 inline clrChanT getMinRGB() const { return mjr::math::odr::min3(getRed(), getGreen(), getBlue()); } /* Requires: Inherits numChan>2 from getC2. */
2845 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2846 /** Compute the dot product between the current color and the given color. i.e. c1.r*c2.r+c1.g*c2.g+...
2847 @param aColor the given color
2848 @return Returns dot product.*/
2849 inline channelArithFltType dotProd(colorArgType aColor) const {
2850 channelArithFltType daProd = 0;
2851 for(int i=0; i<numChan; i++)
2852 daProd += static_cast<channelArithFltType>(static_cast<channelArithFltType>(getChanNC(i)) * static_cast<channelArithFltType>(aColor.getChanNC(i)));
2853 return daProd;
2854 }
2855 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2856 /** Distance between current color and given one (sum squares of channel differences -- Euclidean distance squared).
2857 @param aColor The given color
2858 @return Returns Distance */
2859 inline channelArithFltType distHypot(colorArgType aColor) const {
2860 channelArithFltType daDist = 0;
2861 for(int i=0; i<numChan; i++)
2862 daDist += (static_cast<channelArithFltType>((static_cast<channelArithFltType>(getChanNC(i)) - static_cast<channelArithFltType>(aColor.getChanNC(i))) *
2863 (static_cast<channelArithFltType>(getChanNC(i)) - static_cast<channelArithFltType>(aColor.getChanNC(i)))));
2864 return static_cast<channelArithFltType>(std::sqrt(daDist));
2865 }
2866 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2867 /** Distance between current color and given one (sum of absolute channel differences).
2868 @param aColor the given color
2869 @return Returns Distance */
2870 inline channelArithSPType distSumAbs(colorArgType aColor) const {
2871 channelArithSPType daDist = 0;
2872 for(int i=0; i<numChan; i++)
2873 daDist += static_cast<channelArithSPType>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))));
2874 return daDist;
2875 }
2876 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2877 /** Distance between current color and given one (maximum of absolute value of channel differences).
2878 @param aColor the given color
2879 @return Returns Distance */
2880 inline channelArithSPType distMaxAbs(colorArgType aColor) const {
2881 channelArithSPType daDist = 0;
2882 for(int i=0; i<numChan; i++) {
2883 channelArithSPType tmp = static_cast<channelArithSPType>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))));
2884 if (daDist < tmp)
2885 daDist = tmp;
2886 }
2887 return daDist;
2888 }
2889 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2890 /** LAB Delta E* distance between current color and given one.
2891 Note: The Delta E* 1976 distance measurement is inherently an RGB measurement in that the colors are converted to LAB* as part of the computation.
2892 @param aColor the given color
2893 @return Returns Distance -- note return is a double not a channelArithFltType. */
2894 inline double distDeltaE1976(colorArgType aColor) const {
2895 colConDbl3 acol1 = rgb2colorSpace(colorSpaceEnum::LAB);
2896 colConDbl3 acol2 = aColor.rgb2colorSpace(colorSpaceEnum::LAB);
2897 double daDist = 0;
2898 for (int c=0; c<3; c++)
2899 daDist += std::pow(acol1.getChanNC(c) - acol2.getChanNC(c), 2);
2900 daDist = std::sqrt(daDist);
2901 return daDist;
2902 }
2903 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2904 /** LAB Delta E* 1994 (graphic arts) distance between current color and given one.
2905 Note: The Delta E* 1994 distance measurement is inherently an RGB measurement in that the colors are converted to LAB* as part of the computation.
2906 Note: The Delta E* 1994 distance measurement is NOT symetric -- the 1976 one is!
2907 @param aColor the given color
2908 @return Returns Distance -- note return is a double not a channelArithFltType. */
2909 inline double distDeltaE1994(colorArgType aColor) const {
2910 colConDbl3 acol1 = rgb2colorSpace(colorSpaceEnum::LAB);
2911 colConDbl3 acol2 = aColor.rgb2colorSpace(colorSpaceEnum::LAB);
2912 double k1 = 0.045;
2913 double k2 = 0.015;
2914 double kL = 1.000;
2915 double kC = 1.000;
2916 double kH = 1.000;
2917 double sL = 1.000;
2918 double dL = acol1.getC0() - acol2.getC0();
2919 double da = acol1.getC1() - acol2.getC1();
2920 double db = acol1.getC2() - acol2.getC2();
2921 double c1 = std::sqrt(std::pow(acol1.getC1(), 2) + std::pow(acol1.getC2(), 2));
2922 double c2 = std::sqrt(std::pow(acol2.getC1(), 2) + std::pow(acol2.getC2(), 2));
2923 double sH = 1.000 + k2 * c1;
2924 double sC = 1.000 + k1 * c1;
2925 double dC = c2 - c2;
2926 double dH2 = std::pow(da, 2) + std::pow(db, 2) - std::pow(dC, 2);
2927 if (dH2 < 0.0)
2928 dH2 = 0.000;
2929 double dE = std::sqrt(std::pow(dL/kL/sL, 2) + std::pow(dC/kC/sC, 2) + dH2/std::pow(kH*sH, 2));
2930 return dE;
2931 }
2932 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2933 /** Returns non-zero if the current color is close to aColor (the maximum delta between any two channels is less than or equal to epsilon).
2934 Note the implications for floating point clrChanT.
2935 @return non-zero if the given color is logically the same as the current color*/
2936 inline bool isClose(colorArgType aColor, clrChanT epsilon) const {
2937 for(int i=0; i<numChan; i++)
2938 if (std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))) > epsilon)
2939 return false;
2940 return true;
2941 }
2942 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2943 /** Like isClose(), but only checks the R, G, & B channels.
2944 @return non-zero if the given RGB color is the same as the current color*/
2945 inline bool isCloseRGB(colorArgType aColor, clrChanT epsilon) const requires(blueChan >= 0) {
2946 for (int i : {redChan, blueChan, greenChan})
2947 if (std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))) > epsilon)
2948 return false;
2949 return true;
2950 }
2951 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2952 /** Returns non-zero if the current color is precicely equal to aColor.
2953 Note the implications for floating point clrChanT.
2954 @return non-zero if the given color is logically the same as the current color*/
2955 inline bool isEqual(colorArgType aColor) const {
2956 if constexpr (perfectMask)
2957 return (getMaskNC() == aColor.getMaskNC());
2958 else
2959 for(int i=0; i<numChan; i++)
2960 if(getChanNC(i) != aColor.getChanNC(i))
2961 return false;
2962 return true;
2963 }
2964 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2965 /** Like isEqual(), but only checks the R, G, & B channels.
2966 @return non-zero if the given RGB color is the same as the current color*/
2967 inline bool isEqualRGB(colorArgType aColor) const {
2968 /* Requires: Inherits RGB channel requirements from getRed/getGreen/getBlue. */
2969 return ((getRed() == aColor.getRed() ) &&
2970 (getGreen() == aColor.getGreen()) &&
2971 (getBlue() == aColor.getBlue()));
2972 }
2973 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2974 /** Returns non-zero if the given color is logically NOT the same as the current color.
2975 Note the implications for floating point clrChanT.
2976 @return non-zero if the given color is logically the same as the current color*/
2977 inline bool isNotEqual(colorArgType aColor) const { return !(isEqual(aColor)); }
2978 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2979 /** Returns non-zero if the given color is black (all componnets are zero)
2980 @return non-zero if the given color is black (all componnets are zero) */
2981 inline bool isBlack() {
2982 if constexpr (perfectMask)
2983 return (getMaskNC() == maskAllZero);
2984 else
2985 for(int i=0; i<numChan; i++)
2986 if(getChanNC(i) != 0)
2987 return false;
2988 return true;
2989 }
2990 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2991 /** LIke isBlack(), but only checks the R, G, & B channels
2992 @return non-zero if the given color is black (R, G, & B are are zero) */
2993 inline bool isBlackRGB() const { return ((getRed() == 0) && (getGreen() == 0) && (getBlue() == 0)); } /* Requires: Inherits RGB channel requirements from getRed/getGreen/getBlue. */
2994 //@}
2995
2996 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2997 /** @name Channel Clipping Functions */
2998 //@{
2999 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3000 /** Clamp a value to (infinity, maxChanVal].
3001 Input values larger than maxChanVal are mapped to maxChanVal. Values less than minChanVal are not changed.
3002 @param arithValue The value to clamp */
3003 template <typename iT>
3004 requires (std::same_as<iT, clrChanT> || std::same_as<iT, channelArithDType> || std::same_as<iT, channelArithSPType> || std::same_as<iT, channelArithSDPType> || std::same_as<iT, channelArithLogType>)
3005 inline clrChanT clampTop(iT arithValue) {
3006 if(arithValue > static_cast<iT>(maxChanVal))
3007 return static_cast<clrChanT>(maxChanVal);
3008 else
3009 return static_cast<clrChanT>(arithValue);
3010 }
3011 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3012 /** Clamp a value to [minChanVal, infinity).
3013 @param arithValue The value to clamp */
3014 template <typename iT>
3015 requires (std::same_as<iT, clrChanT> || std::same_as<iT, channelArithDType> || std::same_as<iT, channelArithSPType> || std::same_as<iT, channelArithSDPType> || std::same_as<iT, channelArithLogType>)
3016 inline clrChanT clampBot(iT arithValue) {
3017 if(arithValue < static_cast<iT>(minChanVal))
3018 return static_cast<clrChanT>(minChanVal);
3019 else
3020 return static_cast<clrChanT>(arithValue);
3021 }
3022 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3023 /** Clamp a value to [minChanVal, maxChanVal].
3024 @param arithValue The value to clamp */
3025 template <typename iT>
3026 requires (std::same_as<iT, clrChanT> || std::same_as<iT, channelArithDType> || std::same_as<iT, channelArithSPType> || std::same_as<iT, channelArithSDPType> || std::same_as<iT, channelArithLogType>)
3027 inline clrChanT clampAll(iT arithValue) {
3028 if (arithValue > static_cast<iT>(maxChanVal))
3029 return static_cast<clrChanT>(maxChanVal);
3030 else if(arithValue < static_cast<iT>(minChanVal))
3031 return static_cast<clrChanT>(minChanVal);
3032 else
3033 return static_cast<clrChanT>(arithValue);
3034 }
3035 //@}
3036
3037 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3038 /** @name Meta Color Schemes */
3039 //@{
3040 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3041#if !(MISSING_P1907R1)
3042 /** Compute a color from a polynomial space curve in the RGB color space. This is a continuous color scheme!
3043 @tparam coefs Polynomial coefficients*/
3044 template<double...coefs>
3046 public:
3047 /** Set given colorTpl instance to the selected color in the color scheme.
3048 @param aColor color object to set.
3049 @param csX A value in [0, 1] that identifies the color in the scheme.
3050 @return Returns a reference to \a aColor. */
3051 static inline colorTpl& c(colorRefType aColor, csFltType csX) {
3052 double pR = pcoff[0 * psize];
3053 double pG = pcoff[1 * psize];
3054 double pB = pcoff[2 * psize];
3055 for (unsigned int i=1; i<psize; i++) {
3056 pR = pR * csX + pcoff[i + 0 * psize];
3057 pG = pG * csX + pcoff[i + 1 * psize];
3058 pB = pB * csX + pcoff[i + 2 * psize];
3059 }
3060 return aColor.setChansRGB_dbl(std::clamp(pR, 0.0, 1.0), std::clamp(pG, 0.0, 1.0), std::clamp(pB, 0.0, 1.0));
3061 }
3062 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3063 @param csX A value in [0, 1] that identifies the color in the scheme.
3064 @return Returns a colorTpl value */
3065 static inline colorTpl c(csFltType csX) { colorTpl tmp; return c(tmp, csX); }
3066 private:
3067 constexpr static int psize = (sizeof...(coefs)) / 3;
3068 constexpr static double pcoff[] = { coefs... };
3069 };
3070#endif
3071#if !(MISSING_P1907R1)
3072 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3073 /** Compute a color from Dave Green's cubehelix scheme. See: Green, D. A., 2011, Bulletin of the Astronomical Society of India, Vol.39, p.289.
3074 This is a continous color scheme!
3075 @tparam start colour (1=red, 2=green, 3=blue; ex: 0.5=purple;
3076 @tparam rots Rotations in colour in [-1.5, 1.5]. ex: -1.0 is one blue->green->red cycle;
3077 @tparam hue Hue intensity scaling in [0, 1] (0 == greyscale).
3078 @tparam gamma Gamma correction for intensity. */
3079 template<double start, double rots, double hue, double gamma>
3081 public:
3082 /** Set given colorTpl instance to the selected color in the color scheme.
3083 @param aColor color object to set.
3084 @param csX A value in [0, 1] that identifies the color in the scheme.
3085 @return Returns a reference to \a aColor. */
3086 static inline colorTpl& c(colorRefType aColor, csFltType csX) {
3087 //csX=mjr::math::ivl::wrapCC(csX, 0.0, 1.0);
3088 double angle=2*std::numbers::pi*(start/3.0+1.0+rots*csX);
3089 csX=std::pow(csX, gamma);
3090 double ampl=hue*csX*(1-csX)/2.0;
3091 return aColor.setChansRGB_dbl(std::clamp(csX+ampl*(-0.14861*std::cos(angle)+1.78277*std::sin(angle)), 0.0, 1.0),
3092 std::clamp(csX+ampl*(-0.29227*std::cos(angle)-0.90649*std::sin(angle)), 0.0, 1.0),
3093 std::clamp(csX+ampl*(+1.97294*std::cos(angle)), 0.0, 1.0));
3094 }
3095 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3096 @param csX A value in [0, 1] that identifies the color in the scheme.
3097 @return Returns a colorTpl value */
3098 static inline colorTpl c(csFltType csX) { colorTpl tmp; return c(tmp, csX); }
3099 };
3100#endif
3101 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3102 /** Template for HSL color schemes.
3103 If clrChanT is integral, this is a discrete color scheme, otherwise it is continuous.. */
3104 template<cornerColorEnum corner>
3106 public:
3107 constexpr static csIntType numC = (chanIsInt ? meanChanVal : 0);
3108 /** Set given colorTpl instance to the selected color in the color scheme.
3109 @param aColor color object to set.
3110 @param csVal Index of color in pallet. Wrapped to [0, meanChanVal].
3111 @return Returns a reference to \a aColor. */
3112 static inline colorTpl& c(colorRefType aColor, csNatType csVal) {
3113 clrChanT cVal = static_cast<clrChanT>(mjr::math::ivl::wrapCC(csVal, meanChanVal));
3114 colorTpl cc(corner);
3115 return aColor.setChansRGB(static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getRed() ? cVal : -cVal)),
3116 static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getGreen() ? cVal : -cVal)),
3117 static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getBlue() ? cVal : -cVal)));
3118 }
3119 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3120 @param csVal Index of color in pallet. Wrapped to [0, meanChanVal].
3121 @return Returns a colorTpl value */
3122 static inline colorTpl c(csNatType csVal) { colorTpl tmp; return c(tmp, csVal); }
3123 };
3124 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3125 /** Template providing RGB color cube gradiant color schemes */
3126 template<cornerColorEnum...corners>
3127 class csCC_tpl {
3128 public:
3129 constexpr static csIntType numC = ((sizeof...(corners)) - 1) * chanStepMax + 1;
3130 /** Set given colorTpl instance to the selected color in the color scheme.
3131 @param aColor color object to set.
3132 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3133 @return Returns a reference to \a aColor. */
3134 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) {
3135 csFltType csX = static_cast<csFltType>(csG);
3136 return aColor.cmpRGBcornerCGradiant(csX, numA, cols);
3137 }
3138 /** Set given colorTpl instance to the selected color in the color scheme.
3139 @param aColor color object to set.
3140 @param csG Integer used to select a color from the discrete gradiaant.
3141 @return Returns a reference to \a aColor. */
3142 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) {
3143 csIntType csIdx = static_cast<csIntType>(csG);
3144 return aColor.cmpRGBcornerDGradiant(csIdx % numC, numA, cols);
3145 }
3146 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3147 @param csG color scheme selector
3148 @return Returns a colorTpl value */
3149 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) {
3150 colorTpl tmp;
3151 return c(tmp, csG);
3152 }
3153 private:
3154 constexpr static int numA = (sizeof...(corners));
3155 constexpr static cornerColorEnum cols[] = { corners... };
3156 };
3157 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3158 /** Binary color scheme. First color for even inputs and second color for odd. */
3159 template<cornerColorEnum a, cornerColorEnum b>
3161 public:
3162 constexpr static csIntType numC = 2;
3163 /** Set given colorTpl instance to the selected color in the color scheme.
3164 @param aColor color object to set.
3165 @param csIdx Index of color in pallet. Not wrapped or clipped. Even values get color \a a, while odd values get color \a b.
3166 @return Returns a reference to \a aColor. */
3167 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) { if (csIdx % 2) return aColor.setToCorner(b); else return aColor.setToCorner(a); }
3168 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3169 @param csIdx Index of color in pallet. Not wrapped or clipped. Even values get color \a a, while odd values get color \a b.
3170 @return Returns a colorTpl value */
3171 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3172 };
3173 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3174 /** Template for fixed size pallets. */
3175 template<uint32_t...colors>
3176 class csFP_tpl {
3177 public:
3178 constexpr static csIntType numC = (sizeof...(colors));
3179 /** Set given colorTpl instance to the selected color in the color scheme.
3180 @param aColor color object to set.
3181 @param csG Integer used to select a color from the discrete gradiaant.
3182 @return Returns a reference to \a aColor. */
3183 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) {
3184 csFltType csX = static_cast<csFltType>(csG);
3185 return aColor.cmpGradiant(mjr::math::ivl::wrapCC(csX, 1.0), numC, d);
3186 }
3187 /** Set given colorTpl instance to the selected color in the color scheme.
3188 @param aColor color object to set.
3189 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3190 @return Returns a reference to \a aColor. */
3191 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) {
3192 csIntType csIdx = static_cast<csIntType>(csG);
3193 return aColor.setRGBfromLogPackIntARGB(d[csIdx % numC]);
3194 }
3195 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3196 @param csG color scheme color selector
3197 @return Returns a colorTpl value */
3198 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) {
3199 colorTpl tmp;
3200 return c(tmp, csG);
3201 }
3202 private:
3203 constexpr static uint32_t d[] = { colors... };
3204 };
3205 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3206 /** Template for Color Brewer 2 variable sized pallets. */
3207 template<csIntType mx, uint32_t...colors>
3208 class csCB_tpl {
3209 public:
3210 constexpr static csIntType minNumC = 3;
3211 constexpr static csIntType maxNumC = mx;
3212 /** Set given colorTpl instance to the selected color in the color scheme.
3213 @param aColor color object to set.
3214 @param csG Integer used to select a color from the discrete gradiaant.
3215 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3216 @return Returns a reference to \a aColor. */
3217 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG, csIntType numC=maxNumC) requires (std::floating_point<saT>) {
3218 csFltType csX = static_cast<csFltType>(csG);
3219 csIntType b = std::clamp(numC, minNumC, maxNumC);
3220 return aColor.cmpGradiant(mjr::math::ivl::wrapCC(csX, 1.0), b, &d[b*(b-1)/2-3+0]);
3221 }
3222 /** Set given colorTpl instance to the selected color in the color scheme.
3223 @param aColor color object to set.
3224 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3225 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3226 @return Returns a reference to \a aColor. */
3227 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG, csIntType numC=maxNumC) requires (std::integral<saT>) {
3228 csIntType csIdx = static_cast<csIntType>(csG);
3229 csIntType b = std::clamp(numC, minNumC, maxNumC);
3230 csIntType i = csIdx % b;
3231 return aColor.setRGBfromLogPackIntARGB(d[b*(b-1)/2-3+i]);
3232 }
3233 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3234 @param csG color scheme color selector
3235 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3236 @return Returns a colorTpl value */
3237 template<typename saT> static inline colorTpl c(saT csG, csIntType numC=maxNumC) requires (std::integral<saT> || std::floating_point<saT>) {
3238 colorTpl tmp;
3239 return c(tmp, csG, numC);
3240 }
3241 private:
3242 constexpr static uint32_t d[] = { colors... };
3243 };
3244 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3245 /** Wrapper for Color Brewer 2 variable sized pallet template to produce a simple fixed color scheme with a numC member.
3246 @tparam varColorScheme A color brewer variable sized color scheme
3247 @tparam numClr The number of colors wanted in the fixed sized scheme.*/
3248 template<class varColorScheme, csIntType numClr>
3249 requires((varColorScheme::minNumC <= numClr) && (varColorScheme::maxNumC >= numClr))
3251 public:
3252 constexpr static csIntType numC = numClr;
3253 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) { return varColorScheme::c(aColor, csG, numClr); }
3254 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) { return varColorScheme::c(aColor, csG, numClr); }
3255 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) { return varColorScheme::c(csG, numC); }
3256 };
3257 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3258 /** Template for web safe 216 pallets. */
3259 template<uint32_t...colors>
3260 class csWS_tpl {
3261 public:
3262 constexpr static csIntType numC = (sizeof...(colors));
3263 /** Set given colorTpl instance to the selected color in the color scheme.
3264 @param aColor color object to set.
3265 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3266 @return Returns a reference to \a aColor. */
3267 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) { return aColor.setRGBfromLogPackIntARGB(d[csIdx % numC]); }
3268 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3269 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3270 @return Returns a reference a colorTpl value. */
3271 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3272 /** Set given colorTpl instance to the selected color in the color scheme.
3273 @param aColor color object to set.
3274 @param csCol input color to convert to a web safe color.
3275 @return Returns a reference to \a aColor. */
3276 static colorTpl& c(colorRefType aColor, colorRefType csCol) {
3277 aColor.copy(csCol);
3278 aColor.tfrmWebSafeRGB();
3279 int colIdx = 36 * (aColor.getRed_byte() / 0x33) + 6 * (aColor.getGreen_byte() / 0x33) + 1 * (aColor.getBlue_byte() / 0x33) + 1;
3280 return aColor.setRGBfromLogPackIntARGB(d[colIdx]);
3281 }
3282 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3283 @param csCol input color to convert to a web safe color.
3284 @return Returns a reference a colorTpl value. */
3285 static colorTpl c(colorRefType csCol) { colorTpl tmp; return c(tmp, csCol); }
3286 private:
3287 constexpr static uint32_t d[] = { colors... };
3288 };
3289 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3290 /** Template for Thaller 2D color schemes. */
3291 template<bool useHSL, bool maxV, double cutDepth, double argCuts, double absCuts, bool logAbs>
3292 requires( !(useHSL && maxV))
3294 public:
3295 /** Set given colorTpl instance to the selected color in the color scheme.
3296 @param aColor color object to set.
3297 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
3298 @param csY A value that, along with csX, identifies the color in the scheme.
3299 @return Returns a reference to \a aColor. */
3300 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
3301 double tau = std::numbers::pi * 2; // 2*Pi
3302 double zAbs = std::sqrt(csX*csX+csY*csY); // Abs
3303 double zArg = std::atan2(csY, csX); // Arg
3304 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
3305 double val = (maxV ? 1 : 4.0*std::atan(zAbs)/tau); // V for HSV
3306 if (useHSL)
3307 aColor.setRGBfromUnitHSL(pzArg, 1.0, val);
3308 else
3309 aColor.setRGBfromUnitHSV(pzArg, 1.0, val);
3310 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
3311 }
3312 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3313 @param csX A value that, along with csY, identifies the color in the scheme.
3314 @param csY A value that, along with csX, identifies the color in the scheme.
3315 @return Returns a colorTpl value */
3316 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
3317 /** Set given colorTpl instance to the selected color in the color scheme.
3318 @param aColor color object to set.
3319 @param csZ A value that identifies the color in the scheme.
3320 @return Returns a reference to \a aColor. */
3321 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
3322 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3323 @param csZ A value that identifies the color in the scheme.
3324 @return Returns a colorTpl value */
3325 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
3326 };
3327 //@}
3328
3329 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3330 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3331 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3332
3333 /** @cond color-schemes */
3334 /* Doxygen is pretty bad at formatting these bits... */
3335
3336 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3337 /** @defgroup cs Color Schemes */
3338
3339#if !(MISSING_P1907R1)
3340 //========================================================================================================================================================
3341 /** @name Color Schemes: Polynomial */
3342 //@{
3343 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3344 /*- @class csPLYgrey
3345 @ingroup cs
3346 @extends csPLY_tpl
3347 Greyscale */
3348 typedef csPLY_tpl<1.0, 0.0,
3349 1.0, 0.0,
3350 1.0, 0.0> csPLYgrey;
3351 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3352 /** @class csPLYquad
3353 @ingroup cs
3354 @extends csPLY_tpl
3355 Quadratic */
3356 typedef csPLY_tpl<1.0, 0.0, 0.0,
3357 1.0, 0.0, 0.0,
3358 1.0, 0.0, 0.0> csPLYquad;
3359 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3360 /** @class csPLYturbo
3361 @ingroup cs
3362 @extends csPLY_tpl
3363 Similar to the Google turbo colormap.
3364 Note this colormap is not identical to turbo, and lacks some of it's more sophisticated characteristics; however, it looks nice.
3365 See: https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html */
3366 typedef csPLY_tpl< 40703.92740, -218720.2701, 492368.2177, -590441.1804, 384271.9078, -101352.6555, -30425.81099,
3367 32619.05953, -10529.162296, 1625.5688083, -124.13217495, 4.867108400, 0.15787894011,
3368 20766.64723, -122258.4886, 315808.0723, -470687.9792, 447662.9929, -283594.9850, 121141.42864,
3369 -34482.96363, 6288.268231, -682.8118257, 37.74849512, 2.025549368, 0.06643490255,
3370 -94331.85477, 587011.8043, -1597312.2220, 2495306.9899, -2470958.0510, 1616523.3372, -706621.97816,
3371 204052.57726, -37536.525321, 4109.7062335, -257.68681737, 13.750387410, 0.16179522842> csPLYturbo;
3372 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3373 /** @class csPLYparula
3374 @ingroup cs
3375 @extends csPLY_tpl
3376 Similar to the Matlab parula colormap.
3377 Note this colormap is not identical to parula, and lacks some of it's more sophisticated characteristics; however, it looks nice.
3378 See: https://www.mathworks.com/help/matlab/ref/parula.html */
3379 typedef csPLY_tpl< 62043.87545, -399037.6523, 1122946.9120, -1812238.5254, 1846100.4184, -1230398.5816, 537273.93047,
3380 -149254.730651, 24535.019552, -2015.3894764, 44.825447931, 0.6772663755, 0.2018889435,
3381 -17121.77553, 108751.1007, -300422.7570, 473217.4661, -468061.6834, 301522.8593, -126770.41694,
3382 33776.781210, -5288.933402, 404.6316583, -7.800267203, 1.3431462881, 0.1677335602,
3383 -17004.66127, 100139.7442, -255248.5285, 366029.9549, -319570.5392, 169195.6211, -48015.67328,
3384 2478.369459, 2717.762128, -795.8032035, 72.119793045, 1.1497391882, 0.5347179324> csPLYparula;
3385 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3386 /** @class csPLYmagma
3387 @ingroup cs
3388 @extends csPLY_tpl
3389 Similar, but not identical, to the matplotlib magma colormap.
3390 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3391 typedef csPLY_tpl<746.7387907, -3433.588054, 6464.361262, -6369.328232, 3470.981211, -1010.528460, 141.7946515,
3392 -15.78575778, 6.066078845, 0.2765580349, 0.000406276347,
3393 885.3555317, -5488.721941, 14347.739660, -20613.711506, 17758.797775, -9380.063372, 2976.8215781,
3394 -529.56166374, 45.254936301, -0.9276250448, 0.006923020887,
3395 -3360.6362774, 17553.826465, -38851.355442, 47349.901018, -34548.072322, 15336.155184, -3997.3017542,
3396 548.12480687, -32.540585926, 2.6406562133, 0.006263758764> csPLYmagma;
3397 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3398 /** @class csPLYinferno
3399 @ingroup cs
3400 @extends csPLY_tpl
3401 Similar, but not identical, to the matplotlib inferno colormap.
3402 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3403 typedef csPLY_tpl<-19.63292067, 452.2107953, -1685.008066, 2775.510486, -2442.279827, 1181.312494, -280.5809421,
3404 10.74924866, 8.60430465, 0.1030211659, 0.002048171596,
3405 1970.76446015, -10379.8617699, 23277.924908, -28925.873437, 21688.815122, -10002.539645, 2763.0755166,
3406 -419.99828889, 28.92908793, -0.2365793129, 0.001175881895,
3407 2525.53763382, -12168.1567723, 24862.266312, -28273.600973, 19817.598983, -8983.810158, 2683.7805375,
3408 -515.72960422, 52.67809976, 0.0641022894, 0.024051180021> csPLYinferno;
3409 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3410 /** @class csPLYplasma
3411 @ingroup cs
3412 @extends csPLY_tpl
3413 Similar, but not identical, to the matplotlib plasma colormap.
3414 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3415 typedef csPLY_tpl<-43.8322257, 285.8375115, -806.7514473, 1301.765273, -1325.274751, 878.0715655, -374.7228293,
3416 98.20716947, -15.31425214, 2.899584724, 0.05309687850,
3417 1014.1378090, -5599.3136737, 13256.9879694, -17529.001879, 14102.556299, -7032.4501033, 2110.7323912,
3418 -350.31653834, 28.69509557, -1.086029536, 0.03452846048,
3419 -829.5844973, 4029.2020771, -8461.6295286, 10078.322085, -7471.246818, 3531.4365043, -1036.2596994,
3420 175.24253651, -17.51426724, 1.646647586, 0.52562476199> csPLYplasma;
3421 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3422 /** @class csPLYviridis
3423 @ingroup cs
3424 @extends csPLY_tpl
3425 Similar, but not identical, to the matplotlib viridis colormap.
3426 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3427 typedef csPLY_tpl<-5.432077171, 4.751786889, 6.203735901, -4.599931518, -0.32724109679, 0.1077083262, 0.274455424454,
3428 4.641571316, -13.749439404, 14.153964947, -5.758238189, 0.21481356454, 1.3964696839, 0.005767962397,
3429 26.272107604, -65.320967828, 56.656299565, -19.291808950, 0.09197688076, 1.3867705979, 0.332663881113> csPLYviridis;
3430 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3431 /** @class csPLYcividis
3432 @ingroup cs
3433 @extends csPLY_tpl
3434 Similar, but not identical, to the cividis colormap.
3435 Note this map dosen't have the flat red and sharp increase in blue at the start of the map.
3436 See: https://github.com/marcosci/cividis and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3437 typedef csPLY_tpl<-10.6296994279, 27.5479183452, -25.1086313881, 9.3401209056, -0.1385953043, -0.0177903167,
3438 -0.2641767638, 0.6924831686, -0.5155427716, 0.2071305342, 0.6695454456, 0.1273928107,
3439 9.7085048454, -25.9409393982, 24.1852720215, -9.7350011883, 1.7347333905, 0.3185822998> csPLYcividis;
3440 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3441 /** @class csPLYhsvRB
3442 @ingroup cs
3443 @extends csPLY_tpl
3444 Similar to csCColdeRainbow, but a little softer. */
3445 typedef csPLY_tpl<8.746561257e-11, 4.285714286, -4.285714286, 1.166666667e+00,
3446 1.200000000e+01, -21.000000000, 9.023809524, -2.161907281e-13,
3447 -1.200000000e+01, 15.000000000, -3.023809524, 2.380952381e-02> csPLYhsvRB;
3448 //@}
3449#endif
3450
3451#if !(MISSING_P1907R1)
3452 //========================================================================================================================================================
3453 /** @name Color Schemes: CubeHelix */
3454 //@{
3455 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3456 /** @class csCHstd
3457 @ingroup cs
3458 @extends csCubeHelix_tpl
3459 The "standard" cubehelix color scheme with start=0.5, rots=-1.5, hue=1, and gamma=1. */
3460 typedef csCubeHelix_tpl<0.5, -1.5, 1.0, 1.0> csCHstd;
3461 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3462 /** @class csCHblu
3463 @ingroup cs
3464 @extends csCubeHelix_tpl
3465 The "blues" cubehelix color scheme with start=0.5, rots=-0.5, hue=1, and gamma=1. */
3466 typedef csCubeHelix_tpl<0.5, -0.5, 1.0, 1.0> csCHblu;
3467 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3468 /** @class csCHvio
3469 @ingroup cs
3470 @extends csCubeHelix_tpl
3471 The "violets" cubehelix color scheme with start=0.5, rots=0.0, hue=1, and gamma=1. */
3472 typedef csCubeHelix_tpl<0.5, 0.0, 1.0, 1.0> csCHvio;
3473 //@}
3474#endif
3475
3476 //========================================================================================================================================================
3477 /** @name Color Schemes: White In Center Circular Gradients */
3478 //@{
3479 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3480 /** @class csCCwicR
3481 @ingroup cs
3482 @extends csCC_tpl
3483 Color cycle starting and ending with red with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3484 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::WHITE, cornerColorEnum::RED> csCCwicR;
3485 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3486 /** @class csCCwicG
3487 @ingroup cs
3488 @extends csCC_tpl
3489 Color cycle starting and ending with green with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3490 typedef csCC_tpl<cornerColorEnum::GREEN, cornerColorEnum::WHITE, cornerColorEnum::GREEN> csCCwicG;
3491 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3492 /** @class csCCwicB
3493 @ingroup cs
3494 @extends csCC_tpl
3495 Color cycle starting and ending with blue with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3496 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::WHITE, cornerColorEnum::BLUE> csCCwicB;
3497 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3498 /** @class csCCwicM
3499 @ingroup cs
3500 @extends csCC_tpl
3501 Color cycle starting and ending with magenta with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3502 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::WHITE, cornerColorEnum::MAGENTA> csCCwicM;
3503 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3504 /** @class csCCwicY
3505 @ingroup cs
3506 @extends csCC_tpl
3507 Color cycle starting and ending with yellow with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3508 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::WHITE, cornerColorEnum::YELLOW> csCCwicY;
3509 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3510 /** @class csCCwicC
3511 @ingroup cs
3512 @extends csCC_tpl
3513 Color cycle starting and ending with cyan with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3514 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::WHITE, cornerColorEnum::CYAN> csCCwicC;
3515 //@}
3516
3517 //========================================================================================================================================================
3518 /** @name Color Schemes: RGB Constant Brightness Ramps */
3519 //@{
3520 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3521 /** @class csCCconsTwo
3522 @ingroup cs
3523 @extends csCC_tpl
3524 Color cycle around the cube with constant brightness of two. Provides (mjr::colorTpl::chanStepMax*3+1) unique colors. */
3525 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csCCconsTwo;
3526 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3527 /** @class csCCconsOne
3528 @ingroup cs
3529 @extends csCC_tpl
3530 Color cycle around the cube with constant brightness of one. Provides (mjr::colorTpl::chanStepMax*3+1) unique colors. */
3531 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::RED, cornerColorEnum::GREEN, cornerColorEnum::BLUE> csCCconsOne;
3532 //@}
3533
3534 //========================================================================================================================================================
3535 /** @name Color Schemes: Start and end with a primary with the secondary mixed from the primaries in the middle. */
3536 //@{
3537 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3538 /** @class csCCmixRYG
3539 @ingroup cs
3540 @extends csCC_tpl
3541 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3542 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::GREEN> csCCmixRYG;
3543 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3544 /** @class csCCmixRMB
3545 @ingroup cs
3546 @extends csCC_tpl
3547 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3548 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::MAGENTA, cornerColorEnum::BLUE> csCCmixRMB;
3549 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3550 /** @class csCCmixGCB
3551 @ingroup cs
3552 @extends csCC_tpl
3553 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3554 typedef csCC_tpl<cornerColorEnum::GREEN, cornerColorEnum::CYAN, cornerColorEnum::BLUE> csCCmixGCB;
3555 //@}
3556
3557 //========================================================================================================================================================
3558 /** @name Color Schemes: RGB Divergent Ramps */
3559 //@{
3560 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3561 /** @class csCCdivBWR
3562 @ingroup cs
3563 @extends csCC_tpl
3564 Divergent color scheme with blue on one end and red on the other -- white in the middle. Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3565 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::WHITE, cornerColorEnum::RED> csCCdivBWR;
3566 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3567 /** @class csCCdivCWM
3568 @ingroup cs
3569 @extends csCC_tpl
3570 Divergent color scheme with cyan on one end and magenta on the other -- white in the middle. Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3571 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::WHITE, cornerColorEnum::MAGENTA> csCCdivCWM;
3572 //@}
3573
3574 //========================================================================================================================================================
3575 /** @name Color Schemes: RGB Cube Diagional Ramps */
3576 //@{
3577 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3578 /** @class csCCdiag01
3579 @ingroup cs
3580 @extends csCC_tpl
3581 Gradient across the diagonal of the RGB color cube from black to white. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3582 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csCCdiag01;
3583 /** @class csCCdiag10
3584 @ingroup cs
3585 @extends csCC_tpl
3586 Gradient across the diagonal of the RGB color cube from white to black. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3587 typedef csCC_tpl<cornerColorEnum::WHITE, cornerColorEnum::BLACK> csCCdiag10;
3588 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3589 /** @class csCCdiagCR
3590 @ingroup cs
3591 @extends csCC_tpl
3592 Gradient across the diagonal of the RGB color cube from cyan to red. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3593 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::RED> csCCdiagCR;
3594 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3595 /** @class csCCdiagMG
3596 @ingroup cs
3597 @extends csCC_tpl
3598 Gradient across the diagonal of the RGB color cube from magenta to green. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3599 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::GREEN> csCCdiagMG;
3600 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3601 /** @class csCCdiagYB
3602 @ingroup cs
3603 @extends csCC_tpl
3604 Gradient across the diagonal of the RGB color cube from yellow to blue. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3605 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::BLUE> csCCdiagYB;
3606 //@}
3607
3608 //========================================================================================================================================================
3609 /** @name Color Schemes: Classic RGB Ramps */
3610 //@{
3611 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3612 /** @class csCColdeFireRamp
3613 @ingroup cs
3614 @extends csCC_tpl
3615 Classic color cube "Fire Ramp". */
3616 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCColdeFireRamp;
3617 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3618 /** @class csCColdeColdToHot
3619 @ingroup cs
3620 @extends csCC_tpl
3621 Classical cold to hot color cube ramp. Provides (mjr::colorTpl::chanStepMax*4+1) unique colors. */
3622 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::GREEN,
3623 cornerColorEnum::YELLOW, cornerColorEnum::RED> csCColdeColdToHot;
3624 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3625 /** @class csCColdeIceToWaterToHot
3626 @ingroup cs
3627 @extends csCC_tpl
3628 Modified version of the classical cold to hot color cube ramp.ramp. It starts at white (ice), moves up to blue (cold),
3629 then yellow through red (hot). Provides (mjr::colorTpl::chanStepMax*4+1) unique colors. */
3630 typedef csCC_tpl<cornerColorEnum::WHITE, cornerColorEnum::CYAN, cornerColorEnum::BLUE,
3631 cornerColorEnum::YELLOW, cornerColorEnum::RED> csCColdeIceToWaterToHot;
3632 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3633 /** @class csCColdeRainbow
3634 @ingroup cs
3635 @extends csCC_tpl
3636 The classic HSV rainbow color scheme based upon an edge traversal of the RGB color cube. Provides (6 * mjr::colorTpl::chanStepMax + 1) colors. */
3637 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::GREEN, cornerColorEnum::CYAN,
3638 cornerColorEnum::BLUE, cornerColorEnum::MAGENTA, cornerColorEnum::RED> csCColdeRainbow;
3639 //@}
3640
3641 //========================================================================================================================================================
3642 /** @name Color Schemes: Classic Fractal RGB Gradients.
3643 Gradients frequently used to color fractal images. */
3644 //@{
3645 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3646 /** @class csCCfractal0RYBCW
3647 @ingroup cs
3648 @extends csCC_tpl
3649 Provides (5 * mjr::colorTpl::chanStepMax + 1) colors. */
3650 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW,
3651 cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCfractal0RYBCW;
3652 /** @class csCCfractalYR
3653 @ingroup cs
3654 @extends csCC_tpl
3655 Provides (mjr::colorTpl::chanStepMax + 1) colors. */
3656 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::RED> csCCfractalYR;
3657 /** @class csCCfractalYB
3658 @ingroup cs
3659 @extends csCC_tpl
3660 Provides (mjr::colorTpl::chanStepMax + 1) colors. */
3661 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::BLUE> csCCfractalYB;
3662 //@}
3663
3664 //========================================================================================================================================================
3665 /** @name Color Schemes: RGB Sum Ramps */
3666 //@{
3667 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3668 /** @class csCCsumRGB
3669 @ingroup cs
3670 @extends csCC_tpl
3671 RGB cube sum-ramp: RGB == Black -> Red -> Yellow -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3672 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCCsumRGB;
3673 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3674 /** @class csCCsumBGR
3675 @ingroup cs
3676 @extends csCC_tpl
3677 RGB cube sum-ramp: BGR == Black -> Blue -> cyan -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3678 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCsumBGR;
3679 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3680 /** @class csCCsumGRB
3681 @ingroup cs
3682 @extends csCC_tpl
3683 RGB cube sum-ramp: GRB == Black -> Green -> yellow -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3684 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCCsumGRB;
3685 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3686 /** @class csCCsumGBR
3687 @ingroup cs
3688 @extends csCC_tpl
3689 RGB cube sum-ramp: GBR == Black -> Green -> cyan -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3690 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCsumGBR;
3691 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3692 /** @class csCCsumBRG
3693 @ingroup cs
3694 @extends csCC_tpl
3695 RGB cube sum-ramp: BRG == Black -> Blue -> magenta -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3696 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE, cornerColorEnum::MAGENTA, cornerColorEnum::WHITE> csCCsumBRG;
3697 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3698 /** @class csCCsumRBG
3699 @ingroup cs
3700 @extends csCC_tpl
3701 RGB cube sum-ramp: RBG Black -> Red -> Magenta -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3702 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::MAGENTA, cornerColorEnum::WHITE> csCCsumRBG;
3703 //@}
3704
3705 //========================================================================================================================================================
3706 /** @name Color Schemes: RGB Up-Down Ramps */
3707 //@{
3708 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3709 /** @class csCCudRg
3710 @ingroup cs
3711 @extends csCC_tpl
3712 RGB Up-Down Ramp: Rg == Red Up and Green Down == cyan -> magenta. Provides chanStepMax different colors.*/
3713 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::MAGENTA> csCCudRg;
3714 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3715 /** @class csCCudRb
3716 @ingroup cs
3717 @extends csCC_tpl
3718 RGB Up-Down Ramp: Rb == Red Up and Blue Down == cyan -> yellow. Provides chanStepMax different colors.*/
3719 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::YELLOW> csCCudRb;
3720 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3721 /** @class csCCudGr
3722 @ingroup cs
3723 @extends csCC_tpl
3724 RGB Up-Down Ramp: Gr == Green Up and Red Down == magenta -> cyan. Provides chanStepMax different colors. */
3725 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::CYAN> csCCudGr;
3726 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3727 /** @class csCCudGb
3728 @ingroup cs
3729 @extends csCC_tpl
3730 RGB Up-Down Ramp: Gb == Green Up and Blue Down == magenta -> yellow. Provides chanStepMax different colors. */
3731 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW> csCCudGb;
3732 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3733 /** @class csCCudBr
3734 @ingroup cs
3735 @extends csCC_tpl
3736 RGB Up-Down Ramp: Br == Blue Up and Red Down == yellow -> cyan. Provides chanStepMax different colors. */
3737 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csCCudBr;
3738 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3739 /** @class csCCudBg
3740 @ingroup cs
3741 @extends csCC_tpl
3742 RGB Up-Down Ramp: Bg == Blue Up and Green Down == yellow -> magenta. Provides chanStepMax different colors. */
3743 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::MAGENTA> csCCudBg;
3744 //@}
3745
3746 //========================================================================================================================================================
3747 /** @name Color Schemes: Ramp from black to corner */
3748 //@{
3749 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csCCu0W; //!< Ramp from black to white
3750 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED> csCCu0R; //!< Ramp from black to red
3751 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE> csCCu0B; //!< Ramp from black to blue
3752 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN> csCCu0G; //!< Ramp from black to green
3753 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::CYAN> csCCu0C; //!< Ramp from black to cyan
3754 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::MAGENTA> csCCu0M; //!< Ramp from black to magenta
3755 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::YELLOW> csCCu0Y; //!< Ramp from black to yellow
3756 //@}
3757
3758 //========================================================================================================================================================
3759 /** @name Color Schemes: Binary */
3760 //@{
3761 typedef csBin_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csBin01; //!< Binary Black-White color scheme. First color for even inputs and second color for odd.
3762 typedef csBin_tpl<cornerColorEnum::GREEN, cornerColorEnum::BLUE> csBinGB; //!< Binary Green-Blue color scheme. First color for even inputs and second color for odd.
3763 typedef csBin_tpl<cornerColorEnum::RED, cornerColorEnum::BLUE> csBinRB; //!< Binary Red-Blue color scheme. First color for even inputs and second color for odd.
3764 typedef csBin_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::CYAN> csBinMC; //!< Binary Magenta-Cyan color scheme. First color for even inputs and second color for odd.
3765 typedef csBin_tpl<cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csBinYC; //!< Binary Yellow-Cyan color scheme. First color for even inputs and second color for odd.
3766 typedef csBin_tpl<cornerColorEnum::RED, cornerColorEnum::GREEN> csBinRG; //!< Binary Red-Green color scheme. First color for even inputs and second color for odd.
3767 typedef csBin_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW> csBinMY; //!< Binary Magenta-Yellow color scheme. First color for even inputs and second color for odd.
3768 //@}
3769
3770 //========================================================================================================================================================
3771 /** @name Color Schemes: Pseudo-Grey
3772 These color schemes start with black and move toward white trying to increase perceptional brightness, they don't stay precisely on the diagonal. */
3773 //@{
3774 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3775 /** @class csPGrey3x
3776 @ingroup cs
3777 A Pseudo-Grey color scheme with 3 * mjr::colorTpl::chanStepMax colors. */
3778 class csPGrey3x {
3779 public:
3780 constexpr static csIntType numC = 3*chanStepMax;
3781 /** Set given colorTpl instance to the selected color in the color scheme.
3782 @param aColor color object to set.
3783 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3784 @return Returns a reference to \a aColor. */
3785 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) {
3786 csIdx = csIdx % numC;
3787 return aColor.setChansRGB(static_cast<clrChanT>(csIdx / 3 + (csIdx%3==0?1:0)),
3788 static_cast<clrChanT>(csIdx / 3 + (csIdx%3==1?1:0)),
3789 static_cast<clrChanT>(csIdx / 3 + (csIdx%3==2?1:0)));
3790 }
3791 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3792 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3793 @return Returns a colorTpl value */
3794 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3795 };
3796 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3797 /** @class csPGrey4x
3798 @ingroup cs
3799 A Pseudo-Grey color scheme with 4 * mjr::colorTpl::chanStepMax colors. */
3800 class csPGrey4x {
3801 public:
3802 constexpr static csIntType numC = 4*chanStepMax;
3803 /** Set given colorTpl instance to the selected color in the color scheme.
3804 @param aColor color object to set.
3805 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3806 @return Returns a reference to \a aColor. */
3807 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) {
3808 csIdx = csIdx % numC;
3809 return aColor.setChansRGB(static_cast<clrChanT>(csIdx / 4 + ((csIdx+1)%4==0?1:0)),
3810 static_cast<clrChanT>(csIdx / 4 + ((csIdx+2)%4==0?1:0)),
3811 static_cast<clrChanT>(csIdx / 4 + ((csIdx+3)%4==0?1:0)));
3812 }
3813 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3814 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3815 @return Returns a colorTpl value */
3816 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3817 };
3818 //@}
3819
3820 //========================================================================================================================================================
3821 /** @name Color Schemes: HSL Saturation Ramps */
3822 //@{
3823 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3824 /** @class csHSLhR
3825 @ingroup cs
3826 @extends csHSLh_tpl
3827 HSL color scheme extending from the center of the HSL color space to the red vertex.
3828 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3829 typedef csHSLh_tpl<cornerColorEnum::RED> csHSLhR;
3830 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3831 /** @class csHSLhG
3832 @ingroup cs
3833 @extends csHSLh_tpl
3834 HSL color scheme extending from the center of the HSL color space to the green vertex.
3835 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3836 typedef csHSLh_tpl<cornerColorEnum::GREEN> csHSLhG;
3837 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3838 /** @class csHSLhB
3839 @ingroup cs
3840 @extends csHSLh_tpl
3841 HSL color scheme extending from the center of the HSL color space to the blue vertex.
3842 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3843 typedef csHSLh_tpl<cornerColorEnum::BLUE> csHSLhB;
3844 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3845 /** @class csHSLhC
3846 @ingroup cs
3847 @extends csHSLh_tpl
3848 HSL color scheme extending from the center of the HSL color space to the cyan vertex.
3849 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3850 typedef csHSLh_tpl<cornerColorEnum::CYAN> csHSLhC;
3851 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3852 /** @class csHSLhM
3853 @ingroup cs
3854 @extends csHSLh_tpl
3855 HSL color scheme extending from the center of the HSL color space to the magenta vertex.
3856 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3857 typedef csHSLh_tpl<cornerColorEnum::MAGENTA> csHSLhM;
3858 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3859 /** @class csHSLhY
3860 @ingroup cs
3861 @extends csHSLh_tpl
3862 HSL color scheme extending from the center of the HSL color space to the yellow vertex.
3863 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3864 typedef csHSLh_tpl<cornerColorEnum::YELLOW> csHSLhY;
3865 //@}
3866
3867 //========================================================================================================================================================
3868 /** @name Color Schemes: Rainbows */
3869 //@{
3870 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3871 /** @class csRainbowLA
3872 @ingroup cs
3873 Computes a color value based upon a linear approximation of the color match functions used to approximate wavelength to RGB conversion.
3874 The linear color function approximation is not very accurate, but it is quite attractive. */
3875 class csRainbowLA {
3876 public:
3877 /** Set given colorTpl instance to the selected color in the color scheme.
3878 @param aColor color object to set.
3879 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3880 @param numC Number of colors to provide
3881 @return Returns a reference to \a aColor. */
3882 static inline colorTpl& c(colorRefType aColor, csIntType csIdx, csIntType numC) {
3883 csIdx = mjr::math::ivl::wrapCC(csIdx, numC);
3884 return aColor.setRGBfromWavelengthLA(mjr::math::linm::gen_map(static_cast<double>(csIdx),
3885 static_cast<double>(0),
3886 static_cast<double>(numC),
3887 static_cast<double>(minWavelength),
3888 static_cast<double>(maxWavelength)));
3889 }
3890 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3891 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3892 @param numC Number of colors to provide
3893 @return Returns a reference a colorTpl value. */
3894 static inline colorTpl c(csIntType csIdx, csIntType numC) {
3895 colorTpl tmp;
3896 return c(tmp, numC, csIdx);
3897 }
3898 };
3899 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3900 /** @class csRainbowCM
3901 @ingroup cs
3902 Computes a color value based upon an algorithm to convert wavelength to RGB that uses the Color Matching functions.
3903 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum) */
3904 class csRainbowCM {
3905 public:
3906 /** Set given colorTpl instance to the selected color in the color scheme.
3907 @param aColor color object to set.
3908 @param numC Number of colors to provide.
3909 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3910 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
3911 @return Returns a reference to \a aColor. */
3912 static inline colorTpl& c(colorRefType aColor, csIntType csIdx, csIntType numC, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
3913 csIdx = mjr::math::ivl::wrapCC(csIdx, numC);
3914 return aColor.setRGBfromWavelengthCM(mjr::math::linm::gen_map(static_cast<double>(csIdx),
3915 static_cast<double>(0),
3916 static_cast<double>(numC),
3917 static_cast<double>(minWavelength),
3918 static_cast<double>(maxWavelength)),
3919 interpMethod);
3920 }
3921 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3922 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3923 @param numC Number of colors to provide.
3924 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
3925 @return Returns a reference a colorTpl value. */
3926 static inline colorTpl c(csIntType csIdx, csIntType numC, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
3927 colorTpl tmp;
3928 return c(tmp, numC, csIdx, interpMethod);
3929 }
3930 };
3931 //@}
3932
3933 //========================================================================================================================================================
3934 /** @name "Web Safe" Color Schemes */
3935 //@{
3936 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3937 /** @class csWSnormalVision
3938 @ingroup cs
3939 @extends csWS_tpl
3940 The "web safe" color pallet of 216 colors as seen by someone with normal color vision.
3941 These colors were originally designed for low color web browsers in the early days of the internet. Today they provide a simple (easy to compute)
3942 pallet for color reduction. The colors are ordered in lexicographical ordering based upon the hexadecimal web-based color name scheme "#RRGGBB" --
3943 0 maps to "#000000", and 215 maps to "#ffffff". Note that one can transform an rgb color into the nearest web safe color via tfrmWebSafeRGB(). */
3944 typedef csWS_tpl<0x000000, 0x000033, 0x000066, 0x000099, 0x0000CC, 0x0000FF, 0x003300, 0x003333, 0x003366, 0x003399, 0x0033CC,
3945 0x0033FF, 0x006600, 0x006633, 0x006666, 0x006699, 0x0066CC, 0x0066FF, 0x009900, 0x009933, 0x009966, 0x009999,
3946 0x0099CC, 0x0099FF, 0x00CC00, 0x00CC33, 0x00CC66, 0x00CC99, 0x00CCCC, 0x00CCFF, 0x00FF00, 0x00FF33, 0x00FF66,
3947 0x00FF99, 0x00FFCC, 0x00FFFF, 0x330000, 0x330033, 0x330066, 0x330099, 0x3300CC, 0x3300FF, 0x333300, 0x333333,
3948 0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336600, 0x336633, 0x336666, 0x336699, 0x3366CC, 0x3366FF, 0x339900,
3949 0x339933, 0x339966, 0x339999, 0x3399CC, 0x3399FF, 0x33CC00, 0x33CC33, 0x33CC66, 0x33CC99, 0x33CCCC, 0x33CCFF,
3950 0x33FF00, 0x33FF33, 0x33FF66, 0x33FF99, 0x33FFCC, 0x33FFFF, 0x660000, 0x660033, 0x660066, 0x660099, 0x6600CC,
3951 0x6600FF, 0x663300, 0x663333, 0x663366, 0x663399, 0x6633CC, 0x6633FF, 0x666600, 0x666633, 0x666666, 0x666699,
3952 0x6666CC, 0x6666FF, 0x669900, 0x669933, 0x669966, 0x669999, 0x6699CC, 0x6699FF, 0x66CC00, 0x66CC33, 0x66CC66,
3953 0x66CC99, 0x66CCCC, 0x66CCFF, 0x66FF00, 0x66FF33, 0x66FF66, 0x66FF99, 0x66FFCC, 0x66FFFF, 0x990000, 0x990033,
3954 0x990066, 0x990099, 0x9900CC, 0x9900FF, 0x993300, 0x993333, 0x993366, 0x993399, 0x9933CC, 0x9933FF, 0x996600,
3955 0x996633, 0x996666, 0x996699, 0x9966CC, 0x9966FF, 0x999900, 0x999933, 0x999966, 0x999999, 0x9999CC, 0x9999FF,
3956 0x99CC00, 0x99CC33, 0x99CC66, 0x99CC99, 0x99CCCC, 0x99CCFF, 0x99FF00, 0x99FF33, 0x99FF66, 0x99FF99, 0x99FFCC,
3957 0x99FFFF, 0xCC0000, 0xCC0033, 0xCC0066, 0xCC0099, 0xCC00CC, 0xCC00FF, 0xCC3300, 0xCC3333, 0xCC3366, 0xCC3399,
3958 0xCC33CC, 0xCC33FF, 0xCC6600, 0xCC6633, 0xCC6666, 0xCC6699, 0xCC66CC, 0xCC66FF, 0xCC9900, 0xCC9933, 0xCC9966,
3959 0xCC9999, 0xCC99CC, 0xCC99FF, 0xCCCC00, 0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCCC, 0xCCCCFF, 0xCCFF00, 0xCCFF33,
3960 0xCCFF66, 0xCCFF99, 0xCCFFCC, 0xCCFFFF, 0xFF0000, 0xFF0033, 0xFF0066, 0xFF0099, 0xFF00CC, 0xFF00FF, 0xFF3300,
3961 0xFF3333, 0xFF3366, 0xFF3399, 0xFF33CC, 0xFF33FF, 0xFF6600, 0xFF6633, 0xFF6666, 0xFF6699, 0xFF66CC, 0xFF66FF,
3962 0xFF9900, 0xFF9933, 0xFF9966, 0xFF9999, 0xFF99CC, 0xFF99FF, 0xFFCC00, 0xFFCC33, 0xFFCC66, 0xFFCC99, 0xFFCCCC,
3963 0xFFCCFF, 0xFFFF00, 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFFFFFF> csWSnormalVision;
3964 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3965 /** @class csWSprotanopia
3966 @ingroup cs
3967 @extends csWS_tpl
3968 The "web safe" color pallet of 216 colors as seen by someone with Protanopia.
3969 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSprotanopiaAlt. */
3970 typedef csWS_tpl<0x000000, 0x002346, 0x004487, 0x0060C1, 0x0078F0, 0x719CFF, 0x312C00, 0x2E2E30, 0x0D3366, 0x0053A6,
3971 0x006FDE, 0x5B91FF, 0x635800, 0x61592E, 0x5C5B5F, 0x4E5F93, 0x1A66CC, 0x007EFE, 0x948500, 0x93852D, 0x90865E,
3972 0x8A898F, 0x7E8DC2, 0x6792F8, 0xC5B000, 0xC5B12B, 0xC3B25D, 0xBFB38D, 0xB8B6BF, 0xADBAF2, 0xF6DC00, 0xF6DD29,
3973 0xF5DD5C, 0xF2DF8C, 0xEDE1BD, 0xE6E4EE, 0x1E1B08, 0x002448, 0x00468B, 0x0062C4, 0x0079F2, 0x739DFF, 0x373200,
3974 0x343333, 0x19376A, 0x0054AA, 0x0070E1, 0x6094FF, 0x655B00, 0x645B2F, 0x5E5D61, 0x506195, 0x2067CD, 0x2581FF,
3975 0x958600, 0x95862E, 0x92875E, 0x8C8A90, 0x7F8EC3, 0x6993FA, 0xC6B100, 0xC6B22C, 0xC4B25D, 0xC0B48E, 0xB9B7BF,
3976 0xAEBBF2, 0xF7DD00, 0xF7DD29, 0xF5DE5C, 0xF3DF8C, 0xEEE2BD, 0xE7E5EF, 0x3C360F, 0x323748, 0x00478E, 0x0065CA,
3977 0x007CF8, 0x7AA1FF, 0x4A420B, 0x46433A, 0x324676, 0x0059B4, 0x0074EA, 0x6E9AFF, 0x6F6300, 0x6D6432, 0x686666,
3978 0x59699C, 0x326ED5, 0x518DFF, 0x9B8B00, 0x9B8B2F, 0x988C61, 0x918F93, 0x8593C7, 0x6E98FE, 0xCAB500, 0xCAB52D,
3979 0xC8B65E, 0xC4B88F, 0xBDBBC1, 0xB2BEF5, 0xFAE000, 0xFAE02A, 0xF8E15D, 0xF6E28D, 0xF1E4BF, 0xEAE7F0, 0x5A5117,
3980 0x55514A, 0x39538F, 0x0067D0, 0x2782FF, 0x83A6FF, 0x635913, 0x5F5941, 0x505B80, 0x005EBF, 0x007AF6, 0x7DA2FF,
3981 0x7F720D, 0x7E7237, 0x78746D, 0x6A77A5, 0x497BDF, 0x709BFF, 0xA69500, 0xA59532, 0xA29665, 0x9B9899, 0x8F9CCE,
3982 0x83A4FF, 0xD2BC00, 0xD1BC2F, 0xCFBD61, 0xCBBF93, 0xC4C1C6, 0xB9C5FA, 0xFFE41C, 0xFFE532, 0xFEE65E, 0xFBE790,
3983 0xF7E9C1, 0xEFECF4, 0x786C1E, 0x746C4C, 0x646D90, 0x356FD5, 0x5D91FF, 0x8CABFF, 0x7E711B, 0x7B7146, 0x707387,
3984 0x5275C8, 0x4387FF, 0x8AAAFF, 0x948415, 0x92853C, 0x8C8675, 0x7F88AF, 0x648CEB, 0x87A7FF, 0xB5A20E, 0xB5A336,
3985 0xB1A46A, 0xAAA5A0, 0x9EA8D7, 0x98B1FF, 0xDDC600, 0xDDC631, 0xDBC764, 0xD7C997, 0xCFCBCB, 0xC4CEFF, 0xFFE655,
3986 0xFFE75C, 0xFFE873, 0xFFEB97, 0xFFF1C5, 0xF8F4F8, 0x968726, 0x93874E, 0x888892, 0x6E89D7, 0x7BA0FF, 0x96B1FF,
3987 0x9A8B23, 0x988B4A, 0x8F8C8B, 0x7A8ECE, 0x779DFF, 0x96B1FF, 0xAC9A1E, 0xAA9A42, 0xA59B7C, 0x999DB9, 0x82A0F6,
3988 0x98B2FF, 0xC8B317, 0xC7B43A, 0xC4B470, 0xBDB6A8, 0xB1B8E0, 0xAABDFF, 0xECD30F, 0xECD435, 0xE9D469, 0xE5D69D,
3989 0xDED8D2, 0xCFD7FF, 0xFFE871, 0xFFE975, 0xFFEA86, 0xFFEDA2, 0xFFF2C8, 0xFFFAFA> csWSprotanopia;
3990 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3991 /** @class csWSdeutanopia
3992 @ingroup cs
3993 @extends csWS_tpl
3994 The "web safe" color pallet of 216 colors as seen by someone with Deutanopia.
3995 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSdeutanopiaAlt. */
3996 typedef csWS_tpl<0x000000, 0x002135, 0x004168, 0x005E97, 0x0076BE, 0x008BDF, 0x362A0C, 0x2F2D34, 0x003E68, 0x005E9A, 0x0078C2,
3997 0x008CE2, 0x6D5418, 0x6A5538, 0x5E5A69, 0x3D629A, 0x0078C9, 0x0090EC, 0xA37E25, 0xA27E3D, 0x9B816C, 0x8D869D,
3998 0x728ECF, 0x3398FF, 0xDAA831, 0xD9A844, 0xD4AA6F, 0xCBAEA0, 0xBBB3D1, 0xA5BBFF, 0xFFCD72, 0xFFCD77, 0xFFCF87,
3999 0xFFD3A6, 0xFBDAD4, 0xE6DCFF, 0x221A00, 0x131E30, 0x003F67, 0x005D96, 0x0076BF, 0x008BDF, 0x3D2F09, 0x373133,
4000 0x003B65, 0x005D99, 0x0078C2, 0x008CE2, 0x705617, 0x6D5737, 0x615B68, 0x43639A, 0x0078C9, 0x0090EC, 0xA58600,
4001 0xA4803C, 0x9D826B, 0x8F879D, 0x758FCE, 0x3999FF, 0xDBA830, 0xDAA943, 0xD6AB6F, 0xCCAEA0, 0xBDB4D1, 0xA7BBFF,
4002 0xFFCD74, 0xFFCD78, 0xFFCF88, 0xFFD4A6, 0xFCDBD4, 0xE7DDFF, 0x453500, 0x3F352F, 0x253D60, 0x005A94, 0x0076BF,
4003 0x008BE1, 0x534000, 0x4F4031, 0x3D4763, 0x005995, 0x0076C2, 0x008CE4, 0x7B5E11, 0x795F35, 0x6F6367, 0x586A98,
4004 0x0076C9, 0x0090EE, 0xAC8421, 0xAA853B, 0xA4876A, 0x978C9C, 0x8093CD, 0x519CFE, 0xE0AC2E, 0xDFAC42, 0xDAAE6E,
4005 0xD2B29F, 0xC3B7D1, 0xADBEFF, 0xFFCE79, 0xFFCF7C, 0xFFD08B, 0xFFD5A7, 0xFFDDD3, 0xEBDFFF, 0x674F00, 0x634E2C,
4006 0x57535F, 0x385B90, 0x0073C0, 0x008CE5, 0x705600, 0x6C552D, 0x625961, 0x496192, 0x0073C2, 0x008DE8, 0x8E6C00,
4007 0x8C6D31, 0x847064, 0x737696, 0x507FC7, 0x0090F3, 0xA69500, 0xB78E37, 0xB29068, 0xA6949A, 0x929BCC, 0x6FA4FD,
4008 0xE9B22A, 0xE8B33F, 0xE4B56C, 0xDBB89D, 0xCEBDCF, 0xB9C4FF, 0xFFD080, 0xFFD184, 0xFFD291, 0xFFD6A9, 0xFFDDD0,
4009 0xF4E4FF, 0x886900, 0x856726, 0x7E6A5E, 0x6E7190, 0x4B7AC0, 0x008CEC, 0x8F6D00, 0x8C6C27, 0x856F5F, 0x767591,
4010 0x577EC2, 0x008DEF, 0xA67F00, 0xA47E2B, 0x9E8161, 0x918694, 0x7B8DC5, 0x4C97F6, 0xCA9A00, 0xC99B32, 0xC49D65,
4011 0xBAA198, 0xAAA7C9, 0x8FAEFB, 0xF6C600, 0xF5BC3B, 0xF1BE6A, 0xEAC19B, 0xDEC6CD, 0xCBCCFF, 0xFFD389, 0xFFD38C,
4012 0xFFD497, 0xFFD8AB, 0xFFDECC, 0xFFEAFD, 0xA98200, 0xA8801A, 0xA2835B, 0x97888E, 0x838FC0, 0x5E98F1, 0xAE8600,
4013 0xAD841C, 0xA7875C, 0x9D8B8F, 0x8A92C1, 0x679BF2, 0xC09300, 0xBF9322, 0xBB955E, 0xB19992, 0xA09FC3, 0x85A7F5,
4014 0xDFAA00, 0xDEAB2A, 0xDAAC62, 0xD2B095, 0xC5B5C7, 0xB0BCF9, 0xFFC750, 0xFFC857, 0xFFCA6F, 0xFCCD99, 0xF1D2CB,
4015 0xE1D8FD, 0xFFD592, 0xFFD594, 0xFFD79D, 0xFFDAAD, 0xFFDFC8, 0xFFE8EF> csWSdeutanopia;
4016 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4017 /** @class csWStritanoptia
4018 @ingroup cs
4019 @extends csWS_tpl
4020 The "web safe" color pallet of 216 colors as seen by someone with Tritanoptia.
4021 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWStritanoptiaAlt. */
4022 typedef csWS_tpl<0x000000, 0x001C1D, 0x003739, 0x005155, 0x006A6E, 0x007F85, 0x173033, 0x0A3236, 0x004347, 0x00595E, 0x006F74,
4023 0x008389, 0x2D5F66, 0x2A6068, 0x15656D, 0x00727A, 0x00828A, 0x00929A, 0x448F9A, 0x42909A, 0x39929D, 0x1F97A3,
4024 0x00A1AC, 0x00ACB7, 0x5ABFCD, 0x59BFCD, 0x54C1CF, 0x47C4D3, 0x29CAD9, 0x00D0DF, 0x73EDFF, 0x73EDFF, 0x73EEFF,
4025 0x72EEFF, 0x70EFFF, 0x6EEFFF, 0x330600, 0x301517, 0x212A2D, 0x00474B, 0x006469, 0x007C82, 0x363033, 0x333236,
4026 0x263C41, 0x005056, 0x006A70, 0x008187, 0x415F66, 0x3F6068, 0x35656D, 0x146D76, 0x007F87, 0x009099, 0x518F9A,
4027 0x4F909A, 0x49929D, 0x3997A3, 0x00A0AC, 0x00ABB7, 0x64BFD7, 0x63BFCD, 0x5EC1CF, 0x54C4D3, 0x3ECAD9, 0x00D1E0,
4028 0x7AEDFF, 0x7AEDFF, 0x79EEFF, 0x78EEFF, 0x76EFFF, 0x74EFFF, 0x660B00, 0x651615, 0x602B2D, 0x563F44, 0x42545B,
4029 0x006B73, 0x673033, 0x663336, 0x623D41, 0x584C51, 0x445D64, 0x007179, 0x6C5F66, 0x6B6067, 0x67656C, 0x5E6D75,
4030 0x4D7982, 0x228791, 0x758F9A, 0x74909A, 0x71929D, 0x6997A3, 0x5A9FAB, 0x3EA9B6, 0x82BECD, 0x81BFCD, 0x7EC1CF,
4031 0x77C4D3, 0x6BCAD9, 0x57D1E1, 0x92EDFF, 0x92EDFF, 0x90EEFF, 0x8EEEFF, 0x8BEFFF, 0x88EFFF, 0x991100, 0x981612,
4032 0x962B2C, 0x904044, 0x87555B, 0x796A71, 0x9A3032, 0x993335, 0x963D40, 0x914C51, 0x885D64, 0x7A7078, 0x9D5F66,
4033 0x9C6067, 0x9A656C, 0x946D75, 0x8C7982, 0x7E8791, 0xA28F99, 0xA2909A, 0x9F929D, 0x9A97A3, 0x929FAB, 0x86A9B6,
4034 0xABBECD, 0xAABFCD, 0xA8C1CF, 0xA3C4D3, 0x9CCAD9, 0x91D1E1, 0xB6EDFF, 0xB5EDFF, 0xB4EEFF, 0xB0EEFF, 0xACEFFF,
4035 0xA6EFFF, 0xCC1600, 0xCB170B, 0xCA2B2B, 0xC64043, 0xC0555A, 0xB76A71, 0xCC3030, 0xCC3334, 0xCA3D3F, 0xC64C50,
4036 0xC15E64, 0xB87178, 0xCF5F65, 0xCE6067, 0xCC656C, 0xC96E75, 0xC37982, 0xBB8791, 0xD38F99, 0xD2909A, 0xD0929D,
4037 0xCD98A2, 0xC79FAB, 0xBFA9B6, 0xD9BECC, 0xD8BFCD, 0xD7C1CF, 0xD3C4D3, 0xCECAD9, 0xC6D1E1, 0xE0EEFF, 0xE0EEFF,
4038 0xDDEEFF, 0xD9EEFF, 0xD3EFFF, 0xCBEFFF, 0xFE1C00, 0xFE1A00, 0xFD2B28, 0xFA4042, 0xF6555A, 0xF06A71, 0xFF3331,
4039 0xFF3332, 0xFE3D3E, 0xFB4C4F, 0xF75E63, 0xF07178, 0xFF6569, 0xFF656A, 0xFF666C, 0xFD6E74, 0xF87981, 0xF28791,
4040 0xFF949C, 0xFF949D, 0xFF959E, 0xFF99A2, 0xFC9FAA, 0xF6A9B5, 0xFFBECA, 0xFFBFCA, 0xFFC0CD, 0xFFC4D1, 0xFFCAD8,
4041 0xFBD1E1, 0xFFE4F2, 0xFFE5F3, 0xFFE6F5, 0xFFEAF9, 0xFDEFFF, 0xF4F0FF> csWStritanoptia;
4042 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4043 /** @class csWSprotanopiaAlt
4044 @ingroup cs
4045 @extends csWS_tpl
4046 The "web safe" color pallet of 216 colors as seen by someone with Protanopia.
4047 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSprotanopia. */
4048 typedef csWS_tpl<0x000000, 0x000E33, 0x001D66, 0x002B99, 0x003ACC, 0x0048FF, 0x422F00, 0x303133, 0x003566, 0x003D99, 0x0047CC,
4049 0x0053FF, 0x845D00, 0x7E5E33, 0x606266, 0x266699, 0x006BCC, 0x0072FF, 0xC68C00, 0xC38D33, 0xB38F66, 0x909399,
4050 0x6896CC, 0x009BFF, 0xFFBB00, 0xFFBB32, 0xFCBD66, 0xE6C099, 0xC0C4CC, 0x9DC7FF, 0xFFE900, 0xFFEA31, 0xFFEB65,
4051 0xFFED99, 0xFFF1CC, 0xF0F5FF, 0x1A1202, 0x001633, 0x002166, 0x002E99, 0x003BCC, 0x0049FF, 0x453100, 0x333333,
4052 0x003766, 0x003F99, 0x0048CC, 0x0053FF, 0x855E00, 0x7F5F33, 0x616366, 0x2A6699, 0x006CCC, 0x0072FF, 0xC78C00,
4053 0xC38D33, 0xB48F66, 0x919499, 0x6997CC, 0x009BFF, 0xFFBB00, 0xFFBB32, 0xFCBD66, 0xE6C099, 0xC0C5CC, 0x9DC8FF,
4054 0xFFEA00, 0xFFEA31, 0xFFEB65, 0xFFED99, 0xFFF1CC, 0xF0F6FF, 0x332405, 0x1D2733, 0x002D66, 0x003699, 0x0042CC,
4055 0x004EFF, 0x4F3804, 0x413A33, 0x003E66, 0x004499, 0x004DCC, 0x0057FF, 0x8A6100, 0x846233, 0x666666, 0x376999,
4056 0x006ECC, 0x0075FF, 0xC98E00, 0xC68F33, 0xB79166, 0x939599, 0x6E99CC, 0x009DFF, 0xFFBC00, 0xFFBD32, 0xFEBE66,
4057 0xE8C199, 0xC2C6CC, 0xA0C9FF, 0xFFEA00, 0xFFEB32, 0xFFEC65, 0xFFEE99, 0xFFF2CC, 0xF2F6FF, 0x4D3607, 0x3E3833,
4058 0x003C66, 0x004399, 0x004CCC, 0x0057FF, 0x604407, 0x564533, 0x2E4966, 0x004E99, 0x0056CC, 0x005FFF, 0x926703,
4059 0x8D6833, 0x726C66, 0x496F99, 0x0074CC, 0x007AFF, 0xCE9200, 0xCB9233, 0xBD9566, 0x999999, 0x769CCC, 0x00A0FF,
4060 0xFFBF00, 0xFFBF32, 0xFFC166, 0xEDC499, 0xC6C8CC, 0xA5CBFF, 0xFFEC00, 0xFFED32, 0xFFEE66, 0xFFF099, 0xFFF4CC,
4061 0xF4F8FF, 0x66490A, 0x5E4A33, 0x3A4E66, 0x005299, 0x0059CC, 0x0062FF, 0x745209, 0x6D5333, 0x4D5766, 0x005B99,
4062 0x0061CC, 0x0069FF, 0x9E7008, 0x9A7133, 0x837466, 0x5E7899, 0x007CCC, 0x0081FF, 0xD69700, 0xD39833, 0xC59A66,
4063 0xA59E99, 0x82A1CC, 0x16A5FF, 0xFFC300, 0xFFC333, 0xFFC466, 0xF3C799, 0xCCCCCC, 0xACCFFF, 0xFFEF00, 0xFFEF32,
4064 0xFFF166, 0xFFF399, 0xFFF6CC, 0xF9FBFF, 0x805B0C, 0x7A5C34, 0x5C6066, 0x006399, 0x0069CC, 0x0070FF, 0x8A620C,
4065 0x856334, 0x676766, 0x396A99, 0x006FCC, 0x0076FF, 0xAE7B0B, 0xAA7C34, 0x967E66, 0x738299, 0x2786CC, 0x008BFF,
4066 0xE19F08, 0xDE9F33, 0xD1A166, 0xB3A599, 0x90A9CC, 0x4FACFF, 0xFFC800, 0xFFC833, 0xFFCA66, 0xFCCC99, 0xD7D1CC,
4067 0xB7D4FF, 0xFFF300, 0xFFF332, 0xFFF466, 0xFFF799, 0xFFFACC, 0xFFFFFF> csWSprotanopiaAlt;
4068 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4069 /** @class csWSdeutanopiaAlt
4070 @ingroup cs
4071 @extends csWS_tpl
4072 The "web safe" color pallet of 216 colors as seen by someone with Deutanopia.
4073 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSdeutanopia. */
4074 typedef csWS_tpl<0x000000, 0x001433, 0x002866, 0x003C99, 0x0050CB, 0x0064FE, 0x3A2A0B, 0x2C2F33, 0x003866, 0x004699, 0x0057CB,
4075 0x0069FE, 0x755316, 0x6F5635, 0x585D67, 0x226599, 0x0070CC, 0x007EFF, 0xAF7D20, 0xAC7E39, 0x9E8468, 0x848C9A,
4076 0x5F93CC, 0x009DFF, 0xEAA72B, 0xE8A83F, 0xDFAB6B, 0xCBB29B, 0xAFBBCD, 0x8FC2FF, 0xFFD036, 0xFFD146, 0xFFD46E,
4077 0xFFD99D, 0xF7E1CE, 0xDBE9FF, 0x231800, 0x001F33, 0x002D66, 0x003F99, 0x0052CB, 0x0065FE, 0x412E09, 0x333333,
4078 0x003C66, 0x004999, 0x0059CB, 0x006BFE, 0x775515, 0x725735, 0x5B5F66, 0x2C6799, 0x0072CC, 0x007FFE, 0xB17E20,
4079 0xAE7F39, 0xA08568, 0x858D9A, 0x6294CC, 0x009EFF, 0xEBA72B, 0xE9A83F, 0xE0AC6B, 0xCCB39B, 0xB0BBCD, 0x91C2FF,
4080 0xFFD136, 0xFFD246, 0xFFD46E, 0xFFDA9D, 0xF8E2CE, 0xDCEAFF, 0x453000, 0x393532, 0x003E65, 0x004B98, 0x005ACB,
4081 0x006CFE, 0x563C00, 0x4D4032, 0x2C4865, 0x005398, 0x0061CB, 0x0071FE, 0x825C11, 0x7D5E34, 0x666666, 0x446D99,
4082 0x0077CC, 0x0084FE, 0xB7821E, 0xB48338, 0xA78968, 0x8C9199, 0x6C98CC, 0x00A1FF, 0xEFAA2A, 0xEDAB3E, 0xE4AF6A,
4083 0xD2B69B, 0xB5BECD, 0x97C5FF, 0xFFD335, 0xFFD445, 0xFFD66E, 0xFFDC9D, 0xFCE4CE, 0xE0ECFF, 0x684900, 0x624B2F,
4084 0x485364, 0x005C98, 0x0069CB, 0x0077FE, 0x725000, 0x6D5230, 0x545A64, 0x106398, 0x006ECB, 0x007CFE, 0x946800,
4085 0x906A32, 0x7E7165, 0x617898, 0x0081CB, 0x008DFE, 0xC38A1A, 0xC08B37, 0xB49067, 0x999999, 0x7E9FCC, 0x38A8FF,
4086 0xF7B027, 0xF5B13D, 0xEDB46A, 0xDBBB9B, 0xBEC4CD, 0xA3CAFF, 0xFFD733, 0xFFD844, 0xFFDA6D, 0xFFE09D, 0xFFE7CE,
4087 0xE7F0FF, 0x8B6100, 0x87632C, 0x736A63, 0x537297, 0x007BCA, 0x0087FE, 0x926600, 0x8E682C, 0x7B6F63, 0x5E7697,
4088 0x007FCA, 0x008BFE, 0xAC7900, 0xA97A2F, 0x9A8064, 0x7F8897, 0x5790CB, 0x009AFE, 0xD4960E, 0xD19734, 0xC79B66,
4089 0xB0A398, 0x94ABCB, 0x68B2FE, 0xFFB822, 0xFFB93A, 0xFABC68, 0xEAC39A, 0xCCCCCC, 0xB3D2FF, 0xFFDE30, 0xFFDE42,
4090 0xFFE16C, 0xFFE69C, 0xFFEDCD, 0xF1F6FF, 0xAE7900, 0xAB7A26, 0x9D8061, 0x818996, 0x5B90CA, 0x009AFD, 0xB37D00,
4091 0xB07E27, 0xA38461, 0x878C96, 0x6494CA, 0x009DFD, 0xC78C00, 0xC58D2A, 0xB99162, 0x9F9A96, 0x83A1CA, 0x47AAFD,
4092 0xE9A400, 0xE7A52F, 0xDEA964, 0xCAB097, 0xAEB9CA, 0x8DC0FE, 0xFFC319, 0xFFC436, 0xFFC767, 0xFDCD99, 0xE2D6CB,
4093 0xC8DDFE, 0xFFE62B, 0xFFE73F, 0xFFE96B, 0xFFEE9B, 0xFFF5CD, 0xFFFFFF> csWSdeutanopiaAlt;
4094 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4095 /** @class csWStritanoptiaAlt
4096 @ingroup cs
4097 @extends csWS_tpl
4098 The "web safe" color pallet of 216 colors as seen by someone with Tritanoptia.
4099 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWStritanoptia. */
4100 typedef csWS_tpl<0x000000, 0x00191E, 0x00323D, 0x004B5B, 0x00647A, 0x007C98, 0x202E31, 0x113237, 0x00404A, 0x005463, 0x006A7F,
4101 0x00819C, 0x415C61, 0x3C5D63, 0x21646D, 0x00707E, 0x008093, 0x0093AC, 0x618A92, 0x5F8B93, 0x548F99, 0x3296A4,
4102 0x00A1B4, 0x00AFC7, 0x82B8C2, 0x80B8C3, 0x79BBC7, 0x69C0CF, 0x42C8DA, 0x00D3EA, 0xA2E6F3, 0xA1E6F3, 0x9CE8F6,
4103 0x91ECFC, 0x7DF2FF, 0x53FAFF, 0x340010, 0x2C1A1C, 0x00333A, 0x004B5A, 0x006479, 0x007D98, 0x392E2F, 0x333333,
4104 0x004147, 0x005462, 0x006A7E, 0x00819C, 0x4D5C5F, 0x4A5E62, 0x39646C, 0x00707D, 0x008093, 0x0093AB, 0x698A91,
4105 0x678B92, 0x5D8F98, 0x4296A3, 0x00A1B3, 0x00AFC6, 0x87B8C1, 0x85B8C2, 0x7FBBC6, 0x70C0CE, 0x4FC8DA, 0x00D3E9,
4106 0xA6E6F2, 0xA5E6F3, 0xA0E8F6, 0x95ECFC, 0x82F2FF, 0x5CFAFF, 0x670021, 0x651527, 0x583338, 0x364E52, 0x006674,
4107 0x007E94, 0x692C35, 0x673139, 0x5B4244, 0x3C565B, 0x006C7A, 0x008298, 0x725C5E, 0x705E60, 0x666666, 0x507278,
4108 0x00818F, 0x0094A8, 0x838B8D, 0x818C8E, 0x7B9094, 0x6B97A0, 0x46A2B0, 0x00B0C4, 0x9AB8BF, 0x99B9C0, 0x94BCC4,
4109 0x88C1CC, 0x71C9D8, 0x3CD4E7, 0xB5E6F0, 0xB4E7F1, 0xB0E9F4, 0xA7ECFA, 0x97F3FF, 0x7AFBFF, 0x9B0031, 0x990035,
4110 0x933041, 0x854D54, 0x686969, 0x1C808C, 0x9C293F, 0x9A2E42, 0x943F4C, 0x86565B, 0x6B6E6F, 0x288591, 0xA15B63,
4111 0xA05D65, 0x9A656A, 0x8D7275, 0x758387, 0x4496A2, 0xAC8B8E, 0xAA8C8F, 0xA59092, 0x999999, 0x86A4AA, 0x63B2BF,
4112 0xBABABA, 0xB9BABB, 0xB5BDBF, 0xADC2C7, 0x9DCAD3, 0x83D5E3, 0xD0E7EC, 0xCFE8ED, 0xCBEAF0, 0xC4EDF6, 0xB7F3FF,
4113 0xA3FCFF, 0xCE0042, 0xCD0044, 0xC92A4E, 0xC04A5D, 0xB1676F, 0x978284, 0xCF214C, 0xCE284E, 0xCA3C56, 0xC15463,
4114 0xB26D75, 0x988788, 0xD3596B, 0xD25B6C, 0xCE6371, 0xC5717B, 0xB68388, 0x9E9899, 0xDA8A92, 0xD98B93, 0xD58F97,
4115 0xCD989D, 0xBFA5A7, 0xAAB4B6, 0xE5B9BD, 0xE4BABE, 0xE0BDC0, 0xD9C3C5, 0xCCCCCC, 0xBBD6DD, 0xF3E8E9, 0xF2E9E9,
4116 0xEFEBEB, 0xE9EFF0, 0xDFF5FA, 0xD0FDFF, 0xFF0052, 0xFF0054, 0xFE205B, 0xF84668, 0xED6478, 0xDD818B, 0xFF095A,
4117 0xFF1B5C, 0xFF3662, 0xF8506E, 0xEE6B7D, 0xDE858F, 0xFF5674, 0xFF5875, 0xFF607A, 0xFB6F83, 0xF1818F, 0xE1979E,
4118 0xFF8898, 0xFF8999, 0xFF8E9C, 0xFF96A3, 0xF7A3AC, 0xE8B3B8, 0xFFB8C1, 0xFFB9C2, 0xFFBCC4, 0xFFC2C9, 0xFFCBD0,
4119 0xF2D7D9, 0xFFE7EC, 0xFFE8ED, 0xFFEAEE, 0xFFEFF2, 0xFFF6F7, 0xFFFFFF> csWStritanoptiaAlt;
4120 //@}
4121 //========================================================================================================================================================
4122 /** @name Interesting Pallets */
4123 //@{
4124 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4125 /** @class csFPcircular12
4126 @ingroup cs
4127 @extends csFP_tpl */
4128 typedef csFP_tpl<0xFF0000, 0xFF7D00, 0xFFFF00, 0x7DFF00, 0x66CC00, 0x66FFB2, 0x00FFFF,
4129 0x007DFF, 0x0000FF, 0x7D00FF, 0xFF00FF, 0xFF007D> csFPcircular12;
4130 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4131 /** @class csFPcircular24
4132 @ingroup cs
4133 @extends csFP_tpl */
4134 typedef csFP_tpl<0xFF0000, 0xFF3F00, 0xFF7D00, 0xFFBE00, 0xFFE100, 0xFFFF00, 0x7DFF00, 0x7DCC00, 0x009600, 0x00BE00, 0x00FF5A,
4135 0x00FFBE, 0x00FFFF, 0x00BEFF, 0x007DFF, 0x003FFF, 0x0000FF, 0x3F00FF, 0x7D00FF, 0xBE00FF, 0xFF00FF, 0xFF00BE,
4136 0xFF007D, 0xFF003F> csFPcircular24;
4137 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4138 /** @class csFPblAqGrYeOrReVi200
4139 @ingroup cs
4140 @extends csFP_tpl */
4141 typedef csFP_tpl<0x0000FF, 0x0008FF, 0x000FFF, 0x0017FF, 0x001FFF, 0x0027FF, 0x002EFF, 0x0036FF, 0x003EFF, 0x0046FF, 0x004DFF,
4142 0x0055FF, 0x005DFF, 0x0064FF, 0x006CFF, 0x0074FF, 0x007CFF, 0x0083FF, 0x008BFF, 0x0093FF, 0x009BFF, 0x00A2FF,
4143 0x00AAFF, 0x00B2FF, 0x00B9FF, 0x00C1FF, 0x00C9FF, 0x00D1FF, 0x00D8FF, 0x00E0FF, 0x00E8FF, 0x00F0FF, 0x00F7FF,
4144 0x00FFFF, 0x00FDF8, 0x00FAF0, 0x01F8E9, 0x01F6E2, 0x01F3DB, 0x01F1D3, 0x02EFCC, 0x02EDC5, 0x02EABE, 0x02E8B6,
4145 0x03E6AF, 0x03E3A8, 0x03E1A0, 0x03DF99, 0x04DC92, 0x04DA8B, 0x04D883, 0x04D67C, 0x05D375, 0x05D16E, 0x05CF66,
4146 0x05CC5F, 0x06CA58, 0x06C850, 0x06C549, 0x06C342, 0x07C13B, 0x07BF33, 0x07BC2C, 0x07BA25, 0x08B81E, 0x08B516,
4147 0x08B30F, 0x0FB50F, 0x17B70E, 0x1EBA0E, 0x25BC0D, 0x2CBE0D, 0x34C00C, 0x3BC30C, 0x42C50B, 0x49C70B, 0x51C90B,
4148 0x58CC0A, 0x5FCE0A, 0x66D009, 0x6ED209, 0x75D508, 0x7CD708, 0x84D908, 0x8BDB07, 0x92DD07, 0x99E006, 0xA1E206,
4149 0xA8E405, 0xAFE605, 0xB6E904, 0xBEEB04, 0xC5ED04, 0xCCEF03, 0xD3F203, 0xDBF402, 0xE2F602, 0xE9F801, 0xF0FB01,
4150 0xF8FD00, 0xFFFF00, 0xFFFC00, 0xFFFA00, 0xFFF700, 0xFFF400, 0xFFF100, 0xFFEF00, 0xFFEC00, 0xFFE900, 0xFFE600,
4151 0xFFE400, 0xFFE100, 0xFFDE00, 0xFFDC00, 0xFFD900, 0xFFD600, 0xFFD300, 0xFFD100, 0xFFCE00, 0xFFCB00, 0xFFC800,
4152 0xFFC600, 0xFFC300, 0xFFC000, 0xFFBE00, 0xFFBB00, 0xFFB800, 0xFFB500, 0xFFB300, 0xFFB000, 0xFFAD00, 0xFFAA00,
4153 0xFFA800, 0xFFA500, 0xFFA000, 0xFF9B00, 0xFF9600, 0xFF9100, 0xFF8C00, 0xFF8700, 0xFF8200, 0xFF7D00, 0xFF7800,
4154 0xFF7300, 0xFF6E00, 0xFF6900, 0xFF6400, 0xFF5F00, 0xFF5A00, 0xFF5500, 0xFF5000, 0xFF4B00, 0xFF4600, 0xFF4100,
4155 0xFF3C00, 0xFF3700, 0xFF3200, 0xFF2D00, 0xFF2800, 0xFF2300, 0xFF1E00, 0xFF1900, 0xFF1400, 0xFF0F00, 0xFF0A00,
4156 0xFF0500, 0xFF0000, 0xFA0004, 0xF50008, 0xF0000C, 0xEB0010, 0xE60015, 0xE00019, 0xDB001D, 0xD60021, 0xD10025,
4157 0xCC0029, 0xC7002D, 0xC20031, 0xBD0036, 0xB8003A, 0xB3003E, 0xAE0042, 0xA80046, 0xA3004A, 0x9E004E, 0x990052,
4158 0x940057, 0x8F005B, 0x8A005F, 0x850063, 0x800067, 0x7B006B, 0x76006F, 0x700073, 0x6B0078, 0x66007C, 0x610080,
4159 0x5C0084, 0x570088> csFPblAqGrYeOrReVi200;
4160 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4161 /** @class csFPcmoceanAlgae
4162 @ingroup cs
4163 @extends csFP_tpl */
4164 typedef csFP_tpl<0xD7F9D0, 0xD6F8CE, 0xD4F7CD, 0xD3F6CB, 0xD2F5CA, 0xD1F4C8, 0xCFF4C7, 0xCEF3C5, 0xCDF2C4, 0xCCF1C3, 0xCAF0C1,
4165 0xC9EFC0, 0xC8EEBE, 0xC7EDBD, 0xC5ECBB, 0xC4EBBA, 0xC3EBB9, 0xC2EAB7, 0xC0E9B6, 0xBFE8B4, 0xBEE7B3, 0xBDE6B1,
4166 0xBBE5B0, 0xBAE4AF, 0xB9E4AD, 0xB8E3AC, 0xB6E2AB, 0xB5E1A9, 0xB4E0A8, 0xB2DFA6, 0xB1DEA5, 0xB0DEA4, 0xAFDDA2,
4167 0xADDCA1, 0xACDBA0, 0xABDA9E, 0xAADA9D, 0xA8D99C, 0xA7D89A, 0xA6D799, 0xA4D698, 0xA3D596, 0xA2D595, 0xA0D494,
4168 0x9FD392, 0x9ED291, 0x9DD190, 0x9BD18F, 0x9AD08D, 0x99CF8C, 0x97CE8B, 0x96CD8A, 0x95CD88, 0x93CC87, 0x92CB86,
4169 0x91CA85, 0x8FCA83, 0x8EC982, 0x8CC881, 0x8BC780, 0x8AC77E, 0x88C67D, 0x87C57C, 0x85C47B, 0x84C47A, 0x83C379,
4170 0x81C277, 0x80C176, 0x7EC175, 0x7DC074, 0x7BBF73, 0x7ABE72, 0x78BE71, 0x77BD6F, 0x75BC6E, 0x74BB6D, 0x72BB6C,
4171 0x71BA6B, 0x6FB96A, 0x6EB969, 0x6CB868, 0x6BB767, 0x69B666, 0x67B665, 0x66B564, 0x64B463, 0x62B462, 0x61B361,
4172 0x5FB260, 0x5DB25F, 0x5BB15E, 0x5AB05D, 0x58AF5D, 0x56AF5C, 0x54AE5B, 0x52AD5A, 0x50AD59, 0x4EAC59, 0x4CAB58,
4173 0x4AAB57, 0x48AA57, 0x46A956, 0x44A855, 0x42A855, 0x3FA754, 0x3DA654, 0x3BA654, 0x39A553, 0x37A453, 0x34A353,
4174 0x32A352, 0x30A252, 0x2EA152, 0x2CA052, 0x2AA052, 0x289F51, 0x269E51, 0x249D51, 0x229C51, 0x209C51, 0x1E9B51,
4175 0x1C9A51, 0x1B9951, 0x199851, 0x189750, 0x169650, 0x159650, 0x139550, 0x129450, 0x109350, 0x0F9250, 0x0E9150,
4176 0x0D904F, 0x0C8F4F, 0x0B8F4F, 0x0A8E4F, 0x098D4F, 0x098C4F, 0x088B4E, 0x088A4E, 0x07894E, 0x07884E, 0x07874D,
4177 0x07864D, 0x07864D, 0x07854D, 0x07844D, 0x07834C, 0x07824C, 0x08814C, 0x08804B, 0x087F4B, 0x097E4B, 0x097D4B,
4178 0x0A7C4A, 0x0A7C4A, 0x0B7B4A, 0x0B7A49, 0x0C7949, 0x0C7849, 0x0D7748, 0x0D7648, 0x0E7548, 0x0E7447, 0x0F7347,
4179 0x0F7347, 0x107246, 0x107146, 0x117045, 0x116F45, 0x126E45, 0x126D44, 0x126C44, 0x136B43, 0x136A43, 0x146A43,
4180 0x146942, 0x146842, 0x156741, 0x156641, 0x156540, 0x166440, 0x166340, 0x16623F, 0x17623F, 0x17613E, 0x17603E,
4181 0x175F3D, 0x185E3D, 0x185D3C, 0x185C3C, 0x185B3B, 0x185B3B, 0x195A3A, 0x19593A, 0x195839, 0x195739, 0x195638,
4182 0x195538, 0x195437, 0x195437, 0x1A5336, 0x1A5235, 0x1A5135, 0x1A5034, 0x1A4F34, 0x1A4E33, 0x1A4D33, 0x1A4D32,
4183 0x1A4C32, 0x1A4B31, 0x1A4A30, 0x1A4930, 0x1A482F, 0x1A472F, 0x1A472E, 0x1A462E, 0x1A452D, 0x1A442C, 0x1A432C,
4184 0x19422B, 0x19412B, 0x19402A, 0x194029, 0x193F29, 0x193E28, 0x193D27, 0x193C27, 0x183B26, 0x183B26, 0x183A25,
4185 0x183924, 0x183824, 0x183723, 0x173622, 0x173522, 0x173521, 0x173420, 0x173320, 0x16321F, 0x16311E, 0x16301E,
4186 0x162F1D, 0x152F1C, 0x152E1C, 0x152D1B, 0x142C1A, 0x142B1A, 0x142A19, 0x142918, 0x132918, 0x132817, 0x132716,
4187 0x122616, 0x122515, 0x122414> csFPcmoceanAlgae;
4188 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4189 /** @class csFPcmoceanAmp
4190 @ingroup cs
4191 @extends csFP_tpl */
4192 typedef csFP_tpl<0xF1EDEC, 0xF1ECEB, 0xF0EBE9, 0xEFE9E8, 0xEFE8E7, 0xEEE7E5, 0xEEE6E4, 0xEDE5E3, 0xEDE3E1, 0xECE2E0, 0xECE1DE,
4193 0xEBE0DD, 0xEBDFDC, 0xEADDDA, 0xEADCD9, 0xE9DBD7, 0xE9DAD6, 0xE9D9D4, 0xE8D8D3, 0xE8D6D2, 0xE7D5D0, 0xE7D4CF,
4194 0xE6D3CD, 0xE6D2CC, 0xE6D1CA, 0xE5CFC9, 0xE5CEC8, 0xE4CDC6, 0xE4CCC5, 0xE4CBC3, 0xE3C9C2, 0xE3C8C0, 0xE2C7BF,
4195 0xE2C6BD, 0xE2C5BC, 0xE1C4BB, 0xE1C3B9, 0xE1C1B8, 0xE0C0B6, 0xE0BFB5, 0xDFBEB3, 0xDFBDB2, 0xDFBCB0, 0xDEBAAF,
4196 0xDEB9AE, 0xDEB8AC, 0xDDB7AB, 0xDDB6A9, 0xDDB5A8, 0xDCB4A6, 0xDCB2A5, 0xDCB1A3, 0xDBB0A2, 0xDBAFA1, 0xDBAE9F,
4197 0xDAAD9E, 0xDAAC9C, 0xD9AA9B, 0xD9A999, 0xD9A898, 0xD8A796, 0xD8A695, 0xD8A594, 0xD7A492, 0xD7A291, 0xD7A18F,
4198 0xD6A08E, 0xD69F8C, 0xD69E8B, 0xD59D89, 0xD59C88, 0xD59A87, 0xD49985, 0xD49884, 0xD49782, 0xD39681, 0xD3957F,
4199 0xD3947E, 0xD2927D, 0xD2917B, 0xD2907A, 0xD18F78, 0xD18E77, 0xD18D76, 0xD08C74, 0xD08B73, 0xD08971, 0xCF8870,
4200 0xCF876F, 0xCF866D, 0xCE856C, 0xCE846A, 0xCD8369, 0xCD8168, 0xCD8066, 0xCC7F65, 0xCC7E64, 0xCC7D62, 0xCB7C61,
4201 0xCB7A60, 0xCB795E, 0xCA785D, 0xCA775B, 0xC9765A, 0xC97559, 0xC97457, 0xC87256, 0xC87155, 0xC87054, 0xC76F52,
4202 0xC76E51, 0xC66D50, 0xC66B4E, 0xC66A4D, 0xC5694C, 0xC5684A, 0xC56749, 0xC46548, 0xC46447, 0xC36346, 0xC36244,
4203 0xC36143, 0xC25F42, 0xC25E41, 0xC15D3F, 0xC15C3E, 0xC05B3D, 0xC0593C, 0xC0583B, 0xBF573A, 0xBF5639, 0xBE5438,
4204 0xBE5336, 0xBD5235, 0xBD5134, 0xBD4F33, 0xBC4E32, 0xBC4D31, 0xBB4C30, 0xBB4A30, 0xBA492F, 0xBA482E, 0xB9462D,
4205 0xB9452C, 0xB8442B, 0xB8422B, 0xB7412A, 0xB74029, 0xB63F29, 0xB53D28, 0xB53C27, 0xB43B27, 0xB43926, 0xB33826,
4206 0xB23726, 0xB23525, 0xB13425, 0xB03325, 0xB03125, 0xAF3024, 0xAE2F24, 0xAE2D24, 0xAD2C24, 0xAC2B24, 0xAB2A24,
4207 0xAA2824, 0xAA2724, 0xA92624, 0xA82524, 0xA72424, 0xA62225, 0xA52125, 0xA42025, 0xA31F25, 0xA21E25, 0xA11D25,
4208 0xA01C26, 0x9F1B26, 0x9E1A26, 0x9D1926, 0x9C1827, 0x9B1727, 0x9A1627, 0x991527, 0x981527, 0x971428, 0x951328,
4209 0x941328, 0x931228, 0x921128, 0x911129, 0x901029, 0x8E1029, 0x8D1029, 0x8C0F29, 0x8B0F29, 0x890F29, 0x880F29,
4210 0x870E29, 0x850E29, 0x840E29, 0x830E29, 0x810E29, 0x800E29, 0x7F0E29, 0x7D0E29, 0x7C0E29, 0x7B0E29, 0x790E29,
4211 0x780E28, 0x770E28, 0x750E28, 0x740E28, 0x730E27, 0x710E27, 0x700E27, 0x6F0E26, 0x6D0E26, 0x6C0F26, 0x6B0F25,
4212 0x690F25, 0x680F25, 0x670F24, 0x650F24, 0x640E23, 0x630E23, 0x610E22, 0x600E22, 0x5F0E21, 0x5D0E21, 0x5C0E21,
4213 0x5B0E20, 0x5A0E1F, 0x580E1F, 0x570E1E, 0x560E1E, 0x540D1D, 0x530D1D, 0x520D1C, 0x510D1C, 0x4F0D1B, 0x4E0D1A,
4214 0x4D0C1A, 0x4B0C19, 0x4A0C19, 0x490C18, 0x480B17, 0x460B17, 0x450B16, 0x440B16, 0x430A15, 0x410A14, 0x400A14,
4215 0x3F0A13, 0x3D0912, 0x3C0912> csFPcmoceanAmp;
4216 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4217 /** @class csFPcmoceanBalance
4218 @ingroup cs
4219 @extends csFP_tpl */
4220 typedef csFP_tpl<0x181C43, 0x191E46, 0x1A1F49, 0x1B214C, 0x1C224F, 0x1D2352, 0x1E2555, 0x1F2658, 0x20275B, 0x21295F, 0x212A62,
4221 0x222B65, 0x232D69, 0x242E6C, 0x252F6F, 0x253073, 0x263276, 0x27337A, 0x27347D, 0x283681, 0x283784, 0x293888,
4222 0x293A8C, 0x293B8F, 0x293C93, 0x293E97, 0x293F9A, 0x29409E, 0x2942A2, 0x2843A5, 0x2745A9, 0x2647AC, 0x2548B0,
4223 0x234AB3, 0x214CB6, 0x1F4EB8, 0x1C50BA, 0x1952BC, 0x1655BD, 0x1357BE, 0x1059BE, 0x0D5BBE, 0x0C5EBE, 0x0A60BE,
4224 0x0A62BE, 0x0A64BE, 0x0B66BD, 0x0D68BD, 0x0F6ABD, 0x116CBC, 0x136EBC, 0x1670BC, 0x1972BB, 0x1B74BB, 0x1E76BB,
4225 0x2178BB, 0x237ABA, 0x267BBA, 0x297DBA, 0x2B7FBA, 0x2E81BA, 0x3083BA, 0x3384BA, 0x3686BA, 0x3888BA, 0x3B89BA,
4226 0x3E8BBA, 0x408DBA, 0x438FBA, 0x4690BA, 0x4892BA, 0x4B94BA, 0x4E95BA, 0x5197BA, 0x5399BA, 0x569ABB, 0x599CBB,
4227 0x5C9DBB, 0x5F9FBB, 0x62A0BB, 0x65A2BC, 0x68A4BC, 0x6BA5BC, 0x6EA7BD, 0x71A8BD, 0x75AABE, 0x78ABBE, 0x7BACBF,
4228 0x7EAEBF, 0x81AFC0, 0x85B1C0, 0x88B2C1, 0x8BB4C2, 0x8EB5C3, 0x91B7C3, 0x94B8C4, 0x98BAC5, 0x9BBBC6, 0x9EBCC7,
4229 0xA1BEC8, 0xA4BFC9, 0xA7C1CA, 0xAAC2CB, 0xADC4CC, 0xB0C5CD, 0xB3C7CE, 0xB6C9CF, 0xB9CAD0, 0xBCCCD2, 0xBFCDD3,
4230 0xC1CFD4, 0xC4D0D5, 0xC7D2D7, 0xCAD4D8, 0xCDD5D9, 0xD0D7DA, 0xD3D9DC, 0xD5DADD, 0xD8DCDE, 0xDBDEE0, 0xDEE0E1,
4231 0xE1E1E3, 0xE3E3E4, 0xE6E5E6, 0xE9E7E7, 0xEBE9E9, 0xEEEAEA, 0xF1ECEC, 0xF1ECEB, 0xF0EAE9, 0xEFE8E6, 0xEEE5E3,
4232 0xEDE3E0, 0xECE0DE, 0xEBDEDB, 0xEADCD8, 0xE9D9D5, 0xE8D7D2, 0xE7D5CF, 0xE6D2CD, 0xE5D0CA, 0xE5CEC7, 0xE4CBC4,
4233 0xE3C9C1, 0xE2C7BE, 0xE1C4BB, 0xE1C2B8, 0xE0C0B5, 0xDFBDB2, 0xDFBBB0, 0xDEB9AD, 0xDDB6AA, 0xDCB4A7, 0xDCB2A4,
4234 0xDBAFA1, 0xDAAD9E, 0xDAAB9B, 0xD9A998, 0xD8A696, 0xD8A493, 0xD7A290, 0xD69F8D, 0xD69D8A, 0xD59B87, 0xD49984,
4235 0xD39681, 0xD3947F, 0xD2927C, 0xD18F79, 0xD18D76, 0xD08B73, 0xCF8970, 0xCF866E, 0xCE846B, 0xCD8268, 0xCD7F65,
4236 0xCC7D63, 0xCB7B60, 0xCA795D, 0xCA765B, 0xC97458, 0xC87255, 0xC76F53, 0xC76D50, 0xC66B4D, 0xC5684B, 0xC46648,
4237 0xC36346, 0xC36143, 0xC25F41, 0xC15C3F, 0xC05A3C, 0xBF573A, 0xBE5538, 0xBE5236, 0xBD5034, 0xBC4D32, 0xBB4B30,
4238 0xBA482E, 0xB9452C, 0xB8432B, 0xB74029, 0xB63D28, 0xB43B27, 0xB33826, 0xB23525, 0xB13325, 0xAF3024, 0xAE2E24,
4239 0xAC2B24, 0xAB2924, 0xA92624, 0xA72424, 0xA52125, 0xA31F25, 0xA11D25, 0x9F1B26, 0x9D1926, 0x9B1727, 0x991627,
4240 0x971428, 0x941328, 0x921228, 0x901029, 0x8D1029, 0x8B0F29, 0x880F29, 0x860E29, 0x830E29, 0x800E29, 0x7E0E29,
4241 0x7B0E29, 0x780E28, 0x760E28, 0x730E27, 0x700E27, 0x6D0E26, 0x6B0F25, 0x680F25, 0x650F24, 0x630E23, 0x600E22,
4242 0x5E0E21, 0x5B0E20, 0x580E1F, 0x560E1E, 0x530D1D, 0x510D1C, 0x4E0D1B, 0x4B0C19, 0x490C18, 0x460B17, 0x440B16,
4243 0x410A14, 0x3F0A13, 0x3C0912> csFPcmoceanBalance;
4244 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4245 /** @class csFPcmoceanCurl
4246 @ingroup cs
4247 @extends csFP_tpl */
4248 typedef csFP_tpl<0x151D44, 0x151F45, 0x162146, 0x162347, 0x172548, 0x172749, 0x18294A, 0x182B4B, 0x182D4C, 0x192F4D, 0x19314F,
4249 0x1A3350, 0x1A3551, 0x1A3652, 0x1B3853, 0x1B3A54, 0x1B3C56, 0x1B3E57, 0x1C4058, 0x1C4259, 0x1C435A, 0x1C455B,
4250 0x1C475D, 0x1C495E, 0x1C4B5F, 0x1C4C60, 0x1C4E61, 0x1C5062, 0x1C5263, 0x1C5465, 0x1B5666, 0x1B5867, 0x1B5968,
4251 0x1A5B69, 0x1A5D6A, 0x1A5F6B, 0x19616C, 0x19636D, 0x18656E, 0x17666F, 0x176870, 0x166A71, 0x156C72, 0x146E73,
4252 0x147074, 0x137275, 0x127476, 0x127676, 0x117777, 0x117978, 0x117B79, 0x117D79, 0x117F7A, 0x12817B, 0x13837B,
4253 0x14847C, 0x16867C, 0x17887D, 0x1A8A7D, 0x1C8C7E, 0x1F8D7E, 0x228F7E, 0x25917F, 0x29937F, 0x2C947F, 0x309680,
4254 0x349880, 0x389981, 0x3B9B81, 0x3F9C81, 0x439E82, 0x479F82, 0x4BA183, 0x50A284, 0x54A484, 0x57A585, 0x5BA686,
4255 0x5FA887, 0x63A988, 0x67AB89, 0x6BAC8A, 0x6FAD8B, 0x72AF8C, 0x76B08D, 0x7AB18E, 0x7DB390, 0x81B491, 0x85B593,
4256 0x88B794, 0x8BB896, 0x8FBA97, 0x92BB99, 0x96BC9B, 0x99BE9D, 0x9CBF9F, 0xA0C0A0, 0xA3C2A2, 0xA6C3A4, 0xA9C5A6,
4257 0xACC6A9, 0xB0C8AB, 0xB3C9AD, 0xB6CBAF, 0xB9CCB2, 0xBCCEB4, 0xBFCFB6, 0xC2D1B9, 0xC5D2BB, 0xC8D4BE, 0xCBD5C0,
4258 0xCED7C3, 0xD1D8C5, 0xD3DAC8, 0xD6DCCB, 0xD9DDCD, 0xDCDFD0, 0xDFE1D3, 0xE2E2D6, 0xE4E4D8, 0xE7E6DB, 0xEAE8DE,
4259 0xEDEAE1, 0xF0EBE4, 0xF2EDE7, 0xF5EFEA, 0xF8F1ED, 0xFBF3F0, 0xFDF5F3, 0xFEF6F5, 0xFCF4F1, 0xFBF1EE, 0xFAEFEB,
4260 0xF9ECE7, 0xF8EAE4, 0xF6E7E1, 0xF5E5DD, 0xF4E2DA, 0xF3E0D6, 0xF2DDD3, 0xF2DBD0, 0xF1D8CC, 0xF0D6C9, 0xEFD3C6,
4261 0xEED1C3, 0xEDCFBF, 0xECCCBC, 0xECCAB9, 0xEBC7B6, 0xEAC5B3, 0xE9C2AF, 0xE9C0AC, 0xE8BDA9, 0xE7BBA6, 0xE7B8A3,
4262 0xE6B6A0, 0xE5B39D, 0xE5B19A, 0xE4AE98, 0xE3AC95, 0xE3A992, 0xE2A78F, 0xE1A48D, 0xE1A28A, 0xE09F88, 0xE09D85,
4263 0xDF9A83, 0xDE9880, 0xDE957E, 0xDD937C, 0xDC907A, 0xDB8E78, 0xDB8B76, 0xDA8974, 0xD98672, 0xD88471, 0xD7816F,
4264 0xD67F6E, 0xD67C6C, 0xD57A6B, 0xD4776A, 0xD37569, 0xD27268, 0xD07067, 0xCF6E66, 0xCE6B65, 0xCD6964, 0xCC6764,
4265 0xCA6463, 0xC96263, 0xC86062, 0xC65D62, 0xC55B61, 0xC35961, 0xC25761, 0xC05561, 0xBF5360, 0xBD5160, 0xBB4E60,
4266 0xBA4C60, 0xB84A60, 0xB64860, 0xB44660, 0xB34460, 0xB14260, 0xAF4160, 0xAD3F60, 0xAB3D60, 0xA93B60, 0xA73960,
4267 0xA53760, 0xA33660, 0xA13460, 0x9F3260, 0x9D3060, 0x9B2F60, 0x992D61, 0x972B61, 0x952A61, 0x922861, 0x902760,
4268 0x8E2560, 0x8C2460, 0x892260, 0x872160, 0x852060, 0x821F60, 0x801D5F, 0x7D1C5F, 0x7B1B5E, 0x781A5E, 0x76195D,
4269 0x73195D, 0x71185C, 0x6E175B, 0x6C175A, 0x691659, 0x661658, 0x641557, 0x611556, 0x5E1455, 0x5C1453, 0x591452,
4270 0x571350, 0x54134E, 0x51134D, 0x4F124B, 0x4C1249, 0x491247, 0x471145, 0x441143, 0x421041, 0x3F103F, 0x3D0F3D,
4271 0x3A0F3B, 0x380E39, 0x350D36> csFPcmoceanCurl;
4272 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4273 /** @class csFPcmoceanDeep
4274 @ingroup cs
4275 @extends csFP_tpl */
4276 typedef csFP_tpl<0xFDFECC, 0xFBFDCB, 0xF9FCCA, 0xF7FBC8, 0xF5FAC7, 0xF3FAC6, 0xF1F9C5, 0xEFF8C4, 0xEDF7C3, 0xEBF7C1, 0xE9F6C0,
4277 0xE7F5BF, 0xE5F4BE, 0xE3F4BD, 0xE1F3BC, 0xDFF2BB, 0xDDF2BA, 0xDBF1B9, 0xD9F0B8, 0xD7EFB7, 0xD4EFB6, 0xD2EEB5,
4278 0xD0EDB4, 0xCEECB3, 0xCCECB3, 0xCAEBB2, 0xC8EAB1, 0xC6EAB0, 0xC4E9AF, 0xC1E8AF, 0xBFE7AE, 0xBDE7AD, 0xBBE6AC,
4279 0xB9E5AC, 0xB7E5AB, 0xB5E4AA, 0xB2E3AA, 0xB0E2A9, 0xAEE2A9, 0xACE1A8, 0xAAE0A8, 0xA7E0A7, 0xA5DFA7, 0xA3DEA6,
4280 0xA1DDA6, 0x9FDDA5, 0x9CDCA5, 0x9ADBA5, 0x98DAA4, 0x96DAA4, 0x94D9A4, 0x92D8A4, 0x90D7A4, 0x8DD7A3, 0x8BD6A3,
4281 0x89D5A3, 0x87D4A3, 0x85D3A3, 0x83D3A3, 0x81D2A3, 0x7FD1A3, 0x7DD0A3, 0x7CCFA3, 0x7ACEA3, 0x78CEA3, 0x76CDA3,
4282 0x75CCA3, 0x73CBA3, 0x71CAA3, 0x70C9A3, 0x6EC8A3, 0x6DC7A3, 0x6BC6A3, 0x6AC5A4, 0x69C4A4, 0x67C3A4, 0x66C2A4,
4283 0x65C2A4, 0x64C1A4, 0x63C0A4, 0x62BFA4, 0x61BEA4, 0x60BDA4, 0x5FBCA4, 0x5EBBA4, 0x5DBAA4, 0x5CB9A4, 0x5BB8A4,
4284 0x5AB7A4, 0x5AB6A4, 0x59B4A4, 0x58B3A4, 0x58B2A4, 0x57B1A4, 0x56B0A4, 0x56AFA4, 0x55AEA3, 0x55ADA3, 0x54ACA3,
4285 0x53ABA3, 0x53AAA3, 0x52A9A3, 0x52A8A3, 0x51A7A3, 0x51A6A2, 0x51A5A2, 0x50A4A2, 0x50A3A2, 0x4FA2A2, 0x4FA1A2,
4286 0x4FA0A2, 0x4E9FA1, 0x4E9EA1, 0x4D9DA1, 0x4D9CA1, 0x4D9BA1, 0x4C9AA0, 0x4C99A0, 0x4B98A0, 0x4B97A0, 0x4B96A0,
4287 0x4A959F, 0x4A949F, 0x4A939F, 0x49929F, 0x49919E, 0x49909E, 0x488F9E, 0x488E9E, 0x488D9D, 0x478C9D, 0x478B9D,
4288 0x478A9D, 0x46899D, 0x46889C, 0x46879C, 0x45869C, 0x45859C, 0x45849B, 0x44839B, 0x44829B, 0x44819B, 0x44809B,
4289 0x437F9A, 0x437E9A, 0x437D9A, 0x427C9A, 0x427B99, 0x427A99, 0x427999, 0x417899, 0x417799, 0x417698, 0x407598,
4290 0x407498, 0x407398, 0x407298, 0x407197, 0x3F7097, 0x3F6F97, 0x3F6E97, 0x3F6D97, 0x3F6C96, 0x3E6B96, 0x3E6A96,
4291 0x3E6996, 0x3E6896, 0x3E6795, 0x3E6695, 0x3E6595, 0x3E6495, 0x3E6394, 0x3E6294, 0x3E6194, 0x3E6094, 0x3E5F93,
4292 0x3E5E93, 0x3E5C93, 0x3E5B93, 0x3E5A92, 0x3E5992, 0x3E5892, 0x3E5791, 0x3E5691, 0x3F5590, 0x3F5490, 0x3F538F,
4293 0x3F528F, 0x3F508E, 0x404F8D, 0x404E8D, 0x404D8C, 0x404C8B, 0x414B8A, 0x414A89, 0x414988, 0x414887, 0x414785,
4294 0x414684, 0x414583, 0x414481, 0x424380, 0x41427E, 0x41417D, 0x41407B, 0x41407A, 0x413F78, 0x413E76, 0x413D75,
4295 0x403C73, 0x403C71, 0x403B70, 0x403A6E, 0x3F396C, 0x3F386B, 0x3F3869, 0x3E3767, 0x3E3666, 0x3D3564, 0x3D3562,
4296 0x3D3461, 0x3C335F, 0x3C325D, 0x3B325C, 0x3B315A, 0x3A3058, 0x3A3057, 0x392F55, 0x392E54, 0x382D52, 0x382D51,
4297 0x372C4F, 0x362B4D, 0x362A4C, 0x352A4A, 0x352949, 0x342847, 0x342846, 0x332744, 0x322643, 0x322541, 0x312540,
4298 0x30243E, 0x30233D, 0x2F223B, 0x2F223A, 0x2E2139, 0x2D2037, 0x2D1F36, 0x2C1F34, 0x2B1E33, 0x2B1D32, 0x2A1C30,
4299 0x291C2F, 0x281B2D, 0x281A2C> csFPcmoceanDeep;
4300 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4301 /** @class csFPcmoceanDense
4302 @ingroup cs
4303 @extends csFP_tpl */
4304 typedef csFP_tpl<0xE6F1F1, 0xE4F0F0, 0xE3EFEF, 0xE1EEEF, 0xDFEDEE, 0xDDEDED, 0xDCECED, 0xDAEBEC, 0xD8EAEC, 0xD7E9EB, 0xD5E9EB,
4305 0xD3E8EA, 0xD1E7EA, 0xD0E6E9, 0xCEE5E9, 0xCCE4E8, 0xCBE4E8, 0xC9E3E8, 0xC7E2E7, 0xC6E1E7, 0xC4E0E6, 0xC2DFE6,
4306 0xC1DFE6, 0xBFDEE6, 0xBEDDE5, 0xBCDCE5, 0xBADBE5, 0xB9DAE4, 0xB7DAE4, 0xB6D9E4, 0xB4D8E4, 0xB2D7E4, 0xB1D6E3,
4307 0xAFD5E3, 0xAED4E3, 0xACD4E3, 0xABD3E3, 0xA9D2E3, 0xA8D1E3, 0xA6D0E3, 0xA5CFE2, 0xA3CEE2, 0xA2CEE2, 0xA0CDE2,
4308 0x9FCCE2, 0x9ECBE2, 0x9CCAE2, 0x9BC9E2, 0x9AC8E2, 0x98C7E2, 0x97C6E2, 0x96C5E2, 0x94C5E2, 0x93C4E2, 0x92C3E2,
4309 0x90C2E2, 0x8FC1E2, 0x8EC0E2, 0x8DBFE2, 0x8CBEE2, 0x8ABDE3, 0x89BCE3, 0x88BBE3, 0x87BAE3, 0x86B9E3, 0x85B8E3,
4310 0x84B7E3, 0x83B6E3, 0x82B5E3, 0x81B4E3, 0x80B3E3, 0x7FB2E3, 0x7FB1E4, 0x7EB0E4, 0x7DAFE4, 0x7CAEE4, 0x7BADE4,
4311 0x7BACE4, 0x7AABE4, 0x79AAE4, 0x79A9E4, 0x78A8E4, 0x78A7E4, 0x77A6E4, 0x77A5E4, 0x76A4E5, 0x76A3E5, 0x75A1E5,
4312 0x75A0E5, 0x759FE5, 0x759EE5, 0x749DE5, 0x749CE4, 0x749BE4, 0x749AE4, 0x7498E4, 0x7397E4, 0x7396E4, 0x7395E4,
4313 0x7394E4, 0x7393E3, 0x7391E3, 0x7390E3, 0x738FE3, 0x738EE2, 0x748DE2, 0x748BE2, 0x748AE2, 0x7489E1, 0x7488E1,
4314 0x7487E0, 0x7485E0, 0x7584DF, 0x7583DF, 0x7582DE, 0x7581DE, 0x757FDD, 0x757EDD, 0x767DDC, 0x767CDC, 0x767BDB,
4315 0x7679DA, 0x7678DA, 0x7777D9, 0x7776D8, 0x7775D7, 0x7773D7, 0x7772D6, 0x7871D5, 0x7870D4, 0x786FD3, 0x786ED2,
4316 0x786CD2, 0x786BD1, 0x786AD0, 0x7969CF, 0x7968CE, 0x7966CD, 0x7965CC, 0x7964CB, 0x7963CA, 0x7962C9, 0x7961C8,
4317 0x7960C7, 0x795EC5, 0x795DC4, 0x795CC3, 0x795BC2, 0x795AC1, 0x7959C0, 0x7958BF, 0x7957BD, 0x7956BC, 0x7954BB,
4318 0x7953BA, 0x7952B8, 0x7951B7, 0x7950B6, 0x794FB5, 0x784EB3, 0x784DB2, 0x784CB1, 0x784BAF, 0x784AAE, 0x7849AD,
4319 0x7748AB, 0x7747AA, 0x7746A9, 0x7745A7, 0x7743A6, 0x7642A5, 0x7641A3, 0x7640A2, 0x763FA0, 0x753E9F, 0x753D9D,
4320 0x753C9C, 0x743B9B, 0x743B99, 0x743A98, 0x733996, 0x733895, 0x733793, 0x723692, 0x723590, 0x72348F, 0x71338D,
4321 0x71328C, 0x70318A, 0x703088, 0x6F2F87, 0x6F2E85, 0x6E2D84, 0x6E2D82, 0x6D2C81, 0x6D2B7F, 0x6C2A7E, 0x6C297C,
4322 0x6B287A, 0x6B2879, 0x6A2777, 0x6A2675, 0x692574, 0x682472, 0x682471, 0x67236F, 0x67226D, 0x66216C, 0x65216A,
4323 0x652068, 0x641F67, 0x631F65, 0x621E63, 0x621D62, 0x611D60, 0x601C5E, 0x5F1B5D, 0x5F1B5B, 0x5E1A59, 0x5D1A58,
4324 0x5C1956, 0x5B1954, 0x5A1853, 0x5A1851, 0x591750, 0x58174E, 0x57164C, 0x56164B, 0x551649, 0x541548, 0x531546,
4325 0x521544, 0x511443, 0x501441, 0x4F1440, 0x4E133E, 0x4D133D, 0x4B133B, 0x4A133A, 0x491238, 0x481237, 0x471236,
4326 0x461234, 0x451133, 0x441132, 0x421130, 0x41112F, 0x40102E, 0x3F102D, 0x3E102B, 0x3C102A, 0x3B0F29, 0x3A0F28,
4327 0x390F27, 0x380F25, 0x360E24> csFPcmoceanDense;
4328 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4329 /** @class csFPcmoceanHaline
4330 @ingroup cs
4331 @extends csFP_tpl */
4332 typedef csFP_tpl<0x2A186C, 0x2A196E, 0x2A1971, 0x2B1973, 0x2B1975, 0x2C1A78, 0x2C1A7A, 0x2D1A7D, 0x2D1A7F, 0x2D1B82, 0x2E1B84,
4333 0x2E1B87, 0x2E1C89, 0x2E1C8C, 0x2E1C8E, 0x2E1D91, 0x2E1D93, 0x2E1E95, 0x2E1E98, 0x2E1F9A, 0x2D209C, 0x2D219D,
4334 0x2C229F, 0x2B24A0, 0x2A25A1, 0x2927A2, 0x2829A3, 0x262BA3, 0x252DA3, 0x242EA3, 0x2230A3, 0x2132A2, 0x2034A2,
4335 0x1E35A1, 0x1D37A1, 0x1C39A0, 0x1B3AA0, 0x193C9F, 0x183D9E, 0x173F9E, 0x16409D, 0x15419C, 0x14439C, 0x13449B,
4336 0x12459B, 0x11479A, 0x104899, 0x0F4999, 0x0F4A98, 0x0E4C97, 0x0D4D97, 0x0D4E96, 0x0D4F96, 0x0C5095, 0x0C5195,
4337 0x0C5294, 0x0C5394, 0x0C5493, 0x0D5593, 0x0D5692, 0x0D5792, 0x0E5891, 0x0E5991, 0x0F5A91, 0x0F5B90, 0x105C90,
4338 0x115D8F, 0x115E8F, 0x125F8F, 0x13608E, 0x14618E, 0x14628E, 0x15638E, 0x16638D, 0x17648D, 0x18658D, 0x18668C,
4339 0x19678C, 0x1A688C, 0x1B698C, 0x1C6A8C, 0x1D6B8B, 0x1D6B8B, 0x1E6C8B, 0x1F6D8B, 0x206E8B, 0x216F8B, 0x22708A,
4340 0x22718A, 0x23718A, 0x24728A, 0x25738A, 0x26748A, 0x26758A, 0x27768A, 0x287689, 0x297789, 0x297889, 0x2A7989,
4341 0x2B7A89, 0x2B7B89, 0x2C7C89, 0x2D7C89, 0x2D7D89, 0x2E7E89, 0x2F7F89, 0x2F8089, 0x308189, 0x318289, 0x318288,
4342 0x328388, 0x338488, 0x338588, 0x348688, 0x348788, 0x358888, 0x358988, 0x368988, 0x378A88, 0x378B88, 0x388C88,
4343 0x388D88, 0x398E88, 0x398F88, 0x3A9087, 0x3A9087, 0x3B9187, 0x3B9287, 0x3C9387, 0x3C9487, 0x3D9587, 0x3D9687,
4344 0x3E9787, 0x3E9886, 0x3F9986, 0x3F9986, 0x409A86, 0x419B86, 0x419C85, 0x429D85, 0x429E85, 0x439F85, 0x43A084,
4345 0x44A184, 0x44A284, 0x45A384, 0x46A483, 0x46A483, 0x47A583, 0x48A682, 0x48A782, 0x49A882, 0x4AA981, 0x4AAA81,
4346 0x4BAB81, 0x4CAC80, 0x4CAD80, 0x4DAE7F, 0x4EAE7F, 0x4FAF7E, 0x50B07E, 0x51B17D, 0x51B27D, 0x52B37C, 0x53B47C,
4347 0x54B57B, 0x55B67B, 0x56B77A, 0x57B879, 0x58B879, 0x5AB978, 0x5BBA77, 0x5CBB77, 0x5DBC76, 0x5EBD75, 0x5FBE75,
4348 0x61BF74, 0x62BF73, 0x63C072, 0x65C172, 0x66C271, 0x68C370, 0x69C46F, 0x6BC46E, 0x6CC56E, 0x6EC66D, 0x70C76C,
4349 0x71C86B, 0x73C86A, 0x75C969, 0x77CA68, 0x78CB68, 0x7ACB67, 0x7CCC66, 0x7ECD65, 0x80CE64, 0x82CE63, 0x84CF62,
4350 0x86D062, 0x89D061, 0x8BD160, 0x8DD25F, 0x8FD25F, 0x92D35E, 0x94D35D, 0x97D45D, 0x99D45D, 0x9BD55C, 0x9ED65C,
4351 0xA0D65C, 0xA3D75C, 0xA5D75C, 0xA8D85C, 0xAAD85C, 0xADD85C, 0xAFD95D, 0xB1D95D, 0xB4DA5E, 0xB6DA5F, 0xB8DB60,
4352 0xBBDB61, 0xBDDC62, 0xBFDC63, 0xC1DD64, 0xC4DD65, 0xC6DE66, 0xC8DE67, 0xCADF69, 0xCCDF6A, 0xCEE06C, 0xD0E06D,
4353 0xD2E16F, 0xD4E170, 0xD6E272, 0xD8E273, 0xDAE375, 0xDCE377, 0xDEE479, 0xE0E57A, 0xE1E57C, 0xE3E67E, 0xE5E680,
4354 0xE7E781, 0xE9E783, 0xEBE885, 0xECE987, 0xEEE989, 0xF0EA8A, 0xF2EA8C, 0xF3EB8E, 0xF5EC90, 0xF7EC92, 0xF8ED94,
4355 0xFAEE96, 0xFCEE98, 0xFDEF9A> csFPcmoceanHaline;
4356 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4357 /** @class csFPcmoceanIce
4358 @ingroup cs
4359 @extends csFP_tpl */
4360 typedef csFP_tpl<0x040613, 0x050614, 0x050715, 0x060817, 0x070918, 0x080A1A, 0x090B1B, 0x0A0C1D, 0x0B0D1E, 0x0C0D1F, 0x0D0E21,
4361 0x0E0F22, 0x0F1024, 0x101125, 0x111227, 0x121328, 0x13132A, 0x14142B, 0x15152C, 0x16162E, 0x17172F, 0x171831,
4362 0x181832, 0x191934, 0x1A1A35, 0x1B1B37, 0x1C1C38, 0x1D1C3A, 0x1E1D3B, 0x1F1E3D, 0x1F1F3E, 0x201F40, 0x212041,
4363 0x222143, 0x232244, 0x242246, 0x252347, 0x252449, 0x26254A, 0x27254C, 0x28264E, 0x29274F, 0x292851, 0x2A2852,
4364 0x2B2954, 0x2C2A55, 0x2C2B57, 0x2D2B59, 0x2E2C5A, 0x2F2D5C, 0x2F2E5E, 0x302F5F, 0x312F61, 0x313062, 0x323164,
4365 0x333266, 0x333267, 0x343369, 0x35346B, 0x35356C, 0x36356E, 0x363670, 0x373771, 0x383873, 0x383975, 0x393976,
4366 0x393A78, 0x3A3B7A, 0x3A3C7B, 0x3A3D7D, 0x3B3E7F, 0x3B3E80, 0x3C3F82, 0x3C4084, 0x3C4185, 0x3D4287, 0x3D4389,
4367 0x3D448A, 0x3E458C, 0x3E468D, 0x3E478F, 0x3E4890, 0x3E4992, 0x3E4993, 0x3F4A95, 0x3F4B96, 0x3F4C97, 0x3F4E99,
4368 0x3F4F9A, 0x3F509B, 0x3F519D, 0x3F529E, 0x3F539F, 0x3F54A0, 0x3F55A1, 0x3F56A2, 0x3F57A3, 0x3F58A4, 0x3F59A5,
4369 0x3E5AA6, 0x3E5CA7, 0x3E5DA8, 0x3E5EA9, 0x3E5FAA, 0x3E60AB, 0x3E61AB, 0x3E62AC, 0x3E63AD, 0x3E65AD, 0x3E66AE,
4370 0x3E67AF, 0x3E68AF, 0x3E69B0, 0x3E6AB0, 0x3F6BB1, 0x3F6CB2, 0x3F6EB2, 0x3F6FB3, 0x3F70B3, 0x3F71B4, 0x4072B4,
4371 0x4073B4, 0x4074B5, 0x4075B5, 0x4176B6, 0x4178B6, 0x4279B7, 0x427AB7, 0x427BB7, 0x437CB8, 0x437DB8, 0x447EB9,
4372 0x447FB9, 0x4580B9, 0x4581BA, 0x4682BA, 0x4684BB, 0x4785BB, 0x4786BB, 0x4887BC, 0x4988BC, 0x4989BC, 0x4A8ABD,
4373 0x4B8BBD, 0x4B8CBD, 0x4C8DBE, 0x4D8EBE, 0x4E8FBF, 0x4E90BF, 0x4F91BF, 0x5092C0, 0x5194C0, 0x5195C0, 0x5296C1,
4374 0x5397C1, 0x5498C2, 0x5599C2, 0x559AC2, 0x569BC3, 0x579CC3, 0x589DC3, 0x599EC4, 0x5A9FC4, 0x5BA0C5, 0x5CA1C5,
4375 0x5DA2C5, 0x5EA3C6, 0x5FA4C6, 0x5FA6C7, 0x60A7C7, 0x61A8C7, 0x62A9C8, 0x63AAC8, 0x64ABC9, 0x65ACC9, 0x67ADC9,
4376 0x68AECA, 0x69AFCA, 0x6AB0CB, 0x6BB1CB, 0x6CB2CB, 0x6DB3CC, 0x6EB4CC, 0x6FB5CD, 0x71B6CD, 0x72B8CE, 0x73B9CE,
4377 0x74BACE, 0x75BBCF, 0x77BCCF, 0x78BDD0, 0x79BED0, 0x7BBFD0, 0x7CC0D1, 0x7DC1D1, 0x7FC2D2, 0x80C3D2, 0x82C4D3,
4378 0x83C5D3, 0x85C6D3, 0x86C7D4, 0x88C8D4, 0x89C9D5, 0x8BCAD5, 0x8CCBD6, 0x8ECCD6, 0x90CDD7, 0x92CED7, 0x93CFD8,
4379 0x95D0D8, 0x97D1D9, 0x99D2D9, 0x9AD3DA, 0x9CD4DA, 0x9ED5DB, 0xA0D6DC, 0xA2D6DC, 0xA4D7DD, 0xA6D8DE, 0xA8D9DE,
4380 0xA9DADF, 0xABDBE0, 0xADDCE0, 0xAFDDE1, 0xB1DEE2, 0xB3DFE3, 0xB5E0E3, 0xB7E1E4, 0xB9E2E5, 0xBAE3E6, 0xBCE4E7,
4381 0xBEE5E7, 0xC0E6E8, 0xC2E6E9, 0xC4E7EA, 0xC6E8EB, 0xC8E9EC, 0xC9EAED, 0xCBEBEE, 0xCDECEF, 0xCFEDEF, 0xD1EEF0,
4382 0xD3EFF1, 0xD5F0F2, 0xD6F1F3, 0xD8F2F4, 0xDAF3F5, 0xDCF4F6, 0xDEF5F7, 0xE0F6F8, 0xE1F7F9, 0xE3F9FA, 0xE5FAFB,
4383 0xE7FBFB, 0xE8FCFC, 0xEAFDFD> csFPcmoceanIce;
4384 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4385 /** @class csFPcmoceanTempo
4386 @ingroup cs
4387 @extends csFP_tpl */
4388 typedef csFP_tpl<0xFFF6F4, 0xFDF5F3, 0xFCF4F1, 0xFBF3F0, 0xF9F2EE, 0xF8F1ED, 0xF7F0EB, 0xF5EFEA, 0xF4EEE8, 0xF2EDE7, 0xF1ECE5,
4389 0xF0EBE4, 0xEEEAE2, 0xEDEAE1, 0xEBE9DF, 0xEAE8DE, 0xE9E7DD, 0xE7E6DB, 0xE6E5DA, 0xE4E4D8, 0xE3E3D7, 0xE2E2D6,
4390 0xE0E2D4, 0xDFE1D3, 0xDDE0D1, 0xDCDFD0, 0xDBDECF, 0xD9DDCD, 0xD8DDCC, 0xD6DCCB, 0xD5DBC9, 0xD3DAC8, 0xD2D9C7,
4391 0xD1D8C5, 0xCFD8C4, 0xCED7C3, 0xCCD6C1, 0xCBD5C0, 0xC9D4BF, 0xC8D4BE, 0xC6D3BC, 0xC5D2BB, 0xC3D1BA, 0xC2D1B9,
4392 0xC0D0B7, 0xBFCFB6, 0xBDCEB5, 0xBCCEB4, 0xBACDB3, 0xB9CCB2, 0xB7CBB0, 0xB6CBAF, 0xB4CAAE, 0xB3C9AD, 0xB1C8AC,
4393 0xB0C8AB, 0xAEC7AA, 0xACC6A9, 0xABC5A8, 0xA9C5A6, 0xA8C4A5, 0xA6C3A4, 0xA4C3A3, 0xA3C2A2, 0xA1C1A1, 0xA0C0A0,
4394 0x9EC09F, 0x9CBF9F, 0x9BBE9E, 0x99BE9D, 0x97BD9C, 0x96BC9B, 0x94BC9A, 0x92BB99, 0x91BA98, 0x8FBA97, 0x8DB997,
4395 0x8BB896, 0x8AB795, 0x88B794, 0x86B693, 0x85B593, 0x83B592, 0x81B491, 0x7FB390, 0x7DB390, 0x7CB28F, 0x7AB18E,
4396 0x78B18E, 0x76B08D, 0x74AF8D, 0x72AF8C, 0x71AE8B, 0x6FAD8B, 0x6DAD8A, 0x6BAC8A, 0x69AB89, 0x67AB89, 0x65AA88,
4397 0x63A988, 0x61A987, 0x5FA887, 0x5DA786, 0x5BA686, 0x59A685, 0x57A585, 0x56A485, 0x54A484, 0x52A384, 0x50A284,
4398 0x4EA183, 0x4BA183, 0x49A083, 0x479F82, 0x459F82, 0x439E82, 0x419D82, 0x3F9C81, 0x3D9C81, 0x3B9B81, 0x3A9A81,
4399 0x389981, 0x369880, 0x349880, 0x329780, 0x309680, 0x2E9580, 0x2C947F, 0x2A937F, 0x29937F, 0x27927F, 0x25917F,
4400 0x24907F, 0x228F7E, 0x218E7E, 0x1F8D7E, 0x1E8D7E, 0x1C8C7E, 0x1B8B7D, 0x1A8A7D, 0x19897D, 0x17887D, 0x16877C,
4401 0x16867C, 0x15857C, 0x14847C, 0x13847B, 0x13837B, 0x12827B, 0x12817B, 0x11807A, 0x117F7A, 0x117E7A, 0x117D79,
4402 0x117C79, 0x117B79, 0x117A78, 0x117978, 0x117878, 0x117777, 0x117677, 0x127676, 0x127576, 0x127476, 0x137375,
4403 0x137275, 0x137174, 0x147074, 0x146F73, 0x146E73, 0x156D73, 0x156C72, 0x166B72, 0x166A71, 0x166971, 0x176870,
4404 0x176770, 0x17666F, 0x18656F, 0x18656E, 0x18646E, 0x19636D, 0x19626D, 0x19616C, 0x19606C, 0x1A5F6B, 0x1A5E6B,
4405 0x1A5D6A, 0x1A5C6A, 0x1A5B69, 0x1B5A68, 0x1B5968, 0x1B5867, 0x1B5867, 0x1B5766, 0x1B5666, 0x1C5565, 0x1C5465,
4406 0x1C5364, 0x1C5263, 0x1C5163, 0x1C5062, 0x1C4F62, 0x1C4E61, 0x1C4D61, 0x1C4C60, 0x1C4C5F, 0x1C4B5F, 0x1C4A5E,
4407 0x1C495E, 0x1C485D, 0x1C475D, 0x1C465C, 0x1C455B, 0x1C445B, 0x1C435A, 0x1C425A, 0x1C4259, 0x1C4158, 0x1C4058,
4408 0x1B3F57, 0x1B3E57, 0x1B3D56, 0x1B3C56, 0x1B3B55, 0x1B3A54, 0x1B3954, 0x1B3853, 0x1A3753, 0x1A3652, 0x1A3651,
4409 0x1A3551, 0x1A3450, 0x1A3350, 0x19324F, 0x19314F, 0x19304E, 0x192F4D, 0x192E4D, 0x182D4C, 0x182C4C, 0x182B4B,
4410 0x182A4B, 0x18294A, 0x17284A, 0x172749, 0x172648, 0x172548, 0x172447, 0x162347, 0x162246, 0x162146, 0x162045,
4411 0x151F45, 0x151E44, 0x151D44> csFPcmoceanTempo;
4412 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4413 /** @class csFPmplBrBG
4414 @ingroup cs
4415 @extends csFP_tpl */
4416 typedef csFP_tpl<0x563105, 0x5A3305, 0x5E3605, 0x633906, 0x673B06, 0x6C3E07, 0x704007, 0x744307, 0x794608, 0x7B4708, 0x824B09,
4417 0x844C09, 0x8A5009, 0x8C510A, 0x93570E, 0x955910, 0x9A5F14, 0x9E6217, 0xA16418, 0xA76A1C, 0xAA6E1F, 0xAF7122,
4418 0xB17323, 0xB67927, 0xBA7D2A, 0xBF802D, 0xC08330, 0xC48B39, 0xC6903F, 0xC99546, 0xCA9749, 0xCE9F52, 0xD0A458,
4419 0xD3A95F, 0xD5AE65, 0xD8B36B, 0xDAB972, 0xDBBB75, 0xDFC27E, 0xE1C583, 0xE3C889, 0xE4CB8E, 0xE6CE94, 0xE8D199,
4420 0xEAD49F, 0xEBD6A2, 0xEDDAAA, 0xEFDDAF, 0xF1E0B5, 0xF3E3BA, 0xF5E6C0, 0xF5E8C4, 0xF5E9C8, 0xF5EACA, 0xF5EBD0,
4421 0xF5ECD4, 0xF5EDD8, 0xF5EEDC, 0xF5EFE0, 0xF5F0E4, 0xF5F1E8, 0xF5F2EA, 0xF5F3F0, 0xF5F4F4, 0xF2F4F4, 0xEEF3F2,
4422 0xEBF2F1, 0xE7F1F0, 0xE3F0EF, 0xE0F0ED, 0xDCEFEC, 0xD9EEEB, 0xD5EDEA, 0xD1ECE8, 0xCEEBE7, 0xCCEBE6, 0xC6E9E4,
4423 0xC1E7E2, 0xBBE5DF, 0xB6E3DC, 0xB0E0D9, 0xABDED6, 0xA5DCD4, 0xA0DAD1, 0x9AD7CE, 0x94D5CB, 0x8FD3C8, 0x89D0C5,
4424 0x84CEC3, 0x7ECBC0, 0x78C7BC, 0x75C5BA, 0x6CBFB4, 0x67BAB0, 0x61B6AC, 0x5BB2A8, 0x55AEA4, 0x4FAAA0, 0x49A59C,
4425 0x43A198, 0x3D9D94, 0x379990, 0x32958D, 0x2E9189, 0x2A8D85, 0x268981, 0x22857D, 0x20837B, 0x1A7E76, 0x167A72,
4426 0x12766E, 0x0E726A, 0x0A6E66, 0x066A62, 0x02665E, 0x00635B, 0x006057, 0x005C54, 0x005950, 0x00564C, 0x005349,
4427 0x004F45, 0x004C42, 0x004A40, 0x00453A, 0x004237, 0x003F33, 0x003B2F> csFPmplBrBG;
4428 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4429 /** @class csFPmplOcean
4430 @ingroup cs
4431 @extends csFP_tpl */
4432 typedef csFP_tpl<0x007E01, 0x007B03, 0x007705, 0x007507, 0x007208, 0x006E0A, 0x006B0C, 0x00690F, 0x006611, 0x006411, 0x006015,
4433 0x005E16, 0x005918, 0x00581A, 0x00541C, 0x00521D, 0x004D21, 0x004B23, 0x004923, 0x004426, 0x004228, 0x003F2A,
4434 0x003D2B, 0x00382F, 0x003631, 0x003333, 0x003134, 0x002D36, 0x002A38, 0x00263B, 0x00253B, 0x00213F, 0x001D41,
4435 0x001A42, 0x001844, 0x001546, 0x001149, 0x001049, 0x000C4D, 0x00084F, 0x000550, 0x000352, 0x000054, 0x000356,
4436 0x000559, 0x000759, 0x000C5D, 0x000F5E, 0x001160, 0x001562, 0x001864, 0x001A67, 0x001D69, 0x001F69, 0x00236D,
4437 0x00266E, 0x002A70, 0x002D72, 0x002F75, 0x003377, 0x003679, 0x003779, 0x003B7C, 0x003F7E, 0x004280, 0x004482,
4438 0x004885, 0x004B87, 0x004D89, 0x00508A, 0x00548C, 0x00568E, 0x005990, 0x005D93, 0x006095, 0x006195, 0x006699,
4439 0x00699A, 0x006B9C, 0x006E9E, 0x0072A1, 0x0075A3, 0x0077A5, 0x007BA7, 0x007EA8, 0x0380AA, 0x0883AC, 0x0F87AF,
4440 0x1589B1, 0x1A8CB3, 0x2190B5, 0x2391B5, 0x2D95B8, 0x3399BA, 0x389CBC, 0x3F9EBF, 0x44A1C1, 0x4BA5C3, 0x50A8C4,
4441 0x56AAC6, 0x5DAEC8, 0x62B1CA, 0x69B3CD, 0x6EB6CF, 0x75BAD1, 0x7BBCD3, 0x80BFD4, 0x83C1D6, 0x8CC6D8, 0x93C8DB,
4442 0x99CCDD, 0x9ECFDF, 0xA5D1E1, 0xAAD4E2, 0xB1D8E4, 0xB6DBE6, 0xBCDDE8, 0xC3E1EB, 0xC8E4ED, 0xCFE6EF, 0xD4E9F0,
4443 0xDBEDF2, 0xE1EFF4, 0xE4F1F6, 0xEDF6F9, 0xF2F9FB, 0xF9FBFD, 0xFFFFFF> csFPmplOcean;
4444 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4445 /** @class csFPmplOranges
4446 @ingroup cs
4447 @extends csFP_tpl */
4448 typedef csFP_tpl<0xFEF4EA, 0xFEF3E8, 0xFEF2E6, 0xFEF1E4, 0xFEF0E2, 0xFEEFE0, 0xFEEEDF, 0xFEEDDD, 0xFEEDDB, 0xFEECDA, 0xFEEBD7,
4449 0xFEEAD6, 0xFEE9D4, 0xFEE8D3, 0xFEE7D0, 0xFEE6CF, 0xFDE5CC, 0xFDE3C9, 0xFDE3C8, 0xFDE1C4, 0xFDDFC1, 0xFDDEBE,
4450 0xFDDDBD, 0xFDDBB9, 0xFDDAB6, 0xFDD8B3, 0xFDD8B2, 0xFDD6AE, 0xFDD4AB, 0xFDD3A8, 0xFDD2A7, 0xFDD0A3, 0xFDCE9F,
4451 0xFDCC9C, 0xFDCA98, 0xFDC895, 0xFDC692, 0xFDC590, 0xFDC18B, 0xFDBF87, 0xFDBD84, 0xFDBB80, 0xFDB97D, 0xFDB779,
4452 0xFDB576, 0xFDB374, 0xFDB06F, 0xFDAE6C, 0xFDAC68, 0xFDAA66, 0xFDA863, 0xFDA660, 0xFDA45D, 0xFDA35B, 0xFDA057,
4453 0xFD9E54, 0xFD9C51, 0xFD994E, 0xFD974B, 0xFD9548, 0xFD9345, 0xFD9244, 0xFD8F3F, 0xFD8D3C, 0xFC8B3A, 0xFB8937,
4454 0xFA8634, 0xFA8432, 0xF9822F, 0xF8802D, 0xF77D2A, 0xF77B28, 0xF67925, 0xF57622, 0xF47420, 0xF4731F, 0xF3701B,
4455 0xF26D18, 0xF16B16, 0xF16913, 0xEF6712, 0xEE6510, 0xEC630F, 0xEB610E, 0xE95F0D, 0xE85C0C, 0xE65A0B, 0xE5580A,
4456 0xE35609, 0xE25407, 0xE05206, 0xDF5106, 0xDD4E04, 0xDC4C03, 0xDA4A02, 0xD94801, 0xD64701, 0xD34501, 0xCF4401,
4457 0xCC4301, 0xC94201, 0xC64101, 0xC34001, 0xBF3F01, 0xBC3D02, 0xB93C02, 0xB63B02, 0xB43B02, 0xAF3902, 0xAC3802,
4458 0xA93702, 0xA63602, 0xA33503, 0xA13403, 0x9E3303, 0x9C3203, 0x993103, 0x973003, 0x952F03, 0x922E03, 0x902D03,
4459 0x8D2C03, 0x8B2B03, 0x8A2B03, 0x862903, 0x832803, 0x812703, 0x7E2603> csFPmplOranges;
4460 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4461 /** @class csFPneoDdivVegetationA
4462 @ingroup cs
4463 @extends csFP_tpl */
4464 typedef csFP_tpl<0x530000, 0x540000, 0x540000, 0x550000, 0x560000, 0x560000, 0x570000, 0x580000, 0x5A0000, 0x5A0000, 0x5B0000,
4465 0x5B0000, 0x5D0000, 0x5E0000, 0x5F0000, 0x600000, 0x610000, 0x610000, 0x620000, 0x630000, 0x640000, 0x650000,
4466 0x670000, 0x670000, 0x690000, 0x6A0000, 0x6B0000, 0x6C0000, 0x6D0000, 0x6E0000, 0x700000, 0x710000, 0x720000,
4467 0x740000, 0x740000, 0x760000, 0x770000, 0x790000, 0x790000, 0x7B0000, 0x7C0000, 0x7D0000, 0x7F0000, 0x800000,
4468 0x830401, 0x830702, 0x860B04, 0x870D05, 0x8A1106, 0x8C1507, 0x8E1908, 0x901D0A, 0x921F0B, 0x93220C, 0x96270D,
4469 0x972A0E, 0x992E0F, 0x9C3211, 0x9E3512, 0x9F3913, 0xA13C14, 0xA23F15, 0xA54417, 0xA74818, 0xA94B19, 0xAB501A,
4470 0xAD531B, 0xB0571D, 0xB25B1E, 0xB35D1F, 0xB66321, 0xB86722, 0xBB6C24, 0xBD6F25, 0xBF7326, 0xC0762A, 0xC1782D,
4471 0xC2792F, 0xC37C33, 0xC57F37, 0xC6813A, 0xC7843E, 0xC88641, 0xC98945, 0xCB8C49, 0xCC8E4C, 0xCC904F, 0xCE9252,
4472 0xCF9656, 0xD09859, 0xD19B5D, 0xD29D60, 0xD49F64, 0xD5A368, 0xD6A56B, 0xD7A86F, 0xD9AA73, 0xD9AC75, 0xDBB07A,
4473 0xDCB27D, 0xDDB581, 0xDFB885, 0xE0BA88, 0xE1BD8D, 0xE2C090, 0xE3C293, 0xE5C597, 0xE6C79A, 0xE7CA9E, 0xE9CDA3,
4474 0xEAD0A6, 0xEBD2A9, 0xECD5AC, 0xEDD7B0, 0xEFDAB4, 0xF0DDB8, 0xF1E1BD, 0xF2E3C0, 0xF3E5C3, 0xF5E8C7, 0xF6EBCB,
4475 0xF7EDCE, 0xF8EFD1, 0xFAF4D6, 0xFBF5D9, 0xFCF8DD, 0xFDFBE1, 0xFFFFE5, 0xFEFFE5, 0xFAFDE0, 0xF8FBDD, 0xF6FBDB,
4476 0xF4F9D7, 0xF1F8D4, 0xEFF7D1, 0xECF6CD, 0xEAF4CA, 0xE7F3C6, 0xE5F2C3, 0xE2F1BF, 0xE0EFBB, 0xDDEEB9, 0xDAEDB5,
4477 0xD8ECB1, 0xD6EAAF, 0xD2E9AB, 0xD0E8A8, 0xCDE7A5, 0xCBE5A1, 0xC8E49F, 0xC6E39B, 0xC3E297, 0xC1E194, 0xBFDF91,
4478 0xBCDE8D, 0xBADD8B, 0xB7DB86, 0xB5DA83, 0xB3D981, 0xB0D87D, 0xAED77A, 0xABD576, 0xA9D574, 0xA6D371, 0xA3D26D,
4479 0xA1D16A, 0x9ED066, 0x9CCE64, 0x9ACD60, 0x97CC5D, 0x96CB5B, 0x93CA57, 0x90C954, 0x8EC750, 0x8CC74E, 0x89C54A,
4480 0x87C448, 0x85C344, 0x83C242, 0x80C03D, 0x7FC03C, 0x7BBE39, 0x77BC37, 0x72B935, 0x6EB733, 0x6BB532, 0x67B331,
4481 0x63B02F, 0x5FAE2D, 0x5BAC2C, 0x58AB2B, 0x54A829, 0x51A628, 0x4DA426, 0x4AA325, 0x46A124, 0x429F22, 0x409D20,
4482 0x3B9A1E, 0x38991D, 0x34971C, 0x31951A, 0x2D9319, 0x299118, 0x278F17, 0x238D15, 0x1F8B13, 0x1B8913, 0x198711,
4483 0x168510, 0x13840F, 0x0F810D, 0x0C800C, 0x0C7E0C, 0x0C7D0C, 0x0B7B0B, 0x0B790B, 0x0B780B, 0x0B770B, 0x0B750B,
4484 0x0B750B, 0x0A730A, 0x0A710A, 0x0A700A, 0x0A6E0A, 0x0A6D0A, 0x0A6C0A, 0x0A6B0A, 0x096909, 0x096709, 0x096609,
4485 0x096609, 0x096409, 0x096309, 0x086108, 0x086108, 0x085F08, 0x085F08, 0x085D08, 0x085C08, 0x085A08, 0x085A08,
4486 0x075907, 0x075807, 0x075607, 0x075507, 0x075507, 0x075407, 0x075207, 0x075107, 0x065106, 0x065006, 0x064F06,
4487 0x064E06, 0x064D06, 0x064C06> csFPneoDdivVegetationA;
4488 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4489 /** @class csFPneoDivVegetationC
4490 @ingroup cs
4491 @extends csFP_tpl */
4492 typedef csFP_tpl<0x795B13, 0x865614, 0x8A5513, 0x8A5513, 0x875715, 0x875715, 0x895A0A, 0x8C590A, 0x935711, 0x945812, 0x945812,
4493 0x955913, 0x965A14, 0x975B15, 0x985C16, 0x985C16, 0x9B5F19, 0x9B5F19, 0x9C601A, 0x9C601A, 0x9D611B, 0x9E621C,
4494 0x9F631D, 0x9F631D, 0xAA681A, 0xAA681A, 0xAA681A, 0xAB691B, 0xAC6A1C, 0xAD6B1D, 0xAE6C1E, 0xAE6C1E, 0xB47224,
4495 0xB57325, 0xB67426, 0xB87628, 0xBA782A, 0xBB792B, 0xBD7B2D, 0xBD7B2D, 0xBB8231, 0xBB8231, 0xBD8433, 0xBF8635,
4496 0xC28737, 0xC38838, 0xC58A3A, 0xC58A3A, 0xC38A3B, 0xC48B3C, 0xC48D3D, 0xC68F3F, 0xC49140, 0xC69342, 0xC59543,
4497 0xC69548, 0xC89E52, 0xC99F53, 0xC9A255, 0xCAA356, 0xCDA65B, 0xCFA85D, 0xCFA95E, 0xD0AA5F, 0xD5AF66, 0xD6B067,
4498 0xD7B26B, 0xD8B36C, 0xD9B76F, 0xDBB971, 0xDCBA72, 0xDDBB73, 0xDCBE78, 0xDDBF79, 0xDEC07A, 0xE0C27C, 0xE1C47E,
4499 0xE3C684, 0xE4C785, 0xE5C789, 0xE6CA89, 0xE7CA8E, 0xE6CC8F, 0xE7CC94, 0xE9CE96, 0xEACF97, 0xEBD098, 0xECD199,
4500 0xEAD9A5, 0xEBD9A9, 0xEBDBAA, 0xEDDDAC, 0xEEDDAF, 0xF0DFB1, 0xEFE1B2, 0xF0E1B6, 0xECDFB3, 0xECDEB7, 0xEEE0B9,
4501 0xEFE1BA, 0xF0E4BE, 0xF2E6C0, 0xF3E7C1, 0xF4E8C2, 0xF0EAD0, 0xF0EAD4, 0xF1EBD5, 0xF1EBD5, 0xF1EBD5, 0xF2ECD6,
4502 0xF1ECD6, 0xF1ECD9, 0xF0EDDA, 0xF1EEDF, 0xF0EEDF, 0xF0EEDF, 0xF1EFE0, 0xF1EFE0, 0xF1EFE0, 0xF1EFE3, 0xF1F1E9,
4503 0xF1F0EC, 0xF2F1ED, 0xF2F1ED, 0xF2F3EE, 0xF2F3EE, 0xF2F4F1, 0xF2F4F1, 0xF1F3F2, 0xF1F3F2, 0xEEF2F1, 0xEEF2F1,
4504 0xEDF1F2, 0xECF0F1, 0xEBF1F1, 0xEBF1F1, 0xE5EEED, 0xE5EEED, 0xE4EDEC, 0xE4EDEC, 0xE2ECED, 0xE2ECED, 0xE0ECEC,
4505 0xE0ECEC, 0xD9E7E7, 0xD9E7E7, 0xD7E7E7, 0xD7E7E7, 0xD4E6E6, 0xD3E5E5, 0xD3E5E5, 0xD3E5E5, 0xC3EEE5, 0xC3EEE5,
4506 0xC2EDE4, 0xC0EBE2, 0xBDEBE1, 0xBBE9DF, 0xB7E9DE, 0xB7E9DE, 0xB0E4D8, 0xAFE3D7, 0xADE3D6, 0xABE1D4, 0xA8E0D3,
4507 0xA6DED1, 0xA4DED0, 0xA3DDCF, 0x9BDDCF, 0x9ADCCE, 0x97DBCC, 0x94D8C9, 0x92D6C7, 0x8FD3C4, 0x8BD2C2, 0x8AD1C1,
4508 0x8BD4C3, 0x8AD3C2, 0x89D2C1, 0x87D0BF, 0x84CEBD, 0x82CCBB, 0x81CBBA, 0x80CAB9, 0x74C7B5, 0x74C7B5, 0x71C6B3,
4509 0x6FC4B1, 0x6DC2AF, 0x6BC0AD, 0x68BFAC, 0x67BEAB, 0x60B7A6, 0x5FB6A5, 0x5CB5A3, 0x5BB4A2, 0x57B2A0, 0x55B09E,
4510 0x53AE9C, 0x53AE9C, 0x52A9A0, 0x51A89F, 0x4FA69D, 0x4EA59C, 0x4AA49A, 0x48A298, 0x47A197, 0x46A096, 0x3E9A8F,
4511 0x3D998E, 0x3B988D, 0x39968B, 0x379489, 0x369388, 0x359287, 0x349186, 0x2C9183, 0x2C9183, 0x2A8F81, 0x298E80,
4512 0x278C7E, 0x258A7C, 0x24897B, 0x23887A, 0x1F8476, 0x1F8476, 0x1E8375, 0x1D8274, 0x1C8173, 0x1C8173, 0x1B8072,
4513 0x1B8072, 0x197D71, 0x187C70, 0x177B6F, 0x167A6E, 0x14786C, 0x13776B, 0x12766A, 0x117569, 0x0F7367, 0x0F7367,
4514 0x0F7367, 0x0E7266, 0x0D7165, 0x0D7165, 0x0C7064, 0x0C7064, 0x066B5B, 0x066B5B, 0x066B59, 0x086958, 0x0B6655,
4515 0x0B6655, 0x056951, 0x056951> csFPneoDivVegetationC;
4516 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4517 /** @class csFPneoModisNdvi
4518 @ingroup cs
4519 @extends csFP_tpl */
4520 typedef csFP_tpl<0xECE0D7, 0xEBDFD6, 0xEADED4, 0xEADDD3, 0xE9DDD1, 0xE8DCD0, 0xE7DBCE, 0xE7DACD, 0xE6D9CC, 0xE5D8CA, 0xE4D7C9,
4521 0xE3D6C7, 0xE3D6C6, 0xE2D5C5, 0xE1D4C3, 0xE0D3C2, 0xE0D2C0, 0xDFD1BF, 0xDED0BD, 0xDDCFBC, 0xDDCFBB, 0xDCCEB9,
4522 0xDBCDB8, 0xDACCB6, 0xD9CBB5, 0xD9CAB4, 0xD8C9B2, 0xD7C8B1, 0xD6C8AF, 0xD6C7AE, 0xD5C6AC, 0xD4C5AB, 0xD3C4AA,
4523 0xD2C3A8, 0xD1C3A7, 0xD1C2A5, 0xD0C1A4, 0xCFC0A2, 0xCEC0A1, 0xCDBF9F, 0xCCBE9E, 0xCCBD9C, 0xCBBC9B, 0xCABC99,
4524 0xC9BB98, 0xC8BA96, 0xC7B995, 0xC7B994, 0xC6B892, 0xC5B791, 0xC4B68F, 0xC3B58E, 0xC2B58C, 0xC1B48B, 0xC1B389,
4525 0xC0B288, 0xBFB186, 0xBEB185, 0xBDB083, 0xBCAF82, 0xBCAE80, 0xBBAE7F, 0xBAAD7D, 0xB9AC7C, 0xB8AB7A, 0xB7AB79,
4526 0xB6AA77, 0xB5A975, 0xB4A974, 0xB3A872, 0xB2A770, 0xB1A76F, 0xB0A66D, 0xAFA56B, 0xAEA469, 0xADA468, 0xACA366,
4527 0xABA264, 0xAAA263, 0xAAA161, 0xA9A05F, 0xA8A05E, 0xA79F5C, 0xA69E5A, 0xA59E59, 0xA49D57, 0xA39C55, 0xA29C54,
4528 0xA19B52, 0xA09A50, 0x9F994E, 0x9E994D, 0x9D984B, 0x9C9749, 0x9B9748, 0x9A9646, 0x999545, 0x989544, 0x979442,
4529 0x969341, 0x959340, 0x93923F, 0x92913D, 0x91913C, 0x90903B, 0x8F8F3A, 0x8E8E38, 0x8D8E37, 0x8C8D36, 0x8B8C35,
4530 0x8A8C33, 0x898B32, 0x878A31, 0x868A30, 0x85892E, 0x84882D, 0x83882C, 0x82872B, 0x818629, 0x808628, 0x7F8527,
4531 0x7E8426, 0x7C8324, 0x7B8323, 0x7A8222, 0x798121, 0x78811F, 0x77801E, 0x767F1E, 0x757F1E, 0x747E1E, 0x737D1E,
4532 0x727C1E, 0x717C1F, 0x707B1F, 0x6F7A1F, 0x6E791F, 0x6D791F, 0x6C781F, 0x6B771F, 0x6A761F, 0x69761F, 0x68751F,
4533 0x677420, 0x667320, 0x657320, 0x647220, 0x637120, 0x627020, 0x617020, 0x606F20, 0x5F6E20, 0x5E6D20, 0x5D6D20,
4534 0x5C6C21, 0x5B6B21, 0x5A6A21, 0x596A21, 0x586921, 0x576821, 0x566721, 0x556621, 0x556621, 0x546521, 0x536421,
4535 0x526321, 0x516321, 0x516221, 0x506121, 0x4F6021, 0x4E5F21, 0x4D5F21, 0x4C5E21, 0x4C5D21, 0x4B5C21, 0x4A5C21,
4536 0x495B21, 0x485A21, 0x485921, 0x475821, 0x465821, 0x455721, 0x445621, 0x445521, 0x435421, 0x425421, 0x415321,
4537 0x405221, 0x3F5121, 0x3F5121, 0x3E5021, 0x3D4F21, 0x3C4E20, 0x3B4E1F, 0x3A4D1E, 0x394C1D, 0x384C1C, 0x374B1B,
4538 0x364A1A, 0x354A19, 0x344918, 0x334817, 0x324816, 0x314715, 0x304614, 0x2F4613, 0x2E4512, 0x2E4511, 0x2D440F,
4539 0x2C430E, 0x2B430D, 0x2A420C, 0x29410B, 0x28410A, 0x274009, 0x263F08, 0x253F07, 0x243E06, 0x233D05, 0x223D04,
4540 0x213C03, 0x203B02, 0x1F3B01, 0x1E3A00, 0x1D3900, 0x1D3900, 0x1C3800, 0x1C3700, 0x1B3600, 0x1A3601, 0x1A3501,
4541 0x193401, 0x183401, 0x183301, 0x173201, 0x173101, 0x163101, 0x153001, 0x152F01, 0x142F02, 0x132E02, 0x132D02,
4542 0x122C02, 0x122C02, 0x112B02, 0x102A02, 0x102902, 0x0F2902, 0x0E2802, 0x0E2702, 0x0D2703, 0x0D2603, 0x0C2503,
4543 0x0B2403, 0x0B2403, 0x000000> csFPneoModisNdvi;
4544 //@}
4545
4546
4547 //========================================================================================================================================================
4548 /** @name ColorBrewer2 Color Schemes */
4549 //@{
4550 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4551 /** @class csCBSpectral
4552 @ingroup cs
4553 @extends csCB_tpl
4554 ColorBrewer2 "Spectral" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4555 typedef csCB_tpl<11,
4556 0xFC8D59, 0xFFFFBF, 0x99D594,
4557 0xD7191C, 0xFDAE61, 0xABDDA4, 0x2B83BA,
4558 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xABDDA4, 0x2B83BA,
4559 0xD53E4F, 0xFC8D59, 0xFEE08B, 0xE6F598, 0x99D594, 0x3288BD,
4560 0xD53E4F, 0xFC8D59, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0x99D594, 0x3288BD,
4561 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD,
4562 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD,
4563 0x9E0142, 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD, 0x5E4FA2,
4564 0x9E0142, 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD, 0x5E4FA2> csCBSpectral;
4565 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4566 /** @class csCBRdYlGn
4567 @ingroup cs
4568 @extends csCB_tpl
4569 ColorBrewer2 "RdYlGn" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4570 typedef csCB_tpl<11,
4571 0xFC8D59, 0xFFFFBF, 0x91CF60,
4572 0xD7191C, 0xFDAE61, 0xA6D96A, 0x1A9641,
4573 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xA6D96A, 0x1A9641,
4574 0xD73027, 0xFC8D59, 0xFEE08B, 0xD9EF8B, 0x91CF60, 0x1A9850,
4575 0xD73027, 0xFC8D59, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0x91CF60, 0x1A9850,
4576 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850,
4577 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850,
4578 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850, 0x006837,
4579 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850, 0x006837> csCBRdYlGn;
4580 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4581 /** @class csCBRdBu
4582 @ingroup cs
4583 @extends csCB_tpl
4584 ColorBrewer2 "RdBu" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4585 typedef csCB_tpl<11,
4586 0xEF8A62, 0xF7F7F7, 0x67A9CF,
4587 0xCA0020, 0xF4A582, 0x92C5DE, 0x0571B0,
4588 0xCA0020, 0xF4A582, 0xF7F7F7, 0x92C5DE, 0x0571B0,
4589 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xD1E5F0, 0x67A9CF, 0x2166AC,
4590 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x67A9CF, 0x2166AC,
4591 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC,
4592 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC,
4593 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC, 0x053061,
4594 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC, 0x053061> csCBRdBu;
4595 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4596 /** @class csCBPiYG
4597 @ingroup cs
4598 @extends csCB_tpl
4599 ColorBrewer2 "PiYG" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4600 typedef csCB_tpl<11,
4601 0xE9A3C9, 0xF7F7F7, 0xA1D76A,
4602 0xD01C8B, 0xF1B6DA, 0xB8E186, 0x4DAC26,
4603 0xD01C8B, 0xF1B6DA, 0xF7F7F7, 0xB8E186, 0x4DAC26,
4604 0xC51B7D, 0xE9A3C9, 0xFDE0EF, 0xE6F5D0, 0xA1D76A, 0x4D9221,
4605 0xC51B7D, 0xE9A3C9, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xA1D76A, 0x4D9221,
4606 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221,
4607 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221,
4608 0x8E0152, 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221, 0x276419,
4609 0x8E0152, 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221, 0x276419> csCBPiYG;
4610 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4611 /** @class csCBPRGn
4612 @ingroup cs
4613 @extends csCB_tpl
4614 ColorBrewer2 "PRGn" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4615 typedef csCB_tpl<11,
4616 0xAF8DC3, 0xF7F7F7, 0x7FBF7B,
4617 0x7B3294, 0xC2A5CF, 0xA6DBA0, 0x008837,
4618 0x7B3294, 0xC2A5CF, 0xF7F7F7, 0xA6DBA0, 0x008837,
4619 0x762A83, 0xAF8DC3, 0xE7D4E8, 0xD9F0D3, 0x7FBF7B, 0x1B7837,
4620 0x762A83, 0xAF8DC3, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0x7FBF7B, 0x1B7837,
4621 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837,
4622 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837,
4623 0x40004B, 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837, 0x00441B,
4624 0x40004B, 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837, 0x00441B> csCBPRGn;
4625 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4626 /** @class csCBRdYlBu
4627 @ingroup cs
4628 @extends csCB_tpl
4629 ColorBrewer2 "RdYlBu" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4630 typedef csCB_tpl<11,
4631 0xFC8D59, 0xFFFFBF, 0x91BFDB,
4632 0xD7191C, 0xFDAE61, 0xABD9E9, 0x2C7BB6,
4633 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xABD9E9, 0x2C7BB6,
4634 0xD73027, 0xFC8D59, 0xFEE090, 0xE0F3F8, 0x91BFDB, 0x4575B4,
4635 0xD73027, 0xFC8D59, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0x91BFDB, 0x4575B4,
4636 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4,
4637 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4,
4638 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4, 0x313695,
4639 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4, 0x313695> csCBRdYlBu;
4640 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4641 /** @class csCBBrBG
4642 @ingroup cs
4643 @extends csCB_tpl
4644 ColorBrewer2 "BrBG" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4645 typedef csCB_tpl<11,
4646 0xD8B365, 0xF5F5F5, 0x5AB4AC,
4647 0xA6611A, 0xDFC27D, 0x80CDC1, 0x018571,
4648 0xA6611A, 0xDFC27D, 0xF5F5F5, 0x80CDC1, 0x018571,
4649 0x8C510A, 0xD8B365, 0xF6E8C3, 0xC7EAE5, 0x5AB4AC, 0x01665E,
4650 0x8C510A, 0xD8B365, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x5AB4AC, 0x01665E,
4651 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E,
4652 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E,
4653 0x543005, 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E, 0x003C30,
4654 0x543005, 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E, 0x003C30> csCBBrBG;
4655 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4656 /** @class csCBRdGy
4657 @ingroup cs
4658 @extends csCB_tpl
4659 ColorBrewer2 "RdGy" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4660 typedef csCB_tpl<11,
4661 0xEF8A62, 0xFFFFFF, 0x999999,
4662 0xCA0020, 0xF4A582, 0xBABABA, 0x404040,
4663 0xCA0020, 0xF4A582, 0xFFFFFF, 0xBABABA, 0x404040,
4664 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xE0E0E0, 0x999999, 0x4D4D4D,
4665 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0x999999, 0x4D4D4D,
4666 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D,
4667 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D,
4668 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D, 0x1A1A1A,
4669 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D, 0x1A1A1A> csCBRdGy;
4670 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4671 /** @class csCBPuOr
4672 @ingroup cs
4673 @extends csCB_tpl
4674 ColorBrewer2 "PuOr" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4675 typedef csCB_tpl<11,
4676 0xF1A340, 0xF7F7F7, 0x998EC3,
4677 0xE66101, 0xFDB863, 0xB2ABD2, 0x5E3C99,
4678 0xE66101, 0xFDB863, 0xF7F7F7, 0xB2ABD2, 0x5E3C99,
4679 0xB35806, 0xF1A340, 0xFEE0B6, 0xD8DAEB, 0x998EC3, 0x542788,
4680 0xB35806, 0xF1A340, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0x998EC3, 0x542788,
4681 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788,
4682 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788,
4683 0x7F3B08, 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788, 0x2D004B,
4684 0x7F3B08, 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788, 0x2D004B> csCBPuOr;
4685 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4686 /** @class csCBSet2
4687 @ingroup cs
4688 @extends csCB_tpl
4689 ColorBrewer2 "Set2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4690 typedef csCB_tpl<8,
4691 0x66C2A5, 0xFC8D62, 0x8DA0CB,
4692 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3,
4693 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854,
4694 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F,
4695 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F, 0xE5C494,
4696 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F, 0xE5C494, 0xB3B3B3> csCBSet2;
4697 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4698 /** @class csCBAccent
4699 @ingroup cs
4700 @extends csCB_tpl
4701 ColorBrewer2 "Accent" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4702 typedef csCB_tpl<8,
4703 0x7FC97F, 0xBEAED4, 0xFDC086,
4704 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99,
4705 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0,
4706 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F,
4707 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F, 0xBF5B17,
4708 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F, 0xBF5B17, 0x666666> csCBAccent;
4709 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4710 /** @class csCBSet1
4711 @ingroup cs
4712 @extends csCB_tpl
4713 ColorBrewer2 "Set1" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4714 typedef csCB_tpl<9,
4715 0xE41A1C, 0x377EB8, 0x4DAF4A,
4716 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3,
4717 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00,
4718 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33,
4719 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628,
4720 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628, 0xF781BF,
4721 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628, 0xF781BF, 0x999999> csCBSet1;
4722 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4723 /** @class csCBSet3
4724 @ingroup cs
4725 @extends csCB_tpl
4726 ColorBrewer2 "Set3" color scheme of 3 to 12 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4727 typedef csCB_tpl<12,
4728 0x8DD3C7, 0xFFFFB3, 0xBEBADA,
4729 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072,
4730 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3,
4731 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462,
4732 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69,
4733 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5,
4734 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9,
4735 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD,
4736 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD, 0xCCEBC5,
4737 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD, 0xCCEBC5, 0xFFED6F> csCBSet3;
4738 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4739 /** @class csCBDark2
4740 @ingroup cs
4741 @extends csCB_tpl
4742 ColorBrewer2 "Dark2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4743 typedef csCB_tpl<8,
4744 0x1B9E77, 0xD95F02, 0x7570B3,
4745 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A,
4746 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E,
4747 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02,
4748 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02, 0xA6761D,
4749 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02, 0xA6761D, 0x666666> csCBDark2;
4750 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4751 /** @class csCBPaired
4752 @ingroup cs
4753 @extends csCB_tpl
4754 ColorBrewer2 "Paired" color scheme of 3 to 12 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4755 typedef csCB_tpl<12,
4756 0xA6CEE3, 0x1F78B4, 0xB2DF8A,
4757 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C,
4758 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99,
4759 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C,
4760 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F,
4761 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00,
4762 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6,
4763 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A,
4764 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A, 0xFFFF99,
4765 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A, 0xFFFF99, 0xB15928> csCBPaired;
4766 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4767 /** @class csCBPastel2
4768 @ingroup cs
4769 @extends csCB_tpl
4770 ColorBrewer2 "Pastel2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4771 typedef csCB_tpl<8,
4772 0xB3E2CD, 0xFDCDAC, 0xCBD5E8,
4773 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4,
4774 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9,
4775 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE,
4776 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE, 0xF1E2CC,
4777 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE, 0xF1E2CC, 0xCCCCCC> csCBPastel2;
4778 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4779 /** @class csCBPastel1
4780 @ingroup cs
4781 @extends csCB_tpl
4782 ColorBrewer2 "Pastel1" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4783 typedef csCB_tpl<9,
4784 0xFBB4AE, 0xB3CDE3, 0xCCEBC5,
4785 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4,
4786 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6,
4787 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC,
4788 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD,
4789 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD, 0xFDDAEC,
4790 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD, 0xFDDAEC, 0xF2F2F2> csCBPastel1;
4791 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4792 /** @class csCBOrRd
4793 @ingroup cs
4794 @extends csCB_tpl
4795 ColorBrewer2 "RdYlGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4796 typedef csCB_tpl<9,
4797 0xFEE8C8, 0xFDBB84, 0xE34A33,
4798 0xFEF0D9, 0xFDCC8A, 0xFC8D59, 0xD7301F,
4799 0xFEF0D9, 0xFDCC8A, 0xFC8D59, 0xE34A33, 0xB30000,
4800 0xFEF0D9, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xE34A33, 0xB30000,
4801 0xFEF0D9, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0x990000,
4802 0xFFF7EC, 0xFEE8C8, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0x990000,
4803 0xFFF7EC, 0xFEE8C8, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0xB30000, 0x7F0000> csCBOrRd;
4804 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4805 /** @class csCBPuBu
4806 @ingroup cs
4807 @extends csCB_tpl
4808 ColorBrewer2 "PuBu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4809 typedef csCB_tpl<9,
4810 0xECE7F2, 0xA6BDDB, 0x2B8CBE,
4811 0xF1EEF6, 0xBDC9E1, 0x74A9CF, 0x0570B0,
4812 0xF1EEF6, 0xBDC9E1, 0x74A9CF, 0x2B8CBE, 0x045A8D,
4813 0xF1EEF6, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x2B8CBE, 0x045A8D,
4814 0xF1EEF6, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x034E7B,
4815 0xFFF7FB, 0xECE7F2, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x034E7B,
4816 0xFFF7FB, 0xECE7F2, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x045A8D, 0x023858> csCBPuBu;
4817 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4818 /** @class csCBBuPu
4819 @ingroup cs
4820 @extends csCB_tpl
4821 ColorBrewer2 "CbBuPu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4822 typedef csCB_tpl<9,
4823 0xE0ECF4, 0x9EBCDA, 0x8856A7,
4824 0xEDF8FB, 0xB3CDE3, 0x8C96C6, 0x88419D,
4825 0xEDF8FB, 0xB3CDE3, 0x8C96C6, 0x8856A7, 0x810F7C,
4826 0xEDF8FB, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8856A7, 0x810F7C,
4827 0xEDF8FB, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x6E016B,
4828 0xF7FCFD, 0xE0ECF4, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x6E016B,
4829 0xF7FCFD, 0xE0ECF4, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x810F7C, 0x4D004B> csCBBuPu;
4830 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4831 /** @class csCBOranges
4832 @ingroup cs
4833 @extends csCB_tpl
4834 ColorBrewer2 "Oranges" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4835 typedef csCB_tpl<9,
4836 0xFEE6CE, 0xFDAE6B, 0xE6550D,
4837 0xFEEDDE, 0xFDBE85, 0xFD8D3C, 0xD94701,
4838 0xFEEDDE, 0xFDBE85, 0xFD8D3C, 0xE6550D, 0xA63603,
4839 0xFEEDDE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xE6550D, 0xA63603,
4840 0xFEEDDE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0x8C2D04,
4841 0xFFF5EB, 0xFEE6CE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0x8C2D04,
4842 0xFFF5EB, 0xFEE6CE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0xA63603, 0x7F2704> csCBOranges;
4843 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4844 /** @class csCBBuGn
4845 @ingroup cs
4846 @extends csCB_tpl
4847 ColorBrewer2 "BuGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4848 typedef csCB_tpl<9,
4849 0xE5F5F9, 0x99D8C9, 0x2CA25F,
4850 0xEDF8FB, 0xB2E2E2, 0x66C2A4, 0x238B45,
4851 0xEDF8FB, 0xB2E2E2, 0x66C2A4, 0x2CA25F, 0x006D2C,
4852 0xEDF8FB, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x2CA25F, 0x006D2C,
4853 0xEDF8FB, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x005824,
4854 0xF7FCFD, 0xE5F5F9, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x005824,
4855 0xF7FCFD, 0xE5F5F9, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x006D2C, 0x00441B> csCBBuGn;
4856 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4857 /** @class csCBYlOrBr
4858 @ingroup cs
4859 @extends csCB_tpl
4860 ColorBrewer2 "YlOrBr" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4861 typedef csCB_tpl<9,
4862 0xFFF7BC, 0xFEC44F, 0xD95F0E,
4863 0xFFFFD4, 0xFED98E, 0xFE9929, 0xCC4C02,
4864 0xFFFFD4, 0xFED98E, 0xFE9929, 0xD95F0E, 0x993404,
4865 0xFFFFD4, 0xFEE391, 0xFEC44F, 0xFE9929, 0xD95F0E, 0x993404,
4866 0xFFFFD4, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x8C2D04,
4867 0xFFFFE5, 0xFFF7BC, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x8C2D04,
4868 0xFFFFE5, 0xFFF7BC, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x993404, 0x662506> csCBYlOrBr;
4869 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4870 /** @class csCBYlGn
4871 @ingroup cs
4872 @extends csCB_tpl
4873 ColorBrewer2 "csCBYlGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4874 typedef csCB_tpl<9,
4875 0xF7FCB9, 0xADDD8E, 0x31A354,
4876 0xFFFFCC, 0xC2E699, 0x78C679, 0x238443,
4877 0xFFFFCC, 0xC2E699, 0x78C679, 0x31A354, 0x006837,
4878 0xFFFFCC, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x31A354, 0x006837,
4879 0xFFFFCC, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x005A32,
4880 0xFFFFE5, 0xF7FCB9, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x005A32,
4881 0xFFFFE5, 0xF7FCB9, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x006837, 0x004529> csCBYlGn;
4882 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4883 /** @class csCBReds
4884 @ingroup cs
4885 @extends csCB_tpl
4886 ColorBrewer2 "Reds" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4887 typedef csCB_tpl<9,
4888 0xFEE0D2, 0xFC9272, 0xDE2D26,
4889 0xFEE5D9, 0xFCAE91, 0xFB6A4A, 0xCB181D,
4890 0xFEE5D9, 0xFCAE91, 0xFB6A4A, 0xDE2D26, 0xA50F15,
4891 0xFEE5D9, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xDE2D26, 0xA50F15,
4892 0xFEE5D9, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0x99000D,
4893 0xFFF5F0, 0xFEE0D2, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0x99000D,
4894 0xFFF5F0, 0xFEE0D2, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0xA50F15, 0x67000D> csCBReds;
4895 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4896 /** @class csCBRdPu
4897 @ingroup cs
4898 @extends csCB_tpl
4899 ColorBrewer2 "RdPu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4900 typedef csCB_tpl<9,
4901 0xFDE0DD, 0xFA9FB5, 0xC51B8A,
4902 0xFEEBE2, 0xFBB4B9, 0xF768A1, 0xAE017E,
4903 0xFEEBE2, 0xFBB4B9, 0xF768A1, 0xC51B8A, 0x7A0177,
4904 0xFEEBE2, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xC51B8A, 0x7A0177,
4905 0xFEEBE2, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177,
4906 0xFFF7F3, 0xFDE0DD, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177,
4907 0xFFF7F3, 0xFDE0DD, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177, 0x49006A> csCBRdPu;
4908 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4909 /** @class csCBGreens
4910 @ingroup cs
4911 @extends csCB_tpl
4912 ColorBrewer2 "Greens" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4913 typedef csCB_tpl<9,
4914 0xE5F5E0, 0xA1D99B, 0x31A354,
4915 0xEDF8E9, 0xBAE4B3, 0x74C476, 0x238B45,
4916 0xEDF8E9, 0xBAE4B3, 0x74C476, 0x31A354, 0x006D2C,
4917 0xEDF8E9, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x31A354, 0x006D2C,
4918 0xEDF8E9, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x005A32,
4919 0xF7FCF5, 0xE5F5E0, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x005A32,
4920 0xF7FCF5, 0xE5F5E0, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x006D2C, 0x00441B> csCBGreens;
4921 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4922 /** @class csCBYlGnBu
4923 @ingroup cs
4924 @extends csCB_tpl
4925 ColorBrewer2 "YlGnBu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4926 typedef csCB_tpl<9,
4927 0xEDF8B1, 0x7FCDBB, 0x2C7FB8,
4928 0xFFFFCC, 0xA1DAB4, 0x41B6C4, 0x225EA8,
4929 0xFFFFCC, 0xA1DAB4, 0x41B6C4, 0x2C7FB8, 0x253494,
4930 0xFFFFCC, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x2C7FB8, 0x253494,
4931 0xFFFFCC, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x0C2C84,
4932 0xFFFFD9, 0xEDF8B1, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x0C2C84,
4933 0xFFFFD9, 0xEDF8B1, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x253494, 0x081D58> csCBYlGnBu;
4934 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4935 /** @class csCBPurples
4936 @ingroup cs
4937 @extends csCB_tpl
4938 ColorBrewer2 "Purples" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4939 typedef csCB_tpl<9,
4940 0xEFEDF5, 0xBCBDDC, 0x756BB1,
4941 0xF2F0F7, 0xCBC9E2, 0x9E9AC8, 0x6A51A3,
4942 0xF2F0F7, 0xCBC9E2, 0x9E9AC8, 0x756BB1, 0x54278F,
4943 0xF2F0F7, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x756BB1, 0x54278F,
4944 0xF2F0F7, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x4A1486,
4945 0xFCFBFD, 0xEFEDF5, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x4A1486,
4946 0xFCFBFD, 0xEFEDF5, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x54278F, 0x3F007D> csCBPurples;
4947 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4948 /** @class csCBGnBu
4949 @ingroup cs
4950 @extends csCB_tpl
4951 ColorBrewer2 "GnBu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4952 typedef csCB_tpl<9,
4953 0xE0F3DB, 0xA8DDB5, 0x43A2CA,
4954 0xF0F9E8, 0xBAE4BC, 0x7BCCC4, 0x2B8CBE,
4955 0xF0F9E8, 0xBAE4BC, 0x7BCCC4, 0x43A2CA, 0x0868AC,
4956 0xF0F9E8, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x43A2CA, 0x0868AC,
4957 0xF0F9E8, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x08589E,
4958 0xF7FCF0, 0xE0F3DB, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x08589E,
4959 0xF7FCF0, 0xE0F3DB, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x0868AC, 0x084081> csCBGnBu;
4960 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4961 /** @class csCBGreys
4962 @ingroup cs
4963 @extends csCB_tpl
4964 ColorBrewer2 "Greys" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4965 typedef csCB_tpl<9,
4966 0xF0F0F0, 0xBDBDBD, 0x636363,
4967 0xF7F7F7, 0xCCCCCC, 0x969696, 0x525252,
4968 0xF7F7F7, 0xCCCCCC, 0x969696, 0x636363, 0x252525,
4969 0xF7F7F7, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x636363, 0x252525,
4970 0xF7F7F7, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525,
4971 0xFFFFFF, 0xF0F0F0, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525,
4972 0xFFFFFF, 0xF0F0F0, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525, 0x000000> csCBGreys;
4973 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4974 /** @class csCBYlOrRd
4975 @ingroup cs
4976 @extends csCB_tpl
4977 ColorBrewer2 "YlOrRd" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4978 typedef csCB_tpl<8,
4979 0xFFEDA0, 0xFEB24C, 0xF03B20,
4980 0xFFFFB2, 0xFECC5C, 0xFD8D3C, 0xE31A1C,
4981 0xFFFFB2, 0xFECC5C, 0xFD8D3C, 0xF03B20, 0xBD0026,
4982 0xFFFFB2, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xF03B20, 0xBD0026,
4983 0xFFFFB2, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xFC4E2A, 0xE31A1C, 0xB10026,
4984 0xFFFFCC, 0xFFEDA0, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xFC4E2A, 0xE31A1C, 0xB10026> csCBYlOrRd;
4985 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4986 /** @class csCBPuRd
4987 @ingroup cs
4988 @extends csCB_tpl
4989 ColorBrewer2 "PuRd" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4990 typedef csCB_tpl<9,
4991 0xE7E1EF, 0xC994C7, 0xDD1C77,
4992 0xF1EEF6, 0xD7B5D8, 0xDF65B0, 0xCE1256,
4993 0xF1EEF6, 0xD7B5D8, 0xDF65B0, 0xDD1C77, 0x980043,
4994 0xF1EEF6, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xDD1C77, 0x980043,
4995 0xF1EEF6, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x91003F,
4996 0xF7F4F9, 0xE7E1EF, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x91003F,
4997 0xF7F4F9, 0xE7E1EF, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x980043, 0x67001F> csCBPuRd;
4998 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4999 /** @class csCBBlues
5000 @ingroup cs
5001 @extends csCB_tpl
5002 ColorBrewer2 "Blues" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
5003 typedef csCB_tpl<9,
5004 0xDEEBF7, 0x9ECAE1, 0x3182BD,
5005 0xEFF3FF, 0xBDD7E7, 0x6BAED6, 0x2171B5,
5006 0xEFF3FF, 0xBDD7E7, 0x6BAED6, 0x3182BD, 0x08519C,
5007 0xEFF3FF, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x3182BD, 0x08519C,
5008 0xEFF3FF, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x084594,
5009 0xF7FBFF, 0xDEEBF7, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x084594,
5010 0xF7FBFF, 0xDEEBF7, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x08519C, 0x08306B> csCBBlues;
5011 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5012 /** @class csCBPuBuGn
5013 @ingroup cs
5014 @extends csCB_tpl
5015 ColorBrewer2 "PuBuGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
5016 typedef csCB_tpl<9,
5017 0xECE2F0, 0xA6BDDB, 0x1C9099,
5018 0xF6EFF7, 0xBDC9E1, 0x67A9CF, 0x02818A,
5019 0xF6EFF7, 0xBDC9E1, 0x67A9CF, 0x1C9099, 0x016C59,
5020 0xF6EFF7, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x1C9099, 0x016C59,
5021 0xF6EFF7, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016450,
5022 0xFFF7FB, 0xECE2F0, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016450,
5023 0xFFF7FB, 0xECE2F0, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016C59, 0x014636> csCBPuBuGn;
5024 //@}
5025
5026 /** @endcond */
5027
5028 //========================================================================================================================================================
5029 /** @name 2D Color Schemes */
5030 //@{
5031#if !(MISSING_P1907R1)
5032 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5033 /** Compute a color from Richardson's 2D complex number coloring scheme.
5034 See: Richardson (1991); Visualizing quantum scattering on the CM-2 supercomputer; Computer Physics Communications 63; pp 84-94"
5035 This is a continuous, 2D color scheme!
5036 @tparam cutDepth See: tfrmComplexCut()
5037 @tparam argCuts See: tfrmComplexCut()
5038 @tparam absCuts See: tfrmComplexCut()
5039 @tparam logAbs See: tfrmComplexCut() */
5040 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5042 public:
5043 /** Set given colorTpl instance to the selected color in the color scheme.
5044 @param aColor color object to set.
5045 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5046 @param csY A value that, along with csX, identifies the color in the scheme.
5047 @return Returns a reference to \a aColor. */
5048 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5049 csFltType c_abs2 = csX*csX+csY*csY;
5050 csFltType c_abs = std::sqrt(c_abs2);
5051 csFltType c_abs2p1 = 1 + c_abs2;
5052 csFltType x_scl = csX / std::sqrt(30.0/5.0);
5053 csFltType y_scl = csY / std::sqrt(2.0);
5054 csFltType ofs = (c_abs<1 ? -1.0 : 1.0) * (0.5 - c_abs/c_abs2p1);
5055 aColor.setChansRGB_dbl(std::clamp(ofs + (0.5 + (std::sqrt(2.0/3.0) * csX) / c_abs2p1), 0.0, 1.0),
5056 std::clamp(ofs + (0.5 - (x_scl - y_scl) / c_abs2p1), 0.0, 1.0),
5057 std::clamp(ofs + (0.5 - (x_scl + y_scl) / c_abs2p1), 0.0, 1.0));
5058 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5059 }
5060 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5061 @param csX A value that, along with csY, identifies the color in the scheme.
5062 @param csY A value that, along with csX, identifies the color in the scheme.
5063 @return Returns a colorTpl value */
5064 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5065 /** Set given colorTpl instance to the selected color in the color scheme.
5066 @param aColor color object to set.
5067 @param csZ A value that identifies the color in the scheme.
5068 @return Returns a reference to \a aColor. */
5069 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5070 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5071 @param csZ A value that identifies the color in the scheme.
5072 @return Returns a colorTpl value */
5073 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5074 };
5075 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5076 /** Compute a color for a point in @f$\mathbb{R}^2@f$ using a discrete color scheme for the phase angle.
5077 This is a continuous, 2D color scheme!
5078 @tparam colorScheme Integer indexed color scheme to use for the argument. csCColdeRainbow is a traditional choice.
5079 @tparam argWrap Number of times to wrap around the color ramp for arg
5080 @tparam cutDepth See: tfrmComplexCut()
5081 @tparam argCuts See: tfrmComplexCut()
5082 @tparam absCuts See: tfrmComplexCut()
5083 @tparam logAbs See: tfrmComplexCut() */
5084 template<typename colorScheme, int argWrap, double cutDepth, double argCuts, double absCuts, bool logAbs>
5086 public:
5087 /** Set given colorTpl instance to the selected color in the color scheme.
5088 @param aColor color object to set.
5089 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5090 @param csY A value that, along with csX, identifies the color in the scheme.
5091 @return Returns a reference to \a aColor. */
5092 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5093 csIntType numC = colorScheme::numC;
5094 double tau = std::numbers::pi * 2; // 2*Pi
5095 double zArg = std::atan2(csY, csX); // Arg
5096 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
5097 aColor.csSet<colorScheme>(static_cast<csIntType>(mjr::math::ivl::wrapCC(mjr::math::linm::scl_real_to_int(mjr::math::ivl::unit_clamp(pzArg), numC*argWrap), numC)));
5098 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5099 }
5100 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5101 @param csX A value that, along with csY, identifies the color in the scheme.
5102 @param csY A value that, along with csX, identifies the color in the scheme.
5103 @return Returns a colorTpl value */
5104 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5105 /** Set given colorTpl instance to the selected color in the color scheme.
5106 @param aColor color object to set.
5107 @param csZ A value that identifies the color in the scheme.
5108 @return Returns a reference to \a aColor. */
5109 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5110 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5111 @param csZ A value that identifies the color in the scheme.
5112 @return Returns a colorTpl value */
5113 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5114 };
5115 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5116 /** Compute a color for a point in @f$\mathbb{R}^2@f$ using a continuous color scheme for the phase angle.
5117 This is a continuous, 2D color scheme!
5118 @tparam colorScheme Integer indexed color scheme to use for the argument. csCColdeRainbow is a traditional choice.
5119 @tparam argWrap Number of times to wrap around the color ramp for arg
5120 @tparam cutDepth See: tfrmComplexCut()
5121 @tparam argCuts See: tfrmComplexCut()
5122 @tparam absCuts See: tfrmComplexCut()
5123 @tparam logAbs See: tfrmComplexCut() */
5124 template<typename colorScheme, int argWrap, double cutDepth, double argCuts, double absCuts, bool logAbs>
5126 public:
5127 /** Set given colorTpl instance to the selected color in the color scheme.
5128 @param aColor color object to set.
5129 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5130 @param csY A value that, along with csX, identifies the color in the scheme.
5131 @return Returns a reference to \a aColor. */
5132 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5133 double tau = std::numbers::pi * 2; // 2*Pi
5134 double zArg = std::atan2(csY, csX); // Arg
5135 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
5136 aColor.csSet<colorScheme>(static_cast<csFltType>(mjr::math::ivl::wrapCC(mjr::math::ivl::unit_clamp(pzArg)*argWrap, 1.0)));
5137 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5138 }
5139 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5140 @param csX A value that, along with csY, identifies the color in the scheme.
5141 @param csY A value that, along with csX, identifies the color in the scheme.
5142 @return Returns a colorTpl value */
5143 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5144 /** Set given colorTpl instance to the selected color in the color scheme.
5145 @param aColor color object to set.
5146 @param csZ A value that identifies the color in the scheme.
5147 @return Returns a reference to \a aColor. */
5148 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5149 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5150 @param csZ A value that identifies the color in the scheme.
5151 @return Returns a colorTpl value */
5152 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5153 };
5154 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5155 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSL.
5156 See: Bernd Thaller (2000); Visual Quantum Mechanics; pp 2-8
5157 This is a continuous, 2D color scheme!
5158 @tparam cutDepth See: tfrmComplexCut()
5159 @tparam argCuts See: tfrmComplexCut()
5160 @tparam absCuts See: tfrmComplexCut()
5161 @tparam logAbs See: tfrmComplexCut() */
5162 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5164 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5165 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSV and maximum value.
5166 See: Bernd Thaller (2000); Visual Quantum Mechanics; pp 2-8
5167 This is a continuous, 2D color scheme!
5168 @tparam cutDepth See: tfrmComplexCut()
5169 @tparam argCuts See: tfrmComplexCut()
5170 @tparam absCuts See: tfrmComplexCut()
5171 @tparam logAbs See: tfrmComplexCut() */
5172 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5174 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5175 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSV and dynamic value.
5176 See: Bernd Thaller (2000); Visual Quantum Mechanics; pp 2-8
5177 This is a continuous, 2D color scheme!
5178 @tparam cutDepth See: tfrmComplexCut()
5179 @tparam argCuts See: tfrmComplexCut()
5180 @tparam absCuts See: tfrmComplexCut()
5181 @tparam logAbs See: tfrmComplexCut() */
5182 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5184#endif
5185 //@}
5186
5187 template <class csT, class csAT> colorTpl& csSet(csAT csArg) { return csT::c(*this, csArg); }
5188 template <class csT, class csAT> colorTpl& csSet(csAT csArg1, csAT csArg2) { return csT::c(*this, csArg1, csArg2); }
5189
5190 };
5191
5192////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5193 /** i/O stream output operator for colorTpl types. */
5194 template <class clrChanT, int numChan, int redChanIdx = -1, int blueChanIdx = -1, int greenChanIdx = -1, int alphaChanIdx = -1>
5195 requires ((numChan>0) && // Must have at least 1 chan
5196 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
5197 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
5198 (redChanIdx < numChan) &&
5199 (blueChanIdx < numChan) &&
5200 (greenChanIdx < numChan) &&
5201 (alphaChanIdx < numChan) &&
5202 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
5203 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
5204 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
5205 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
5206 (redChanIdx != blueChanIdx) &&
5207 (redChanIdx != alphaChanIdx) &&
5208 (greenChanIdx != blueChanIdx) &&
5209 (greenChanIdx != alphaChanIdx) &&
5210 (blueChanIdx != alphaChanIdx)))) // Chans can't be teh same if non-negative
5211 inline std::ostream&
5212 operator<< (std::ostream &out, colorTpl<clrChanT, numChan> const& color) {
5213 // MJR BUG NOTE operator<<: Will fail if 'char' is bigger than uint64_t -- I shudder to imagine a future that might bring such a condition..
5214 out << "<";
5215 if (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) > sizeof(uint64_t))) {
5216 for(int i=0; i<(numChan-1); i++)
5217 out << color.getChan(i) << ", ";
5218 out << color.getChan(numChan-1) << ">";
5219 } else {
5220 for(int i=0; i<(numChan-1); i++)
5221 out << static_cast<uint64_t>(color.getChan(i)) << ", ";
5222 out << static_cast<uint64_t>(color.getChan(numChan-1)) << ">";
5223 }
5224 return out;
5225 }
5226
5227////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5228 /** Inequality operator for colorTpl types. */
5229 template <class clrChanT, int numChan, int redChanIdx = -1, int blueChanIdx = -1, int greenChanIdx = -1, int alphaChanIdx = -1>
5230 requires ((numChan>0) && // Must have at least 1 chan
5231 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
5232 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
5233 (redChanIdx < numChan) &&
5234 (blueChanIdx < numChan) &&
5235 (greenChanIdx < numChan) &&
5236 (alphaChanIdx < numChan) &&
5237 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
5238 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
5239 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
5240 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
5241 (redChanIdx != blueChanIdx) &&
5242 (redChanIdx != alphaChanIdx) &&
5243 (greenChanIdx != blueChanIdx) &&
5244 (greenChanIdx != alphaChanIdx) &&
5245 (blueChanIdx != alphaChanIdx)))) // Chans can't be teh same if non-negative
5246 inline bool
5247 operator!= (colorTpl<clrChanT, numChan> const& color1, colorTpl<clrChanT, numChan> const& color2) {
5248 return color1.isNotEqual(color2);
5249 }
5250
5251} // end namespace mjr
5252
5253#define MJR_INCLUDE_MRcolorTpl
5254#endif
uint64_t mjr_uintBiggest_t
The largest unsigned integer supported on the platform.
int64_t mjr_intBiggest_t
The largest signed integer supported on the platform.
Compute a color for a point in using a continuous color scheme for the phase angle.
static colorTpl & c(colorRefType aColor, csCplxType csZ)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csFltType csX, csFltType csY)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl c(csCplxType csZ)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csFltType csX, csFltType csY)
Set given colorTpl instance to the selected color in the color scheme.
Compute a color for a point in using a discrete color scheme for the phase angle.
static colorTpl c(csFltType csX, csFltType csY)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csCplxType csZ)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csCplxType csZ)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csFltType csX, csFltType csY)
Set given colorTpl instance to the selected color in the color scheme.
Compute a color from Richardson's 2D complex number coloring scheme.
static colorTpl & c(colorRefType aColor, csCplxType csZ)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csFltType csX, csFltType csY)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csCplxType csZ)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl c(csFltType csX, csFltType csY)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
Template for Thaller 2D color schemes.
static colorTpl & c(colorRefType aColor, csFltType csX, csFltType csY)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csCplxType csZ)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csCplxType csZ)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csFltType csX, csFltType csY)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
Binary color scheme.
static colorTpl c(csIntType csIdx)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csIntType csIdx)
Set given colorTpl instance to the selected color in the color scheme.
Template for Color Brewer 2 variable sized pallets.
static colorTpl c(saT csG, csIntType numC=maxNumC)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, saT csG, csIntType numC=maxNumC)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, saT csG, csIntType numC=maxNumC)
Set given colorTpl instance to the selected color in the color scheme.
Template providing RGB color cube gradiant color schemes.
static colorTpl & c(colorRefType aColor, saT csG)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, saT csG)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(saT csG)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
Compute a color from Dave Green's cubehelix scheme.
static colorTpl c(csFltType csX)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csFltType csX)
Set given colorTpl instance to the selected color in the color scheme.
Template for fixed size pallets.
static colorTpl & c(colorRefType aColor, saT csG)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(saT csG)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, saT csG)
Set given colorTpl instance to the selected color in the color scheme.
Template for HSL color schemes.
static colorTpl & c(colorRefType aColor, csNatType csVal)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csNatType csVal)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
Compute a color from a polynomial space curve in the RGB color space.
static colorTpl c(csFltType csX)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csFltType csX)
Set given colorTpl instance to the selected color in the color scheme.
Wrapper for Color Brewer 2 variable sized pallet template to produce a simple fixed color scheme with...
static colorTpl c(saT csG)
static colorTpl & c(colorRefType aColor, saT csG)
static colorTpl & c(colorRefType aColor, saT csG)
Template for web safe 216 pallets.
static colorTpl c(csIntType csIdx)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csIntType csIdx)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(colorRefType csCol)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, colorRefType csCol)
Set given colorTpl instance to the selected color in the color scheme.
Template Class used to house colors for ramCanvas objects.
colorTpl & tfrmShiftR(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & setRGBAfromLogPackIntABGR(packed4Cint anInt)
colorTpl & setChans_byte(colConALLbyte byteColor)
colorTpl< double, 3 > colConRGBdbl
RGB with double channels.
uint8_t getChan_byte(int chan) const
colorTpl & setChansRGBA_dbl(colConRGBAdbl dblColor)
double getC0_dbl() const
colorTpl & tfrmGreyScaleRGB(void)
Transform the current color by rendering it into a true grey via the same method used by the luminanc...
colorTpl & tfrmStdPowSqr(void)
The Standard Power Transform with p=2.
colorTpl & tfrmNegDiffClamp(colorArgType aCol)
Computes the negative of the arithmetic difference of the given color from the current one.
colorTpl & tfrmMod(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colConDbl3 rgb2colorSpace(colorSpaceEnum space) const
Compute channels for given color space coordinates for the current color.
colorTpl & tfrmStdPowSqrt(void)
The Standard Power Transform with p=1/2.
colorTpl & setToBlack()
colorTpl & setRGBfromColorSpace(colorSpaceEnum space, double inCh1, double inCh2, double inCh3)
Set the color indicated by the color space and values.
void setChansToMean()
Set all channels to meanChanVal.
clrChanT getRed() const
colorTpl & setChansRGB_byte(colConRGBbyte byteColor)
colorTpl & setRGBAfromLogPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx, uint8_t aIdx)
Set the color based upon the bytes of the given integer ordered from LSB to MSB.
colorTpl & csSet(csAT csArg1, csAT csArg2)
clrChanT getMaxC() const
Returns the value of the largest component.
uint8_t getC3_byte() const
colorTpl< uint8_t, numChan > colConALLbyte
Color with the same number of challens as colorT, but with uint8_t channels.
colConRGBAdbl getColConRGBA_dbl()
bool isBlackRGB() const
LIke isBlack(), but only checks the R, G, & B channels.
clrChanT getC1() const
colorTpl & setChansRGBA(clrChanTup4 chanValues)
colorTpl & tfrmShiftR(colorArgType aCol)
The Shift Right Transform modifies the current color.
colorTpl & tfrmPow(double p)
Power: c=maxChanVal*(c/maxChanVal)^p.
colorTpl(std::string colorString)
Uses the setColorFromString() method to set the initialize the object.
clrChanT thePartsA[numChan]
colorTpl & linearInterpolateRGB(double aDouble, colorArgType col1, colorArgType col2)
Set the RGB channels of the current color to a value linearly interpolated between the two given colo...
std::tuple< clrChanT, clrChanT, clrChanT > clrChanTup3
colorTpl & setC3_byte(uint8_t cVal)
colorTpl & tfrmShiftL(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
std::string colorSpaceToString(colorSpaceEnum space)
Compute channels for given color space coordinates for the current color.
colorTpl & setAlpha(clrChanT cVal)
colorTpl & tfrmDiv(colorArgType aCol)
Computes the arithmetic division of the current color by the given color.
std::tuple< clrChanT, clrChanT, clrChanT, clrChanT > clrChanTup4
colConRGBdbl getColConRGB_dbl()
colorTpl & cmpRGBcornerDGradiant(csIntType csIdx, const char *cornerColors)
This is simply a version of cmpRGBcornerDGradiant() that computes the length of the final argument as...
uint8_t convertChanToByte(clrChanT cVal) const
Convert a clrChanT to a uint8_t (for floating point clrChanT)
colorTpl & setC3(clrChanT cVal)
colorTpl & setChansRGB_byte(uint8_t r, uint8_t g, uint8_t b)
colorTpl & tfrmInvert()
Transforms the color: r=maxChanVal-r, g=maxChanVal-r, and b=maxChanVal-b.
colorTpl & setRGBcmpGreyTGA24bit(uint32_t tga24val)
Computes a 24-bit truecolor value intended for use in producing 24-bit greyscale TGA.
uint8_t getAlpha_byte() const
clrChanT channelArithFlt2clrChan(channelArithFltType flt)
Convert a channelArithFltType value into a clrChanT value.
colorTpl & tfrmAnd(colorArgType aCol)
Performs a logical AND with the current object and the given object and places the value in the curre...
colorTpl & setChans(clrChanTup4 chanValues)
Sets the first four channels current object.
void setChansToMax()
Set all channels to maxChanVal.
colorTpl & setChansRGB_dbl(colConRGBdbl dblColor)
colorTpl & tfrmCopy(colorArgType aCol)
Copies the given argument into the current color object.
colorType const & colorCRefType
Reference to const colorTpl.
clrChanT getBlue() const
colConRGBAbyte getColConRGBA_byte()
colorTpl & setChansRGBA_byte(colConRGBAbyte byteColor)
colorTpl< double, numChan > colConALLdbl
Color with the same number of challens as colorT, but with double channels.
colorType * colorPtrType
Pointer to colorTpl.
double getBlue_dbl() const
colorTpl & tfrmWebSafeRGB()
The 216 Palate Web Safe Transform modifies the current color into the closest web safe color from the...
colorTpl & tfrmOr(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & setChansRGBA_byte(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
colorTpl & setToBlue()
maskType getMaskNC() const
Return the mask value.
colorTpl & setC1(clrChanT cVal)
colorTpl & interplColorSpace(colorSpaceEnum space, double aDouble, colorArgType col1, colorArgType col2)
Set the current color to a value linearly interpolated between the two given colors.
std::tuple< clrChanT > clrChanTup1
bool isNotEqual(colorArgType aColor) const
Returns non-zero if the given color is logically NOT the same as the current color.
colorTpl & cmpGradiant(csFltType csX, csIntType numColors, const packed4Cint *colors)
Identical to the other equidistant cmpGradiant() function except that this one works on just the RGB ...
colorTpl< double, 3 > colConDbl3
Used for color space computations. Type identical to colConRGBdbl, but might not be RGB.
colorTpl & setToMagenta()
double distDeltaE1976(colorArgType aColor) const
LAB Delta E* distance between current color and given one.
colorTpl & setRGBfromLogPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx)
Just like setRGBAfromLogPackIntGen, but no A.
colorTpl & tfrmNand(colorArgType aCol)
Performs a logical NAND with the current object and the given object and places the value in the curr...
colorTpl & setChanToMax(int chan)
colorTpl & wMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3, colorArgType col1, colorArgType col2, colorArgType col3)
This is an overloaded member function, provided for convenience. It differs from the above function o...
union mjr::colorTpl::@0 theColor
Holds the color channel data.
bool isEqualRGB(colorArgType aColor) const
Like isEqual(), but only checks the R, G, & B channels.
clrChanT clampAll(iT arithValue)
Clamp a value to [minChanVal, maxChanVal].
colorTpl & setChansRGB_dbl(double r, double g, double b)
colConALLbyte getColCon_byte()
colorTpl & setToHalf()
clrChanT clampTop(iT arithValue)
Clamp a value to (infinity, maxChanVal].
colorTpl(clrChanT r, clrChanT g, clrChanT b, clrChanT a)
colorTpl & uMean(channelArithFltType w1, colorArgType col1, colorArgType col2)
This is an overloaded member function, provided for convenience. It differs from the above function o...
clrChanT convertHexStringToChan(std::string hexString) const
Convert hex CString to clrChanT (for floating point clrChanT)
double distDeltaE1994(colorArgType aColor) const
LAB Delta E* 1994 (graphic arts) distance between current color and given one.
colorTpl & setBlue(clrChanT cVal)
std::vector< clrChanT > clrChanVec
colorTpl & setRGBfromLogPackIntARGB(packed4Cint anInt)
channelArithFltType intensityScaledRGB() const
Compute the scaled intensity (sum of the first three components divided by the maximum intensity poss...
colorTpl & setChans_byte(uint8_t cVal)
colorTpl & tfrmComplexCut(std::complex< double > z, double cutDepth, double argCuts, double absCuts, bool logAbs=true)
Perform a tfrmLinearGreyLevelScale based on a complex number.
colorTpl & setC1_dbl(double cVal)
colorTpl & tfrmNor(colorArgType aCol)
Performs a logical NOR with the current object and the given object and places the value in the curre...
colorTpl & tfrmStdPowRGB(double rp, double gp, double bp)
The Standard Power Transform modifies the current color such that: R=maxChanVal*(R/maxChanVal)**rp,...
colorTpl & cmpRGBcornerDGradiant(csIntType csIdx, csIntType numColors, const ccT *cornerColors)
Color value based upon a color ramp passing through the given sequence of corner colors at equal inte...
colorTpl & setRGBfromPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx)
Just like setRGBAfromPackIntGen, but no A.
colorTpl & setChanNC(int chan, clrChanT cVal)
Sets the specified color channel value with no index check.
colorTpl & tfrmShiftL(colorArgType aCol)
The Shift Left Transform modifies the current color.
colorTpl & setRGBfromLogPackIntBGRA(packed4Cint anInt)
maskType theInt
colorTpl & setToGreen()
clrChanT getMaxRGB() const
Returns the value of the largest component from R, G, and B.
colorTpl & setRGBAfromLogPackIntARGB(packed4Cint anInt)
~colorTpl()
The destructor for this class is a no-op.
channelArithSPType distSumAbs(colorArgType aColor) const
Distance between current color and given one (sum of absolute channel differences).
colorTpl & setRGBAfromLogPackIntRGBA(packed4Cint anInt)
colorTpl & tfrmDiracTot(colorArgType aCol)
The DiracTot (total) Transform modifies the current color: Set current color to white if it equals aC...
channelArithFltType intensityScaled() const
Compute the scaled intensity (sum of the components divided by the maximum intensity possible) of the...
colorTpl & tfrmMean(colorArgType aCol)
Computes the arithmetic mean of the given color and the current one.
colorTpl & setRGBfromLogPackIntABGR(packed4Cint anInt)
colorTpl & setColorFromString(std::string colorString)
Sets the current color based upon the contents of the given std::string.
colorTpl & tfrmMin(colorArgType aCol)
Makes each component of the current color the minimum of that component and the corresponding compone...
colorTpl(clrChanT r, clrChanT g, clrChanT b)
uint8_t getBlue_byte() const
clrChanT getChan(int chan) const
clrChanT getC3() const
colorTpl & wMean(channelArithFltType w1, channelArithFltType w2, colorArgType col1, colorArgType col2)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEqual(colorArgType aColor) const
Returns non-zero if the current color is precicely equal to aColor.
colorTpl & setBlue_byte(uint8_t cVal)
uint32_t packed4Cint
Used for passing & returning integers with packed 8-bit channels.
bool isBlack()
Returns non-zero if the given color is black (all componnets are zero)
colorTpl & tfrmMult(colorArgType aCol)
Computes the arithmetic product of the given color and the current one.
colConALLdbl getColCon_dbl()
std::conditional< ptrIsSmaller, colorCRefType, colorType >::type colorArgType
A type for passing colorTpl objects to functions.
clrChanT getGreen() const
uint8_t getC2_byte() const
double getGreen_dbl() const
colorTpl & tfrmLinearGreyLevelScaleRGB(double rc, double rb, double gc, double gb, double bc, double bb)
The Linear Grey Level Scale transform modifies the current color such that: R=rc*R+rb,...
void setMaskNC(maskType aMask)
Set the mask value.
colorTpl & tfrmAddDivClamp(colorArgType aCol, colorArgType dCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & tfrmAbsDiff(colorArgType aCol)
Computes the absolute value of the difference for each channel between the given color and the curren...
colorTpl & setChans(clrChanTup3 chanValues)
Sets the first three channels current object.
colorTpl & setToWhite()
colorTpl & cmpGradiant(csFltType csX, std::vector< colorType > const &colors)
Identical to the other cmpGradiant() function except that equidistant anchors are automatically gener...
clrChanT getC2() const
colorTpl & setRGBAfromLogPackIntABRG(packed4Cint anInt)
colorTpl & tfrmDiv(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & tfrmNot(void)
Template specialization member function differing from the above function only in supported template ...
colorTpl & setToCorner(char cornerColor)
Set the current color based upon the single character given – 0==black, R, G, B, M,...
clrChanT getChanNC(int chan) const
Provides access to an specified color channel value with no index check.
colorTpl()
The no arg constructor is a noop so we don't needlessly initialize millions of pixels – compiler warn...
colorTpl & tfrmMod(colorArgType aCol)
Computes the arithmetic modulus of the current by the given one.
colorType & colorRefType
Reference to colorTpl)
colorTpl & setC0_byte(uint8_t cVal)
double getChan_dbl(int chan) const
colorTpl & tfrmNand(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & setRed(clrChanT cVal)
colorTpl & tfrmMultClamp(colorArgType aCol)
Computes the product of the given color and the current one.
colorTpl & tfrmNxor(colorArgType aCol)
Performs a logical NOT EXCLUSIVE OR (NXOR) with the current object and the given object and places th...
std::tuple< clrChanT, clrChanT, clrChanT, clrChanT > clrChanTup6
double hslHelperVal(double n1, double n2, double hue)
This is a helper function for setRGBfromColorSpace.
colConRGBbyte getColConRGB_byte()
colorTpl & tfrmFuzzyDirac(colorArgType ctrCol, colorArgType radCol)
The Fuzzy Dirac Transform modifies the current color: C_i=ifelse(|R-ctrCol.R|<=radCol....
colorTpl(const colorType &aColor)
Copy constructor (heavily used for assignment in the ramCanvas library).
colorTpl & tfrmAddDivClamp(colorArgType aCol, colorArgType dCol)
Computes the arithmetic sum of the current color and aCol, then divids by dCol.
void setChansToMin()
Set all channels to minChanVal.
channelArithFltType luminanceRGB(void) const
Compute the luminance of the current color via the definition given in the ITU-R Recommendation BT....
colorTpl & setChans_dbl(double cVal)
colorTpl & cmpRGBcornerCGradiant(csFltType csX, const char *cornerColors)
This is simply a version of cmpRGBcornerCGradiant() that computes the length of the final argument as...
double getC3_dbl() const
colorTpl & cmpGradiant(csFltType csX, std::vector< csFltType > const &anchors, std::vector< colorType > const &colors)
Convert a double to a color value based upon a color ramp passing through the given sequence of corne...
colorTpl & setChansRGBA_dbl(double r, double g, double b, double a)
double getRed_dbl() const
uint8_t convertChanToByte(clrChanT cVal) const
Convert a clrChanT to a uint8_t (for integral clrChanT)
colorTpl & wMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3, channelArithFltType w4, colorArgType col1, colorArgType col2, colorArgType col3, colorArgType col4)
Compute the weighted mean of the given colors.
colorTpl & setAlpha_byte(uint8_t cVal)
uint8_t getGreen_byte() const
colorTpl & linearInterpolate(double aDouble, colorArgType col1, colorArgType col2)
Set the current color to a value linearly interpolated between the two given colors.
colorTpl(cornerColorEnum cornerColor)
Uses the setToCorner() method to set the initialize the object.
colorTpl & tfrmMinI(colorArgType aCol)
Makes the current color the minimum of the current color or the given color.
colorTpl< uint8_t, 4 > colConRGBAbyte
RGBA with uint8_t channels.
colorTpl & tfrmLn1()
Template specialization member function differing from the above function only in supported template ...
colorTpl & setAlpha_dbl(double cVal)
clrChanT convertHexStringToChan(std::string hexString) const
Convert hex CString to clrChanT (for integral clrChanT)
colorTpl & tfrmSqDiff(colorArgType aCol)
Computes the square of the difference for each channel between the given color and the current color ...
colorTpl & setRGBfromWavelengthLA(double wavelength)
Set the color indicated by the given wavelength.
double convertChanToDouble(clrChanT cVal) const
Convert a clrChanT to a double.
colorTpl & tfrmStep(colorArgType lowCol, colorArgType highCol)
The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, maxChanVal,...
colorTpl & setGreen_dbl(double cVal)
bool isCloseRGB(colorArgType aColor, clrChanT epsilon) const
Like isClose(), but only checks the R, G, & B channels.
double getC2_dbl() const
colorTpl< uint8_t, 3 > colConRGBbyte
RGB with uint8_t channels.
clrChanT channelType
Type for the channels (clrChanT)
colorTpl & setC3_dbl(double cVal)
std::tuple< clrChanT, clrChanT, clrChanT, clrChanT > clrChanTup5
colorTpl & setC1_byte(uint8_t cVal)
clrChanT getMinRGB() const
Returns the value of the smallest component from R, G, and B.
colorTpl & setToRed()
colorTpl & setRed_dbl(double cVal)
std::tuple< clrChanT, clrChanT > clrChanTup2
colorTpl & tfrmNor(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & tfrmNxor(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & setRGBfromLogPackIntRGBA(packed4Cint anInt)
channelArithSPType distMaxAbs(colorArgType aColor) const
Distance between current color and given one (maximum of absolute value of channel differences).
colorTpl & csSet(csAT csArg)
colorSpaceEnum
Color spaces.
colorTpl & setChanToMin(int chan)
colorTpl & setToCorner(cornerColorEnum cornerColor)
Set the color to the given corner color.
colorTpl & setToCyan()
colorTpl & setRGBfromUnitHSL(double H, double S, double L)
Set the color indicated by the given HSL values.
channelArithSPType intensityRGB(void) const
Compute the unscaled intensity (sum of the R, G, & B components) of the current color.
uint8_t getC1_byte() const
colorTpl(const char *colorCString)
Uses the setColorFromString() method to set the initialize the object.
colorTpl colorType
This object type.
colorTpl & tfrmLn1()
Adds 1.0 and takes the natural logarithm of each channel.
uint8_t getC0_byte() const
colorTpl & setGreen_byte(uint8_t cVal)
colorTpl & tfrmXor(colorArgType aCol)
Performs a logical EXCLUSIVE OR (XOR) with the current object and the given object and places the val...
colorTpl & tfrmDiffClamp(colorArgType aCol)
Computes the arithmetic difference of the given color from the current one.
clrChanT clampBot(iT arithValue)
Clamp a value to [minChanVal, infinity).
colorTpl & uMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3, colorArgType col1, colorArgType col2, colorArgType col3, colorArgType col4)
Compute the unit weighted mean of the given colors – like wMean(), but last weight is computed such t...
colorTpl & setChansRGB(clrChanT r, clrChanT g, clrChanT b)
colorTpl & setRGBfromWavelengthCM(double wavelength, cmfInterpolationEnum interpMethod=cmfInterpolationEnum::LINEAR)
Set the color indicated by the given wavelength.
colorTpl & tfrmAddClamp(colorArgType aCol)
Computes the arithmetic sum of the given color from the current one.
colorTpl & tfrmMax(colorArgType aCol)
Makes each component of the current color the maximum of that component and the corresponding compone...
channelArithFltType dotProd(colorArgType aColor) const
Compute the dot product between the current color and the given color.
colorTpl & setToYellow()
colorTpl & setRGBfromLogPackIntABRG(packed4Cint anInt)
colorTpl & setRGBfromColorSpace(colorSpaceEnum space, colConDbl3 inColor)
This is an overloaded member function, provided for convenience. It differs from the above function o...
colorTpl & tfrmNot(void)
Performs logical (bit-wise) negation of current object.
clrChanT getAlpha() const
colorTpl & setC0_dbl(double cVal)
colorTpl & cmpRGBcornerCGradiant(csFltType csX, csIntType numColors, const ccT *cornerColors)
Color value based upon a color ramp passing through the given sequence of corner colors at equal inte...
colorTpl(std::initializer_list< clrChanT > cVals)
Initializer list.
cmfInterpolationEnum
Interpolation methods for emperical color matching functions.
colorTpl & setChans(clrChanT cVal)
colorTpl & setChans(clrChanVec &chanValues)
This function sets color channels from the data in a std::vector.
colorTpl< double, 4 > colConRGBAdbl
RGBA with double channels.
colorTpl & setC2_dbl(double cVal)
colorTpl & tfrmGmean(colorArgType aCol)
Computes the geometric mean of the given color and the current one.
colorTpl & tfrmSaw(colorArgType lowCol, colorArgType highCol)
The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, C_i, 0)
colorTpl & setBlue_dbl(double cVal)
channelArithFltType distHypot(colorArgType aColor) const
Distance between current color and given one (sum squares of channel differences – Euclidean distance...
channelArithFltType rgb2GreyDotProd(channelArithFltType redWt=RGBluminanceWeightR, channelArithFltType greenWt=RGBluminanceWeightG, channelArithFltType blueWt=RGBluminanceWeightB) const
Use the R, G, & B channels to compute a floating point value representing a grey scale.
colorTpl & setChan_dbl(int chan, double cVal)
colorTpl & tfrmDiff(colorArgType aCol)
Computes the arithmetic difference of the given color from the current one.
clrChanT convertByteToChan(uint8_t cVal) const
Convert a uint8_t to a clrChanT (for integral clrChanT)
colorTpl & setChansRGB(clrChanTup3 chanValues)
double getC1_dbl() const
colorTpl & setC2_byte(uint8_t cVal)
double getAlpha_dbl() const
colorTpl & setChan(int chan, clrChanT cVal)
bool isClose(colorArgType aColor, clrChanT epsilon) const
Returns non-zero if the current color is close to aColor (the maximum delta between any two channels ...
clrChanT convertDoubleToChan(double cVal) const
Convert a double to a clrChanT.
colorTpl & setGreen(clrChanT cVal)
colorTpl & setRGBAfromPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx, uint8_t aIdx)
Set the color based upon the bytes of the given integer ordered as in RAM.
colorTpl & uMean(channelArithFltType w1, channelArithFltType w2, colorArgType col1, colorArgType col2, colorArgType col3)
This is an overloaded member function, provided for convenience. It differs from the above function o...
clrChanT getC0() const
colorTpl & setC2(clrChanT cVal)
colorTpl & tfrmSignDiff(colorArgType aCol)
Computes the component wise scaled sign of the difference between the current color and the given one...
colorTpl & tfrmLn(double scale)
Template specialization member function differing from the above function only in supported template ...
colorTpl & tfrmDirac(colorArgType aCol)
The Dirac Transform modifies the current color: C_i = ifelse(C_i==aCol.C_i, maxChanVal,...
colorTpl & tfrmMix(double aDouble, colorArgType tooCol)
Linearly interpolate between the current color and the given color (at a point scaled the unit interv...
uint8_t getRed_byte() const
cornerColorEnum
Colors at the corners of the RGB color cube.
colorTpl & tfrmMaxI(colorArgType aCol)
Makes the current color the maximum of the current color or the given color.
colorTpl & tfrmOr(colorArgType aCol)
Performs a logical OR with the current object and the given object and places the value in the curren...
colorTpl & setChan_byte(int chan, uint8_t cVal)
colorTpl & tfrmAdd(colorArgType aCol)
Computes the arithmetic sum of the given color and the current one.
colorTpl & setRed_byte(uint8_t cVal)
colorTpl(clrChanT cVal)
Uses setChans() to set all channels to the given value.
colorTpl & setC0(clrChanT cVal)
colorTpl & setRGBfromUnitHSV(double H, double S, double V)
Set the color indicated by the given HSV values.
colorTpl & tfrmLinearGreyLevelScale(double c, double b)
The Linear Grey Level Scale transform modifies the current color such that: C_n=c*C_n+b.
colorTpl & setChans_dbl(colConALLdbl dblColor)
colorTpl & setChans(std::string colorHexString, bool clearUndefinedChannels=false)
Sets the current color based upon the contents of the given color hex string.
colorTpl & tfrmStdPow(double p)
The Standard Power Transform modifies the current color such that: C_i = maxChanVal*(C_i / maxChanVal...
clrChanT convertByteToChan(uint8_t cVal) const
Convert a uint8_t to a clrChanT (for floating point clrChanT)
colorTpl & setChansRGBA(clrChanT r, clrChanT g, clrChanT b, clrChanT a)
colorTpl & setRGBcmpGreyTGA16bit(uint32_t tga16val)
Computes a 24-bit truecolor value intended for use in producing 16-bit greyscale TGA.
colorTpl & tfrmLn(double scale)
Computes ln(c)*scale for each channel value c.
colorTpl & tfrmXor(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
clrChanT getMinC() const
Returns the value of the smallest component.
colorTpl & setToCorner(std::string cornerColor)
Set the color to the named corner color.
channelArithSPType intensity() const
Compute the sum of the components.
colorTpl & setRGBAfromLogPackIntBGRA(packed4Cint anInt)
colorTpl & copy(colorArgType aCol)
Copy the contents of the given color object into the current object.
colorTpl & tfrmAnd(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...