Loading [MathJax]/extensions/tex2jax.js
MRaster lib 22.0.0.0
Image Processing Library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 <functional> /* STL funcs C++98 */
49#include <iomanip> /* C++ stream formatting C++11 */
50#include <iostream> /* C++ iostream C++11 */
51#include <limits> /* C++ Numeric limits C++11 */
52#include <span> /* STL spans C++20 */
53#include <sstream> /* C++ string stream C++ */
54#include <string> /* C++ strings C++11 */
55#include <tuple> /* STL tuples C++11 */
56#include <type_traits> /* C++ metaprogramming C++11 */
57#include <utility> /* STL Misc Utilities C++11 */
58#include <vector> /* STL vector C++11 */
59
60////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
61/** Set to 1 to look for 128-bit integer types, and 0 to not look for them.
62 Right now this only works on GCC & Clang! */
63#ifndef MJR_LOOK_FOR_128_BIT_TYPES
64#define MJR_LOOK_FOR_128_BIT_TYPES MRASTER_OPT_128_INT
65#endif
66
67////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
68#if MJR_LOOK_FOR_128_BIT_TYPES
69#ifdef __GNUC__
70#ifdef __SIZEOF_INT128__
71#if __SIZEOF_INT128__ == 16
72typedef unsigned __int128 mjr_uint128_t;
73typedef __int128 mjr_int128_t;
74#define MJR_HAVE_128_BIT_TYPES
75#endif
76#endif
77#endif
78#endif
79
80////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81#ifdef MJR_HAVE_128_BIT_TYPES
82typedef mjr_uint128_t mjr_uintBiggest_t; //!< The largest unsigned integer supported on the platform
83typedef mjr_int128_t mjr_intBiggest_t; //!< The largest signed integer supported on the platform
84#else
85typedef uint64_t mjr_uintBiggest_t; //!< The largest unsigned integer supported on the platform
86typedef int64_t mjr_intBiggest_t; //!< The largest signed integer supported on the platform
87#endif
88
89////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
90// Put everything in the mjr namespace
91namespace mjr {
92
93////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
94
95/** @brief Template Class used to house colors for ramCanvas objects.@EOL
96
97 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
98 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
99 "fundamental" type for tools requiring a space efficient and high performance set of concrete objects representing colors. The canonical example is
100 representing an image as a very large, rectangular array of colors.
101
102 @par Size efficiency
103
104 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
105 largest hardware supported integer. This is because the library uses an integer to cover color channel array in RAM to make memory operations faster.
106 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
107 detail on the "mask" is provided later in the section "Memory Layout and Performance".
108
109 @par Passing colors as function arguments
110
111 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
112 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
113 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
114 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
115 the end user can employ to use this same strategy: colorArgType.
116
117 @par Memory Layout and Performance
118
119 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
120 integer type exists that can cover the entire channel array without wasting too much space, we can achieve serious performance gains. The trick is
121 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"
122 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:
123
124 - An RGBA color with 8-bit channels (32-bits total) is covered by a uint32_t with no lost space.
125 - 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.
126 - 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.
127 - A 6 channel color with 8-bit channels (48-bits total) is would be covered by a uint64_t -- a 25% waste of space.
128
129 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.
130
131 Some common diagrams of common cases might help:
132
133 2222222222222222 Cover: 16-bits
134 11111111 1x8 Waste 1/2 => No Cover
135 1111111122222222 2x8 Waste 0/2 => Cover with 16-bits
136
137 44444444444444444444444444444444 Cover: 32-bits
138 111111112222222233333333 3x8 Waste 1/4 => Cover with 32-bits
139 11111111222222223333333344444444 4x8 Waste 0/4 => Cover with 32-bits
140
141 8888888888888888888888888888888888888888888888888888888888888888
142 1111111122222222333333334444444455555555 5x8 Waste 3/8 => No cover
143 111111112222222233333333444444445555555566666666 6x8 Waste 2/8 => Cover with 64-bits
144 111111111111111122222222222222223333333333333333 3x16 Waste 2/8 => Cover with 64-bits
145
146 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
147 1111111122222222333333334444444455555555666666667777777788888888999999990000000011111111 11x8 Waste 5/16 => No Cover
148 111111112222222233333333444444445555555566666666777777778888888899999999000000001111111122222222 12x8 Waste 4/16 => Cover with uint128_t
149 11111111111111112222222222222222333333333333333344444444444444445555555555555555 5x16 Waste 6/16 == No Cover
150 111111111111111122222222222222223333333333333333444444444444444455555555555555556666666666666666 6x16 Waste 4/16 => Cover with uint128_t
151 111111111111111111111111111111112222222222222222222222222222222233333333333333333333333333333333 3x32 Waste 4/16 => Cover with uint128_t
152
153 @par Usage
154
155 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
156 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
157 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
158 another example, this provides the ability to do "method chaining" like so: aColor.setToRed().setToBlack() -- which will lead to aColor being black. The
159 obvious potential performance impact of returning unused references is generally optimized away by modern compilers.
160
161 Several methods are provided that transform the color object as a whole. For example, methods are provided to compute component-wise linear histogram
162 transformations. Note that transformation methods are not provided to transform just one component of an object or a range of components. The philosophy
163 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
164 function to add the second half of two integers together -- integers are one "thingy" and so are colors. :)
165
166 @par Construction
167
168 Several constructors are provided. All in all, the goal is to make it easy to construct color objects with a specified color.
169
170 |--------------------------------+---------------------+----------------------------------------|
171 | Type | Member Helper | Cast Application |
172 |--------------------------------+---------------------+----------------------------------------|
173 | colorT | copy | |
174 | four clrChanT | setChans | |
175 | three clrChanT | setChans | |
176 | two clrChanT | setChans | |
177 | one clrChanT | setChans | drawPoint(x, y, 128); |
178 | Named Corner Colors via string | setColorFromString | drawPoint(x, y, "Red"); |
179 | Web hex string | setColorFromString | drawPoint(x, y, "#FF0000"); |
180 | Extended web hex string | setColorFromString | drawPoint(x, y, "##FFFF00000000"); |
181 | Single character string | setColorFromString | drawPoint(x, y, "R"); |
182 | Named Corner Colors via ENUM | setToCorner | drawPoint(x, y, cornerColorEnum::RED); |
183 |--------------------------------+---------------------+----------------------------------------|
184
185 @tparam clrChanT Type to contain the channel information. This type should be a unsigned integral type, a float, or double.
186 @tparam numChan The number of channels this color will have. Common choices are 1 for greyscale, 3 for RGB, and 4 for RGBA.
187 @tparam redChanIdx Index for the Red channel. -1 indicates no Red chan.
188 @tparam blueChanIdx Index for the Blue channel. -1 indicates no Red channel.
189 @tparam greenChanIdx Index for the Green channel. -1 indicates no Red channel.
190 @tparam alphaChanIdx Index for the Alpha channel. -1 indicates no Red channel.
191 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
192 are all negative and numChan == 3, then alphaChanIdx won't be assigned, but red, blue, and green will be. */
193 template <class clrChanT, int numChan, int redChanIdx = -1, int greenChanIdx = -1, int blueChanIdx = -1, int alphaChanIdx = -1>
194 requires ((numChan>0) && // Must have at least 1 chan
195 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
196 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
197 (redChanIdx < numChan) &&
198 (blueChanIdx < numChan) &&
199 (greenChanIdx < numChan) &&
200 (alphaChanIdx < numChan) &&
201 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
202 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
203 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
204 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
205 (redChanIdx != blueChanIdx) &&
206 (redChanIdx != alphaChanIdx) &&
207 (greenChanIdx != blueChanIdx) &&
208 (greenChanIdx != alphaChanIdx) &&
209 (blueChanIdx != alphaChanIdx)))) // Chans can't be teh same if non-negative
210 class colorTpl {
211
212 public:
213
214 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
215 /** @name Public type related types -- meta-types? ;) */
216 //@{
217 /** This object type */
219 /** Pointer to colorTpl */
221 /** Reference to colorTpl) */
223 /** Reference to const colorTpl */
224 typedef colorType const& colorCRefType;
225 /** Type for the channels (clrChanT) */
226 typedef clrChanT channelType;
227 //@}
228
229 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
230 /** @name Public types for std::tuple & std::vector containing clrChanT values */
231 //@{
232 typedef std::tuple<clrChanT, clrChanT, clrChanT, clrChanT> clrChanTup6;
233 typedef std::tuple<clrChanT, clrChanT, clrChanT, clrChanT> clrChanTup5;
234 typedef std::tuple<clrChanT, clrChanT, clrChanT, clrChanT> clrChanTup4;
235 typedef std::tuple<clrChanT, clrChanT, clrChanT> clrChanTup3;
236 typedef std::tuple<clrChanT, clrChanT> clrChanTup2;
237 typedef std::tuple<clrChanT> clrChanTup1;
238
239 typedef std::vector<clrChanT> clrChanVec;
240 //@}
241
242 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
243 /** @name Color transform function types. */
244 //@{
245 typedef std::function<colorTpl(colorTpl)> co2co_func_t; //!< color to color (transform)
246 typedef std::function<colorTpl&(colorTpl&)> cr2cr_func_t; //!< color reference to color reference (transform)
247 typedef std::function<colorTpl(colorTpl&)> cr2co_func_t; //!< color reference to color (transform)
248 typedef std::function<void(colorTpl&)> cr2void_func_t; //!< color reference to void (transform)
249 //@}
250
251 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
252 /** @name Public types for for packed integers. */
253 //@{
254 typedef uint32_t packed4Cint; //!< Used for passing & returning integers with packed 8-bit channels
255 //@}
256
257 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
258 /** @name Public color types related to colorT.
259 These types are used for things like color space computations and sources for setting channels, etc...*/
260 //@{
261 typedef colorTpl<double, 3> colConDbl3; //!< Used for color space computations. Type identical to colConRGBdbl, but might not be RGB.
262 typedef colorTpl<double, 3> colConRGBdbl; //!< RGB with double channels.
263 typedef colorTpl<double, 4> colConRGBAdbl; //!< RGBA with double channels.
264 typedef colorTpl<uint8_t, 3> colConRGBbyte; //!< RGB with uint8_t channels.
265 typedef colorTpl<uint8_t, 4> colConRGBAbyte; //!< RGBA with uint8_t channels.
266 typedef colorTpl<double, numChan> colConALLdbl; //!< Color with the same number of challens as colorT, but with double channels
267 typedef colorTpl<uint8_t, numChan> colConALLbyte; //!< Color with the same number of challens as colorT, but with uint8_t channels
268 //@}
269
270 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
271 /** @cond pat */
272 /** @name Public arithmetic types */
273 //@{
274 /** @typedef maskType
275 Unsigned integer mask to cover the channel array without wasting too much space.
276 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
277 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
278 64 bits. When a cover can't be found, this type is set to uint8_t -- to avoid any alignment issues in RAM.
279
280 The constant goodMask can be used to tell if maskType is large enough to cover.
281 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
282 typedef typename std::conditional<std::cmp_greater_equal(sizeof(uint8_t), sizeof(clrChanT)*numChan), uint8_t,
283 typename std::conditional<std::cmp_greater_equal(sizeof(uint16_t), sizeof(clrChanT)*numChan), uint16_t,
284 typename std::conditional<std::cmp_greater_equal(sizeof(uint32_t), sizeof(clrChanT)*numChan), uint32_t,
285 typename std::conditional<std::cmp_greater_equal(sizeof(uint64_t), sizeof(clrChanT)*numChan),
286 typename std::conditional<std::cmp_less_equal(3*sizeof(uint64_t), sizeof(clrChanT)*numChan*4), uint64_t,
287 uint8_t
288 >::type,
289 typename std::conditional<std::cmp_greater_equal(sizeof(mjr_uintBiggest_t), sizeof(clrChanT)*numChan),
290 typename std::conditional<std::cmp_less_equal(3*sizeof(mjr_uintBiggest_t), sizeof(clrChanT)*numChan*4), mjr_uintBiggest_t,
291 uint8_t
292 >::type,
293 uint8_t
294 >::type>::type>::type>::type>::type maskType;
295
296 /** @typedef channelArithDType
297 Arithmetic type for differences of clrChanT values.
298 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.
299
300 The constant goodArithD can be used to tell if channelArithDType is large enough.
301 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
302 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
303 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)*2), int8_t,
304 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)*2), int16_t,
305 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)*2), int32_t,
306 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)*2), int64_t,
308 >::type>::type>::type>::type>::type channelArithDType;
309
310 /** @typedef channelArithSPType
311 Arithmetic type for sums and products of clrChanT values.
312 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.
313
314 The constant goodArithSP can be used to tell if channelArithSPType is large enough.
315 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
316 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
317 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)*2), uint8_t,
318 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)*2), uint16_t,
319 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)*2), uint32_t,
320 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)*2), uint64_t,
322 >::type>::type>::type>::type>::type channelArithSPType;
323
324 /** @typedef channelArithSDPType
325 Arithmetic type for sums, differences, and products of clrChanT values.
326 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.
327
328 The constant goodArithSDP can be used to tell if channelArithSDPType is large enough.
329 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
330 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
331 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)*4), int8_t,
332 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)*4), int16_t,
333 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)*4), int32_t,
334 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)*4), int64_t,
336 >::type>::type>::type>::type>::type channelArithSDPType;
337
338 /** @typedef channelArithFltType
339 Floating point type suitable for arithmetic of clrChanT values.
340 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.
341
342 The constant goodArithFlt can be used to tell if channelArithFltType is large enough.
343 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
344 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
345 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)), float,
346 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)), float,
347 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)), double,
348 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)), long double,
349 long double
350 >::type>::type>::type>::type>::type channelArithFltType;
351
352 /** @typedef channelArithLogType
353 Arithmetic type suitable for for logical operations of clrChanT values.
354
355 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
356 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
357 general the size of quad floats can vary a bit across hardware platforms, so I suggest not using them for channel types.
358
359 The constant goodArithLog can be used to tell if channelArithLogType the same size as clrChanT.
360 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
361 typedef typename std::conditional<std::is_integral<clrChanT>::value, clrChanT,
362 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)), uint32_t,
363 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)), uint64_t,
364 typename std::conditional<std::cmp_greater_equal(sizeof(mjr_uintBiggest_t), sizeof(clrChanT)), mjr_uintBiggest_t,
365 uint64_t
366 >::type>::type>::type>::type channelArithLogType;
367 //@}
368 /** @endcond */
369
370 private:
371
372 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
373 /** @name Private Object Data */
374 //@{
375 /** Holds the color channel data.
376 The union is used to overlay a mask integer leading to dramatic performance improvements for common color types.
377
378 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
379 "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
380 "correct" way with modern C++; however, I'll need to do quite a bit of performance testing first... */
381 union {
382 maskType theInt;
383 clrChanT thePartsA[numChan];
384 } theColor;
385 //@}
386
387 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
388 /** @name Private utility functions */
389 //@{
390 //--------------------------------------------------------------------------------------------------------------------------------------------------------
391 /** This is a helper function for setRGBfromColorSpace. */
392 inline double hslHelperVal(double n1, double n2, double hue) {
393 hue = mjr::math::ivl::wrapCO(hue, 360.0);
394 if(hue<60)
395 return n1+(n2-n1)*hue/60.0;
396 else if(hue<180)
397 return n2;
398 else if (hue < 240)
399 return n1+(n2-n1)*(240-hue)/60.0;
400 else
401 return n1;
402 }
403 //--------------------------------------------------------------------------------------------------------------------------------------------------------
404 /** Set all channels to meanChanVal. */
405 inline void setChansToMean() { std::fill_n(theColor.thePartsA, numChan, meanChanVal); }
406 //--------------------------------------------------------------------------------------------------------------------------------------------------------
407 /** Set all channels to minChanVal. */
408 inline void setChansToMin() {
409 if constexpr (goodMask)
410 setMaskNC(maskAllZero);
411 else
412 std::fill_n(theColor.thePartsA, numChan, minChanVal);
413 }
414 //--------------------------------------------------------------------------------------------------------------------------------------------------------
415 /** Set all channels to maxChanVal. */
416 inline void setChansToMax() {
417 if(chanIsInt && goodMask)
418 setMaskNC(~static_cast<maskType>(0));
419 else
420 std::fill_n(theColor.thePartsA, numChan, maxChanVal);
421 }
422 //--------------------------------------------------------------------------------------------------------------------------------------------------------
423 /** Sets the current color based upon the contents of the given std::string.
424 This is the guts of the magic constructor taking a string. If colorString starts with a "#", then setChans() will be used.
425 Otherwise setToCorner() will be used */
426 inline colorTpl& setColorFromString(std::string colorString) {
427 if ( !(colorString.empty())) {
428 if(colorString[0] == '#') {
429 setChans(colorString, true);
430 } else {
431 if(((colorString[0] == 'b') || (colorString[0] == 'B')) && (colorString.size() > 1)) {
432 if( (colorString[2]=='u') || (colorString[2]=='U') )
433 setToBlue();
434 else
435 setToBlack();
436 } else {
437 setToCorner(colorString[0]);
438 }
439 }
440 }
441 return *this;
442 }
443 //--------------------------------------------------------------------------------------------------------------------------------------------------------
444 /** Convert a uint8_t to a clrChanT (for integral clrChanT) */
445 inline clrChanT convertByteToChan(uint8_t cVal) const requires (std::integral<clrChanT>) {
446 if(chanIsByte)
447 return cVal;
448 else
449 return static_cast<clrChanT>(static_cast<channelArithSPType>(cVal) * static_cast<channelArithSPType>(maxChanVal) / static_cast<channelArithSPType>(255));
450 }
451 //--------------------------------------------------------------------------------------------------------------------------------------------------------
452 /** Convert a uint8_t to a clrChanT (for floating point clrChanT)*/
453 inline clrChanT convertByteToChan(uint8_t cVal) const requires (std::floating_point<clrChanT>) {
454 return (static_cast<clrChanT>(cVal) / static_cast<clrChanT>(255));
455 }
456 //--------------------------------------------------------------------------------------------------------------------------------------------------------
457 /** Convert hex CString to clrChanT (for integral clrChanT) */
458 inline clrChanT convertHexStringToChan(std::string hexString) const requires (std::integral<clrChanT>) {
459 if (sizeof(unsigned long) >= sizeof(clrChanT))
460 return static_cast<clrChanT>( std::stoul(hexString, nullptr, 16));
461 else
462 return static_cast<clrChanT>(std::stoull(hexString, nullptr, 16));
463 }
464 //--------------------------------------------------------------------------------------------------------------------------------------------------------
465 /** Convert hex CString to clrChanT (for floating point clrChanT)*/
466 inline clrChanT convertHexStringToChan(std::string hexString) const requires (std::floating_point<clrChanT>) {
467 if (sizeof(unsigned long) >= sizeof(clrChanT))
468 return static_cast<clrChanT>( std::stoul(hexString, nullptr, 16)) / static_cast<clrChanT>((chanIsInt ? 1 : std::pow(2, bitsPerChan)));
469 else
470 return static_cast<clrChanT>(std::stoull(hexString, nullptr, 16)) / static_cast<clrChanT>((chanIsInt ? 1 : std::pow(2, bitsPerChan)));
471 }
472 //--------------------------------------------------------------------------------------------------------------------------------------------------------
473 /** Convert a clrChanT to a uint8_t (for floating point clrChanT) */
474 inline uint8_t convertChanToByte(clrChanT cVal) const requires (std::floating_point<clrChanT>) {
475 return static_cast<uint8_t>(cVal * static_cast<clrChanT>(255) / maxChanVal);
476 }
477 //--------------------------------------------------------------------------------------------------------------------------------------------------------
478 /** Convert a clrChanT to a uint8_t (for integral clrChanT) */
479 inline uint8_t convertChanToByte(clrChanT cVal) const requires (std::integral<clrChanT>) {
480 /* 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
481 below. */
482 if constexpr (chanIsByte)
483 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.
484 else
485 return static_cast<uint8_t>(static_cast<channelArithSPType>(cVal) * static_cast<channelArithSPType>(255) / static_cast<channelArithSPType>(maxChanVal));
486 }
487 //--------------------------------------------------------------------------------------------------------------------------------------------------------
488 /** Convert a double to a clrChanT */
489 inline clrChanT convertDoubleToChan(double cVal) const {
490 /* Performance: Not all compilers recognize multiplication by 1.0 as a NOOP. Hence the if-then below. */
491 if constexpr (chanIsInt)
492 return static_cast<clrChanT>(cVal * maxChanVal);
493 else
494 return static_cast<clrChanT>(cVal);
495 }
496 //--------------------------------------------------------------------------------------------------------------------------------------------------------
497 /** Convert a clrChanT to a double */
498 inline double convertChanToDouble(clrChanT cVal) const {
499 if constexpr (chanIsInt)
500 return static_cast<double>(cVal) / static_cast<double>(maxChanVal);
501 else
502 return static_cast<double>(cVal);
503 }
504 //--------------------------------------------------------------------------------------------------------------------------------------------------------
505 /** Return the mask value */
506 inline maskType getMaskNC() const {
507#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
508#pragma GCC diagnostic push
509#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
510#endif
511 return theColor.theInt;
512#if __GNUC__
513#pragma GCC diagnostic pop
514#endif
515 }
516 //--------------------------------------------------------------------------------------------------------------------------------------------------------
517 /** Set the mask value */
518 inline void setMaskNC(maskType aMask) { theColor.theInt = aMask; }
519 //@}
520
521 public:
522
523 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
524 /** @name Public Constants Related to RGBA channels */
525 //@{
526 constexpr static int noRGBchanIdx = (redChanIdx < 0) && (greenChanIdx < 0) && (blueChanIdx < 0) && (alphaChanIdx < 0);
527 constexpr static int redChan = (noRGBchanIdx && numChan > 0 ? 0 : redChanIdx);
528 constexpr static int greenChan = (noRGBchanIdx && numChan > 1 ? 1 : greenChanIdx);
529 constexpr static int blueChan = (noRGBchanIdx && numChan > 2 ? 2 : blueChanIdx);
530 constexpr static int alphaChan = (noRGBchanIdx && numChan > 3 ? 3 : alphaChanIdx);
531 //@}
532
533 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
534 /** @name Public Constants Related to template paramaters */
535 //@{
536 constexpr static int bitsPerChan = (int)(sizeof(clrChanT)*CHAR_BIT); //!< Number of bits in clrChanT
537 constexpr static int bitsPerPixel = numChan*bitsPerChan; //!< Number of color data bits
538 constexpr static bool chanIsInt = std::is_integral<clrChanT>::value; //!< clrChanT is an integral type
539 constexpr static bool chanIsFloat = std::is_floating_point<clrChanT>::value; //!< clrChanT is a floating pint type
540 constexpr static bool chanIsUnsigned = std::is_unsigned<clrChanT>::value; //!< clrChanT is an unsigned integral type
541 constexpr static bool chanIsByte = std::is_same<clrChanT, uint8_t>::value; //!< is clrChanT an 8-bit unsigned int?
542 constexpr static bool chanIsDouble = std::is_same<clrChanT, double>::value; //!< is clrChanT a double?
543 constexpr static bool goodMask = (sizeof(maskType) >= sizeof(clrChanT)*numChan); //!< maskType is big enough
544 constexpr static bool perfectMask = (sizeof(maskType) == sizeof(clrChanT)*numChan); //!< maskType is perfectly sized
545 constexpr static bool goodArithD = (chanIsFloat || (sizeof(channelArithDType) >= sizeof(clrChanT)*2)); //!< channelArithDType is big enough
546 constexpr static bool goodArithSP = (chanIsFloat || (sizeof(channelArithSPType) >= sizeof(clrChanT)*2)); //!< channelArithSPType is big enough
547 constexpr static bool goodArithSDP = (chanIsFloat || (sizeof(channelArithSDPType) >= sizeof(clrChanT)*4)); //!< channelArithSDPType is big enough
548 constexpr static bool goodArithFlt = (chanIsFloat || (sizeof(channelArithFltType) > sizeof(clrChanT))); //!< channelArithFltType is big enough
549 constexpr static bool goodArithLog = (sizeof(channelArithLogType) == sizeof(clrChanT)); //!< channelArithLogType is the right size
550 constexpr static int sizeOfColor = (int)(goodMask ? sizeof(maskType) : sizeof(clrChanT)*numChan); //!< Size of this object
551 constexpr static bool ptrIsSmaller = sizeOfColor > (int)sizeof(colorPtrType); //!< This object smaller than a pointer
552 constexpr static clrChanT maxChanVal = (chanIsInt ? std::numeric_limits<clrChanT>::max() : 1); //!< maximum value for a channel
553 constexpr static clrChanT minChanVal = (chanIsInt ? std::numeric_limits<clrChanT>::min() : 0); //!< maximum value for a channel
554 constexpr static clrChanT meanChanVal = (maxChanVal-minChanVal)/2; //!< middle value for a channel
555 constexpr static maskType maskAllOne = ~(static_cast<maskType>(0)); //!< mask value all ones
556 constexpr static maskType maskAllZero = static_cast<maskType>(0); //!< mask value all zeros
557 constexpr static int channelCount = numChan; //!< Number of channels
558 //@}
559
560 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
561 /** @name Public type for argument passing */
562 //@{
563 /** A type for passing colorTpl objects to functions.
564
565 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
566 colorType const& -- resulting in pass by refrence. */
567 typedef typename std::conditional<ptrIsSmaller, colorCRefType, colorType>::type colorArgType;
568 //@}
569
570 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
571 /** @cond cst */
572 /** @name Color Scheme Related Types */
573 //@{
574 /** A type used for discreet color scheme indexes.
575 This will be uint64_t for floating point clrChanT, and the larger of uint32_t and colorChanArithSPType for integral clrChanT.
576 We use cmp_less because < confuses Doxygen.*/
577 typedef typename std::conditional<std::cmp_less(sizeof(channelArithSPType), sizeof(uint32_t)), uint32_t,
578 typename std::conditional<std::is_floating_point<clrChanT>::value, uint64_t,
579 channelArithSPType
580 >::type>::type csIntType;
581
582 /** A type used for continous color scheme indexes. */
583 typedef double csFltType;
584 /** A type used for 2D continous color scheme indexes. */
585 typedef std::complex<csFltType> csCplxType;
586 /** A clrChanT-similar type color scheme indexes. */
587 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, csFltType, csIntType>::type csNatType;
588 //@}
589 /** @endcond */
590
591 /** @name Color Scheme Constants */
592 //@{
593 /* 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. */
594 constexpr static csIntType chanStepMax = (chanIsInt ? static_cast<csIntType>(maxChanVal) : std::numeric_limits<uint32_t>::max()); //!< Finite "steps" for a color scheme: [0, chanStepMax]
595 constexpr static int minWavelength = 360; //!< Minimum wavelength for wavelength conversion
596 constexpr static int maxWavelength = 830; //!< Maximum wavelength for wavelength conversion
597 //@}
598
599 /** @name Default RGB Luminescence Weights */
600 //@{
601 constexpr static double RGBluminanceWeightR = 0.2126;
602 constexpr static double RGBluminanceWeightG = 0.7152;
603 constexpr static double RGBluminanceWeightB = 0.0722;
604 //@}
605
606 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
607 /** @name Public Enums Constants */
608 //@{
609 /** Colors at the corners of the RGB color cube. */
610 enum class cornerColorEnum { BLACK, //!< Color cube corner color with RGB=000
611 RED, //!< Color cube corner color with RGB=100
612 GREEN, //!< Color cube corner color with RGB=010
613 BLUE, //!< Color cube corner color with RGB=001
614 YELLOW, //!< Color cube corner color with RGB=110
615 CYAN, //!< Color cube corner color with RGB=011
616 MAGENTA, //!< Color cube corner color with RGB=101
617 WHITE //!< Color cube corner color with RGB=111
618 };
619 /** Color spaces.
620 This ENUM is used by setRGBfromColorSpace(), interplColorSpace(), and rgb2colorSpace(). In this context these color spaces use double values for each
621 channel. Angles (the H of HSV, HSL, & LCH) are in degrees, and will always be normalized to [0, 360). */
622 enum class colorSpaceEnum { RGB, //!< RGB color space. R in [0, 1]. G in [0, 1]. B in [0, 1].
623 HSL, //!< HSL color space. H in [0, 360]. S in [0, 1]. L in [0, 1].
624 HSV, //!< HSV color space. H in [0, 360]. S in [0, 1]. V in [0, 1].
625 LAB, //!< CIE-L*ab color space. L in [0, 100]. A in REALS. B in REALS.
626 XYZ, //!< XYZ color space. X in [0, 1]. Y in [0, 1]. Z in [0, 1].
627 LCH, //!< CIE-L*ch color space. L in [0, 100]. C in [0, 100]. H in [0, 360]
628 NONE //!< Used when the color channels don't have an assocaited color space
629 };
630 /** Interpolation methods for emperical color matching functions. */
631 enum class cmfInterpolationEnum { FLOOR, //!< closest lower
632 CEILING, //!< closest upper
633 NEAREST, //!< closest
634 LINEAR, //!< linear interpolation
635 BUMP //!< exponential bump map interpolation
636 // MJR TODO NOTE cmfInterpolationEnum: Add Chebychev and cubic spline options.
637 };
638 //@}
639
640 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
641 /** @name Constructors: C++ Utility */
642 //@{
643 //--------------------------------------------------------------------------------------------------------------------------------------------------------
644 /** The no arg constructor is a noop so we don't needlessly initialize millions of pixels -- compiler warnings are expected. */
646 //--------------------------------------------------------------------------------------------------------------------------------------------------------
647 /** Copy constructor (heavily used for assignment in the ramCanvas library). */
648 colorTpl(const colorType& aColor) {
649 /* 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.
650 Sometimes we might even want to copy an unitilzied color -- sometimes it makes the code easier to write.*/
651 if constexpr (goodMask)
652 setMaskNC(aColor.getMaskNC());
653 else
654 std::copy_n(aColor.theColor.thePartsA, numChan, theColor.thePartsA);
655 }
656 //--------------------------------------------------------------------------------------------------------------------------------------------------------
657 /** Initializer list. Unspecified channels are set ot minChanVal, and extra channel values are ignored. */
658 colorTpl(std::initializer_list<clrChanT> cVals) {
659 int numChanGiven = static_cast<int>(cVals.size());
660 auto p = cVals.begin();
661 for(int i=0; i<std::min(numChanGiven, numChan); i++) {
662 setChanNC(i, *p);
663 ++p;
664 }
665 if (numChanGiven < numChan)
666 for(int i=numChanGiven; i<numChan; i++)
667 setChanToMin(i);
668 }
669 //@}
670
671 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
672 /** @name Constructors: RGB
673 These all use setChansRGB or setChansRGBA internally; however, these constructors will set any unspecified channels to min. */
674 //@{
675 colorTpl(clrChanT r, clrChanT g, clrChanT b, clrChanT a) {
676 if constexpr (numChan > 4)
677 setChansToMin();
678 setChansRGBA(r, g, b, a);
679 }
680 colorTpl(clrChanT r, clrChanT g, clrChanT b) {
681 if constexpr (numChan > 3)
682 setChansToMin();
683 setChansRGB(r, g, b);
684 }
685 //@}
686
687 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
688 /** @name Constructors: Conversions
689 These are all guarnteed to set all channels of the object. */
690 //@{
691 //--------------------------------------------------------------------------------------------------------------------------------------------------------
692 /** Uses setChans() to set all channels to the given value
693 @param cVal The value to set the channels to */
694 colorTpl(clrChanT cVal) { setChans(cVal); }
695 //--------------------------------------------------------------------------------------------------------------------------------------------------------
696 /** Uses the setToCorner() method to set the initialize the object.
697 Note that no constructor exists taking a character to provide to setToCorner(). Why? Because character literals are integers in C++, and they might
698 be the same as clrChanT -- rendering ambiguous overload cases.*/
699 colorTpl(cornerColorEnum cornerColor) { setToCorner(cornerColor); }
700 //--------------------------------------------------------------------------------------------------------------------------------------------------------
701 /** Uses the setColorFromString() method to set the initialize the object. */
702 colorTpl(std::string colorString) { setColorFromString(colorString); }
703 //--------------------------------------------------------------------------------------------------------------------------------------------------------
704 /** Uses the setColorFromString() method to set the initialize the object. */
705 colorTpl(const char* colorCString) { setColorFromString(std::string(colorCString)); }
706 //@}
707
708 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
709 /** @name Destructor */
710 //@{
711 /** The destructor for this class is a no-op. */
713 //@}
714
715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
716 /** @name Utility Methods */
717 //@{
718 /** Copy the contents of the given color object into the current object.
719 When sizeof(colorTpl)<=sizeof(maskType), this function consists of a single assignment statement. Otherwise it is O(numChan).
720 @return Returns a reference to the current color object.*/
721 inline colorTpl& copy(colorArgType aCol) {
722 if constexpr (goodMask)
723 setMaskNC(aCol.getMaskNC());
724 else
725 for(int i=0; i<numChan; i++)
726 setChanNC(i, aCol.getChanNC(i));
727 return *this;
728 }
729 //@}
730
731 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
732 /** @name Named Channel Access
733 Provides access to the specified color channel value with compile time index check.
734 - _dbl versions work with double values scaled to [0, 1].
735 - _byte versions work with uint8_t values scaled to [0, 255]
736 - Numbered channel names are 0 indexed. */
737 //@{
738 inline clrChanT getRed() const requires ((redChan>=0) && (numChan>redChan)) { return getChanNC(redChan); }
739 inline clrChanT getBlue() const requires ((blueChan>=0) && (numChan>blueChan)) { return getChanNC(blueChan); }
740 inline clrChanT getGreen() const requires ((greenChan>=0) && (numChan>greenChan)) { return getChanNC(greenChan); }
741 inline clrChanT getAlpha() const requires ((alphaChan>=0) && (numChan>alphaChan)) { return getChanNC(alphaChan); }
742
743 inline double getRed_dbl() const { return convertChanToDouble(getRed()); }
744 inline double getGreen_dbl() const { return convertChanToDouble(getGreen()); }
745 inline double getBlue_dbl() const { return convertChanToDouble(getBlue()); }
746 inline double getAlpha_dbl() const { return convertChanToDouble(getAlpha()); }
747
748 inline uint8_t getRed_byte() const { return convertChanToByte(getRed()); }
749 inline uint8_t getGreen_byte() const { return convertChanToByte(getGreen()); }
750 inline uint8_t getBlue_byte() const { return convertChanToByte(getBlue()); }
751 inline uint8_t getAlpha_byte() const { return convertChanToByte(getAlpha()); }
752
753 inline clrChanT getC0() const { return getChanNC(0); }
754 inline clrChanT getC1() const requires (numChan>1) { return getChanNC(1); }
755 inline clrChanT getC2() const requires (numChan>2) { return getChanNC(2); }
756 inline clrChanT getC3() const requires (numChan>3) { return getChanNC(3); }
757
758 inline double getC0_dbl() const { return convertChanToDouble(getC0()); }
759 inline double getC1_dbl() const { return convertChanToDouble(getC1()); }
760 inline double getC2_dbl() const { return convertChanToDouble(getC2()); }
761 inline double getC3_dbl() const { return convertChanToDouble(getC3()); }
762
763 inline uint8_t getC0_byte() const { return convertChanToByte(getC0()); }
764 inline uint8_t getC1_byte() const { return convertChanToByte(getC1()); }
765 inline uint8_t getC2_byte() const { return convertChanToByte(getC2()); }
766 inline uint8_t getC3_byte() const { return convertChanToByte(getC3()); }
767 //@}
768
769 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
770 /** @name Indexed Channel Access
771 Provides access to an indexed color channel value with run time index check.
772 The channels are 0 indexed.
773 - _dbl versions work with double values scaled to [0, 1].
774 - _byte versions work with uint8_t values scaled to [0, 255] */
775 //--------------------------------------------------------------------------------------------------------------------------------------------------------
776 inline clrChanT getChan(int chan) const {
777 if((chan >= 0) && (chan < numChan)) [[likely]]
778 return getChanNC(chan);
779 else
780 return minChanVal;
781 }
782 //--------------------------------------------------------------------------------------------------------------------------------------------------------
783 inline double getChan_dbl(int chan) const {
784 if((chan >= 0) && (chan < numChan)) [[likely]]
785 return convertChanToDouble(getChanNC(chan));
786 else
787 return 0.0;
788 }
789 //--------------------------------------------------------------------------------------------------------------------------------------------------------
790 inline uint8_t getChan_byte(int chan) const {
791 if((chan >= 0) && (chan < numChan)) [[likely]]
792 return convertChanToByte(getChanNC(chan));
793 else
794 return 0;
795 }
796 //@}
797
798 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
799 /** @name Set Named Channel Value
800 Provides access to the specified color channel value with compile time index check.
801 - _dbl versions work with double values scaled to [0, 1].
802 - _byte versions work with uint8_t values scaled to [0, 255]
803 - Numbered channel names are 0 indexed. */
804 //@{
805 /* 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
806 for example. */
807 /* Useablity: We could do this with a template, but that means we need ".template set" syntax in some cases. That's just too uguly. */
808
809 inline colorTpl& setC0(clrChanT cVal) { return setChanNC(0, cVal); }
810 inline colorTpl& setC1(clrChanT cVal) requires (numChan>1) { return setChanNC(1, cVal); }
811 inline colorTpl& setC2(clrChanT cVal) requires (numChan>2) { return setChanNC(2, cVal); }
812 inline colorTpl& setC3(clrChanT cVal) requires (numChan>3) { return setChanNC(3, cVal); }
813
814 inline colorTpl& setC0_dbl(double cVal) { return setC0(convertDoubleToChan(cVal)); }
815 inline colorTpl& setC1_dbl(double cVal) { return setC1(convertDoubleToChan(cVal)); }
816 inline colorTpl& setC2_dbl(double cVal) { return setC2(convertDoubleToChan(cVal)); }
817 inline colorTpl& setC3_dbl(double cVal) { return setC3(convertDoubleToChan(cVal)); }
818
819 inline colorTpl& setC0_byte(uint8_t cVal) { return setC0(convertByteToChan(cVal)); }
820 inline colorTpl& setC1_byte(uint8_t cVal) { return setC1(convertByteToChan(cVal)); }
821 inline colorTpl& setC2_byte(uint8_t cVal) { return setC2(convertByteToChan(cVal)); }
822 inline colorTpl& setC3_byte(uint8_t cVal) { return setC3(convertByteToChan(cVal)); }
823
824 inline colorTpl& setRed(clrChanT cVal) requires ((redChan>=0) && (numChan>redChan)) { return setChanNC(redChan, cVal); }
825 inline colorTpl& setBlue(clrChanT cVal) requires ((blueChan>=0) && (numChan>blueChan)) { return setChanNC(blueChan, cVal); }
826 inline colorTpl& setGreen(clrChanT cVal) requires ((greenChan>=0) && (numChan>greenChan)) { return setChanNC(greenChan, cVal); }
827 inline colorTpl& setAlpha(clrChanT cVal) requires ((alphaChan>=0) && (numChan>alphaChan)) { return setChanNC(alphaChan, cVal); }
828
829 inline colorTpl& setRed_dbl(double cVal) { return setRed(convertDoubleToChan(cVal)); }
830 inline colorTpl& setGreen_dbl(double cVal) { return setGreen(convertDoubleToChan(cVal)); }
831 inline colorTpl& setBlue_dbl(double cVal) { return setBlue(convertDoubleToChan(cVal)); }
832 inline colorTpl& setAlpha_dbl(double cVal) { return setAlpha(convertDoubleToChan(cVal)); }
833
834 inline colorTpl& setRed_byte(uint8_t cVal) { return setRed(convertByteToChan(cVal)); }
835 inline colorTpl& setGreen_byte(uint8_t cVal) { return setGreen(convertByteToChan(cVal)); }
836 inline colorTpl& setBlue_byte(uint8_t cVal) { return setBlue(convertByteToChan(cVal)); }
837 inline colorTpl& setAlpha_byte(uint8_t cVal) { return setAlpha(convertByteToChan(cVal)); }
838
839 inline colorTpl& setChansRGBA(clrChanT r, clrChanT g, clrChanT b, clrChanT a) { setRed(r); setGreen(g); setBlue(b); setAlpha(a); return *this; }
840 inline colorTpl& setChansRGB(clrChanT r, clrChanT g, clrChanT b) { setRed(r); setGreen(g); setBlue(b); return *this; }
841
842 inline colorTpl& setChansRGBA_dbl(double r, double g, double b, double a) { return setChansRGBA(convertDoubleToChan(r), convertDoubleToChan(g), convertDoubleToChan(b), convertDoubleToChan(a)); }
843 inline colorTpl& setChansRGB_dbl(double r, double g, double b) { return setChansRGB(convertDoubleToChan(r), convertDoubleToChan(g), convertDoubleToChan(b)); }
844
845 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)); }
846 inline colorTpl& setChansRGB_byte(uint8_t r, uint8_t g, uint8_t b) { return setChansRGB(convertByteToChan(r), convertByteToChan(g), convertByteToChan(b)); }
847
848 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; }
849 inline colorTpl& setChansRGB(clrChanTup3 chanValues) { setRed(std::get<0>(chanValues)); setGreen(std::get<1>(chanValues)); setBlue(std::get<2>(chanValues)); return *this; }
850 //@}
851
852 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
853 /** @name Canonical Color Types.
854 Provide conversions to/from canonical color types. */
855 //@{
856 inline colorTpl& setChans_dbl(colConALLdbl dblColor) { for(int i=0; i<numChan; i++) setChanNC(i, convertDoubleToChan(dblColor.getChanNC(i))); return *this; }
857 inline colorTpl& setChans_byte(colConALLbyte byteColor) { for(int i=0; i<numChan; i++) setChanNC(i, convertByteToChan(byteColor.getChanNC(i))); return *this; }
858 inline colorTpl& setChansRGBA_dbl(colConRGBAdbl dblColor) { return setChansRGBA(convertDoubleToChan(dblColor.getRed()), convertDoubleToChan(dblColor.getGreen()), convertDoubleToChan(dblColor.getBlue()), convertDoubleToChan(dblColor.getAlpha())); }
859 inline colorTpl& setChansRGB_dbl(colConRGBdbl dblColor) { return setChansRGB( convertDoubleToChan(dblColor.getRed()), convertDoubleToChan(dblColor.getGreen()), convertDoubleToChan(dblColor.getBlue())); }
860 inline colorTpl& setChansRGBA_byte(colConRGBAbyte byteColor) { return setChansRGBA(convertByteToChan(byteColor.getRed()), convertByteToChan(byteColor.getGreen()), convertByteToChan(byteColor.getBlue()), convertByteToChan(byteColor.getAlpha())); }
861 inline colorTpl& setChansRGB_byte(colConRGBbyte byteColor) { return setChansRGB( convertByteToChan(byteColor.getRed()), convertByteToChan(byteColor.getGreen()), convertByteToChan(byteColor.getBlue())); }
862
863 inline colConALLdbl getColCon_dbl() { colConALLdbl rCol; for(int i=0; i<numChan; i++) rCol.setChanNC(i, convertChanToDouble(getChanNC(i))); return rCol; }
864 inline colConALLbyte getColCon_byte() { colConALLbyte rCol; for(int i=0; i<numChan; i++) rCol.setChanNC(i, convertChanToByte( getChanNC(i))); return rCol; }
865 inline colConRGBAdbl getColConRGBA_dbl() { return colConRGBAdbl( getChan_dbl(bestRedChan()), getChan_dbl(bestGreenChan()), getChan_dbl(bestBlueChan()), getChan_dbl(bestAlphaChan())); }
866 inline colConRGBdbl getColConRGB_dbl() { return colConRGBdbl( getChan_dbl(bestRedChan()), getChan_dbl(bestGreenChan()), getChan_dbl(bestBlueChan())); }
867 inline colConRGBAbyte getColConRGBA_byte() { return colConRGBAbyte(getChan_byte(bestRedChan()), getChan_byte(bestGreenChan()), getChan_byte(bestBlueChan()), getChan_byte(bestAlphaChan())); }
868 inline colConRGBbyte getColConRGB_byte() { return colConRGBbyte( getChan_byte(bestRedChan()), getChan_byte(bestGreenChan()), getChan_byte(bestBlueChan())); }
869 //@}
870
871 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
872 /** @name Best guess for named channel index.
873 These are used when we wish to get the named channel index, but the current color might not have specified an approprate value. */
874 //--------------------------------------------------------------------------------------------------------------------------------------------------------
875 /* Returns redChan if non-negative and 0 otherwise */
876 inline int bestRedChan() {
877 if constexpr (redChan >= 0)
878 return redChan; // If we have an identical red, then return it.
879 else
880 return 0; // Otherwise return 0 -- we are guarnteed at least one channel.
881 }
882 //--------------------------------------------------------------------------------------------------------------------------------------------------------
883 /* 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. */
884 inline int bestGreenChan() {
885 if constexpr (greenChan >= 0)
886 return greenChan; // If we have an identified green, then return it.
887 else if constexpr (numChan == 1)
888 return 0; // for greyscale, return chan 0
889 else
890 return 1; // If we have more than 1 channel, then return 1
891 }
892 //--------------------------------------------------------------------------------------------------------------------------------------------------------
893 /* 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. */
894 inline int bestBlueChan() {
895 if constexpr (blueChan >= 0)
896 return blueChan; // If we have an identified blue, then return it.
897 else if constexpr (numChan == 1)
898 return 0; // for greyscale, return chan 0
899 else if constexpr (numChan == 2)
900 return -1; // No sensible value for blue channel with 2 channel images
901 else
902 return 2; // If we have at least three channels, then return chan 2
903 }
904 //--------------------------------------------------------------------------------------------------------------------------------------------------------
905 /* Returns alphaChan if it is non-negative. If we only have four or more channels, then returns 3. Otherwise returns -1. */
906 inline int bestAlphaChan() {
907 if constexpr (alphaChan >= 0)
908 return alphaChan; // If we have an identified alpha, then return it.
909 else if constexpr (numChan >= 4)
910 return 3; // If we have at least four channels, then return chan 3
911 else
912 return -1; // No sensible value for alpha channel
913 }
914 //@}
915
916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
917 /** @name Setting a single Channel by Index
918 Provides access to an indexed color channel value with run time index check.
919 The channels are 0 indexed.
920 - _dbl versions work with double values scaled to [0, 1].
921 - _byte versions work with uint8_t values scaled to [0, 255] */
922 //--------------------------------------------------------------------------------------------------------------------------------------------------------
923 inline colorTpl& setChanToMax(int chan) {
924 if((chan >= 0) && (chan < numChan)) [[likely]]
925 setChanNC(chan, maxChanVal);
926 return *this;
927 }
928 //--------------------------------------------------------------------------------------------------------------------------------------------------------
929 inline colorTpl& setChanToMin(int chan) {
930 if((chan >= 0) && (chan < numChan)) [[likely]]
931 setChanNC(chan, minChanVal);
932 return *this;
933 }
934 //--------------------------------------------------------------------------------------------------------------------------------------------------------
935 inline colorTpl& setChan(int chan, clrChanT cVal) {
936 if((chan >= 0) && (chan < numChan)) [[likely]]
937 setChanNC(chan, cVal);
938 return *this;
939 }
940 //--------------------------------------------------------------------------------------------------------------------------------------------------------
941 inline colorTpl& setChan_dbl(int chan, double cVal) {
942 /* Performance: We expect chan to be in range most of the time. If it is not, we waste time here computing the channel value.. */
943 return setChan(chan, convertDoubleToChan(cVal));
944 }
945 //--------------------------------------------------------------------------------------------------------------------------------------------------------
946 inline colorTpl& setChan_byte(int chan, uint8_t cVal) {
947 /* Performance: We expect chan to be in range most of the time. If it is not, we waste time here computing the channel value.. */
948 /* Performance: When chanIsByte, convertByteToChan is a NOOP. As it's inline, this leads to zero overhead for the chanIsByte case. */
949 return setChan(chan, convertByteToChan(cVal));
950 }
951 //@}
952
953 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
954 /** @name Set/Get Single Channel values with no index checks.
955 @warning These functions are fast, but have no error checking. Use them wrong, and get a segfault! */
956 //@{
957 //--------------------------------------------------------------------------------------------------------------------------------------------------------
958 /** Sets the specified color channel value with no index check. */
959 inline colorTpl& setChanNC(int chan, clrChanT cVal) { theColor.thePartsA[chan] = cVal; return *this; }
960 //--------------------------------------------------------------------------------------------------------------------------------------------------------
961 /** Provides access to an specified color channel value with no index check. */
962 inline clrChanT getChanNC(int chan) const {
963#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
964#pragma GCC diagnostic push
965#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
966#endif
967 return theColor.thePartsA[chan];
968#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
969#pragma GCC diagnostic pop
970#endif
971 }
972 //@}
973
974 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
975 /** @name Set All Channel Values To One Value
976 Sets all components of the current object from to \a cVal.
977 - _dbl versions work with double values scaled to [0, 1].
978 - _byte versions work with uint8_t values scaled to [0, 255] */
979 //@{
980 //--------------------------------------------------------------------------------------------------------------------------------------------------------
981 inline colorTpl& setChans(clrChanT cVal) {
982 for(int i=0; i<numChan; i++)
983 setChanNC(i, cVal);
984 return *this;
985 }
986 //--------------------------------------------------------------------------------------------------------------------------------------------------------
987 inline colorTpl& setChans_dbl(double cVal) { return setChans(convertDoubleToChan(cVal)); }
988 inline colorTpl& setChans_byte(uint8_t cVal) { return setChans(convertByteToChan(cVal)); }
989 //@}
990
991 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
992 /** @name Set Channel Value(s) with clrChanT values */
993 //@{
994 //--------------------------------------------------------------------------------------------------------------------------------------------------------
995 /** Sets the first four 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(clrChanTup4 chanValues) { /* Requires: Inherits numChan>3 from getC3. */
999 setC0(std::get<0>(chanValues));
1000 setC1(std::get<1>(chanValues));
1001 setC2(std::get<2>(chanValues));
1002 return setC3(std::get<3>(chanValues));
1003 }
1004 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1005 /** Sets the first three channels current object.
1006 @param chanValues The values for the components
1007 @return Returns a reference to the current color object.*/
1008 inline colorTpl& setChans(clrChanTup3 chanValues) { /* Requires: Inherits numChan>2 from getC2. */
1009 setC0(std::get<0>(chanValues));
1010 setC1(std::get<1>(chanValues));
1011 return setC2(std::get<2>(chanValues));
1012 }
1013 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1014 /** This function sets color channels from the data in a std::vector.
1015 @warning input vector must have at least #channelCount elements! This is *not* checked!
1016
1017 @param chanValues A std::vector containing the color channels.
1018 @return Returns a reference to the current color object.*/
1019 inline colorTpl& setChans(clrChanVec& chanValues) {
1020 for(int i=0; i<numChan; i++)
1021 setChanNC(i, chanValues[i]);
1022 return *this;
1023 }
1024 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1025 /** Sets the current color based upon the contents of the given color hex string.
1026 A color hex string is similar to the hash hex strings used in HTML, but extended to larger depths and higher channel counts.
1027
1028 #FF0000 -- Red for an RGB color with 8-bit per channels
1029 #FFFF00000000 -- Red for an RGB color with 16-bit per channels
1030 #FF0000EE -- Red for an RGBA color with 8-bit per channels (with alpha set to EE)
1031 #FFFFFFFFFF -- White for a 5 channel color with 8-bit per channels
1032 Fewer channel specifiers may be provided than channels in the current color, then the value of clearUndefinedChannels defines the behavior: NOOP or
1033 set them to #minChanVal. If the colorHexString is somehow invalid, then all channels are considered undefined, and the action is defined by the
1034 value of clearUndefinedChannels.
1035 @param colorHexString Hex string specifying a color.
1036 @param clearUndefinedChannels Specify error action and what to do with unspecified channels.
1037 @return Returns a reference to the current color object.*/
1038 inline colorTpl& setChans(std::string colorHexString, bool clearUndefinedChannels = false) {
1039 std::string::size_type sizeOfString = colorHexString.size();
1040 std::string::size_type digitsPerChan = bitsPerChan / 4;
1041 if (sizeOfString > 0) { // Not empty
1042 if (colorHexString[0] == '#') { // Starts with hash
1043 if (0 == ((sizeOfString-1) % digitsPerChan)) { // Has correct number of digits
1044 if (std::string::npos == colorHexString.find_first_not_of("0123456789abcdefABCDEF", 1)) { // All hex digits after the pound
1045 std::string::size_type numChanGiven = (sizeOfString-1) / digitsPerChan;
1046 if (numChan < numChanGiven)
1047 numChanGiven = numChan;
1048 std::string curHexStr(digitsPerChan, 1);
1049 for(std::string::size_type i=0; i<numChanGiven; i++) {
1050 for(std::string::size_type j=0; j<digitsPerChan; j++)
1051 curHexStr[j] = colorHexString[1+j+digitsPerChan*i];
1052 setChan(static_cast<int>(i), convertHexStringToChan(curHexStr));
1053 }
1054 if (clearUndefinedChannels && (numChanGiven < numChan))
1055 for(std::string::size_type i=numChanGiven; i<numChan; i++)
1056 setChanToMin(static_cast<int>(i));
1057 return *this;
1058 }
1059 }
1060 }
1061 }
1062 if (clearUndefinedChannels)
1063 return setToBlack();
1064 else
1065 return *this;
1066 }
1067 //@}
1068
1069 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1070 /** @name Set To Special Colors (RGB Corners)
1071 While the assumed color model is RGB, these functions are generalized beyond RGB in that non-RGB channels are uniformly, and usefully, manipulated.
1072 For example, setToBlack and setToWhite functions set all channels to minimum and maximum respectively -- both reasonable definitions for "black" and
1073 "white" in many situations. The "primary" colors (red, blue, and green) set all non-RGB channels to minimum, and the "secondary" colors (cyan,
1074 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
1075 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
1076 integer channels and good masks. 2) It makes each secondary an inverse (a logical NOT for integer colors) color from a primary across all
1077 channels. Note that the other functions in this group end with a call to one of the setTo*() functions. */
1078 //@{
1079 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1080 inline colorTpl& setToBlack() { setChansToMin(); return *this; }
1081 inline colorTpl& setToWhite() { setChansToMax(); return *this; }
1082 inline colorTpl& setToRed() { setChansToMin(); setChanToMax(0); return *this; }
1083 inline colorTpl& setToBlue() { setChansToMin(); setChanToMax(2); return *this; }
1084 inline colorTpl& setToGreen() { setChansToMin(); setChanToMax(1); return *this; }
1085 inline colorTpl& setToCyan() { setChansToMax(); setChanToMin(0); return *this; }
1086 inline colorTpl& setToYellow() { setChansToMax(); setChanToMin(2); return *this; }
1087 inline colorTpl& setToMagenta() { setChansToMax(); setChanToMin(1); return *this; }
1088 inline colorTpl& setToHalf() { setChansToMean(); return *this; }
1089 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1090 /** Set the current color based upon the single character given -- 0==black, R, G, B, M, C, Y, W/1==white).
1091 The color is acutally set using one of the setTo*() functions. If \a cornerColor is invalid, then setToBlack().
1092 @param cornerColor Character specifying the color
1093 @return Returns a reference to the current color object.*/
1094 inline colorTpl& setToCorner(char cornerColor) {
1095 /* This case is ordered by the frequency in which colors are generally encountered. This will vary for different applications. */
1096 switch(cornerColor) {
1097 case '0': return setToBlack(); break;
1098 case '1': [[fallthrough]];
1099 case 'w': [[fallthrough]];
1100 case 'W': return setToWhite(); break;
1101 case 'r': [[fallthrough]];
1102 case 'R': return setToRed(); break;
1103 case 'g': [[fallthrough]];
1104 case 'G': return setToGreen(); break;
1105 case 'b': [[fallthrough]];
1106 case 'B': return setToBlue(); break;
1107 case 'y': [[fallthrough]];
1108 case 'Y': return setToYellow(); break;
1109 case 'c': [[fallthrough]];
1110 case 'C': return setToCyan(); break;
1111 case 'm': [[fallthrough]];
1112 case 'M': return setToMagenta(); break;
1113 default: return setToBlack(); break;
1114 }
1115 }
1116 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1117 /** Set the color to the given corner color.
1118 The color is acutally set using one of the setTo*() functions. If \a cornerColor is invalid, then setToBlack().
1119 @param cornerColor Enum value specifying the color
1120 @return Returns a reference to the current color object.*/
1121 inline colorTpl& setToCorner(cornerColorEnum cornerColor) {
1122 /* This case is ordered by the frequency in which colors are generally encountered. This will vary for different applications. */
1123 switch(cornerColor) {
1124 case cornerColorEnum::BLACK: return setToBlack(); break;
1125 case cornerColorEnum::WHITE: return setToWhite(); break;
1126 case cornerColorEnum::RED: return setToRed(); break;
1127 case cornerColorEnum::GREEN: return setToGreen(); break;
1128 case cornerColorEnum::BLUE: return setToBlue(); break;
1129 case cornerColorEnum::YELLOW: return setToYellow(); break;
1130 case cornerColorEnum::CYAN: return setToCyan(); break;
1131 case cornerColorEnum::MAGENTA: return setToMagenta(); break;
1132 default: return setToBlack(); break; // Some compilers don't realize all cases are covered above...
1133 }
1134 return *this;
1135 }
1136 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1137 /** Set the color to the named corner color.
1138 If cornerColor is one character long, then the call is equivalent to setToCorner(cornerColor[0]). Otherwise a valid corner color name string is
1139 expected: red, blue, green, cyan, yellow, magenta, black, or white. If \a cornerColor is invalid, then setToBlack(). The color is actually set
1140 using one of the setTo*() functions.
1141 @param cornerColor String value specifying the color
1142 @return Returns a reference to the current color object.*/
1143 inline colorTpl& setToCorner(std::string cornerColor) {
1144 std::string::size_type sizeOfString = cornerColor.size();
1145 if (sizeOfString > 0) {
1146 if(((cornerColor[0] == 'b') || (cornerColor[0] == 'B')) && (sizeOfString > 0)) {
1147 if( (cornerColor[2]=='u') || (cornerColor[2]=='U') )
1148 return setToBlue();
1149 else
1150 return setToBlack();
1151 } else {
1152 return setToCorner(cornerColor[0]);
1153 }
1154 }
1155 return setToBlack();
1156 }
1157 //@}
1158
1159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1160 /** @name Color Setting Methods via Logically Packed Integers.
1161 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.
1162 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
1163 derived from integer literals in C++ code. setRGBfromLogPackIntARGB() is heavily used for color schemes. */
1164 //@{
1165 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1166 /** Set the color based upon the bytes of the given integer ordered from LSB to MSB.
1167 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
1168 are interpreted as by setChans_byte. Any channels beyond four are left untouched.
1169 @param anInt The integer from which to extract bytes to set color
1170 @param rIdx Location of red byte in \a anInt
1171 @param gIdx Location of green byte in \a anInt
1172 @param bIdx Location of blue byte in \a anInt
1173 @param aIdx Location of alpha byte in \a anInt
1174 @return Returns a reference to the current color object.*/
1175 inline colorTpl& setRGBAfromLogPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx, uint8_t aIdx) {
1176 /* Requires: Inherits numChan>3 from setAlpha. */
1177 uint8_t bytes[4];
1178 bytes[0] = (0xFF & anInt); anInt = anInt >> 8;
1179 bytes[1] = (0xFF & anInt); anInt = anInt >> 8;
1180 bytes[2] = (0xFF & anInt); anInt = anInt >> 8;
1181 bytes[3] = (0xFF & anInt);
1182 setRed_byte( bytes[rIdx]);
1183 setGreen_byte(bytes[gIdx]);
1184 setBlue_byte( bytes[bIdx]);
1185 setAlpha_byte(bytes[aIdx]);
1186 return *this;
1187 }
1188 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1189 /** Just like setRGBAfromLogPackIntGen, but no A */
1190 inline colorTpl& setRGBfromLogPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx) {
1191 uint8_t bytes[4];
1192 /* Requires: Inherits numChan>2 from setBlue. */
1193 bytes[0] = (0xFF & anInt); anInt = anInt >> 8;
1194 bytes[1] = (0xFF & anInt); anInt = anInt >> 8;
1195 bytes[2] = (0xFF & anInt); anInt = anInt >> 8;
1196 bytes[3] = (0xFF & anInt);
1197 setRed_byte( bytes[rIdx]);
1198 setGreen_byte(bytes[gIdx]);
1199 setBlue_byte( bytes[bIdx]);
1200 return *this;
1201 }
1202 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1203 /* These four pixel formats (ARGB, RGBA, ABGR, & BGRA) are commonly used (SDL, OpenGL, ImageJ, etc...). Note we have two methods per pixel format --
1204 one for RGB & one for RGBA */
1205 inline colorTpl& setRGBAfromLogPackIntARGB(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 2, 1, 0, 3); } /* Requires: Inherits numChan>3 from setAlpha. */
1206 inline colorTpl& setRGBfromLogPackIntARGB( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 2, 1, 0); } /* Requires: Inherits numChan>2 from setBlue. */
1207 inline colorTpl& setRGBAfromLogPackIntRGBA(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 3, 2, 1, 0); } /* Requires: Inherits numChan>3 from setAlpha. */
1208 inline colorTpl& setRGBfromLogPackIntRGBA( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 3, 2, 1); } /* Requires: Inherits numChan>2 from setBlue. */
1209 inline colorTpl& setRGBAfromLogPackIntABGR(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 0, 1, 2, 3); } /* Requires: Inherits numChan>3 from setAlpha. */
1210 inline colorTpl& setRGBfromLogPackIntABGR( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 0, 1, 2); } /* Requires: Inherits numChan>2 from setBlue. */
1211 inline colorTpl& setRGBAfromLogPackIntBGRA(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 1, 2, 3, 0); } /* Requires: Inherits numChan>3 from setAlpha. */
1212 inline colorTpl& setRGBfromLogPackIntBGRA( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 1, 2, 3); } /* Requires: Inherits numChan>2 from setBlue. */
1213 /* This pixel format (ABRG) is used by POV-Ray for height fields */
1214 inline colorTpl& setRGBAfromLogPackIntABRG(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 1, 0, 2, 3); } /* Requires: Inherits numChan>3 from setAlpha. */
1215 inline colorTpl& setRGBfromLogPackIntABRG( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 1, 0, 2); } /* Requires: Inherits numChan>2 from setBlue. */
1216 //@}
1217
1218 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1219 /** @name TGA Height Maps for POVray */
1220 //@{
1221 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1222 /** Computes a 24-bit truecolor value intended for use in producing 16-bit greyscale TGA.
1223 This is the color scheme that should be used for POVray 16-bit height files
1224 @param tga16val An integer
1225 @return Returns a reference to the current color object. */
1226 inline colorTpl& setRGBcmpGreyTGA16bit(uint32_t tga16val) requires(chanIsByte) {
1227 /* Requires: Inherits numChan>1 from setGreen. */
1228 tga16val = mjr::math::ivl::wrapCC(tga16val, 0x0000FFFFu);
1229 return setRGBfromLogPackIntABRG(tga16val);
1230 // setChansToMin();
1231 // setGreen_byte(static_cast<clrChanT>( tga16val & 0xff)); // 0
1232 // setRed_byte( static_cast<clrChanT>((tga16val >> 8) & 0xff)); // 1
1233 // return *this;
1234 }
1235 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1236 /** Computes a 24-bit truecolor value intended for use in producing 24-bit greyscale TGA.
1237 @param tga24val An integer
1238 @return Returns a reference to the current color object. */
1239 inline colorTpl& setRGBcmpGreyTGA24bit(uint32_t tga24val) requires(chanIsByte) {
1240 /* Requires: Inherits numChan>2 from setBlue. */
1241 tga24val = mjr::math::ivl::wrapCC(tga24val, 0x00FFFFFFu);
1242 return setRGBfromLogPackIntABRG(tga24val);
1243 // setGreen_byte( tga24val & 0xff); // 0
1244 // setRed_byte( (tga24val >> 8) & 0xff); // 1
1245 // setBlue_byte( (tga24val >> 16) & 0xff); // 2
1246 // return *this;
1247 } //BRG
1248 //@}
1249
1250 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1251 /** @name Color Setting Methods via Physically Packed Integers.
1252 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. */
1253 //@{
1254 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1255 /** Set the color based upon the bytes of the given integer ordered as in RAM.
1256 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
1257 as by setChans_byte. Any channels beyond four are left untouched.
1258 @param anInt The integer from which to extract bytes to set color
1259 @param rIdx Location of red byte in \a anInt
1260 @param gIdx Location of green byte in \a anInt
1261 @param bIdx Location of blue byte in \a anInt
1262 @param aIdx Location of alpha byte in \a anInt
1263 @return Returns a reference to the current color object.*/
1264 inline colorTpl& setRGBAfromPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx, uint8_t aIdx) {
1265 /* Requires: Inherits numChan>3 from setAlpha. */
1266 uint8_t *curByte = (uint8_t *)(&anInt);
1267 setRed_byte( curByte[rIdx]);
1268 setGreen_byte(curByte[gIdx]);
1269 setBlue_byte( curByte[bIdx]);
1270 setAlpha_byte(curByte[aIdx]);
1271 return *this;
1272 }
1273 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1274 /** Just like setRGBAfromPackIntGen, but no A */
1275 inline colorTpl& setRGBfromPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx) {
1276 /* Requires: Inherits numChan>2 from setBlue. */
1277 uint8_t *curByte = (uint8_t *)(&anInt);
1278 setRed_byte( curByte[rIdx]);
1279 setGreen_byte(curByte[gIdx]);
1280 setBlue_byte( curByte[bIdx]);
1281 return *this;
1282 }
1283 //@}
1284
1285 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1286 /** @name Setting Colors Based Upon Other Color Spaces
1287 Other Colorspaces.
1288 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
1289 alternate colorspaces computations all take place with double floating point values. Various other tools are also available for manipulating colors
1290 in other colorspaces (see: interplColorSpace() and rgb2colorSpace() for example).. See the #colorSpaceEnum for details regarding supported colorspaces. */
1291 //@{
1292 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1293 /** Set the color indicated by the given HSV values.
1294 The 'unit' in the name indicates that the values for h, s, and v are the unit interval, [0,1].
1295 @param H The Hue.
1296 @param S The Saturation.
1297 @param V The Value
1298 @return Returns a reference to the current color object. */
1299 inline colorTpl& setRGBfromUnitHSV(double H, double S, double V) { return setRGBfromColorSpace(colorSpaceEnum::HSV, H*360.0, S, V); }
1300 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1301 /** Set the color indicated by the given HSL values.
1302 The 'unit' in the name indicates that The ranges for h, s, and v are the the unit interval -- i.e. [0,1].
1303 @param H The Hue.
1304 @param S The Saturation.
1305 @param L The Lightness or Luminescence
1306 @return Returns a reference to the current color object. */
1307 inline colorTpl& setRGBfromUnitHSL(double H, double S, double L) { return setRGBfromColorSpace(colorSpaceEnum::HSL, H*360.0, S, L); }
1308 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1309 /** Set the color indicated by the color space and values.
1310 @param space The colorspace
1311 @param inCh1 Channel one value for given colorspace
1312 @param inCh2 Channel two value for given colorspace
1313 @param inCh3 Channel three value for given colorspace
1314 @return Returns a reference to the current color object. */
1315 inline colorTpl& setRGBfromColorSpace(colorSpaceEnum space, double inCh1, double inCh2, double inCh3) {
1316 // Note: If space==RGB => C0==R, C1=G, C2=B regardless of redChan, blueChan, & greenChan.
1317 double outR = 0.0, outG = 0.0, outB = 0.0;
1318 if (space == colorSpaceEnum::HSL) {
1319 if( (inCh3 >= 0.0) && (inCh3 <= 1.0) && (inCh2 >= 0.0) && (inCh2 <= 1.0) ) {
1320 double H = mjr::math::ivl::wrapCO(inCh1, 360.0);
1321 const double epsilon = 0.000001;
1322 double m1, m2;
1323 if(inCh3 <= 0.5)
1324 m2 = inCh3 * (1.0 + inCh2);
1325 else
1326 m2 = inCh3 + inCh2 - inCh3 * inCh2;
1327 m1 = 2.0 * inCh3 - m2;
1328 if(inCh2 < epsilon) {
1329 outR = inCh3;
1330 outG = inCh3;
1331 outB = inCh3;
1332 } else {
1333 outR = mjr::math::ivl::unit_clamp(hslHelperVal(m1, m2, H+120));
1334 outG = mjr::math::ivl::unit_clamp(hslHelperVal(m1, m2, H));
1335 outB = mjr::math::ivl::unit_clamp(hslHelperVal(m1, m2, H-120));
1336 }
1337 }
1338 } else if ((space == colorSpaceEnum::LAB) || (space == colorSpaceEnum::XYZ) || (space == colorSpaceEnum::LCH)) {
1339 double X, Y, Z;
1340 if (space == colorSpaceEnum::XYZ) {
1341 X = inCh1 / 100.0;
1342 Y = inCh2 / 100.0;
1343 Z = inCh3 / 100.0;
1344 } else {
1345 Y = ( inCh1 + 16.0 ) / 116.0;
1346 if (space == colorSpaceEnum::LCH) {
1347 X = std::cos(inCh3 * std::numbers::pi / 180.0) * inCh2 / 500.0 + Y;
1348 Z = Y - std::sin(inCh3 * std::numbers::pi / 180.0) * inCh2 / 200.0;
1349 } else {
1350 X = inCh2 / 500.0 + Y;
1351 Z = Y - inCh3 / 200.0;
1352 }
1353 X = (X > 0.206893034423 ? std::pow(X, 3) : ( X - 16.0 / 116.0 ) / 7.787) * 95.047 / 100.0;
1354 Y = (Y > 0.206893034423 ? std::pow(Y, 3) : ( Y - 16.0 / 116.0 ) / 7.787) * 100.000 / 100.0;
1355 Z = (Z > 0.206893034423 ? std::pow(Z, 3) : ( Z - 16.0 / 116.0 ) / 7.787) * 108.883 / 100.0;
1356 }
1357 outR = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
1358 outG = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
1359 outB = X * 0.0557 + Y * -0.2040 + Z * 1.0570;
1360 outR = mjr::math::ivl::unit_clamp((outR > 0.0031308 ? 1.055 * std::pow(outR, 1.0 / 2.4) - 0.055 : 12.92 * outR));
1361 outG = mjr::math::ivl::unit_clamp((outG > 0.0031308 ? 1.055 * std::pow(outG, 1.0 / 2.4) - 0.055 : 12.92 * outG));
1362 outB = mjr::math::ivl::unit_clamp((outB > 0.0031308 ? 1.055 * std::pow(outB, 1.0 / 2.4) - 0.055 : 12.92 * outB));
1363 } else if (space == colorSpaceEnum::RGB) {
1364 outR = mjr::math::ivl::unit_clamp(inCh1);
1365 outG = mjr::math::ivl::unit_clamp(inCh2);
1366 outB = mjr::math::ivl::unit_clamp(inCh3);
1367 } else if (space == colorSpaceEnum::HSV) {
1368 double t;
1369 double f = static_cast<double>(std::modf(inCh1 * 6.0 / 360.0, &t));
1370 int i = static_cast<int>(t) % 6;
1371 double p = inCh3 * (1 - inCh2);
1372 double q = inCh3 * (1 - inCh2 * f);
1373 double u = inCh3 * (1 - (inCh2 * (1 - f)));
1374 double w = inCh3;
1375 switch (i) {
1376 case 0: outR = mjr::math::ivl::unit_clamp(w); outG = mjr::math::ivl::unit_clamp(u); outB = mjr::math::ivl::unit_clamp(p); break;
1377 case 1: outR = mjr::math::ivl::unit_clamp(q); outG = mjr::math::ivl::unit_clamp(w); outB = mjr::math::ivl::unit_clamp(p); break;
1378 case 2: outR = mjr::math::ivl::unit_clamp(p); outG = mjr::math::ivl::unit_clamp(w); outB = mjr::math::ivl::unit_clamp(u); break;
1379 case 3: outR = mjr::math::ivl::unit_clamp(p); outG = mjr::math::ivl::unit_clamp(q); outB = mjr::math::ivl::unit_clamp(w); break;
1380 case 4: outR = mjr::math::ivl::unit_clamp(u); outG = mjr::math::ivl::unit_clamp(p); outB = mjr::math::ivl::unit_clamp(w); break;
1381 case 5: outR = mjr::math::ivl::unit_clamp(w); outG = mjr::math::ivl::unit_clamp(p); outB = mjr::math::ivl::unit_clamp(q); break;
1382 default: outR = 0.0 ; outG = 0.0 ; outB = 0.0 ; break;
1383 }
1384 } else {
1385 std::cerr << "ERROR: Unsupported color space used in setRGBfromColorSpace!" << std::endl;
1386 }
1387 setChansRGB(static_cast<clrChanT>(maxChanVal * outR),
1388 static_cast<clrChanT>(maxChanVal * outG),
1389 static_cast<clrChanT>(maxChanVal * outB));
1390 return *this;
1391 }
1392 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1393 /** @overload */
1395 /* Requires: Inherits numChan>2 from getC2. */
1396 /* This use of getC0/getC1/getC2 for RGB is OK -- that is how colConDbl3 objects work */
1397 return setRGBfromColorSpace(space, inColor.getC0(), inColor.getC1(), inColor.getC2());
1398 }
1399 //@}
1400
1401 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1402 /** @name Setting Colors Based Upon Spectral Color */
1403 //@{
1404 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1405 /** Set the color indicated by the given wavelength.
1406 This function uses an algorithm based upon the color matching functions as tabulated in table 3 from Stockman and Sharpe (2000) -- I believe they
1407 are taken from Stiles and Burch 10-degree (1959). Four of the algorithms are based upon simple linear interpolation, while one is based upon
1408 exponential bump functions closely matching the color matching functions. The method of interpolation may be specified via the final argument.
1409
1410 @warning If you are looking for a wavelength color scheme, then see the csRainbowCM class: http://richmit.github.io/mraster/ColorSchemes.html
1411
1412 @param wavelength The wavelength to convert into RGB
1413 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
1414 @return Returns a reference to the current color object. */
1415 inline colorTpl& setRGBfromWavelengthCM(double wavelength, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
1416 // Color matching function table & metadata.
1417 // Tabulated in table 3 from Stockman and Sharpe (2000). I beleive they are taken from Stiles and Burch 10-degree (1959)
1418 const double minWL = 390.0; // Min wavelength in table
1419 const double maxWL = 830.0; // Max wavelength in table
1420 const int numPT = 89; // Number fo points in the table
1421 const double rScl = 3.1673; // Scale factors for color function
1422 const double gScl = 1.0517;
1423 const double bScl = 1.0019;
1424 const static int cmfW[] = { 390, 395, 400, 405, 410, 415, 420, 425, 430,
1425 435, 440, 445, 450, 455, 460, 465, 470, 475,
1426 480, 485, 490, 495, 500, 505, 510, 515, 520,
1427 525, 530, 535, 540, 545, 550, 555, 560, 565,
1428 570, 575, 580, 585, 590, 595, 600, 605, 610,
1429 615, 620, 625, 630, 635, 640, 645, 650, 655,
1430 660, 665, 670, 675, 680, 685, 690, 695, 700,
1431 705, 710, 715, 720, 725, 730, 735, 740, 745,
1432 750, 755, 760, 765, 770, 775, 780, 785, 790,
1433 795, 800, 805, 810, 815, 820, 825, 830 };
1434 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,
1435 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,
1436 -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,
1437 -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,
1438 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,
1439 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,
1440 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,
1441 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,
1442 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,
1443 3.7700E-05, 2.7600E-05, 2.0300E-05, 1.4900E-05, 1.1000E-05, 8.1800E-06, 6.0900E-06, 4.5500E-06 };
1444 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,
1445 -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,
1446 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,
1447 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,
1448 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,
1449 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,
1450 -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,
1451 -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,
1452 -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,
1453 -1.3700E-07, -8.8000E-08, -5.5300E-08, -3.3600E-08, -1.9600E-08, -1.0900E-08, -5.7000E-09, -2.7700E-09 };
1454 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,
1455 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,
1456 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,
1457 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,
1458 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,
1459 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,
1460 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,
1461 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,
1462 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,
1463 1.5000E-09, 9.8600E-10, 6.3900E-10, 4.0700E-10, 2.5300E-10, 1.5200E-10, -8.6400E-11, 4.4200E-11 };
1464
1465 // Clip the wavelength to be in range
1466 wavelength = std::clamp(wavelength, minWL, maxWL);
1467
1468 // Figure out where we are in our color function table
1469 double fIdx = (wavelength-minWL)/(maxWL-minWL)*(numPT-1.0);
1470 int iIdx1 = static_cast<int>(fIdx);
1471 int iIdx2 = iIdx1+1;
1472
1473 // If we fell off the edge, then we set our indexes to the appropriate edge
1474 if(iIdx2>(numPT-1)) { iIdx1 = numPT-2; iIdx2 = numPT-1; fIdx = static_cast<double>(iIdx1); }
1475 if(iIdx1<0) { iIdx1 = 0; iIdx2 = 1; fIdx = static_cast<double>(iIdx1); }
1476
1477 // Interpolate using our tabulated color matching function
1478 double rf, gf, bf;
1479 switch(interpMethod) {
1480 case cmfInterpolationEnum::FLOOR : // Closest with wavelength lower than given value
1481 rf=cmfR[iIdx1];
1482 gf=cmfG[iIdx1];
1483 bf=cmfB[iIdx1];
1484 break;
1485 case cmfInterpolationEnum::CEILING : // Closest with wavelength greater than given value
1486 rf=cmfR[iIdx2];
1487 gf=cmfG[iIdx2];
1488 bf=cmfB[iIdx2];
1489 break;
1490 case cmfInterpolationEnum::NEAREST : // Closest with wavelength to given value
1491 if( std::abs(wavelength-cmfW[iIdx2]) < std::abs(wavelength-cmfW[iIdx1])) {
1492 rf=cmfR[iIdx2];
1493 gf=cmfG[iIdx2];
1494 bf=cmfB[iIdx2];
1495 } else {
1496 rf=cmfR[iIdx1];
1497 gf=cmfG[iIdx1];
1498 bf=cmfB[iIdx1];
1499 }
1500 break;
1501 case cmfInterpolationEnum::LINEAR : // Linear interpolation between data points
1502 rf = (fIdx-static_cast<double>(iIdx1)) * (cmfR[iIdx2] - cmfR[iIdx1]) + cmfR[iIdx1];
1503 gf = (fIdx-static_cast<double>(iIdx1)) * (cmfG[iIdx2] - cmfG[iIdx1]) + cmfG[iIdx1];
1504 bf = (fIdx-static_cast<double>(iIdx1)) * (cmfB[iIdx2] - cmfB[iIdx1]) + cmfB[iIdx1];
1505 break;
1506 case cmfInterpolationEnum::BUMP : // Use exponential hump functions -- MJR developed algorithm 2007
1507 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));
1508 gf = 1.05 / std::exp(0.0004 * (wavelength-540.0)*(wavelength-540.0));
1509 bf = 1.00 / std::exp(0.0010 * (wavelength-450.0)*(wavelength-450.0));
1510 break;
1511 default:
1512 rf = gf = bf = 0.0;
1513 break;
1514 }
1515
1516 // Make them positive and scale to a [0,1] range
1517 rf=(rf>0.0 ? rf : 0.0)/rScl;
1518 gf=(gf>0.0 ? gf : 0.0)/gScl;
1519 bf=(bf>0.0 ? bf : 0.0)/bScl;
1520
1521 // We are done. Set the color and exit.
1522 setChansRGB_dbl(rf, gf, bf);
1523 return *this;
1524 }
1525 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1526 /** Set the color indicated by the given wavelength.
1527 This function uses an algorithm based upon linear approximations to the color match functions. I believe the original algorithm is due to Dan
1528 Bruton, and his FORTRAN version is available (at least as of 1997) at http://www.physics.sfasu.edu/astro/color.html
1529
1530 @warning If you are looking for a wavelength color scheme, then see the csRainbowLA class: http://richmit.github.io/mraster/ColorSchemes.html
1531
1532 @param wavelength to convert
1533 @return Returns a reference to the current color object. */
1534 inline colorTpl& setRGBfromWavelengthLA(double wavelength) {
1535 double rf, gf, bf;
1536
1537 const double minWL = 380.0; // Min wavelength in table
1538 const double maxWL = 780.0; // Max wavelength in table
1539
1540 // Clip the wavelength to be in range
1541 if(wavelength < minWL)
1542 wavelength = minWL;
1543 if(wavelength > maxWL)
1544 wavelength = maxWL;
1545
1546 // Compute color match functions.
1547 rf = gf = bf = 0;
1548 if ( (wavelength >= 380) && (wavelength < 440)) {
1549 rf = (440-wavelength)/(440-380);
1550 gf = 0.0;
1551 bf = 1.0;
1552 } else if( (wavelength >= 440) && (wavelength < 490)) {
1553 rf = 0.0;
1554 gf = (wavelength-440)/(490-440);
1555 bf = 1.0;
1556 } else if( (wavelength >= 490) && (wavelength < 510)) {
1557 rf = 0.0;
1558 gf = 1.0;
1559 bf = (510-wavelength)/(510-490);
1560 } else if( (wavelength >= 510) && (wavelength < 580)) {
1561 rf = (wavelength-510)/(580-510);
1562 gf = 1.0;
1563 bf = 0.0;
1564 } else if( (wavelength >= 580) && (wavelength < 645)) {
1565 rf = 1.0;
1566 gf = (645-wavelength)/(645-580);
1567 bf = 0.0;
1568 } else if( (wavelength >= 645) && (wavelength <= 780)) {
1569 rf = 1.0;
1570 gf = 0.0;
1571 bf = 0.0;
1572 }
1573
1574 /* Lower the intensity near edges of vision. */
1575 double edgeIntensityAdj;
1576 if(wavelength > 700.0) {
1577 edgeIntensityAdj=0.3 + 0.7 * (780-wavelength)/(780-700);
1578 } else if(wavelength < 420.0) {
1579 edgeIntensityAdj=0.3 + 0.7 * (wavelength - 380)/(420-380);
1580 } else {
1581 edgeIntensityAdj=1.0;
1582 }
1583
1584 return setChansRGB_dbl(edgeIntensityAdj*rf, edgeIntensityAdj*gf, edgeIntensityAdj*bf);
1585 }
1586 //@}
1587
1588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1589 /** @name Color Ramps, Gradients, Interpolation, Binary Thresholds.
1590 Members in this section form the computational foundation for many of the named color schemes found in this class. */
1591 //@{
1592 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1593 /** 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.
1594 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
1595 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
1596 poor performance -- both due to the use of floating point arithmetic. Note this function operates correctly with any channel type and with an
1597 arbitrary number of channels -- it is NOT limited to RGB colors or RGB color corners for anchors.
1598
1599 @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
1600 directly. In fact, the first step might be to see if a suitable gradient color scheme is already are predefined:
1601 http://richmit.github.io/mraster/ColorSchemes.html
1602
1603 @param csX The value to convert
1604 @param anchors Doubles for which color equals the corresponding corner.
1605 @param colors A vector of colors to use
1606 @return A reference to this object */
1607 inline colorTpl& cmpGradiant(csFltType csX, std::vector<csFltType > const& anchors, std::vector<colorType> const& colors) {
1608 typename std::vector<colorType>::size_type numColors = colors.size();
1609 if((numColors >= 2) && (anchors.size() == numColors)) {
1610 for(typename std::vector<colorType>::size_type i=0; i<(numColors-1); i++) {
1611 csFltType lowAnchor = anchors[i];
1612 csFltType highAnchor = anchors[i+1];
1613 if( (csX >= lowAnchor) && (csX <= highAnchor) ) {
1614 return linearInterpolate(std::abs((csX-lowAnchor)/(highAnchor-lowAnchor)), colors[i], colors[i+1]);
1615 }
1616 }
1617 }
1618 return *this;
1619 }
1620 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1621 /** Identical to the other cmpGradiant() function except that equidistant anchors are automatically generated on [0, 1] for the given colors array. */
1622 inline colorTpl& cmpGradiant(csFltType csX, std::vector<colorType> const& colors) {
1623 typename std::vector<colorType>::size_type numColors = colors.size();
1624 if(numColors >= 2) {
1625 for(typename std::vector<colorType>::size_type i=0; i<(numColors-1); i++) {
1626 csFltType lowAnchor = static_cast<csFltType>(i) / static_cast<csFltType>(numColors-1);
1627 csFltType highAnchor = static_cast<csFltType>(i+1)/ static_cast<csFltType>(numColors-1);
1628 if( (csX >= lowAnchor) && (csX <= highAnchor) ) {
1629 return linearInterpolate(std::abs((csX-lowAnchor)/(highAnchor-lowAnchor)), colors[i], colors[i+1]);
1630 }
1631 }
1632 }
1633 return *this;
1634 }
1635 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1636 /** Identical to the other equidistant cmpGradiant() function except that this one works on just the RGB channels and takes an array of packed integers. */
1637 inline colorTpl& cmpGradiant(csFltType csX, csIntType numColors, const packed4Cint* colors) {
1638 if(numColors >= 2) {
1639 for(csIntType i=0; i<(numColors-1); i++) {
1640 csFltType lowAnchor = static_cast<csFltType>(i) / static_cast<csFltType>(numColors-1);
1641 csFltType highAnchor = static_cast<csFltType>(i+1)/ static_cast<csFltType>(numColors-1);
1642 if( (csX >= lowAnchor) && (csX <= highAnchor) ) {
1643 colorTpl c1;
1644 colorTpl c2;
1645 c1.setRGBfromLogPackIntARGB(colors[i]);
1646 c2.setRGBfromLogPackIntARGB(colors[i+1]);
1647 return linearInterpolateRGB(std::abs((csX-lowAnchor)/(highAnchor-lowAnchor)), c1, c2);
1648 }
1649 }
1650 }
1651 return *this;
1652 }
1653 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1654 /** This is simply a version of cmpRGBcornerCGradiant() that computes the length of the final argument as a C-string.
1655 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
1656 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1657
1658 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1659
1660 @param csX The value to convert
1661 @param cornerColors Characters specifying color (as used by setColor)
1662 @return A reference to this object */
1663 inline colorTpl& cmpRGBcornerCGradiant(csFltType csX, const char *cornerColors) {
1664 return cmpRGBcornerCGradiant(csX, static_cast<csIntType>(std::strlen(cornerColors)), cornerColors);
1665 }
1666 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1667 /** This is simply a version of cmpRGBcornerDGradiant() that computes the length of the final argument as a C-string.
1668 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
1669 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1670
1671 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1672
1673 @param csIdx The value to convert
1674 @param cornerColors Characters specifying color (as used by setColor)
1675 @return A reference to this object */
1676 inline colorTpl& cmpRGBcornerDGradiant(csIntType csIdx, const char *cornerColors) {
1677 return cmpRGBcornerDGradiant(csIdx, static_cast<csIntType>(std::strlen(cornerColors)), cornerColors);
1678 }
1679 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1680 /** Color value based upon a color ramp passing through the given sequence of corner colors at equal intervals along [0, (mjr::colorTpl::chanStepMax *
1681 (numColors - 1) + 1)]. At 0, the color will be the first specified color. At (mjr::colorTpl::chanStepMax * ( numColors - 1) + 1) it will be the
1682 last color specified color. This function uses precise integer arithmetic. cornerColors need not be a real C-string -- i.e. no need for an
1683 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1684
1685 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1686
1687 @param csIdx The value to convert
1688 @param numColors The number of colors
1689 @param cornerColors An array of things that can be passed to setToCorner() -- usually char or cornerColorEnum
1690 @return A reference to this object */
1691 template <typename ccT>
1692 inline colorTpl& cmpRGBcornerDGradiant(csIntType csIdx, csIntType numColors, const ccT* cornerColors) {
1693 csIdx = mjr::math::ivl::wrapCC(csIdx, static_cast<csIntType>(chanStepMax * numColors - chanStepMax)); // First wrap to the total color count
1694 csIntType edgeNum = csIdx / chanStepMax;
1695 if (edgeNum == (numColors-1)) {
1696 edgeNum = edgeNum - 1;
1697 csIdx = chanStepMax;
1698 } else {
1699 csIdx = csIdx % chanStepMax;
1700 }
1701 colorTpl c1;
1702 colorTpl c2;
1703 c1.setToCorner(cornerColors[edgeNum]);
1704 c2.setToCorner(cornerColors[edgeNum+1]);
1705 for (int j : {redChan, greenChan, blueChan}) {
1706 csIntType cVal;
1707 if(c1.getChan(j) > c2.getChan(j)) {
1708 cVal = chanStepMax - csIdx;
1709 } else if(c1.getChan(j) < c2.getChan(j)) {
1710 cVal = csIdx;
1711 } else {
1712 cVal = ( c1.getChan(j) > 0 ? chanStepMax : 0);
1713 }
1714 if constexpr (chanIsFloat)
1715 setChan(j, static_cast<clrChanT>(cVal) / static_cast<clrChanT>(chanStepMax));
1716 else
1717 setChan(j, static_cast<clrChanT>(cVal));
1718 }
1719 return *this;
1720 }
1721 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1722 /** 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
1723 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
1724 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1725
1726 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1727
1728 @param csX The value to convert
1729 @param numColors The number of colors
1730 @param cornerColors An array of things that can be passed to setToCorner() -- usually char or cornerColorEnum
1731 @return A reference to this object */
1732 template <typename ccT>
1733 inline colorTpl& cmpRGBcornerCGradiant(csFltType csX, csIntType numColors, const ccT* cornerColors) {
1734 /* 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
1735 the optimizer will figure it out someday... The optimizer works in strange ways. */
1736 if(numColors >= 2) {
1737 csX = mjr::math::ivl::wrapCC(csX, static_cast<csFltType>(1));
1738 csFltType mF = csX * static_cast<csFltType>(numColors - 1);
1739 csIntType mI = static_cast<csIntType>(mF);
1740 if (mI >= (numColors-2)) mI=numColors-2;
1741 colorTpl c1;
1742 colorTpl c2;
1743 c1.setToCorner(cornerColors[mI]);
1744 c2.setToCorner(cornerColors[mI+1]);
1745 return linearInterpolate(mF-static_cast<csFltType>(mI), c1, c2);
1746 } else {
1747 return *this;
1748 }
1749 }
1750 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1751 /** Set the current color to a value linearly interpolated between the two given colors.
1752 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
1753 converted to HSL, the interpolation is done, and the result is converted back to RGB and the current color is set. Unlike linearInterpolate, this
1754 function will NOT interpolate every channel. Rather, as this function deals specifically with RGB and HSL space, only the RGB channels will be
1755 interpolated.
1756 @param space The color space to use
1757 @param aDouble The distance from col1
1758 @param col1 The starting color
1759 @param col2 The ending color
1760 @return Returns a reference to the current color object.*/
1761 inline colorTpl& interplColorSpace(colorSpaceEnum space, double aDouble, colorArgType col1, colorArgType col2) {
1762 /* Requires: Inherits numChan>2 from getC2. */
1763 /* This use of getC0/getC1/getC2 for RGB is OK -- that is how colConDbl3 objects work */
1764 if( (aDouble >= 0.0) && (aDouble <= 1.0) ) {
1765 // Convert our given colors into HSL
1766 colConDbl3 acol1 = col1.rgb2colorSpace(space);
1767 colConDbl3 acol2 = col2.rgb2colorSpace(space);
1768
1769 // Interpolate values
1770 double out1, out2, out3;
1771 if ((space == colorSpaceEnum::HSL) || (space == colorSpaceEnum::HSV))
1772 out1 = mjr::math::linm::interpolate_degrees(acol1.getC0(), acol2.getC0(), aDouble);
1773 else
1774 out1 = mjr::math::linm::interpolate(acol1.getC0(), acol2.getC0(), aDouble);
1775 out2 = mjr::math::linm::interpolate(acol1.getC1(), acol2.getC1(), aDouble);
1776 if (space == colorSpaceEnum::LCH)
1777 out3 = mjr::math::linm::interpolate_degrees(acol1.getC2(), acol2.getC2(), aDouble);
1778 else
1779 out3 = mjr::math::linm::interpolate(acol1.getC2(), acol2.getC2(), aDouble);
1780
1781 // Set color
1782 setRGBfromColorSpace(space, out1, out2, out3);
1783 }
1784 // Return
1785 return *this;
1786 }
1787 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1788 /** Convert a channelArithFltType value into a clrChanT value.
1789
1790 This function works hard to return the nearest clrChanT value to a channelArithFltType value, but it is quite slow.
1791
1792 @param flt Value to convert */
1793 inline clrChanT channelArithFlt2clrChan(channelArithFltType flt) {
1794 return static_cast<clrChanT>(std::round(flt)+0.1);
1795 }
1796 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1797 /** Compute the weighted mean of the given colors.
1798
1799 @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.
1800
1801 @warning Floating point arithmetic results vary with hardware, compiler, and even compiler options. These small differences can have an impact on
1802 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
1803 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
1804 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
1805 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.
1806
1807 @param w1 The first weight
1808 @param w2 The second weight
1809 @param w3 The third weight
1810 @param w4 The fourth weight
1811 @param col1 The first color
1812 @param col2 The second color
1813 @param col3 The third color
1814 @param col4 The fourth color
1815 @return Returns a reference to the current color object. */
1816 inline colorTpl& wMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3, channelArithFltType w4,
1817 colorArgType col1, colorArgType col2, colorArgType col3, colorArgType col4) {
1818 for(int i=0; i<numChan; i++)
1819 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithFltType>(col1.getChanNC(i)) * w1) +
1820 (static_cast<channelArithFltType>(col2.getChanNC(i)) * w2) +
1821 (static_cast<channelArithFltType>(col3.getChanNC(i)) * w3) +
1822 (static_cast<channelArithFltType>(col4.getChanNC(i)) * w4)));
1823
1824 return *this;
1825 }
1826 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1827 /** @overload */
1828 inline colorTpl& wMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3,
1829 colorArgType col1, colorArgType col2, colorArgType col3) {
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 (static_cast<channelArithFltType>(col3.getChanNC(i)) * w3)));
1834 }
1835 return *this;
1836 }
1837 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1838 /** @overload */
1839 inline colorTpl& wMean(channelArithFltType w1, channelArithFltType w2, colorArgType col1, colorArgType col2) {
1840 for(int i=0; i<numChan; i++)
1841 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithFltType>(col1.getChanNC(i)) * w1) +
1842 (static_cast<channelArithFltType>(col2.getChanNC(i)) * w2)));
1843 return *this;
1844 }
1845 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1846 /** Compute the unit weighted mean of the given colors -- like wMean(), but last weight is computed such that weights sum to 1.0.
1847 @param w1 The first weight in the range [0, 1) -- the range not checked!
1848 @param w2 The second weight in the range [0, 1) -- the range not checked!
1849 @param w3 The third weight in the range [0, 1) -- the range not checked!
1850 @param col1 The first color
1851 @param col2 The second color
1852 @param col3 The third color
1853 @param col4 The fourth color
1854 @return Returns a reference to the current color object. */
1855 inline colorTpl& uMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3,
1856 colorArgType col1, colorArgType col2, colorArgType col3, colorArgType col4) {
1857 return wMean(w1, w2, w3, static_cast<channelArithFltType>(1)-w1-w2-w3, col1, col2, col3, col4);
1858 }
1859 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1860 /** @overload */
1861 inline colorTpl& uMean(channelArithFltType w1, channelArithFltType w2, colorArgType col1, colorArgType col2, colorArgType col3) {
1862 return wMean(w1, w2, static_cast<channelArithFltType>(1)-w1-w2, col1, col2, col3);
1863 }
1864 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1865 /** @overload */
1866 inline colorTpl& uMean(channelArithFltType w1, colorArgType col1, colorArgType col2) {
1867 return wMean(w1, static_cast<channelArithFltType>(1)-w1, col1, col2);
1868 }
1869 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1870 /** Set the current color to a value linearly interpolated between the two given colors.
1871 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
1872 conversions and as few type conversions as possible.
1873 @param aDouble The distance from col1
1874 @param col1 The starting color
1875 @param col2 The ending color
1876 @return Returns a reference to the current color object.*/
1877 inline colorTpl& linearInterpolate(double aDouble, colorArgType col1, colorArgType col2) {
1878 if( (aDouble >= 0.0) && (aDouble <= 1.0) )
1879 for(int i=0; i<numChan; i++)
1880 setChanNC(i, static_cast<clrChanT>(mjr::math::linm::interpolate(static_cast<double>(col1.getChanNC(i)), static_cast<double>(col2.getChanNC(i)), aDouble)));
1881 return *this;
1882 }
1883 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1884 /** Set the RGB channels of the current color to a value linearly interpolated between the two given colors.
1885 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
1886 conversions and as few type conversions as possible.
1887 @param aDouble The distance from col1
1888 @param col1 The starting color
1889 @param col2 The ending color
1890 @return Returns a reference to the current color object.*/
1891 inline colorTpl& linearInterpolateRGB(double aDouble, colorArgType col1, colorArgType col2) {
1892 if( (aDouble >= 0.0) && (aDouble <= 1.0) )
1893 for (int i : {redChan, blueChan, greenChan})
1894 setChanNC(i, static_cast<clrChanT>(mjr::math::linm::interpolate(static_cast<double>(col1.getChanNC(i)), static_cast<double>(col2.getChanNC(i)), aDouble)));
1895 return *this;
1896 }
1897 //@}
1898
1899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1900 /** @name Logical Operators */
1901 //@{
1902 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1903 /** Performs a logical OR with the current object and the given object and places the value in the current object.
1904 @param aCol The color to use in the computation.
1905 @return Returns a reference to the current color object.*/
1906 inline colorTpl& tfrmOr(colorArgType aCol) requires (std::integral<clrChanT>) {
1907 if constexpr (goodMask)
1908 setMaskNC(getMaskNC() | aCol.getMaskNC());
1909 else
1910 for(int i=0; i<numChan; i++)
1911 setChanNC(i, getChanNC(i) | aCol.getChanNC(i));
1912 return *this;
1913 }
1914#if !(MISSING_P0476R2)
1915 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1916 /** Template specialization member function differing from the above function only in supported template conditions. */
1917 inline colorTpl& tfrmOr(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1918 /* Performance: Yep. Sometimes floating point colors get a goodMask. */
1919 if constexpr (goodMask)
1920 setMaskNC(getMaskNC() | aCol.getMaskNC());
1921 else
1922 for(int i=0; i<numChan; i++)
1923 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) | std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
1924 return *this;
1925 }
1926#endif
1927 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1928 /** Performs a logical NOR with the current object and the given object and places the value in the current object.
1929 @param aCol The color to use in the computation.
1930 @return Returns a reference to the current color object.*/
1931 inline colorTpl& tfrmNor(colorArgType aCol) requires (std::integral<clrChanT>) {
1932 if constexpr (goodMask)
1933 setMaskNC(~(getMaskNC() | aCol.getMaskNC()));
1934 else
1935 for(int i=0; i<numChan; i++)
1936 setChanNC(i, ~(getChanNC(i) | aCol.getChanNC(i)));
1937 return *this;
1938 }
1939#if !(MISSING_P0476R2)
1940 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1941 /** Template specialization member function differing from the above function only in supported template conditions. */
1942 inline colorTpl& tfrmNor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1943 if constexpr (goodMask)
1944 setMaskNC(~(getMaskNC() | aCol.getMaskNC()));
1945 else
1946 for(int i=0; i<numChan; i++)
1947 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) | std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
1948 return *this;
1949 }
1950#endif
1951 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1952 /** Performs a logical AND with the current object and the given object and places the value in the current object.
1953 @param aCol The color to use in the computation.
1954 @return Returns a reference to the current color object.*/
1955 inline colorTpl& tfrmAnd(colorArgType aCol) requires (std::integral<clrChanT>) {
1956 if constexpr (goodMask)
1957 setMaskNC(getMaskNC() & aCol.getMaskNC());
1958 else
1959 for(int i=0; i<numChan; i++)
1960 setChanNC(i, getChanNC(i) & aCol.getChanNC(i));
1961 return *this;
1962 }
1963#if !(MISSING_P0476R2)
1964 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1965 /** Template specialization member function differing from the above function only in supported template conditions. */
1966 inline colorTpl& tfrmAnd(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1967 if constexpr (goodMask)
1968 setMaskNC(getMaskNC() & aCol.getMaskNC());
1969 else
1970 for(int i=0; i<numChan; i++)
1971 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) & std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
1972 return *this;
1973 }
1974#endif
1975 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1976 /** Performs a logical NAND with the current object and the given object and places the value in the current object.
1977 @param aCol The color to use in the computation.
1978 @return Returns a reference to the current color object.*/
1979 inline colorTpl& tfrmNand(colorArgType aCol) requires (std::integral<clrChanT>) {
1980 if constexpr (goodMask)
1981 setMaskNC(~(getMaskNC() & aCol.getMaskNC()));
1982 else
1983 for(int i=0; i<numChan; i++)
1984 setChanNC(i, ~(getChanNC(i) & aCol.getChanNC(i)));
1985 return *this;
1986 }
1987#if !(MISSING_P0476R2)
1988 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1989 /** Template specialization member function differing from the above function only in supported template conditions. */
1990 inline colorTpl& tfrmNand(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1991 if constexpr (goodMask)
1992 setMaskNC(~(getMaskNC() & aCol.getMaskNC()));
1993 else
1994 for(int i=0; i<numChan; i++)
1995 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) & std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
1996 return *this;
1997 }
1998#endif
1999 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2000 /** Performs a logical EXCLUSIVE OR (XOR) with the current object and the given object and places the value in the current object.
2001 @param aCol The color to use in the computation.
2002 @return Returns a reference to the current color object.*/
2003 inline colorTpl& tfrmXor(colorArgType aCol) requires (std::integral<clrChanT>) {
2004 if constexpr (goodMask)
2005 setMaskNC(getMaskNC() ^ aCol.getMaskNC());
2006 else
2007 for(int i=0; i<numChan; i++)
2008 setChanNC(i, getChanNC(i) ^ aCol.getChanNC(i));
2009 return *this;
2010 }
2011#if !(MISSING_P0476R2)
2012 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2013 /** Template specialization member function differing from the above function only in supported template conditions. */
2014 inline colorTpl& tfrmXor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2015 if constexpr (goodMask)
2016 setMaskNC(getMaskNC() ^ aCol.getMaskNC());
2017 else
2018 for(int i=0; i<numChan; i++)
2019 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) ^ std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
2020 return *this;
2021 }
2022#endif
2023 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2024 /** Performs a logical NOT EXCLUSIVE OR (NXOR) with the current object and the given object and places the value in the current object.
2025 @param aCol The color to use in the computation.
2026 @return Returns a reference to the current color object.*/
2027 inline colorTpl& tfrmNxor(colorArgType aCol) requires (std::integral<clrChanT>) {
2028 if constexpr (goodMask)
2029 setMaskNC(~(getMaskNC() ^ aCol.getMaskNC()));
2030 else
2031 for(int i=0; i<numChan; i++)
2032 setChanNC(i, ~(getChanNC(i) ^ aCol.getChanNC(i)));
2033 return *this;
2034 }
2035#if !(MISSING_P0476R2)
2036 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2037 /** Template specialization member function differing from the above function only in supported template conditions. */
2038 inline colorTpl& tfrmNxor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2039 if constexpr (goodMask)
2040 setMaskNC(~(getMaskNC() ^ aCol.getMaskNC()));
2041 else
2042 for(int i=0; i<numChan; i++)
2043 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) ^ std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
2044 return *this;
2045 }
2046#endif
2047 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2048 /** Performs logical (bit-wise) negation of current object.
2049 @return Returns a reference to the current color object.*/
2050 inline colorTpl& tfrmNot(void) requires (std::integral<clrChanT>) {
2051 if constexpr (goodMask)
2052 setMaskNC(~(getMaskNC()));
2053 else
2054 for(int i=0; i<numChan; i++)
2055 setChanNC(i, ~(getChanNC(i)));
2056 return *this;
2057 }
2058#if !(MISSING_P0476R2)
2059 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2060 /** Template specialization member function differing from the above function only in supported template conditions. */
2061 inline colorTpl& tfrmNot(void) requires (std::floating_point<clrChanT>) {
2062 if constexpr (goodMask)
2063 setMaskNC(~(getMaskNC()));
2064 else
2065 for(int i=0; i<numChan; i++)
2066 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)))));
2067 return *this;
2068 }
2069#endif
2070 //@}
2071
2072 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2073 /** @name Arithmetic Operators */
2074 //@{
2075 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2076 /** Computes the square 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 a reference to the current color object.*/
2080 for(int i=0; i<numChan; i++)
2081 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithSDPType>(getChanNC(i)) - static_cast<channelArithSDPType>(aCol.getChanNC(i))) *
2082 (static_cast<channelArithSDPType>(getChanNC(i)) - static_cast<channelArithSDPType>(aCol.getChanNC(i)))));
2083 return *this;
2084 }
2085 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2086 /** Computes the absolute value of the difference for each channel between the given color and the current color object.
2087 @param aCol The color to use in the computation.
2088 @return Returns the absolute value of the difference for each channel.*/
2090 for(int i=0; i<numChan; i++)
2091 setChanNC(i, static_cast<clrChanT>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i)))));
2092 return *this;
2093 }
2094 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2095 /** Computes the arithmetic sum of the given color and the current one.
2096 @param aCol The color to use in the computation.
2097 @return Returns a reference to the current color object.*/
2099 for(int i=0; i<numChan; i++)
2100 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))));
2101 return *this;
2102 }
2103 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2104 /** Computes the arithmetic division of the current color by the given color.
2105 If a channel of aCol is zero, then the corresponding channel of the current color object will be left untouched.
2106 @param aCol The color to use in the computation.
2107 @return Returns a reference to the current color object.*/
2108 inline colorTpl& tfrmDiv(colorArgType aCol) requires (std::integral<clrChanT>) {
2109 for(int i=0; i<numChan; i++)
2110 if (aCol.getChanNC(i) != 0)
2111 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) / static_cast<channelArithSPType>(aCol.getChanNC(i))));
2112 return *this;
2113 }
2114 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2115 /** Template specialization member function differing from the above function only in supported template conditions. */
2116 inline colorTpl& tfrmDiv(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2117 for(int i=0; i<numChan; i++)
2118 if (mjr::math::fc::not_near_zero(aCol.getChanNC(i), static_cast<clrChanT>(1.0e-8)))
2119 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) / static_cast<channelArithSPType>(aCol.getChanNC(i))));
2120 return *this;
2121 }
2122 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2123 /** Computes the arithmetic product of the given color and the current one.
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, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(aCol.getChanNC(i))));
2129 return *this;
2130 }
2131 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2132 /** Computes the product of the given color and the current one.
2133 If the result of a multiplication is too large, it will be set to the maximum component value.
2134 @param aCol The color to use in the computation.
2135 @return Returns a reference to the current color object.*/
2137 for(int i=0; i<numChan; i++)
2138 setChanNC(i, clampTop(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(aCol.getChanNC(i))));
2139 return *this;
2140 }
2141 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2142 /** Computes the component wise scaled sign of the difference between the current color and the given one.
2143 As an example of the computation, the red component of the current color is computed like this:
2144 - R=#minChanVal iff(R<color.R)
2145 - R=#meanChanVal iff(R==color.R)
2146 - R=#maxChanVal iff(R>color.R)
2147 @param aCol The color to use in the computation.
2148 @return Returns a reference to the current color object.*/
2150 for(int i=0; i<numChan; i++) {
2151 if(getChanNC(i) < aCol.getChanNC(i)) {
2152 setChanNC(i, minChanVal);
2153 } else if(getChanNC(i) > aCol.getChanNC(i)) {
2154 setChanNC(i, maxChanVal);
2155 } else {
2156 setChanNC(i, meanChanVal);
2157 }
2158 }
2159 return *this;
2160 }
2161 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2162 /** Computes the arithmetic difference of the given color from the current one.
2163 If the result a differences is negative, then that component will be set to zero.
2164 @param aCol The color to use in the computation.
2165 @return Returns a reference to the current color object.*/
2167 for(int i=0; i<numChan; i++)
2168 setChanNC(i, clampBot(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i))));
2169 return *this;
2170 }
2171 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2172 /** Computes the negative of the arithmetic difference of the given color from the current one.
2173 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
2174 component will be set to zero.
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, clampBot(static_cast<channelArithDType>(aCol.getChanNC(i)) - static_cast<channelArithDType>(getChanNC(i))));
2180 return *this;
2181 }
2182 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2183 /** Computes the arithmetic sum of the given color from the current one.
2184 If the result of a sum is greater than the maximum value, then that component will be set to the maximum value.
2185 @param aCol The color to use in the computation.
2186 @return Returns a reference to the current color object.*/
2188 for(int i=0; i<numChan; i++)
2189 setChanNC(i, clampTop(static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))));
2190 return *this;
2191 }
2192 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2193 /** Computes the arithmetic sum of the current color and aCol, then divids by dCol.
2194 If the result is greater than the maximum value, then that component will be set to the maximum value.
2195 If a channel of dCol is zero, then the corresponding channel of the current color object will be left untouched.
2196 @param aCol The color to use for initial add.
2197 @param dCol The color to use for final division.
2198 @return Returns a reference to the current color object.*/
2199 inline colorTpl& tfrmAddDivClamp(colorArgType aCol, colorArgType dCol) requires (std::integral<clrChanT>) {
2200 for(int i=0; i<numChan; i++)
2201 if (dCol.getChanNC(i) != 0)
2202 setChanNC(i, clampTop((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) /
2203 static_cast<channelArithSPType>(dCol.getChanNC(i))));
2204 return *this;
2205 }
2206 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2207 /** Template specialization member function differing from the above function only in supported template conditions. */
2208 inline colorTpl& tfrmAddDivClamp(colorArgType aCol, colorArgType dCol) requires (std::floating_point<clrChanT>) {
2209 for(int i=0; i<numChan; i++)
2210 if (mjr::math::fc::not_near_zero(dCol.getChanNC(i), static_cast<clrChanT>(1.0e-8)))
2211 setChanNC(i, clampTop((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) /
2212 static_cast<channelArithSPType>(dCol.getChanNC(i))));
2213 return *this;
2214 }
2215 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2216 /** Computes the arithmetic difference of the given color from the current one.
2217 @param aCol The color to use in the computation.
2218 @return Returns a reference to the current color object.*/
2220 for(int i=0; i<numChan; i++)
2221 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i))));
2222 return *this;
2223 }
2224 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2225 /** Computes the arithmetic modulus of the current by the given one.
2226 If a channel of aCol is zero, then the corresponding channel of the current object is left untouched.
2227 @param aCol The color to use in the computation.
2228 @return Returns a reference to the current color object.*/
2229 inline colorTpl& tfrmMod(colorArgType aCol) requires (std::integral<clrChanT>) {
2230 for(int i=0; i<numChan; i++)
2231 if (aCol.getChanNC(i) != 0)
2232 setChanNC(i, getChanNC(i) % aCol.getChanNC(i));
2233 return *this;
2234 }
2235 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2236 /** Template specialization member function differing from the above function only in supported template conditions. */
2237 inline colorTpl& tfrmMod(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2238 for(int i=0; i<numChan; i++)
2239 if (mjr::math::fc::not_near_zero(aCol.getChanNC(i), static_cast<clrChanT>(1.0e-8)))
2240 setChanNC(i, static_cast<clrChanT>(std::fmod(static_cast<double>(getChanNC(i)), static_cast<double>(aCol.getChanNC(i)))));
2241 return *this;
2242 }
2243 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2244 /** Transforms the color: r=#maxChanVal-r, g=#maxChanVal-r, and b=#maxChanVal-b
2245 @return Returns a reference to the current color object.*/
2247 // MJR TODO NOTE tfrmInvert: This is just as fast as array refs...
2248 // MJR TODO NOTE tfrmInvert: We should use this universally across the library -- to isolate the code from the array specifics...
2249 for(int i=0; i<numChan; i++)
2250 setChanNC(i, maxChanVal - getChanNC(i));
2251 return *this;
2252 }
2253 //@}
2254
2255 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2256 /** @name Named Operators */
2257 //@{
2258 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2259 /** Power: c=maxChanVal*(c/maxChanVal)^p.
2260 Floating point Numbers are used for intermediate values and the result cast to a colorT at the end.
2261 Take care when negative values for p -- this can cause undefined behavior!!
2262 @return Returns a reference to the current color object.*/
2263 inline colorTpl& tfrmPow(double p) {
2264 for(int i=0; i<numChan; i++)
2265 setChanNC(i, static_cast<clrChanT>(static_cast<double>(maxChanVal) * std::pow(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal), p)));
2266 return *this;
2267 }
2268 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2269 /** Adds 1.0 and takes the natural logarithm of each channel.
2270 Floating point Numbers are used for intermediate values and the result cast to a colorT at the end.
2271 If a channel value would result in an undefined result, then the value is left untouched.
2272 @return Returns a reference to the current color object.*/
2273 inline colorTpl& tfrmLn1() requires (std::integral<clrChanT>) {
2274 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2275 for(int i=0; i<numChan; i++)
2276 setChanNC(i, static_cast<clrChanT>(std::log(1.0 + static_cast<double>(getChanNC(i)))));
2277 return *this;
2278 }
2279 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2280 /** Template specialization member function differing from the above function only in supported template conditions. */
2281 inline colorTpl& tfrmLn1() requires (std::floating_point<clrChanT>) {
2282 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2283 for(int i=0; i<numChan; i++) {
2284 clrChanT cVal = getChanNC(i);
2285 if (cVal > static_cast<clrChanT>(-1.0))
2286 setChanNC(i, static_cast<clrChanT>(std::log(1.0 + static_cast<double>(cVal))));
2287 }
2288 return *this;
2289 }
2290 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2291 /** Computes ln(c)*scale for each channel value c. If c==0, then the value is left undisturbed.
2292 Floating point Numbers are used for intermediate values and the result cast to a colorT at the end.
2293 If a channel value would result in an undefined result, then the value is left untouched.
2294 @param scale The scale value to multiply by the final result.
2295 @return Returns a reference to the current color object.*/
2296 inline colorTpl& tfrmLn(double scale) requires (std::integral<clrChanT>) {
2297 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2298 for(int i=0; i<numChan; i++) {
2299 clrChanT cVal = getChanNC(i);
2300 if(cVal != 0)
2301 setChanNC(i, static_cast<clrChanT>(std::log(static_cast<double>(cVal)) * scale));
2302 }
2303 return *this;
2304 }
2305 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2306 /** Template specialization member function differing from the above function only in supported template conditions. */
2307 inline colorTpl& tfrmLn(double scale) requires (std::floating_point<clrChanT>) {
2308 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2309 for(int i=0; i<numChan; i++) {
2310 clrChanT cVal = getChanNC(i);
2311 if (cVal > static_cast<clrChanT>(0.0))
2312 setChanNC(i, static_cast<clrChanT>(std::log(static_cast<double>(cVal)) * scale));
2313 }
2314 return *this;
2315 }
2316 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2317 /** Linearly interpolate between the current color and the given color (at a point scaled the unit interval).
2318 If \a aDouble is 0, then the current color will not change. If \a aDouble is 1, then the current color will be tooCol.
2319 @param aDouble Distance from the current color (on a unit interval)
2320 @param tooCol The color we are interpolating with.
2321 @return Returns a reference to the current color object.*/
2322 inline colorTpl& tfrmMix(double aDouble, colorArgType tooCol) {
2323 if( (aDouble >= 0.0) && (aDouble <= 1.0) )
2324 for(int i=0; i<numChan; i++)
2325 setChanNC(i, static_cast<clrChanT>(mjr::math::linm::interpolate(static_cast<double>(getChanNC(i)), static_cast<double>(tooCol.getChanNC(i)), aDouble)));
2326 return *this;
2327 }
2328 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2329 /** Copies the given argument into the current color object.
2330 Scan as copy() -- just with a name more suited to transformation code.
2331 @return Returns a reference to the current color object.*/
2332 inline colorTpl& tfrmCopy(colorArgType aCol) { return copy(aCol); }
2333 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2334 /** Makes the current color the maximum of the current color or the given color.
2335 Colors are ordered by intensity (thus the 'I' in the name)
2336 @param aCol The color to use in the computation.
2337 @return Returns a reference to the current color object.*/
2339 channelArithSPType thisSum = 0;
2340 channelArithSPType thatSum = 0;
2341 for(int i=0; i<numChan; i++) {
2342 thisSum += static_cast<channelArithSPType>(getChanNC(i));
2343 thatSum += static_cast<channelArithSPType>(aCol.getChanNC(i));
2344 }
2345 if(thisSum < thatSum)
2346 tfrmCopy(aCol);
2347 return *this;
2348 }
2349 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2350 /** Makes the current color the minimum of the current color or the given color.
2351 Colors are ordered by intensity (thus the 'I' in the name)
2352 @param aCol The color to use in the computation.
2353 @return Returns a reference to the current color object.*/
2355 /* Performance: Finding the max of two arrays in parallel with one loop is faster than calling max twice, once for each array. */
2356 channelArithSPType thisSum = 0;
2357 channelArithSPType thatSum = 0;
2358 for(int i=0; i<numChan; i++) {
2359 thisSum += static_cast<channelArithSPType>(getChanNC(i));
2360 thatSum += static_cast<channelArithSPType>(aCol.getChanNC(i));
2361 }
2362 if(thisSum > thatSum)
2363 tfrmCopy(aCol);
2364 return *this;
2365 }
2366 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2367 /** Makes each component of the current color the maximum 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 /** Makes each component of the current color the minimum of that component and the corresponding component of the given color.
2378 @param aCol The color to use in the computation.
2379 @return Returns a reference to the current color object.*/
2381 for(int i=0; i<numChan; i++)
2382 if(getChanNC(i) > aCol.getChanNC(i))
2383 setChanNC(i, aCol.getChanNC(i));
2384 return *this;
2385 }
2386 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2387 /** The Shift Left Transform modifies the current color.
2388 @param aCol Number of bits to shift left
2389 @return Returns a reference to the current color object.*/
2390 inline colorTpl& tfrmShiftL(colorArgType aCol) requires (std::integral<clrChanT>) {
2391 for(int i=0; i<numChan; i++)
2392 setChanNC(i, getChanNC(i) << aCol.getChanNC(i));
2393 return *this;
2394 }
2395#if !(MISSING_P0476R2)
2396 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2397 /** Template specialization member function differing from the above function only in supported template conditions. */
2398 inline colorTpl& tfrmShiftL(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2399 for(int i=0; i<numChan; i++)
2400 /* 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. */
2401 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) << static_cast<uint64_t>(aCol.getChanNC(i))));
2402 return *this;
2403 }
2404#endif
2405 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2406 /** The Shift Right Transform modifies the current color.
2407 @param aCol How many bits to shift.
2408 @return Returns a reference to the current color object.*/
2409 inline colorTpl& tfrmShiftR(colorArgType aCol) requires (std::integral<clrChanT>) {
2410 for(int i=0; i<numChan; i++)
2411 setChanNC(i, getChanNC(i) >> aCol.getChanNC(i));
2412 return *this;
2413 }
2414#if !(MISSING_P0476R2)
2415 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2416 /** Template specialization member function differing from the above function only in supported template conditions. */
2417 inline colorTpl& tfrmShiftR(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2418 for(int i=0; i<numChan; i++)
2419 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) >> static_cast<uint64_t>(aCol.getChanNC(i))));
2420 return *this;
2421 }
2422#endif
2423 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2424 /** The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, C_i, 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& tfrmSaw(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)) ? getChanNC(i) : 0));
2431 return *this;
2432 }
2433 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2434 /** The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, maxChanVal, 0)
2435 @param lowCol lower cutoff value
2436 @param highCol upper cutoff value
2437 @return Returns a reference to the current color object.*/
2438 inline colorTpl& tfrmStep(colorArgType lowCol, colorArgType highCol) {
2439 for(int i=0; i<numChan; i++)
2440 setChanNC(i, ((lowCol.getChanNC(i) <= getChanNC(i)) && (highCol.getChanNC(i) >= getChanNC(i)) ? maxChanVal : 0));
2441 return *this;
2442 }
2443 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2444 /** The DiracTot (total) Transform modifies the current color: Set current color to white if it equals aCol, and black otherwise.
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 if(aCol.getChanNC(i) != getChanNC(i))
2450 return setToBlack();
2451 return setToWhite();
2452 }
2453 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2454 /** The Dirac Transform modifies the current color: C_i = ifelse(C_i==aCol.C_i, maxChanVal, 0)
2455 @param aCol Dirac trigger value
2456 @return Returns a reference to the current color object.*/
2458 for(int i=0; i<numChan; i++)
2459 setChanNC(i, ((aCol.getChanNC(i) == getChanNC(i)) ? maxChanVal : 0));
2460 return *this;
2461 }
2462 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2463 /** The Fuzzy Dirac Transform modifies the current color: C_i=ifelse(|R-ctrCol.R|<=radCol.R), maxChanVal, 0)
2464 @param ctrCol Center Color
2465 @param radCol Radius Color
2466 @return Returns a reference to the current color object.*/
2468 for(int i=0; i<numChan; i++)
2469 setChanNC(i, ((std::abs(ctrCol.getChanNC(i) - getChanNC(i)) <= radCol.getChanNC(i)) ? maxChanVal : 0));
2470 return *this;
2471 }
2472 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2473 /** Computes the arithmetic mean of the given color and the current one.
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>((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) / 2));
2479 return *this;
2480 }
2481 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2482 /** Computes the geometric mean of the given color and the current one.
2483 Floating point Numbers re used for intermediate values and the result cast to a colorT at the end.
2484 @param aCol The color to use in the computation.
2485 @return Returns a reference to the current color object.*/
2487 for(int i=0; i<numChan; i++)
2488 setChanNC(i, static_cast<clrChanT>(std::sqrt(static_cast<channelArithFltType>(getChanNC(i)) * static_cast<channelArithFltType>(aCol.getChanNC(i)))));
2489 return *this;
2490 }
2491 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2492 /** Transform the current color by rendering it into a true grey via the same method used by the luminanceRGB() function.
2493 This function only sets the red, blue, and green channels -- all other channels are left untouched.
2494 @return Returns a reference to the current color object.*/
2496 /* Requires: Inherits numChan>2 from getC2. */
2497 double lumU = static_cast<double>(luminanceRGB());
2498 setRed_dbl( lumU);
2499 setGreen_dbl(lumU);
2500 setBlue_dbl( lumU);
2501 return *this;
2502 }
2503 //@}
2504
2505 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2506 /** @name Color Reduction Transformations */
2507 //@{
2508 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2509 /** The 216 Palate Web Safe Transform modifies the current color into the closest web safe color from the 216 color web safe pallet.
2510 This function only sets the red, blue, and green channels -- all other channels are left untouched.
2511 @return Returns a reference to the current color object.*/
2512 inline colorTpl& tfrmWebSafeRGB() requires (redChan>=0) {
2513 for (int c : {redChan, blueChan, greenChan}) {
2514 int charCompVal = convertChanToByte(getChanNC(c));
2515 int minDist = 256;
2516 int minCol;
2517 for(int pv : { 0x0, 0x33, 0x66, 0x99, 0xCC, 0xFF }) {
2518 int curDist = std::abs(charCompVal - pv);
2519 if( curDist < minDist ) {
2520 minDist = curDist;
2521 minCol = pv;
2522 }
2523 }
2524 setChanNC(c, convertByteToChan(static_cast<uint8_t>(minCol)));
2525 }
2526 return *this;
2527 }
2528 //@}
2529
2530 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2531 /** @name Alternate Color Space Stuff */
2532 //@{
2533 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2534 /** Compute channels for given color space coordinates for the current color.
2535 Note RGB returns float RGB normalized to 1.0.
2536 @param space The color space to convert to
2537 @return An RGB color with double channels. */
2539 /* Requires: Inherits numChan>2 from getBlue. */
2540
2541 double redF = getRed_dbl();
2542 double greenF = getGreen_dbl();
2543 double blueF = getBlue_dbl();
2544
2545 if (space == colorSpaceEnum::RGB)
2546 return colConDbl3(redF, greenF, blueF);
2547
2548 if ((space == colorSpaceEnum::HSL) || (space == colorSpaceEnum::HSV)) {
2549 clrChanT rgbMaxI = getMaxRGB();
2550 clrChanT rgbMinI = getMinRGB();
2551
2552 channelArithSDPType rangeI = rgbMaxI - rgbMinI;
2553
2554 double rgbMaxF = static_cast<double>(rgbMaxI) / static_cast<double>(maxChanVal);
2555 double rgbMinF = static_cast<double>(rgbMinI) / static_cast<double>(maxChanVal);
2556
2557 double rangeF = rgbMaxF - rgbMinF;
2558 double sumF = rgbMaxF + rgbMinF;
2559
2560 // Compute L
2561 double L = sumF / 2.0;
2562 double V = rgbMaxF;
2563
2564 // Compute H & S
2565 double S, H;
2566 if((rgbMaxI == 0) || (rangeI == 0)) {
2567 S = 0.0;
2568 H = 0.0;
2569 } else {
2570
2571 if (space == colorSpaceEnum::HSL) {
2572 if(L <= 0.5)
2573 S = rangeF / sumF;
2574 else
2575 S = rangeF / ( 2.0 - sumF);
2576 } else {
2577 S = rangeF / rgbMaxF;
2578 }
2579
2580 H = 0.0;
2581 if(getRed() == rgbMaxI)
2582 H = 0.0 + (greenF - blueF) / rangeF;
2583 else if(getGreen() == rgbMaxI)
2584 H = 2.0 + (blueF - redF) / rangeF;
2585 else if(getBlue() == rgbMaxI)
2586 H = 4.0 + (redF - greenF) / rangeF;
2587 H = mjr::math::ivl::wrapCO(H * 60.0, 360.0);
2588 }
2589 if (space == colorSpaceEnum::HSL)
2590 return colConDbl3(H, S, L);
2591 else
2592 return colConDbl3(H, S, V);
2593 } else {
2594 redF = 100.0 * ((redF > 0.04045) ? std::pow((redF + 0.055) / 1.055, 2.4) : redF / 12.92);
2595 greenF = 100.0 * ((greenF > 0.04045) ? std::pow((greenF + 0.055) / 1.055, 2.4) : greenF / 12.92);
2596 blueF = 100.0 * ((blueF > 0.04045) ? std::pow((blueF + 0.055) / 1.055, 2.4) : blueF / 12.92);
2597
2598 double X = (0.4124 * redF + 0.3576 * greenF + 0.1805 * blueF);
2599 double Y = (0.2126 * redF + 0.7152 * greenF + 0.0722 * blueF); // luminance with weights RGBluminanceWeightR, RGBluminanceWeightG, RGBluminanceWeightB
2600 double Z = (0.0193 * redF + 0.1192 * greenF + 0.9505 * blueF);
2601
2602 if (space == colorSpaceEnum::XYZ)
2603 return colConDbl3(X, Y, Z);
2604
2605 X /= 95.0429;
2606 Y /= 100.0;
2607 Z /= 108.89;
2608
2609 X = (X > 0.008856 ? std::pow(X, 1.0 / 3.0) : (7.787 * X) + (16.0 / 116.0));
2610 Y = (Y > 0.008856 ? std::pow(Y, 1.0 / 3.0) : (7.787 * Y) + (16.0 / 116.0));
2611 Z = (Z > 0.008856 ? std::pow(Z, 1.0 / 3.0) : (7.787 * Z) + (16.0 / 116.0));
2612
2613 double L = (116.0 * Y) - 16.0;
2614 double A = 500.0 * (X - Y);
2615 double B = 200.0 * (Y - Z);
2616
2617 if (space == colorSpaceEnum::LAB)
2618 return colConDbl3(L, A, B);
2619
2620 double C = std::hypot(A, B);
2621
2622 double H = 0.0;
2623 if ( std::abs(A) > 1.0e-5) // Not Grey
2624 H = mjr::math::ivl::wrapCO(atan2(B,A) * 180.0 / std::numbers::pi, 360.0);
2625
2626 if (space == colorSpaceEnum::LCH)
2627 return colConDbl3(L, C, H);
2628 }
2629
2630 return colConDbl3(0.0, 0.0, 0.0);
2631 }
2632 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2633 /** Compute channels for given color space coordinates for the current color.
2634 Note RGB returns float RGB normalized to 1.0.
2635 @param space The color space to stringify
2636 @return A string representing the color space. */
2637 inline std::string colorSpaceToString(colorSpaceEnum space) {
2638 switch (space) {
2639 case colorSpaceEnum::RGB : return std::string("rgb");
2640 case colorSpaceEnum::HSL : return std::string("HSL");
2641 case colorSpaceEnum::HSV : return std::string("HSV");
2642 case colorSpaceEnum::LAB : return std::string("Lab");
2643 case colorSpaceEnum::XYZ : return std::string("XYZ");
2644 case colorSpaceEnum::LCH : return std::string("Lch");
2645 default: return std::string("ERROR");
2646 }
2647 }
2648 //@}
2649
2650 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2651 /** @name Color Transformation Functions */
2652 //@{
2653 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2654 /** The Linear Grey Level Scale transform modifies the current color such that: C_n=c*C_n+b.
2655 This function transforms all channels --- not just RGBA.
2656 @param c The "contrast" value
2657 @param b The "brightness" value
2658 @return Returns a reference to the current color object.*/
2659 inline colorTpl& tfrmLinearGreyLevelScale(double c, double b) {
2660 for(int i=0; i<numChan; i++)
2661 setChanNC(i, static_cast<clrChanT>(c * static_cast<double>(getChanNC(i)) + b));
2662 return *this;
2663 }
2664 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2665 /** The Linear Grey Level Scale transform modifies the current color such that: R=rc*R+rb, G=gc*G+gb, B=bc*B+bb.
2666 This function ONLY transforms the red, green, and blue channels.
2667 @param rc The "contrast" value for red
2668 @param rb The "brightness" value for red
2669 @param gc The "contrast" value for green
2670 @param gb The "brightness" value for green
2671 @param bc The "contrast" value for blue
2672 @param bb The "brightness" value for blue
2673 @return Returns a reference to the current color object.*/
2674 inline colorTpl& tfrmLinearGreyLevelScaleRGB(double rc, double rb, double gc, double gb, double bc, double bb) {
2675 /* Requires: Inherits numChan>3 from setAlpha & getC3. */
2676 setRed( static_cast<clrChanT>(rc * static_cast<double>(getRed()) + rb));
2677 setGreen(static_cast<clrChanT>(gc * static_cast<double>(getGreen()) + gb));
2678 setBlue( static_cast<clrChanT>(bc * static_cast<double>(getBlue()) + bb));
2679 return *this;
2680 }
2681 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2682 /** Perform a tfrmLinearGreyLevelScale based on a complex number.
2683 @param z The complex number
2684 @param cutDepth Range: @f$[1, ~30]@f$ Smaller means more contrast on cuts.
2685 @param argCuts Number of grey cuts for arg
2686 @param absCuts Number of grey cuts for abs
2687 @param logAbs If true, then take the logorithm of abs for cuts. */
2688 inline colorTpl& tfrmComplexCut(std::complex<double> z, double cutDepth, double argCuts, double absCuts, bool logAbs = true) {
2689 double tau = std::numbers::pi * 2; // 2*Pi
2690 double zArg = std::arg(z); // Arg
2691 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
2692 if (argCuts > 0)
2693 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(pzArg*argCuts) - pzArg*argCuts)/cutDepth, 0);
2694 if (absCuts > 0) {
2695 double zAbs = std::abs(z); // Abs
2696 if (logAbs) {
2697 double lzAbs = std::log(zAbs);
2698 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(lzAbs*absCuts) - lzAbs*absCuts)/cutDepth, 0);
2699 } else {
2700 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(zAbs*absCuts) - zAbs*absCuts)/cutDepth, 0);
2701 }
2702 }
2703 return *this;
2704 }
2705 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2706 /** The Standard Power Transform modifies the current color such that: C_i = maxChanVal*(C_i / maxChanVal)**p.
2707 @return Returns a reference to the current color object.*/
2708 inline colorTpl& tfrmStdPow(double p) {
2709 for(int i=0; i<numChan; i++)
2710 setChanNC(i, static_cast<clrChanT>(std::pow(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal), p) * static_cast<double>(maxChanVal)));
2711 return *this;
2712 }
2713 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2714 /** The Standard Power Transform modifies the current color such that:
2715 R=#maxChanVal*(R/#maxChanVal)**rp, B=#maxChanVal*(B/#maxChanVal)**gp, B=#maxChanVal*(B/#maxChanVal)**bp
2716 @return Returns a reference to the current color object.*/
2717 inline colorTpl& tfrmStdPowRGB(double rp, double gp, double bp) {
2718 /* Requires: Inherits numChan>2 from setBlue & getC2. */
2719 setRed( static_cast<clrChanT>(std::pow(static_cast<double>(getRed()) / static_cast<double>(maxChanVal), rp) * static_cast<double>(maxChanVal)));
2720 setGreen(static_cast<clrChanT>(std::pow(static_cast<double>(getGreen()) / static_cast<double>(maxChanVal), gp) * static_cast<double>(maxChanVal)));
2721 setBlue( static_cast<clrChanT>(std::pow(static_cast<double>(getBlue()) / static_cast<double>(maxChanVal), bp) * static_cast<double>(maxChanVal)));
2722 return *this;
2723 }
2724 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2725 /** The Standard Power Transform with p=2. The new color will be: C_i = C_i * C_i / maxChanVal == (C_i/maxChanVal)^2*maxChanVal
2726 This computation is done with integer math if clrChanT is integral.
2727 @return Returns a reference to the current color object.*/
2728 inline colorTpl& tfrmStdPowSqr(void) {
2729 for(int i=0; i<numChan; i++)
2730 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(getChanNC(i)) /
2731 static_cast<channelArithSPType>(maxChanVal)));
2732 return *this;
2733 }
2734 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2735 /** The Standard Power Transform with p=1/2. The new color will be: C_i = sqrt(C_i / maxChanVal) * maxChanVal
2736 @return Returns a reference to the current color object.*/
2737 inline colorTpl& tfrmStdPowSqrt(void) {
2738 for(int i=0; i<numChan; i++)
2739 setChanNC(i, static_cast<clrChanT>(std::sqrt(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal)) * static_cast<double>(maxChanVal)));
2740 return *this;
2741 }
2742 //@}
2743
2744 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2745 /** @name Mathematical Operations On Color(s)
2746 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
2747 result. */
2748 //@{
2749 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2750 /** Use the R, G, & B channels to compute a floating point value representing a grey scale.
2751 What is returned is the dot product of the given color and the three scalars: R*redWt+G*greenWt+B*blueWt.
2752 @param redWt The red weight
2753 @param greenWt The green weight
2754 @param blueWt The blue weight
2755 @return The integer representing grey value for the given color. */
2756 inline channelArithFltType rgb2GreyDotProd(channelArithFltType redWt = RGBluminanceWeightR,
2757 channelArithFltType greenWt = RGBluminanceWeightG,
2758 channelArithFltType blueWt = RGBluminanceWeightB) const {
2759 /* Requires: Inherits numChan>2 from getC2. */
2760 return (static_cast<channelArithFltType>(getRed()) * static_cast<channelArithFltType>(redWt) +
2761 static_cast<channelArithFltType>(getGreen()) * static_cast<channelArithFltType>(greenWt) +
2762 static_cast<channelArithFltType>(getBlue()) * static_cast<channelArithFltType>(blueWt));
2763 }
2764 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2765 /** Compute the luminance of the current color via the definition given in the ITU-R Recommendation BT.709.
2766 The output value will be between 0 and 1, and is given by: (RGBluminanceWeightR*R+RGBluminanceWeightG*G+RGBluminanceWeightB*B)/#maxChanVal.
2767 @return The luminance for the current object. */
2768 inline channelArithFltType luminanceRGB(void) const {
2769 /* Requires: Inherits numChan>2 from getC2. */
2770 return ((static_cast<channelArithFltType>(getRed()) * static_cast<channelArithFltType>(RGBluminanceWeightR) +
2771 static_cast<channelArithFltType>(getGreen()) * static_cast<channelArithFltType>(RGBluminanceWeightG) +
2772 static_cast<channelArithFltType>(getBlue()) * static_cast<channelArithFltType>(RGBluminanceWeightB)) / static_cast<channelArithFltType>(maxChanVal));
2773 }
2774 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2775 /** Compute the unscaled intensity (sum of the R, G, & B components) of the current color
2776 @return The unscaled intensity for the current object. */
2777 inline channelArithSPType intensityRGB(void) const {
2778 /* Requires: Inherits numChan>2 from getC2. */
2779 return static_cast<channelArithSPType>(static_cast<channelArithSPType>(getRed()) +
2780 static_cast<channelArithSPType>(getGreen()) +
2781 static_cast<channelArithSPType>(getC2()));
2782 }
2783 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2784 /** Compute the sum of the components.
2785 @return Sum of components. */
2786 inline channelArithSPType intensity() const {
2787 channelArithSPType sum = 0;
2788 for(int i=0; i<numChan; i++)
2789 sum += getChan(i);
2790 return (sum);
2791 }
2792 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2793 /** Compute the scaled intensity (sum of the first three components divided by the maximum intensity possible) of the current color
2794 @return The scaled intensity for the current object. */
2795 inline channelArithFltType intensityScaledRGB() const {
2796 return (static_cast<channelArithFltType>(intensityRGB()) / static_cast<channelArithFltType>(3) / static_cast<channelArithFltType>(maxChanVal));
2797 }
2798 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2799 /** Compute the scaled intensity (sum of the components divided by the maximum intensity possible) of the current color
2800 @return Sum of components. */
2801 inline channelArithFltType intensityScaled() const {
2802 return (static_cast<channelArithFltType>(intensity()) / static_cast<channelArithFltType>(numChan) / static_cast<channelArithFltType>(maxChanVal));
2803 }
2804 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2805 /** Returns the value of the largest component.
2806 @return The value of the largest color component currently stored.*/
2807 inline clrChanT getMaxC() const {
2808 /* 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.
2809 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
2810 code. */
2811 if constexpr (numChan == 1) { // 1 channel
2812 return getChanNC(0);
2813 } else if constexpr (numChan == 2) { // 2 channels
2814 return std::max(getChanNC(0), getChanNC(1));
2815 } else if constexpr (numChan == 3) { // 3 channels
2816 return mjr::math::odr::max3(getChanNC(0), getChanNC(1), getChanNC(2));
2817 } else if constexpr (numChan == 4) { // 4 channels
2818 return mjr::math::odr::max4(getChanNC(0), getChanNC(1), getChanNC(2), getChanNC(3));
2819 } else { // More than 3 channels
2820 clrChanT theMax = minChanVal;
2821 for(int i=0; i<numChan; i++)
2822 if(theMax < getChanNC(i))
2823 theMax = getChanNC(i);
2824 return theMax;
2825 }
2826 }
2827 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2828 /** Returns the value of the smallest component.
2829 @return The value of the smallest color component currently stored.*/
2830 inline clrChanT getMinC() const {
2831 if constexpr (numChan == 1) { // 1 channel
2832 return getChanNC(0);
2833 } else if constexpr (numChan == 2) { // 2 channels
2834 return std::min(getChanNC(0), getChanNC(1));
2835 } else if constexpr (numChan == 3) { // 3 channels
2836 return mjr::math::odr::min3(getChanNC(0), getChanNC(1), getChanNC(2));
2837 } else if constexpr (numChan == 4) { // 4 channels
2838 return mjr::math::odr::min4(getChanNC(0), getChanNC(1), getChanNC(2), getChanNC(3));
2839 } else {
2840 clrChanT theMin = maxChanVal;
2841 for(int i=0; i<numChan; i++)
2842 if(theMin > getChanNC(i))
2843 theMin = getChanNC(i);
2844 return theMin;
2845 }
2846 }
2847 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2848 /** Returns the value of the largest component from R, G, and B. This function is highly optimized.
2849 @return The value of the largest color component.*/
2850 inline clrChanT getMaxRGB() const { return mjr::math::odr::max3(getRed(), getGreen(), getBlue()); } /* Requires: Inherits numChan>2 from getC2. */
2851 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2852 /** Returns the value of the smallest component from R, G, and B. This function is highly optimized.
2853 @return The value of the smallest color component.*/
2854 inline clrChanT getMinRGB() const { return mjr::math::odr::min3(getRed(), getGreen(), getBlue()); } /* Requires: Inherits numChan>2 from getC2. */
2855 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2856 /** Compute the dot product between the current color and the given color. i.e. c1.r*c2.r+c1.g*c2.g+...
2857 @param aColor the given color
2858 @return Returns dot product.*/
2859 inline channelArithFltType dotProd(colorArgType aColor) const {
2860 channelArithFltType daProd = 0;
2861 for(int i=0; i<numChan; i++)
2862 daProd += static_cast<channelArithFltType>(static_cast<channelArithFltType>(getChanNC(i)) * static_cast<channelArithFltType>(aColor.getChanNC(i)));
2863 return daProd;
2864 }
2865 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2866 /** Distance between current color and given one (sum squares of channel differences -- Euclidean distance squared).
2867 @param aColor The given color
2868 @return Returns Distance */
2869 inline channelArithFltType distHypot(colorArgType aColor) const {
2870 channelArithFltType daDist = 0;
2871 for(int i=0; i<numChan; i++)
2872 daDist += (static_cast<channelArithFltType>((static_cast<channelArithFltType>(getChanNC(i)) - static_cast<channelArithFltType>(aColor.getChanNC(i))) *
2873 (static_cast<channelArithFltType>(getChanNC(i)) - static_cast<channelArithFltType>(aColor.getChanNC(i)))));
2874 return static_cast<channelArithFltType>(std::sqrt(daDist));
2875 }
2876 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2877 /** Distance between current color and given one (sum of absolute channel differences).
2878 @param aColor the given color
2879 @return Returns Distance */
2880 inline channelArithSPType distSumAbs(colorArgType aColor) const {
2881 channelArithSPType daDist = 0;
2882 for(int i=0; i<numChan; i++)
2883 daDist += static_cast<channelArithSPType>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))));
2884 return daDist;
2885 }
2886 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2887 /** Distance between current color and given one (maximum of absolute value of channel differences).
2888 @param aColor the given color
2889 @return Returns Distance */
2890 inline channelArithSPType distMaxAbs(colorArgType aColor) const {
2891 channelArithSPType daDist = 0;
2892 for(int i=0; i<numChan; i++) {
2893 channelArithSPType tmp = static_cast<channelArithSPType>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))));
2894 if (daDist < tmp)
2895 daDist = tmp;
2896 }
2897 return daDist;
2898 }
2899 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2900 /** LAB Delta E* distance between current color and given one.
2901 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.
2902 @param aColor the given color
2903 @return Returns Distance -- note return is a double not a channelArithFltType. */
2904 inline double distDeltaE1976(colorArgType aColor) const {
2905 colConDbl3 acol1 = rgb2colorSpace(colorSpaceEnum::LAB);
2906 colConDbl3 acol2 = aColor.rgb2colorSpace(colorSpaceEnum::LAB);
2907 double daDist = 0;
2908 for (int c=0; c<3; c++)
2909 daDist += std::pow(acol1.getChanNC(c) - acol2.getChanNC(c), 2);
2910 daDist = std::sqrt(daDist);
2911 return daDist;
2912 }
2913 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2914 /** LAB Delta E* 1994 (graphic arts) distance between current color and given one.
2915 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.
2916 Note: The Delta E* 1994 distance measurement is NOT symetric -- the 1976 one is!
2917 @param aColor the given color
2918 @return Returns Distance -- note return is a double not a channelArithFltType. */
2919 inline double distDeltaE1994(colorArgType aColor) const {
2920 colConDbl3 acol1 = rgb2colorSpace(colorSpaceEnum::LAB);
2921 colConDbl3 acol2 = aColor.rgb2colorSpace(colorSpaceEnum::LAB);
2922 double k1 = 0.045;
2923 double k2 = 0.015;
2924 double kL = 1.000;
2925 double kC = 1.000;
2926 double kH = 1.000;
2927 double sL = 1.000;
2928 double dL = acol1.getC0() - acol2.getC0();
2929 double da = acol1.getC1() - acol2.getC1();
2930 double db = acol1.getC2() - acol2.getC2();
2931 double c1 = std::sqrt(std::pow(acol1.getC1(), 2) + std::pow(acol1.getC2(), 2));
2932 double c2 = std::sqrt(std::pow(acol2.getC1(), 2) + std::pow(acol2.getC2(), 2));
2933 double sH = 1.000 + k2 * c1;
2934 double sC = 1.000 + k1 * c1;
2935 double dC = c2 - c2;
2936 double dH2 = std::pow(da, 2) + std::pow(db, 2) - std::pow(dC, 2);
2937 if (dH2 < 0.0)
2938 dH2 = 0.000;
2939 double dE = std::sqrt(std::pow(dL/kL/sL, 2) + std::pow(dC/kC/sC, 2) + dH2/std::pow(kH*sH, 2));
2940 return dE;
2941 }
2942 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2943 /** 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).
2944 Note the implications for floating point clrChanT.
2945 @return non-zero if the given color is logically the same as the current color*/
2946 inline bool isClose(colorArgType aColor, clrChanT epsilon) const {
2947 for(int i=0; i<numChan; i++)
2948 if (std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))) > epsilon)
2949 return false;
2950 return true;
2951 }
2952 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2953 /** Like isClose(), but only checks the R, G, & B channels.
2954 @return non-zero if the given RGB color is the same as the current color*/
2955 inline bool isCloseRGB(colorArgType aColor, clrChanT epsilon) const requires(blueChan >= 0) {
2956 for (int i : {redChan, blueChan, greenChan})
2957 if (std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))) > epsilon)
2958 return false;
2959 return true;
2960 }
2961 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2962 /** Returns non-zero if the current color is precicely equal to aColor.
2963 Note the implications for floating point clrChanT.
2964 @return non-zero if the given color is logically the same as the current color*/
2965 inline bool isEqual(colorArgType aColor) const {
2966 if constexpr (perfectMask)
2967 return (getMaskNC() == aColor.getMaskNC());
2968 else
2969 for(int i=0; i<numChan; i++)
2970 if(getChanNC(i) != aColor.getChanNC(i))
2971 return false;
2972 return true;
2973 }
2974 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2975 /** Like isEqual(), but only checks the R, G, & B channels.
2976 @return non-zero if the given RGB color is the same as the current color*/
2977 inline bool isEqualRGB(colorArgType aColor) const {
2978 /* Requires: Inherits RGB channel requirements from getRed/getGreen/getBlue. */
2979 return ((getRed() == aColor.getRed() ) &&
2980 (getGreen() == aColor.getGreen()) &&
2981 (getBlue() == aColor.getBlue()));
2982 }
2983 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2984 /** Returns non-zero if the given color is logically NOT the same as the current color.
2985 Note the implications for floating point clrChanT.
2986 @return non-zero if the given color is logically the same as the current color*/
2987 inline bool isNotEqual(colorArgType aColor) const { return !(isEqual(aColor)); }
2988 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2989 /** Returns non-zero if the given color is black (all componnets are zero)
2990 @return non-zero if the given color is black (all componnets are zero) */
2991 inline bool isBlack() {
2992 if constexpr (perfectMask)
2993 return (getMaskNC() == maskAllZero);
2994 else
2995 for(int i=0; i<numChan; i++)
2996 if(getChanNC(i) != 0)
2997 return false;
2998 return true;
2999 }
3000 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3001 /** LIke isBlack(), but only checks the R, G, & B channels
3002 @return non-zero if the given color is black (R, G, & B are are zero) */
3003 inline bool isBlackRGB() const { return ((getRed() == 0) && (getGreen() == 0) && (getBlue() == 0)); } /* Requires: Inherits RGB channel requirements from getRed/getGreen/getBlue. */
3004 //@}
3005
3006 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3007 /** @name Channel Clipping Functions */
3008 //@{
3009 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3010 /** Clamp a value to (infinity, maxChanVal].
3011 Input values larger than maxChanVal are mapped to maxChanVal. Values less than minChanVal are not changed.
3012 @param arithValue The value to clamp */
3013 template <typename iT>
3014 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>)
3015 inline clrChanT clampTop(iT arithValue) {
3016 if(arithValue > static_cast<iT>(maxChanVal))
3017 return static_cast<clrChanT>(maxChanVal);
3018 else
3019 return static_cast<clrChanT>(arithValue);
3020 }
3021 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3022 /** Clamp a value to [minChanVal, infinity).
3023 @param arithValue The value to clamp */
3024 template <typename iT>
3025 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>)
3026 inline clrChanT clampBot(iT arithValue) {
3027 if(arithValue < static_cast<iT>(minChanVal))
3028 return static_cast<clrChanT>(minChanVal);
3029 else
3030 return static_cast<clrChanT>(arithValue);
3031 }
3032 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3033 /** Clamp a value to [minChanVal, maxChanVal].
3034 @param arithValue The value to clamp */
3035 template <typename iT>
3036 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>)
3037 inline clrChanT clampAll(iT arithValue) {
3038 if (arithValue > static_cast<iT>(maxChanVal))
3039 return static_cast<clrChanT>(maxChanVal);
3040 else if(arithValue < static_cast<iT>(minChanVal))
3041 return static_cast<clrChanT>(minChanVal);
3042 else
3043 return static_cast<clrChanT>(arithValue);
3044 }
3045 //@}
3046
3047 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3048 /** @name Meta Color Schemes */
3049 //@{
3050 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3051#if !(MISSING_P1907R1)
3052 /** Compute a color from a polynomial space curve in the RGB color space. This is a continuous color scheme!
3053 @tparam coefs Polynomial coefficients*/
3054 template<double...coefs>
3056 public:
3057 /** Set given colorTpl instance to the selected color in the color scheme.
3058 @param aColor color object to set.
3059 @param csX A value in [0, 1] that identifies the color in the scheme.
3060 @return Returns a reference to \a aColor. */
3061 static inline colorTpl& c(colorRefType aColor, csFltType csX) {
3062 double pR = pcoff[0 * psize];
3063 double pG = pcoff[1 * psize];
3064 double pB = pcoff[2 * psize];
3065 for (unsigned int i=1; i<psize; i++) {
3066 pR = pR * csX + pcoff[i + 0 * psize];
3067 pG = pG * csX + pcoff[i + 1 * psize];
3068 pB = pB * csX + pcoff[i + 2 * psize];
3069 }
3070 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));
3071 }
3072 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3073 @param csX A value in [0, 1] that identifies the color in the scheme.
3074 @return Returns a colorTpl value */
3075 static inline colorTpl c(csFltType csX) { colorTpl tmp; return c(tmp, csX); }
3076 private:
3077 constexpr static int psize = (sizeof...(coefs)) / 3;
3078 constexpr static double pcoff[] = { coefs... };
3079 };
3080#endif
3081#if !(MISSING_P1907R1)
3082 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3083 /** 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.
3084 This is a continous color scheme!
3085 @tparam start colour (1=red, 2=green, 3=blue; ex: 0.5=purple;
3086 @tparam rots Rotations in colour in [-1.5, 1.5]. ex: -1.0 is one blue->green->red cycle;
3087 @tparam hue Hue intensity scaling in [0, 1] (0 == greyscale).
3088 @tparam gamma Gamma correction for intensity. */
3089 template<double start, double rots, double hue, double gamma>
3091 public:
3092 /** Set given colorTpl instance to the selected color in the color scheme.
3093 @param aColor color object to set.
3094 @param csX A value in [0, 1] that identifies the color in the scheme.
3095 @return Returns a reference to \a aColor. */
3096 static inline colorTpl& c(colorRefType aColor, csFltType csX) {
3097 //csX=mjr::math::ivl::wrapCC(csX, 0.0, 1.0);
3098 double angle=2*std::numbers::pi*(start/3.0+1.0+rots*csX);
3099 csX=std::pow(csX, gamma);
3100 double ampl=hue*csX*(1-csX)/2.0;
3101 return aColor.setChansRGB_dbl(std::clamp(csX+ampl*(-0.14861*std::cos(angle)+1.78277*std::sin(angle)), 0.0, 1.0),
3102 std::clamp(csX+ampl*(-0.29227*std::cos(angle)-0.90649*std::sin(angle)), 0.0, 1.0),
3103 std::clamp(csX+ampl*(+1.97294*std::cos(angle)), 0.0, 1.0));
3104 }
3105 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3106 @param csX A value in [0, 1] that identifies the color in the scheme.
3107 @return Returns a colorTpl value */
3108 static inline colorTpl c(csFltType csX) { colorTpl tmp; return c(tmp, csX); }
3109 };
3110#endif
3111 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3112 /** Template for HSL color schemes.
3113 If clrChanT is integral, this is a discrete color scheme, otherwise it is continuous.. */
3114 template<cornerColorEnum corner>
3116 public:
3117 constexpr static csIntType numC = (chanIsInt ? meanChanVal : 0);
3118 /** Set given colorTpl instance to the selected color in the color scheme.
3119 @param aColor color object to set.
3120 @param csVal Index of color in pallet. Wrapped to [0, meanChanVal].
3121 @return Returns a reference to \a aColor. */
3122 static inline colorTpl& c(colorRefType aColor, csNatType csVal) {
3123 clrChanT cVal = static_cast<clrChanT>(mjr::math::ivl::wrapCC(csVal, meanChanVal));
3124 colorTpl cc(corner);
3125 return aColor.setChansRGB(static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getRed() ? cVal : -cVal)),
3126 static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getGreen() ? cVal : -cVal)),
3127 static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getBlue() ? cVal : -cVal)));
3128 }
3129 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3130 @param csVal Index of color in pallet. Wrapped to [0, meanChanVal].
3131 @return Returns a colorTpl value */
3132 static inline colorTpl c(csNatType csVal) { colorTpl tmp; return c(tmp, csVal); }
3133 };
3134 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3135 /** Template providing RGB color cube gradiant color schemes */
3136 template<cornerColorEnum...corners>
3137 class csCC_tpl {
3138 public:
3139 constexpr static csIntType numC = ((sizeof...(corners)) - 1) * chanStepMax + 1;
3140 /** Set given colorTpl instance to the selected color in the color scheme.
3141 @param aColor color object to set.
3142 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3143 @return Returns a reference to \a aColor. */
3144 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) {
3145 csFltType csX = static_cast<csFltType>(csG);
3146 return aColor.cmpRGBcornerCGradiant(csX, numA, cols);
3147 }
3148 /** Set given colorTpl instance to the selected color in the color scheme.
3149 @param aColor color object to set.
3150 @param csG Integer used to select a color from the discrete gradiaant.
3151 @return Returns a reference to \a aColor. */
3152 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) {
3153 csIntType csIdx = static_cast<csIntType>(csG);
3154 return aColor.cmpRGBcornerDGradiant(csIdx % numC, numA, cols);
3155 }
3156 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3157 @param csG color scheme selector
3158 @return Returns a colorTpl value */
3159 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) {
3160 colorTpl tmp;
3161 return c(tmp, csG);
3162 }
3163 private:
3164 constexpr static int numA = (sizeof...(corners));
3165 constexpr static cornerColorEnum cols[] = { corners... };
3166 };
3167 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3168 /** Binary color scheme. First color for even inputs and second color for odd. */
3169 template<cornerColorEnum a, cornerColorEnum b>
3171 public:
3172 constexpr static csIntType numC = 2;
3173 /** Set given colorTpl instance to the selected color in the color scheme.
3174 @param aColor color object to set.
3175 @param csIdx Index of color in pallet. Not wrapped or clipped. Even values get color \a a, while odd values get color \a b.
3176 @return Returns a reference to \a aColor. */
3177 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) { if (csIdx % 2) return aColor.setToCorner(b); else return aColor.setToCorner(a); }
3178 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3179 @param csIdx Index of color in pallet. Not wrapped or clipped. Even values get color \a a, while odd values get color \a b.
3180 @return Returns a colorTpl value */
3181 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3182 };
3183 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3184 /** Template for fixed size pallets. */
3185 template<uint32_t...colors>
3186 class csFP_tpl {
3187 public:
3188 constexpr static csIntType numC = (sizeof...(colors));
3189 /** Set given colorTpl instance to the selected color in the color scheme.
3190 @param aColor color object to set.
3191 @param csG Integer used to select a color from the discrete gradiaant.
3192 @return Returns a reference to \a aColor. */
3193 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) {
3194 csFltType csX = static_cast<csFltType>(csG);
3195 return aColor.cmpGradiant(mjr::math::ivl::wrapCC(csX, 1.0), numC, d);
3196 }
3197 /** Set given colorTpl instance to the selected color in the color scheme.
3198 @param aColor color object to set.
3199 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3200 @return Returns a reference to \a aColor. */
3201 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) {
3202 csIntType csIdx = static_cast<csIntType>(csG);
3203 return aColor.setRGBfromLogPackIntARGB(d[csIdx % numC]);
3204 }
3205 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3206 @param csG color scheme color selector
3207 @return Returns a colorTpl value */
3208 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) {
3209 colorTpl tmp;
3210 return c(tmp, csG);
3211 }
3212 private:
3213 constexpr static uint32_t d[] = { colors... };
3214 };
3215 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3216 /** Template for Color Brewer 2 variable sized pallets. */
3217 template<csIntType mx, uint32_t...colors>
3218 class csCB_tpl {
3219 public:
3220 constexpr static csIntType minNumC = 3;
3221 constexpr static csIntType maxNumC = mx;
3222 /** Set given colorTpl instance to the selected color in the color scheme.
3223 @param aColor color object to set.
3224 @param csG Integer used to select a color from the discrete gradiaant.
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::floating_point<saT>) {
3228 csFltType csX = static_cast<csFltType>(csG);
3229 csIntType b = std::clamp(numC, minNumC, maxNumC);
3230 return aColor.cmpGradiant(mjr::math::ivl::wrapCC(csX, 1.0), b, &d[b*(b-1)/2-3+0]);
3231 }
3232 /** Set given colorTpl instance to the selected color in the color scheme.
3233 @param aColor color object to set.
3234 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3235 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3236 @return Returns a reference to \a aColor. */
3237 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG, csIntType numC=maxNumC) requires (std::integral<saT>) {
3238 csIntType csIdx = static_cast<csIntType>(csG);
3239 csIntType b = std::clamp(numC, minNumC, maxNumC);
3240 csIntType i = csIdx % b;
3241 return aColor.setRGBfromLogPackIntARGB(d[b*(b-1)/2-3+i]);
3242 }
3243 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3244 @param csG color scheme color selector
3245 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3246 @return Returns a colorTpl value */
3247 template<typename saT> static inline colorTpl c(saT csG, csIntType numC=maxNumC) requires (std::integral<saT> || std::floating_point<saT>) {
3248 colorTpl tmp;
3249 return c(tmp, csG, numC);
3250 }
3251 private:
3252 constexpr static uint32_t d[] = { colors... };
3253 };
3254 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3255 /** Wrapper for Color Brewer 2 variable sized pallet template to produce a simple fixed color scheme with a numC member.
3256 @tparam varColorScheme A color brewer variable sized color scheme
3257 @tparam numClr The number of colors wanted in the fixed sized scheme.*/
3258 template<class varColorScheme, csIntType numClr>
3259 requires((varColorScheme::minNumC <= numClr) && (varColorScheme::maxNumC >= numClr))
3261 public:
3262 constexpr static csIntType numC = numClr;
3263 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) { return varColorScheme::c(aColor, csG, numClr); }
3264 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) { return varColorScheme::c(aColor, csG, numClr); }
3265 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) { return varColorScheme::c(csG, numC); }
3266 };
3267 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3268 /** Template for web safe 216 pallets. */
3269 template<uint32_t...colors>
3270 class csWS_tpl {
3271 public:
3272 constexpr static csIntType numC = (sizeof...(colors));
3273 /** Set given colorTpl instance to the selected color in the color scheme.
3274 @param aColor color object to set.
3275 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3276 @return Returns a reference to \a aColor. */
3277 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) { return aColor.setRGBfromLogPackIntARGB(d[csIdx % numC]); }
3278 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3279 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3280 @return Returns a reference a colorTpl value. */
3281 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3282 /** Set given colorTpl instance to the selected color in the color scheme.
3283 @param aColor color object to set.
3284 @param csCol input color to convert to a web safe color.
3285 @return Returns a reference to \a aColor. */
3286 static colorTpl& c(colorRefType aColor, colorRefType csCol) {
3287 aColor.copy(csCol);
3288 aColor.tfrmWebSafeRGB();
3289 int colIdx = 36 * (aColor.getRed_byte() / 0x33) + 6 * (aColor.getGreen_byte() / 0x33) + 1 * (aColor.getBlue_byte() / 0x33) + 1;
3290 return aColor.setRGBfromLogPackIntARGB(d[colIdx]);
3291 }
3292 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3293 @param csCol input color to convert to a web safe color.
3294 @return Returns a reference a colorTpl value. */
3295 static colorTpl c(colorRefType csCol) { colorTpl tmp; return c(tmp, csCol); }
3296 private:
3297 constexpr static uint32_t d[] = { colors... };
3298 };
3299 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3300 /** Template for Thaller 2D color schemes. */
3301 template<bool useHSL, bool maxV, double cutDepth, double argCuts, double absCuts, bool logAbs>
3302 requires( !(useHSL && maxV))
3304 public:
3305 /** Set given colorTpl instance to the selected color in the color scheme.
3306 @param aColor color object to set.
3307 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
3308 @param csY A value that, along with csX, identifies the color in the scheme.
3309 @return Returns a reference to \a aColor. */
3310 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
3311 double tau = std::numbers::pi * 2; // 2*Pi
3312 double zAbs = std::sqrt(csX*csX+csY*csY); // Abs
3313 double zArg = std::atan2(csY, csX); // Arg
3314 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
3315 double val = (maxV ? 1 : 4.0*std::atan(zAbs)/tau); // V for HSV
3316 if (useHSL)
3317 aColor.setRGBfromUnitHSL(pzArg, 1.0, val);
3318 else
3319 aColor.setRGBfromUnitHSV(pzArg, 1.0, val);
3320 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
3321 }
3322 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3323 @param csX A value that, along with csY, identifies the color in the scheme.
3324 @param csY A value that, along with csX, identifies the color in the scheme.
3325 @return Returns a colorTpl value */
3326 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
3327 /** Set given colorTpl instance to the selected color in the color scheme.
3328 @param aColor color object to set.
3329 @param csZ A value that identifies the color in the scheme.
3330 @return Returns a reference to \a aColor. */
3331 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
3332 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3333 @param csZ A value that identifies the color in the scheme.
3334 @return Returns a colorTpl value */
3335 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
3336 };
3337 //@}
3338
3339 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3340 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3341 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3342
3343 /** @cond color-schemes */
3344 /* Doxygen is pretty bad at formatting these bits... */
3345
3346 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3347 /** @defgroup cs Color Schemes */
3348
3349#if !(MISSING_P1907R1)
3350 //========================================================================================================================================================
3351 /** @name Color Schemes: Polynomial */
3352 //@{
3353 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3354 /*- @class csPLYgrey
3355 @ingroup cs
3356 @extends csPLY_tpl
3357 Greyscale */
3358 typedef csPLY_tpl<1.0, 0.0,
3359 1.0, 0.0,
3360 1.0, 0.0> csPLYgrey;
3361 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3362 /** @class csPLYquad
3363 @ingroup cs
3364 @extends csPLY_tpl
3365 Quadratic */
3366 typedef csPLY_tpl<1.0, 0.0, 0.0,
3367 1.0, 0.0, 0.0,
3368 1.0, 0.0, 0.0> csPLYquad;
3369 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3370 /** @class csPLYturbo
3371 @ingroup cs
3372 @extends csPLY_tpl
3373 Similar to the Google turbo colormap.
3374 Note this colormap is not identical to turbo, and lacks some of it's more sophisticated characteristics; however, it looks nice.
3375 See: https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html */
3376 typedef csPLY_tpl< 40703.92740, -218720.2701, 492368.2177, -590441.1804, 384271.9078, -101352.6555, -30425.81099,
3377 32619.05953, -10529.162296, 1625.5688083, -124.13217495, 4.867108400, 0.15787894011,
3378 20766.64723, -122258.4886, 315808.0723, -470687.9792, 447662.9929, -283594.9850, 121141.42864,
3379 -34482.96363, 6288.268231, -682.8118257, 37.74849512, 2.025549368, 0.06643490255,
3380 -94331.85477, 587011.8043, -1597312.2220, 2495306.9899, -2470958.0510, 1616523.3372, -706621.97816,
3381 204052.57726, -37536.525321, 4109.7062335, -257.68681737, 13.750387410, 0.16179522842> csPLYturbo;
3382 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3383 /** @class csPLYparula
3384 @ingroup cs
3385 @extends csPLY_tpl
3386 Similar to the Matlab parula colormap.
3387 Note this colormap is not identical to parula, and lacks some of it's more sophisticated characteristics; however, it looks nice.
3388 See: https://www.mathworks.com/help/matlab/ref/parula.html */
3389 typedef csPLY_tpl< 62043.87545, -399037.6523, 1122946.9120, -1812238.5254, 1846100.4184, -1230398.5816, 537273.93047,
3390 -149254.730651, 24535.019552, -2015.3894764, 44.825447931, 0.6772663755, 0.2018889435,
3391 -17121.77553, 108751.1007, -300422.7570, 473217.4661, -468061.6834, 301522.8593, -126770.41694,
3392 33776.781210, -5288.933402, 404.6316583, -7.800267203, 1.3431462881, 0.1677335602,
3393 -17004.66127, 100139.7442, -255248.5285, 366029.9549, -319570.5392, 169195.6211, -48015.67328,
3394 2478.369459, 2717.762128, -795.8032035, 72.119793045, 1.1497391882, 0.5347179324> csPLYparula;
3395 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3396 /** @class csPLYmagma
3397 @ingroup cs
3398 @extends csPLY_tpl
3399 Similar, but not identical, to the matplotlib magma colormap.
3400 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3401 typedef csPLY_tpl<746.7387907, -3433.588054, 6464.361262, -6369.328232, 3470.981211, -1010.528460, 141.7946515,
3402 -15.78575778, 6.066078845, 0.2765580349, 0.000406276347,
3403 885.3555317, -5488.721941, 14347.739660, -20613.711506, 17758.797775, -9380.063372, 2976.8215781,
3404 -529.56166374, 45.254936301, -0.9276250448, 0.006923020887,
3405 -3360.6362774, 17553.826465, -38851.355442, 47349.901018, -34548.072322, 15336.155184, -3997.3017542,
3406 548.12480687, -32.540585926, 2.6406562133, 0.006263758764> csPLYmagma;
3407 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3408 /** @class csPLYinferno
3409 @ingroup cs
3410 @extends csPLY_tpl
3411 Similar, but not identical, to the matplotlib inferno colormap.
3412 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3413 typedef csPLY_tpl<-19.63292067, 452.2107953, -1685.008066, 2775.510486, -2442.279827, 1181.312494, -280.5809421,
3414 10.74924866, 8.60430465, 0.1030211659, 0.002048171596,
3415 1970.76446015, -10379.8617699, 23277.924908, -28925.873437, 21688.815122, -10002.539645, 2763.0755166,
3416 -419.99828889, 28.92908793, -0.2365793129, 0.001175881895,
3417 2525.53763382, -12168.1567723, 24862.266312, -28273.600973, 19817.598983, -8983.810158, 2683.7805375,
3418 -515.72960422, 52.67809976, 0.0641022894, 0.024051180021> csPLYinferno;
3419 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3420 /** @class csPLYplasma
3421 @ingroup cs
3422 @extends csPLY_tpl
3423 Similar, but not identical, to the matplotlib plasma colormap.
3424 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3425 typedef csPLY_tpl<-43.8322257, 285.8375115, -806.7514473, 1301.765273, -1325.274751, 878.0715655, -374.7228293,
3426 98.20716947, -15.31425214, 2.899584724, 0.05309687850,
3427 1014.1378090, -5599.3136737, 13256.9879694, -17529.001879, 14102.556299, -7032.4501033, 2110.7323912,
3428 -350.31653834, 28.69509557, -1.086029536, 0.03452846048,
3429 -829.5844973, 4029.2020771, -8461.6295286, 10078.322085, -7471.246818, 3531.4365043, -1036.2596994,
3430 175.24253651, -17.51426724, 1.646647586, 0.52562476199> csPLYplasma;
3431 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3432 /** @class csPLYviridis
3433 @ingroup cs
3434 @extends csPLY_tpl
3435 Similar, but not identical, to the matplotlib viridis colormap.
3436 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3437 typedef csPLY_tpl<-5.432077171, 4.751786889, 6.203735901, -4.599931518, -0.32724109679, 0.1077083262, 0.274455424454,
3438 4.641571316, -13.749439404, 14.153964947, -5.758238189, 0.21481356454, 1.3964696839, 0.005767962397,
3439 26.272107604, -65.320967828, 56.656299565, -19.291808950, 0.09197688076, 1.3867705979, 0.332663881113> csPLYviridis;
3440 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3441 /** @class csPLYcividis
3442 @ingroup cs
3443 @extends csPLY_tpl
3444 Similar, but not identical, to the cividis colormap.
3445 Note this map dosen't have the flat red and sharp increase in blue at the start of the map.
3446 See: https://github.com/marcosci/cividis and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3447 typedef csPLY_tpl<-10.6296994279, 27.5479183452, -25.1086313881, 9.3401209056, -0.1385953043, -0.0177903167,
3448 -0.2641767638, 0.6924831686, -0.5155427716, 0.2071305342, 0.6695454456, 0.1273928107,
3449 9.7085048454, -25.9409393982, 24.1852720215, -9.7350011883, 1.7347333905, 0.3185822998> csPLYcividis;
3450 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3451 /** @class csPLYhsvRB
3452 @ingroup cs
3453 @extends csPLY_tpl
3454 Similar to csCColdeRainbow, but a little softer. */
3455 typedef csPLY_tpl<8.746561257e-11, 4.285714286, -4.285714286, 1.166666667e+00,
3456 1.200000000e+01, -21.000000000, 9.023809524, -2.161907281e-13,
3457 -1.200000000e+01, 15.000000000, -3.023809524, 2.380952381e-02> csPLYhsvRB;
3458 //@}
3459#endif
3460
3461#if !(MISSING_P1907R1)
3462 //========================================================================================================================================================
3463 /** @name Color Schemes: CubeHelix */
3464 //@{
3465 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3466 /** @class csCHstd
3467 @ingroup cs
3468 @extends csCubeHelix_tpl
3469 The "standard" cubehelix color scheme with start=0.5, rots=-1.5, hue=1, and gamma=1. */
3470 typedef csCubeHelix_tpl<0.5, -1.5, 1.0, 1.0> csCHstd;
3471 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3472 /** @class csCHblu
3473 @ingroup cs
3474 @extends csCubeHelix_tpl
3475 The "blues" cubehelix color scheme with start=0.5, rots=-0.5, hue=1, and gamma=1. */
3476 typedef csCubeHelix_tpl<0.5, -0.5, 1.0, 1.0> csCHblu;
3477 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3478 /** @class csCHvio
3479 @ingroup cs
3480 @extends csCubeHelix_tpl
3481 The "violets" cubehelix color scheme with start=0.5, rots=0.0, hue=1, and gamma=1. */
3482 typedef csCubeHelix_tpl<0.5, 0.0, 1.0, 1.0> csCHvio;
3483 //@}
3484#endif
3485
3486 //========================================================================================================================================================
3487 /** @name Color Schemes: White In Center Circular Gradients */
3488 //@{
3489 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3490 /** @class csCCwicR
3491 @ingroup cs
3492 @extends csCC_tpl
3493 Color cycle starting and ending with red with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3494 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::WHITE, cornerColorEnum::RED> csCCwicR;
3495 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3496 /** @class csCCwicG
3497 @ingroup cs
3498 @extends csCC_tpl
3499 Color cycle starting and ending with green with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3500 typedef csCC_tpl<cornerColorEnum::GREEN, cornerColorEnum::WHITE, cornerColorEnum::GREEN> csCCwicG;
3501 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3502 /** @class csCCwicB
3503 @ingroup cs
3504 @extends csCC_tpl
3505 Color cycle starting and ending with blue with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3506 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::WHITE, cornerColorEnum::BLUE> csCCwicB;
3507 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3508 /** @class csCCwicM
3509 @ingroup cs
3510 @extends csCC_tpl
3511 Color cycle starting and ending with magenta with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3512 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::WHITE, cornerColorEnum::MAGENTA> csCCwicM;
3513 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3514 /** @class csCCwicY
3515 @ingroup cs
3516 @extends csCC_tpl
3517 Color cycle starting and ending with yellow with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3518 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::WHITE, cornerColorEnum::YELLOW> csCCwicY;
3519 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3520 /** @class csCCwicC
3521 @ingroup cs
3522 @extends csCC_tpl
3523 Color cycle starting and ending with cyan with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3524 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::WHITE, cornerColorEnum::CYAN> csCCwicC;
3525 //@}
3526
3527 //========================================================================================================================================================
3528 /** @name Color Schemes: RGB Constant Brightness Ramps */
3529 //@{
3530 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3531 /** @class csCCconsTwo
3532 @ingroup cs
3533 @extends csCC_tpl
3534 Color cycle around the cube with constant brightness of two. Provides (mjr::colorTpl::chanStepMax*3+1) unique colors. */
3535 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csCCconsTwo;
3536 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3537 /** @class csCCconsOne
3538 @ingroup cs
3539 @extends csCC_tpl
3540 Color cycle around the cube with constant brightness of one. Provides (mjr::colorTpl::chanStepMax*3+1) unique colors. */
3541 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::RED, cornerColorEnum::GREEN, cornerColorEnum::BLUE> csCCconsOne;
3542 //@}
3543
3544 //========================================================================================================================================================
3545 /** @name Color Schemes: Start and end with a primary with the secondary mixed from the primaries in the middle. */
3546 //@{
3547 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3548 /** @class csCCmixRYG
3549 @ingroup cs
3550 @extends csCC_tpl
3551 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3552 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::GREEN> csCCmixRYG;
3553 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3554 /** @class csCCmixRMB
3555 @ingroup cs
3556 @extends csCC_tpl
3557 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3558 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::MAGENTA, cornerColorEnum::BLUE> csCCmixRMB;
3559 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3560 /** @class csCCmixGCB
3561 @ingroup cs
3562 @extends csCC_tpl
3563 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3564 typedef csCC_tpl<cornerColorEnum::GREEN, cornerColorEnum::CYAN, cornerColorEnum::BLUE> csCCmixGCB;
3565 //@}
3566
3567 //========================================================================================================================================================
3568 /** @name Color Schemes: RGB Divergent Ramps */
3569 //@{
3570 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3571 /** @class csCCdivBWR
3572 @ingroup cs
3573 @extends csCC_tpl
3574 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. */
3575 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::WHITE, cornerColorEnum::RED> csCCdivBWR;
3576 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3577 /** @class csCCdivCWM
3578 @ingroup cs
3579 @extends csCC_tpl
3580 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. */
3581 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::WHITE, cornerColorEnum::MAGENTA> csCCdivCWM;
3582 //@}
3583
3584 //========================================================================================================================================================
3585 /** @name Color Schemes: RGB Cube Diagional Ramps */
3586 //@{
3587 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3588 /** @class csCCdiag01
3589 @ingroup cs
3590 @extends csCC_tpl
3591 Gradient across the diagonal of the RGB color cube from black to white. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3592 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csCCdiag01;
3593 /** @class csCCdiag10
3594 @ingroup cs
3595 @extends csCC_tpl
3596 Gradient across the diagonal of the RGB color cube from white to black. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3597 typedef csCC_tpl<cornerColorEnum::WHITE, cornerColorEnum::BLACK> csCCdiag10;
3598 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3599 /** @class csCCdiagCR
3600 @ingroup cs
3601 @extends csCC_tpl
3602 Gradient across the diagonal of the RGB color cube from cyan to red. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3603 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::RED> csCCdiagCR;
3604 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3605 /** @class csCCdiagMG
3606 @ingroup cs
3607 @extends csCC_tpl
3608 Gradient across the diagonal of the RGB color cube from magenta to green. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3609 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::GREEN> csCCdiagMG;
3610 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3611 /** @class csCCdiagYB
3612 @ingroup cs
3613 @extends csCC_tpl
3614 Gradient across the diagonal of the RGB color cube from yellow to blue. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3615 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::BLUE> csCCdiagYB;
3616 //@}
3617
3618 //========================================================================================================================================================
3619 /** @name Color Schemes: Classic RGB Ramps */
3620 //@{
3621 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3622 /** @class csCColdeFireRamp
3623 @ingroup cs
3624 @extends csCC_tpl
3625 Classic color cube "Fire Ramp". */
3626 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCColdeFireRamp;
3627 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3628 /** @class csCColdeColdToHot
3629 @ingroup cs
3630 @extends csCC_tpl
3631 Classical cold to hot color cube ramp. Provides (mjr::colorTpl::chanStepMax*4+1) unique colors. */
3632 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::GREEN,
3633 cornerColorEnum::YELLOW, cornerColorEnum::RED> csCColdeColdToHot;
3634 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3635 /** @class csCColdeIceToWaterToHot
3636 @ingroup cs
3637 @extends csCC_tpl
3638 Modified version of the classical cold to hot color cube ramp.ramp. It starts at white (ice), moves up to blue (cold),
3639 then yellow through red (hot). Provides (mjr::colorTpl::chanStepMax*4+1) unique colors. */
3640 typedef csCC_tpl<cornerColorEnum::WHITE, cornerColorEnum::CYAN, cornerColorEnum::BLUE,
3641 cornerColorEnum::YELLOW, cornerColorEnum::RED> csCColdeIceToWaterToHot;
3642 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3643 /** @class csCColdeRainbow
3644 @ingroup cs
3645 @extends csCC_tpl
3646 The classic HSV rainbow color scheme based upon an edge traversal of the RGB color cube. Provides (6 * mjr::colorTpl::chanStepMax + 1) colors. */
3647 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::GREEN, cornerColorEnum::CYAN,
3648 cornerColorEnum::BLUE, cornerColorEnum::MAGENTA, cornerColorEnum::RED> csCColdeRainbow;
3649 //@}
3650
3651 //========================================================================================================================================================
3652 /** @name Color Schemes: Classic Fractal RGB Gradients.
3653 Gradients frequently used to color fractal images. */
3654 //@{
3655 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3656 /** @class csCCfractal0RYBCW
3657 @ingroup cs
3658 @extends csCC_tpl
3659 Provides (5 * mjr::colorTpl::chanStepMax + 1) colors. */
3660 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW,
3661 cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCfractal0RYBCW;
3662 /** @class csCCfractalYR
3663 @ingroup cs
3664 @extends csCC_tpl
3665 Provides (mjr::colorTpl::chanStepMax + 1) colors. */
3666 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::RED> csCCfractalYR;
3667 /** @class csCCfractalYB
3668 @ingroup cs
3669 @extends csCC_tpl
3670 Provides (mjr::colorTpl::chanStepMax + 1) colors. */
3671 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::BLUE> csCCfractalYB;
3672 //@}
3673
3674 //========================================================================================================================================================
3675 /** @name Color Schemes: RGB Sum Ramps */
3676 //@{
3677 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3678 /** @class csCCsumRGB
3679 @ingroup cs
3680 @extends csCC_tpl
3681 RGB cube sum-ramp: RGB == Black -> Red -> Yellow -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3682 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCCsumRGB;
3683 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3684 /** @class csCCsumBGR
3685 @ingroup cs
3686 @extends csCC_tpl
3687 RGB cube sum-ramp: BGR == Black -> Blue -> cyan -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3688 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCsumBGR;
3689 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3690 /** @class csCCsumGRB
3691 @ingroup cs
3692 @extends csCC_tpl
3693 RGB cube sum-ramp: GRB == Black -> Green -> yellow -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3694 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCCsumGRB;
3695 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3696 /** @class csCCsumGBR
3697 @ingroup cs
3698 @extends csCC_tpl
3699 RGB cube sum-ramp: GBR == Black -> Green -> cyan -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3700 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCsumGBR;
3701 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3702 /** @class csCCsumBRG
3703 @ingroup cs
3704 @extends csCC_tpl
3705 RGB cube sum-ramp: BRG == Black -> Blue -> magenta -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3706 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE, cornerColorEnum::MAGENTA, cornerColorEnum::WHITE> csCCsumBRG;
3707 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3708 /** @class csCCsumRBG
3709 @ingroup cs
3710 @extends csCC_tpl
3711 RGB cube sum-ramp: RBG Black -> Red -> Magenta -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3712 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::MAGENTA, cornerColorEnum::WHITE> csCCsumRBG;
3713 //@}
3714
3715 //========================================================================================================================================================
3716 /** @name Color Schemes: RGB Up-Down Ramps */
3717 //@{
3718 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3719 /** @class csCCudRg
3720 @ingroup cs
3721 @extends csCC_tpl
3722 RGB Up-Down Ramp: Rg == Red Up and Green Down == cyan -> magenta. Provides chanStepMax different colors.*/
3723 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::MAGENTA> csCCudRg;
3724 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3725 /** @class csCCudRb
3726 @ingroup cs
3727 @extends csCC_tpl
3728 RGB Up-Down Ramp: Rb == Red Up and Blue Down == cyan -> yellow. Provides chanStepMax different colors.*/
3729 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::YELLOW> csCCudRb;
3730 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3731 /** @class csCCudGr
3732 @ingroup cs
3733 @extends csCC_tpl
3734 RGB Up-Down Ramp: Gr == Green Up and Red Down == magenta -> cyan. Provides chanStepMax different colors. */
3735 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::CYAN> csCCudGr;
3736 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3737 /** @class csCCudGb
3738 @ingroup cs
3739 @extends csCC_tpl
3740 RGB Up-Down Ramp: Gb == Green Up and Blue Down == magenta -> yellow. Provides chanStepMax different colors. */
3741 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW> csCCudGb;
3742 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3743 /** @class csCCudBr
3744 @ingroup cs
3745 @extends csCC_tpl
3746 RGB Up-Down Ramp: Br == Blue Up and Red Down == yellow -> cyan. Provides chanStepMax different colors. */
3747 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csCCudBr;
3748 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3749 /** @class csCCudBg
3750 @ingroup cs
3751 @extends csCC_tpl
3752 RGB Up-Down Ramp: Bg == Blue Up and Green Down == yellow -> magenta. Provides chanStepMax different colors. */
3753 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::MAGENTA> csCCudBg;
3754 //@}
3755
3756 //========================================================================================================================================================
3757 /** @name Color Schemes: Ramp from black to corner */
3758 //@{
3759 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csCCu0W; //!< Ramp from black to white
3760 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED> csCCu0R; //!< Ramp from black to red
3761 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE> csCCu0B; //!< Ramp from black to blue
3762 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN> csCCu0G; //!< Ramp from black to green
3763 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::CYAN> csCCu0C; //!< Ramp from black to cyan
3764 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::MAGENTA> csCCu0M; //!< Ramp from black to magenta
3765 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::YELLOW> csCCu0Y; //!< Ramp from black to yellow
3766 //@}
3767
3768 //========================================================================================================================================================
3769 /** @name Color Schemes: Binary */
3770 //@{
3771 typedef csBin_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csBin01; //!< Binary Black-White color scheme. First color for even inputs and second color for odd.
3772 typedef csBin_tpl<cornerColorEnum::GREEN, cornerColorEnum::BLUE> csBinGB; //!< Binary Green-Blue color scheme. First color for even inputs and second color for odd.
3773 typedef csBin_tpl<cornerColorEnum::RED, cornerColorEnum::BLUE> csBinRB; //!< Binary Red-Blue color scheme. First color for even inputs and second color for odd.
3774 typedef csBin_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::CYAN> csBinMC; //!< Binary Magenta-Cyan color scheme. First color for even inputs and second color for odd.
3775 typedef csBin_tpl<cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csBinYC; //!< Binary Yellow-Cyan color scheme. First color for even inputs and second color for odd.
3776 typedef csBin_tpl<cornerColorEnum::RED, cornerColorEnum::GREEN> csBinRG; //!< Binary Red-Green color scheme. First color for even inputs and second color for odd.
3777 typedef csBin_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW> csBinMY; //!< Binary Magenta-Yellow color scheme. First color for even inputs and second color for odd.
3778 //@}
3779
3780 //========================================================================================================================================================
3781 /** @name Color Schemes: Pseudo-Grey
3782 These color schemes start with black and move toward white trying to increase perceptional brightness, they don't stay precisely on the diagonal. */
3783 //@{
3784 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3785 /** @class csPGrey3x
3786 @ingroup cs
3787 A Pseudo-Grey color scheme with 3 * mjr::colorTpl::chanStepMax colors. */
3788 class csPGrey3x {
3789 public:
3790 constexpr static csIntType numC = 3*chanStepMax;
3791 /** Set given colorTpl instance to the selected color in the color scheme.
3792 @param aColor color object to set.
3793 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3794 @return Returns a reference to \a aColor. */
3795 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) {
3796 csIdx = csIdx % numC;
3797 return aColor.setChansRGB(static_cast<clrChanT>(csIdx / 3 + (csIdx%3==0?1:0)),
3798 static_cast<clrChanT>(csIdx / 3 + (csIdx%3==1?1:0)),
3799 static_cast<clrChanT>(csIdx / 3 + (csIdx%3==2?1:0)));
3800 }
3801 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3802 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3803 @return Returns a colorTpl value */
3804 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3805 };
3806 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3807 /** @class csPGrey4x
3808 @ingroup cs
3809 A Pseudo-Grey color scheme with 4 * mjr::colorTpl::chanStepMax colors. */
3810 class csPGrey4x {
3811 public:
3812 constexpr static csIntType numC = 4*chanStepMax;
3813 /** Set given colorTpl instance to the selected color in the color scheme.
3814 @param aColor color object to set.
3815 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3816 @return Returns a reference to \a aColor. */
3817 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) {
3818 csIdx = csIdx % numC;
3819 return aColor.setChansRGB(static_cast<clrChanT>(csIdx / 4 + ((csIdx+1)%4==0?1:0)),
3820 static_cast<clrChanT>(csIdx / 4 + ((csIdx+2)%4==0?1:0)),
3821 static_cast<clrChanT>(csIdx / 4 + ((csIdx+3)%4==0?1:0)));
3822 }
3823 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3824 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3825 @return Returns a colorTpl value */
3826 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3827 };
3828 //@}
3829
3830 //========================================================================================================================================================
3831 /** @name Color Schemes: HSL Saturation Ramps */
3832 //@{
3833 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3834 /** @class csHSLhR
3835 @ingroup cs
3836 @extends csHSLh_tpl
3837 HSL color scheme extending from the center of the HSL color space to the red vertex.
3838 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3839 typedef csHSLh_tpl<cornerColorEnum::RED> csHSLhR;
3840 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3841 /** @class csHSLhG
3842 @ingroup cs
3843 @extends csHSLh_tpl
3844 HSL color scheme extending from the center of the HSL color space to the green vertex.
3845 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3846 typedef csHSLh_tpl<cornerColorEnum::GREEN> csHSLhG;
3847 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3848 /** @class csHSLhB
3849 @ingroup cs
3850 @extends csHSLh_tpl
3851 HSL color scheme extending from the center of the HSL color space to the blue vertex.
3852 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3853 typedef csHSLh_tpl<cornerColorEnum::BLUE> csHSLhB;
3854 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3855 /** @class csHSLhC
3856 @ingroup cs
3857 @extends csHSLh_tpl
3858 HSL color scheme extending from the center of the HSL color space to the cyan vertex.
3859 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3860 typedef csHSLh_tpl<cornerColorEnum::CYAN> csHSLhC;
3861 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3862 /** @class csHSLhM
3863 @ingroup cs
3864 @extends csHSLh_tpl
3865 HSL color scheme extending from the center of the HSL color space to the magenta vertex.
3866 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3867 typedef csHSLh_tpl<cornerColorEnum::MAGENTA> csHSLhM;
3868 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3869 /** @class csHSLhY
3870 @ingroup cs
3871 @extends csHSLh_tpl
3872 HSL color scheme extending from the center of the HSL color space to the yellow vertex.
3873 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3874 typedef csHSLh_tpl<cornerColorEnum::YELLOW> csHSLhY;
3875 //@}
3876
3877 //========================================================================================================================================================
3878 /** @name Color Schemes: Rainbows */
3879 //@{
3880 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3881 /** @class csRainbowLA
3882 @ingroup cs
3883 Computes a color value based upon a linear approximation of the color match functions used to approximate wavelength to RGB conversion.
3884 The linear color function approximation is not very accurate, but it is quite attractive. */
3885 class csRainbowLA {
3886 public:
3887 /** Set given colorTpl instance to the selected color in the color scheme.
3888 @param aColor color object to set.
3889 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3890 @param numC Number of colors to provide
3891 @return Returns a reference to \a aColor. */
3892 static inline colorTpl& c(colorRefType aColor, csIntType csIdx, csIntType numC) {
3893 csIdx = mjr::math::ivl::wrapCC(csIdx, numC);
3894 return aColor.setRGBfromWavelengthLA(mjr::math::linm::gen_map(static_cast<double>(csIdx),
3895 static_cast<double>(0),
3896 static_cast<double>(numC),
3897 static_cast<double>(minWavelength),
3898 static_cast<double>(maxWavelength)));
3899 }
3900 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3901 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3902 @param numC Number of colors to provide
3903 @return Returns a reference a colorTpl value. */
3904 static inline colorTpl c(csIntType csIdx, csIntType numC) {
3905 colorTpl tmp;
3906 return c(tmp, numC, csIdx);
3907 }
3908 };
3909 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3910 /** @class csRainbowCM
3911 @ingroup cs
3912 Computes a color value based upon an algorithm to convert wavelength to RGB that uses the Color Matching functions.
3913 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum) */
3914 class csRainbowCM {
3915 public:
3916 /** Set given colorTpl instance to the selected color in the color scheme.
3917 @param aColor color object to set.
3918 @param numC Number of colors to provide.
3919 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3920 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
3921 @return Returns a reference to \a aColor. */
3922 static inline colorTpl& c(colorRefType aColor, csIntType csIdx, csIntType numC, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
3923 csIdx = mjr::math::ivl::wrapCC(csIdx, numC);
3924 return aColor.setRGBfromWavelengthCM(mjr::math::linm::gen_map(static_cast<double>(csIdx),
3925 static_cast<double>(0),
3926 static_cast<double>(numC),
3927 static_cast<double>(minWavelength),
3928 static_cast<double>(maxWavelength)),
3929 interpMethod);
3930 }
3931 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3932 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3933 @param numC Number of colors to provide.
3934 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
3935 @return Returns a reference a colorTpl value. */
3936 static inline colorTpl c(csIntType csIdx, csIntType numC, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
3937 colorTpl tmp;
3938 return c(tmp, numC, csIdx, interpMethod);
3939 }
3940 };
3941 //@}
3942
3943 //========================================================================================================================================================
3944 /** @name "Web Safe" Color Schemes */
3945 //@{
3946 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3947 /** @class csWSnormalVision
3948 @ingroup cs
3949 @extends csWS_tpl
3950 The "web safe" color pallet of 216 colors as seen by someone with normal color vision.
3951 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)
3952 pallet for color reduction. The colors are ordered in lexicographical ordering based upon the hexadecimal web-based color name scheme "#RRGGBB" --
3953 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(). */
3954 typedef csWS_tpl<0x000000, 0x000033, 0x000066, 0x000099, 0x0000CC, 0x0000FF, 0x003300, 0x003333, 0x003366, 0x003399, 0x0033CC,
3955 0x0033FF, 0x006600, 0x006633, 0x006666, 0x006699, 0x0066CC, 0x0066FF, 0x009900, 0x009933, 0x009966, 0x009999,
3956 0x0099CC, 0x0099FF, 0x00CC00, 0x00CC33, 0x00CC66, 0x00CC99, 0x00CCCC, 0x00CCFF, 0x00FF00, 0x00FF33, 0x00FF66,
3957 0x00FF99, 0x00FFCC, 0x00FFFF, 0x330000, 0x330033, 0x330066, 0x330099, 0x3300CC, 0x3300FF, 0x333300, 0x333333,
3958 0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336600, 0x336633, 0x336666, 0x336699, 0x3366CC, 0x3366FF, 0x339900,
3959 0x339933, 0x339966, 0x339999, 0x3399CC, 0x3399FF, 0x33CC00, 0x33CC33, 0x33CC66, 0x33CC99, 0x33CCCC, 0x33CCFF,
3960 0x33FF00, 0x33FF33, 0x33FF66, 0x33FF99, 0x33FFCC, 0x33FFFF, 0x660000, 0x660033, 0x660066, 0x660099, 0x6600CC,
3961 0x6600FF, 0x663300, 0x663333, 0x663366, 0x663399, 0x6633CC, 0x6633FF, 0x666600, 0x666633, 0x666666, 0x666699,
3962 0x6666CC, 0x6666FF, 0x669900, 0x669933, 0x669966, 0x669999, 0x6699CC, 0x6699FF, 0x66CC00, 0x66CC33, 0x66CC66,
3963 0x66CC99, 0x66CCCC, 0x66CCFF, 0x66FF00, 0x66FF33, 0x66FF66, 0x66FF99, 0x66FFCC, 0x66FFFF, 0x990000, 0x990033,
3964 0x990066, 0x990099, 0x9900CC, 0x9900FF, 0x993300, 0x993333, 0x993366, 0x993399, 0x9933CC, 0x9933FF, 0x996600,
3965 0x996633, 0x996666, 0x996699, 0x9966CC, 0x9966FF, 0x999900, 0x999933, 0x999966, 0x999999, 0x9999CC, 0x9999FF,
3966 0x99CC00, 0x99CC33, 0x99CC66, 0x99CC99, 0x99CCCC, 0x99CCFF, 0x99FF00, 0x99FF33, 0x99FF66, 0x99FF99, 0x99FFCC,
3967 0x99FFFF, 0xCC0000, 0xCC0033, 0xCC0066, 0xCC0099, 0xCC00CC, 0xCC00FF, 0xCC3300, 0xCC3333, 0xCC3366, 0xCC3399,
3968 0xCC33CC, 0xCC33FF, 0xCC6600, 0xCC6633, 0xCC6666, 0xCC6699, 0xCC66CC, 0xCC66FF, 0xCC9900, 0xCC9933, 0xCC9966,
3969 0xCC9999, 0xCC99CC, 0xCC99FF, 0xCCCC00, 0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCCC, 0xCCCCFF, 0xCCFF00, 0xCCFF33,
3970 0xCCFF66, 0xCCFF99, 0xCCFFCC, 0xCCFFFF, 0xFF0000, 0xFF0033, 0xFF0066, 0xFF0099, 0xFF00CC, 0xFF00FF, 0xFF3300,
3971 0xFF3333, 0xFF3366, 0xFF3399, 0xFF33CC, 0xFF33FF, 0xFF6600, 0xFF6633, 0xFF6666, 0xFF6699, 0xFF66CC, 0xFF66FF,
3972 0xFF9900, 0xFF9933, 0xFF9966, 0xFF9999, 0xFF99CC, 0xFF99FF, 0xFFCC00, 0xFFCC33, 0xFFCC66, 0xFFCC99, 0xFFCCCC,
3973 0xFFCCFF, 0xFFFF00, 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFFFFFF> csWSnormalVision;
3974 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3975 /** @class csWSprotanopia
3976 @ingroup cs
3977 @extends csWS_tpl
3978 The "web safe" color pallet of 216 colors as seen by someone with Protanopia.
3979 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSprotanopiaAlt. */
3980 typedef csWS_tpl<0x000000, 0x002346, 0x004487, 0x0060C1, 0x0078F0, 0x719CFF, 0x312C00, 0x2E2E30, 0x0D3366, 0x0053A6,
3981 0x006FDE, 0x5B91FF, 0x635800, 0x61592E, 0x5C5B5F, 0x4E5F93, 0x1A66CC, 0x007EFE, 0x948500, 0x93852D, 0x90865E,
3982 0x8A898F, 0x7E8DC2, 0x6792F8, 0xC5B000, 0xC5B12B, 0xC3B25D, 0xBFB38D, 0xB8B6BF, 0xADBAF2, 0xF6DC00, 0xF6DD29,
3983 0xF5DD5C, 0xF2DF8C, 0xEDE1BD, 0xE6E4EE, 0x1E1B08, 0x002448, 0x00468B, 0x0062C4, 0x0079F2, 0x739DFF, 0x373200,
3984 0x343333, 0x19376A, 0x0054AA, 0x0070E1, 0x6094FF, 0x655B00, 0x645B2F, 0x5E5D61, 0x506195, 0x2067CD, 0x2581FF,
3985 0x958600, 0x95862E, 0x92875E, 0x8C8A90, 0x7F8EC3, 0x6993FA, 0xC6B100, 0xC6B22C, 0xC4B25D, 0xC0B48E, 0xB9B7BF,
3986 0xAEBBF2, 0xF7DD00, 0xF7DD29, 0xF5DE5C, 0xF3DF8C, 0xEEE2BD, 0xE7E5EF, 0x3C360F, 0x323748, 0x00478E, 0x0065CA,
3987 0x007CF8, 0x7AA1FF, 0x4A420B, 0x46433A, 0x324676, 0x0059B4, 0x0074EA, 0x6E9AFF, 0x6F6300, 0x6D6432, 0x686666,
3988 0x59699C, 0x326ED5, 0x518DFF, 0x9B8B00, 0x9B8B2F, 0x988C61, 0x918F93, 0x8593C7, 0x6E98FE, 0xCAB500, 0xCAB52D,
3989 0xC8B65E, 0xC4B88F, 0xBDBBC1, 0xB2BEF5, 0xFAE000, 0xFAE02A, 0xF8E15D, 0xF6E28D, 0xF1E4BF, 0xEAE7F0, 0x5A5117,
3990 0x55514A, 0x39538F, 0x0067D0, 0x2782FF, 0x83A6FF, 0x635913, 0x5F5941, 0x505B80, 0x005EBF, 0x007AF6, 0x7DA2FF,
3991 0x7F720D, 0x7E7237, 0x78746D, 0x6A77A5, 0x497BDF, 0x709BFF, 0xA69500, 0xA59532, 0xA29665, 0x9B9899, 0x8F9CCE,
3992 0x83A4FF, 0xD2BC00, 0xD1BC2F, 0xCFBD61, 0xCBBF93, 0xC4C1C6, 0xB9C5FA, 0xFFE41C, 0xFFE532, 0xFEE65E, 0xFBE790,
3993 0xF7E9C1, 0xEFECF4, 0x786C1E, 0x746C4C, 0x646D90, 0x356FD5, 0x5D91FF, 0x8CABFF, 0x7E711B, 0x7B7146, 0x707387,
3994 0x5275C8, 0x4387FF, 0x8AAAFF, 0x948415, 0x92853C, 0x8C8675, 0x7F88AF, 0x648CEB, 0x87A7FF, 0xB5A20E, 0xB5A336,
3995 0xB1A46A, 0xAAA5A0, 0x9EA8D7, 0x98B1FF, 0xDDC600, 0xDDC631, 0xDBC764, 0xD7C997, 0xCFCBCB, 0xC4CEFF, 0xFFE655,
3996 0xFFE75C, 0xFFE873, 0xFFEB97, 0xFFF1C5, 0xF8F4F8, 0x968726, 0x93874E, 0x888892, 0x6E89D7, 0x7BA0FF, 0x96B1FF,
3997 0x9A8B23, 0x988B4A, 0x8F8C8B, 0x7A8ECE, 0x779DFF, 0x96B1FF, 0xAC9A1E, 0xAA9A42, 0xA59B7C, 0x999DB9, 0x82A0F6,
3998 0x98B2FF, 0xC8B317, 0xC7B43A, 0xC4B470, 0xBDB6A8, 0xB1B8E0, 0xAABDFF, 0xECD30F, 0xECD435, 0xE9D469, 0xE5D69D,
3999 0xDED8D2, 0xCFD7FF, 0xFFE871, 0xFFE975, 0xFFEA86, 0xFFEDA2, 0xFFF2C8, 0xFFFAFA> csWSprotanopia;
4000 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4001 /** @class csWSdeutanopia
4002 @ingroup cs
4003 @extends csWS_tpl
4004 The "web safe" color pallet of 216 colors as seen by someone with Deutanopia.
4005 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSdeutanopiaAlt. */
4006 typedef csWS_tpl<0x000000, 0x002135, 0x004168, 0x005E97, 0x0076BE, 0x008BDF, 0x362A0C, 0x2F2D34, 0x003E68, 0x005E9A, 0x0078C2,
4007 0x008CE2, 0x6D5418, 0x6A5538, 0x5E5A69, 0x3D629A, 0x0078C9, 0x0090EC, 0xA37E25, 0xA27E3D, 0x9B816C, 0x8D869D,
4008 0x728ECF, 0x3398FF, 0xDAA831, 0xD9A844, 0xD4AA6F, 0xCBAEA0, 0xBBB3D1, 0xA5BBFF, 0xFFCD72, 0xFFCD77, 0xFFCF87,
4009 0xFFD3A6, 0xFBDAD4, 0xE6DCFF, 0x221A00, 0x131E30, 0x003F67, 0x005D96, 0x0076BF, 0x008BDF, 0x3D2F09, 0x373133,
4010 0x003B65, 0x005D99, 0x0078C2, 0x008CE2, 0x705617, 0x6D5737, 0x615B68, 0x43639A, 0x0078C9, 0x0090EC, 0xA58600,
4011 0xA4803C, 0x9D826B, 0x8F879D, 0x758FCE, 0x3999FF, 0xDBA830, 0xDAA943, 0xD6AB6F, 0xCCAEA0, 0xBDB4D1, 0xA7BBFF,
4012 0xFFCD74, 0xFFCD78, 0xFFCF88, 0xFFD4A6, 0xFCDBD4, 0xE7DDFF, 0x453500, 0x3F352F, 0x253D60, 0x005A94, 0x0076BF,
4013 0x008BE1, 0x534000, 0x4F4031, 0x3D4763, 0x005995, 0x0076C2, 0x008CE4, 0x7B5E11, 0x795F35, 0x6F6367, 0x586A98,
4014 0x0076C9, 0x0090EE, 0xAC8421, 0xAA853B, 0xA4876A, 0x978C9C, 0x8093CD, 0x519CFE, 0xE0AC2E, 0xDFAC42, 0xDAAE6E,
4015 0xD2B29F, 0xC3B7D1, 0xADBEFF, 0xFFCE79, 0xFFCF7C, 0xFFD08B, 0xFFD5A7, 0xFFDDD3, 0xEBDFFF, 0x674F00, 0x634E2C,
4016 0x57535F, 0x385B90, 0x0073C0, 0x008CE5, 0x705600, 0x6C552D, 0x625961, 0x496192, 0x0073C2, 0x008DE8, 0x8E6C00,
4017 0x8C6D31, 0x847064, 0x737696, 0x507FC7, 0x0090F3, 0xA69500, 0xB78E37, 0xB29068, 0xA6949A, 0x929BCC, 0x6FA4FD,
4018 0xE9B22A, 0xE8B33F, 0xE4B56C, 0xDBB89D, 0xCEBDCF, 0xB9C4FF, 0xFFD080, 0xFFD184, 0xFFD291, 0xFFD6A9, 0xFFDDD0,
4019 0xF4E4FF, 0x886900, 0x856726, 0x7E6A5E, 0x6E7190, 0x4B7AC0, 0x008CEC, 0x8F6D00, 0x8C6C27, 0x856F5F, 0x767591,
4020 0x577EC2, 0x008DEF, 0xA67F00, 0xA47E2B, 0x9E8161, 0x918694, 0x7B8DC5, 0x4C97F6, 0xCA9A00, 0xC99B32, 0xC49D65,
4021 0xBAA198, 0xAAA7C9, 0x8FAEFB, 0xF6C600, 0xF5BC3B, 0xF1BE6A, 0xEAC19B, 0xDEC6CD, 0xCBCCFF, 0xFFD389, 0xFFD38C,
4022 0xFFD497, 0xFFD8AB, 0xFFDECC, 0xFFEAFD, 0xA98200, 0xA8801A, 0xA2835B, 0x97888E, 0x838FC0, 0x5E98F1, 0xAE8600,
4023 0xAD841C, 0xA7875C, 0x9D8B8F, 0x8A92C1, 0x679BF2, 0xC09300, 0xBF9322, 0xBB955E, 0xB19992, 0xA09FC3, 0x85A7F5,
4024 0xDFAA00, 0xDEAB2A, 0xDAAC62, 0xD2B095, 0xC5B5C7, 0xB0BCF9, 0xFFC750, 0xFFC857, 0xFFCA6F, 0xFCCD99, 0xF1D2CB,
4025 0xE1D8FD, 0xFFD592, 0xFFD594, 0xFFD79D, 0xFFDAAD, 0xFFDFC8, 0xFFE8EF> csWSdeutanopia;
4026 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4027 /** @class csWStritanoptia
4028 @ingroup cs
4029 @extends csWS_tpl
4030 The "web safe" color pallet of 216 colors as seen by someone with Tritanoptia.
4031 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWStritanoptiaAlt. */
4032 typedef csWS_tpl<0x000000, 0x001C1D, 0x003739, 0x005155, 0x006A6E, 0x007F85, 0x173033, 0x0A3236, 0x004347, 0x00595E, 0x006F74,
4033 0x008389, 0x2D5F66, 0x2A6068, 0x15656D, 0x00727A, 0x00828A, 0x00929A, 0x448F9A, 0x42909A, 0x39929D, 0x1F97A3,
4034 0x00A1AC, 0x00ACB7, 0x5ABFCD, 0x59BFCD, 0x54C1CF, 0x47C4D3, 0x29CAD9, 0x00D0DF, 0x73EDFF, 0x73EDFF, 0x73EEFF,
4035 0x72EEFF, 0x70EFFF, 0x6EEFFF, 0x330600, 0x301517, 0x212A2D, 0x00474B, 0x006469, 0x007C82, 0x363033, 0x333236,
4036 0x263C41, 0x005056, 0x006A70, 0x008187, 0x415F66, 0x3F6068, 0x35656D, 0x146D76, 0x007F87, 0x009099, 0x518F9A,
4037 0x4F909A, 0x49929D, 0x3997A3, 0x00A0AC, 0x00ABB7, 0x64BFD7, 0x63BFCD, 0x5EC1CF, 0x54C4D3, 0x3ECAD9, 0x00D1E0,
4038 0x7AEDFF, 0x7AEDFF, 0x79EEFF, 0x78EEFF, 0x76EFFF, 0x74EFFF, 0x660B00, 0x651615, 0x602B2D, 0x563F44, 0x42545B,
4039 0x006B73, 0x673033, 0x663336, 0x623D41, 0x584C51, 0x445D64, 0x007179, 0x6C5F66, 0x6B6067, 0x67656C, 0x5E6D75,
4040 0x4D7982, 0x228791, 0x758F9A, 0x74909A, 0x71929D, 0x6997A3, 0x5A9FAB, 0x3EA9B6, 0x82BECD, 0x81BFCD, 0x7EC1CF,
4041 0x77C4D3, 0x6BCAD9, 0x57D1E1, 0x92EDFF, 0x92EDFF, 0x90EEFF, 0x8EEEFF, 0x8BEFFF, 0x88EFFF, 0x991100, 0x981612,
4042 0x962B2C, 0x904044, 0x87555B, 0x796A71, 0x9A3032, 0x993335, 0x963D40, 0x914C51, 0x885D64, 0x7A7078, 0x9D5F66,
4043 0x9C6067, 0x9A656C, 0x946D75, 0x8C7982, 0x7E8791, 0xA28F99, 0xA2909A, 0x9F929D, 0x9A97A3, 0x929FAB, 0x86A9B6,
4044 0xABBECD, 0xAABFCD, 0xA8C1CF, 0xA3C4D3, 0x9CCAD9, 0x91D1E1, 0xB6EDFF, 0xB5EDFF, 0xB4EEFF, 0xB0EEFF, 0xACEFFF,
4045 0xA6EFFF, 0xCC1600, 0xCB170B, 0xCA2B2B, 0xC64043, 0xC0555A, 0xB76A71, 0xCC3030, 0xCC3334, 0xCA3D3F, 0xC64C50,
4046 0xC15E64, 0xB87178, 0xCF5F65, 0xCE6067, 0xCC656C, 0xC96E75, 0xC37982, 0xBB8791, 0xD38F99, 0xD2909A, 0xD0929D,
4047 0xCD98A2, 0xC79FAB, 0xBFA9B6, 0xD9BECC, 0xD8BFCD, 0xD7C1CF, 0xD3C4D3, 0xCECAD9, 0xC6D1E1, 0xE0EEFF, 0xE0EEFF,
4048 0xDDEEFF, 0xD9EEFF, 0xD3EFFF, 0xCBEFFF, 0xFE1C00, 0xFE1A00, 0xFD2B28, 0xFA4042, 0xF6555A, 0xF06A71, 0xFF3331,
4049 0xFF3332, 0xFE3D3E, 0xFB4C4F, 0xF75E63, 0xF07178, 0xFF6569, 0xFF656A, 0xFF666C, 0xFD6E74, 0xF87981, 0xF28791,
4050 0xFF949C, 0xFF949D, 0xFF959E, 0xFF99A2, 0xFC9FAA, 0xF6A9B5, 0xFFBECA, 0xFFBFCA, 0xFFC0CD, 0xFFC4D1, 0xFFCAD8,
4051 0xFBD1E1, 0xFFE4F2, 0xFFE5F3, 0xFFE6F5, 0xFFEAF9, 0xFDEFFF, 0xF4F0FF> csWStritanoptia;
4052 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4053 /** @class csWSprotanopiaAlt
4054 @ingroup cs
4055 @extends csWS_tpl
4056 The "web safe" color pallet of 216 colors as seen by someone with Protanopia.
4057 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSprotanopia. */
4058 typedef csWS_tpl<0x000000, 0x000E33, 0x001D66, 0x002B99, 0x003ACC, 0x0048FF, 0x422F00, 0x303133, 0x003566, 0x003D99, 0x0047CC,
4059 0x0053FF, 0x845D00, 0x7E5E33, 0x606266, 0x266699, 0x006BCC, 0x0072FF, 0xC68C00, 0xC38D33, 0xB38F66, 0x909399,
4060 0x6896CC, 0x009BFF, 0xFFBB00, 0xFFBB32, 0xFCBD66, 0xE6C099, 0xC0C4CC, 0x9DC7FF, 0xFFE900, 0xFFEA31, 0xFFEB65,
4061 0xFFED99, 0xFFF1CC, 0xF0F5FF, 0x1A1202, 0x001633, 0x002166, 0x002E99, 0x003BCC, 0x0049FF, 0x453100, 0x333333,
4062 0x003766, 0x003F99, 0x0048CC, 0x0053FF, 0x855E00, 0x7F5F33, 0x616366, 0x2A6699, 0x006CCC, 0x0072FF, 0xC78C00,
4063 0xC38D33, 0xB48F66, 0x919499, 0x6997CC, 0x009BFF, 0xFFBB00, 0xFFBB32, 0xFCBD66, 0xE6C099, 0xC0C5CC, 0x9DC8FF,
4064 0xFFEA00, 0xFFEA31, 0xFFEB65, 0xFFED99, 0xFFF1CC, 0xF0F6FF, 0x332405, 0x1D2733, 0x002D66, 0x003699, 0x0042CC,
4065 0x004EFF, 0x4F3804, 0x413A33, 0x003E66, 0x004499, 0x004DCC, 0x0057FF, 0x8A6100, 0x846233, 0x666666, 0x376999,
4066 0x006ECC, 0x0075FF, 0xC98E00, 0xC68F33, 0xB79166, 0x939599, 0x6E99CC, 0x009DFF, 0xFFBC00, 0xFFBD32, 0xFEBE66,
4067 0xE8C199, 0xC2C6CC, 0xA0C9FF, 0xFFEA00, 0xFFEB32, 0xFFEC65, 0xFFEE99, 0xFFF2CC, 0xF2F6FF, 0x4D3607, 0x3E3833,
4068 0x003C66, 0x004399, 0x004CCC, 0x0057FF, 0x604407, 0x564533, 0x2E4966, 0x004E99, 0x0056CC, 0x005FFF, 0x926703,
4069 0x8D6833, 0x726C66, 0x496F99, 0x0074CC, 0x007AFF, 0xCE9200, 0xCB9233, 0xBD9566, 0x999999, 0x769CCC, 0x00A0FF,
4070 0xFFBF00, 0xFFBF32, 0xFFC166, 0xEDC499, 0xC6C8CC, 0xA5CBFF, 0xFFEC00, 0xFFED32, 0xFFEE66, 0xFFF099, 0xFFF4CC,
4071 0xF4F8FF, 0x66490A, 0x5E4A33, 0x3A4E66, 0x005299, 0x0059CC, 0x0062FF, 0x745209, 0x6D5333, 0x4D5766, 0x005B99,
4072 0x0061CC, 0x0069FF, 0x9E7008, 0x9A7133, 0x837466, 0x5E7899, 0x007CCC, 0x0081FF, 0xD69700, 0xD39833, 0xC59A66,
4073 0xA59E99, 0x82A1CC, 0x16A5FF, 0xFFC300, 0xFFC333, 0xFFC466, 0xF3C799, 0xCCCCCC, 0xACCFFF, 0xFFEF00, 0xFFEF32,
4074 0xFFF166, 0xFFF399, 0xFFF6CC, 0xF9FBFF, 0x805B0C, 0x7A5C34, 0x5C6066, 0x006399, 0x0069CC, 0x0070FF, 0x8A620C,
4075 0x856334, 0x676766, 0x396A99, 0x006FCC, 0x0076FF, 0xAE7B0B, 0xAA7C34, 0x967E66, 0x738299, 0x2786CC, 0x008BFF,
4076 0xE19F08, 0xDE9F33, 0xD1A166, 0xB3A599, 0x90A9CC, 0x4FACFF, 0xFFC800, 0xFFC833, 0xFFCA66, 0xFCCC99, 0xD7D1CC,
4077 0xB7D4FF, 0xFFF300, 0xFFF332, 0xFFF466, 0xFFF799, 0xFFFACC, 0xFFFFFF> csWSprotanopiaAlt;
4078 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4079 /** @class csWSdeutanopiaAlt
4080 @ingroup cs
4081 @extends csWS_tpl
4082 The "web safe" color pallet of 216 colors as seen by someone with Deutanopia.
4083 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSdeutanopia. */
4084 typedef csWS_tpl<0x000000, 0x001433, 0x002866, 0x003C99, 0x0050CB, 0x0064FE, 0x3A2A0B, 0x2C2F33, 0x003866, 0x004699, 0x0057CB,
4085 0x0069FE, 0x755316, 0x6F5635, 0x585D67, 0x226599, 0x0070CC, 0x007EFF, 0xAF7D20, 0xAC7E39, 0x9E8468, 0x848C9A,
4086 0x5F93CC, 0x009DFF, 0xEAA72B, 0xE8A83F, 0xDFAB6B, 0xCBB29B, 0xAFBBCD, 0x8FC2FF, 0xFFD036, 0xFFD146, 0xFFD46E,
4087 0xFFD99D, 0xF7E1CE, 0xDBE9FF, 0x231800, 0x001F33, 0x002D66, 0x003F99, 0x0052CB, 0x0065FE, 0x412E09, 0x333333,
4088 0x003C66, 0x004999, 0x0059CB, 0x006BFE, 0x775515, 0x725735, 0x5B5F66, 0x2C6799, 0x0072CC, 0x007FFE, 0xB17E20,
4089 0xAE7F39, 0xA08568, 0x858D9A, 0x6294CC, 0x009EFF, 0xEBA72B, 0xE9A83F, 0xE0AC6B, 0xCCB39B, 0xB0BBCD, 0x91C2FF,
4090 0xFFD136, 0xFFD246, 0xFFD46E, 0xFFDA9D, 0xF8E2CE, 0xDCEAFF, 0x453000, 0x393532, 0x003E65, 0x004B98, 0x005ACB,
4091 0x006CFE, 0x563C00, 0x4D4032, 0x2C4865, 0x005398, 0x0061CB, 0x0071FE, 0x825C11, 0x7D5E34, 0x666666, 0x446D99,
4092 0x0077CC, 0x0084FE, 0xB7821E, 0xB48338, 0xA78968, 0x8C9199, 0x6C98CC, 0x00A1FF, 0xEFAA2A, 0xEDAB3E, 0xE4AF6A,
4093 0xD2B69B, 0xB5BECD, 0x97C5FF, 0xFFD335, 0xFFD445, 0xFFD66E, 0xFFDC9D, 0xFCE4CE, 0xE0ECFF, 0x684900, 0x624B2F,
4094 0x485364, 0x005C98, 0x0069CB, 0x0077FE, 0x725000, 0x6D5230, 0x545A64, 0x106398, 0x006ECB, 0x007CFE, 0x946800,
4095 0x906A32, 0x7E7165, 0x617898, 0x0081CB, 0x008DFE, 0xC38A1A, 0xC08B37, 0xB49067, 0x999999, 0x7E9FCC, 0x38A8FF,
4096 0xF7B027, 0xF5B13D, 0xEDB46A, 0xDBBB9B, 0xBEC4CD, 0xA3CAFF, 0xFFD733, 0xFFD844, 0xFFDA6D, 0xFFE09D, 0xFFE7CE,
4097 0xE7F0FF, 0x8B6100, 0x87632C, 0x736A63, 0x537297, 0x007BCA, 0x0087FE, 0x926600, 0x8E682C, 0x7B6F63, 0x5E7697,
4098 0x007FCA, 0x008BFE, 0xAC7900, 0xA97A2F, 0x9A8064, 0x7F8897, 0x5790CB, 0x009AFE, 0xD4960E, 0xD19734, 0xC79B66,
4099 0xB0A398, 0x94ABCB, 0x68B2FE, 0xFFB822, 0xFFB93A, 0xFABC68, 0xEAC39A, 0xCCCCCC, 0xB3D2FF, 0xFFDE30, 0xFFDE42,
4100 0xFFE16C, 0xFFE69C, 0xFFEDCD, 0xF1F6FF, 0xAE7900, 0xAB7A26, 0x9D8061, 0x818996, 0x5B90CA, 0x009AFD, 0xB37D00,
4101 0xB07E27, 0xA38461, 0x878C96, 0x6494CA, 0x009DFD, 0xC78C00, 0xC58D2A, 0xB99162, 0x9F9A96, 0x83A1CA, 0x47AAFD,
4102 0xE9A400, 0xE7A52F, 0xDEA964, 0xCAB097, 0xAEB9CA, 0x8DC0FE, 0xFFC319, 0xFFC436, 0xFFC767, 0xFDCD99, 0xE2D6CB,
4103 0xC8DDFE, 0xFFE62B, 0xFFE73F, 0xFFE96B, 0xFFEE9B, 0xFFF5CD, 0xFFFFFF> csWSdeutanopiaAlt;
4104 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4105 /** @class csWStritanoptiaAlt
4106 @ingroup cs
4107 @extends csWS_tpl
4108 The "web safe" color pallet of 216 colors as seen by someone with Tritanoptia.
4109 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWStritanoptia. */
4110 typedef csWS_tpl<0x000000, 0x00191E, 0x00323D, 0x004B5B, 0x00647A, 0x007C98, 0x202E31, 0x113237, 0x00404A, 0x005463, 0x006A7F,
4111 0x00819C, 0x415C61, 0x3C5D63, 0x21646D, 0x00707E, 0x008093, 0x0093AC, 0x618A92, 0x5F8B93, 0x548F99, 0x3296A4,
4112 0x00A1B4, 0x00AFC7, 0x82B8C2, 0x80B8C3, 0x79BBC7, 0x69C0CF, 0x42C8DA, 0x00D3EA, 0xA2E6F3, 0xA1E6F3, 0x9CE8F6,
4113 0x91ECFC, 0x7DF2FF, 0x53FAFF, 0x340010, 0x2C1A1C, 0x00333A, 0x004B5A, 0x006479, 0x007D98, 0x392E2F, 0x333333,
4114 0x004147, 0x005462, 0x006A7E, 0x00819C, 0x4D5C5F, 0x4A5E62, 0x39646C, 0x00707D, 0x008093, 0x0093AB, 0x698A91,
4115 0x678B92, 0x5D8F98, 0x4296A3, 0x00A1B3, 0x00AFC6, 0x87B8C1, 0x85B8C2, 0x7FBBC6, 0x70C0CE, 0x4FC8DA, 0x00D3E9,
4116 0xA6E6F2, 0xA5E6F3, 0xA0E8F6, 0x95ECFC, 0x82F2FF, 0x5CFAFF, 0x670021, 0x651527, 0x583338, 0x364E52, 0x006674,
4117 0x007E94, 0x692C35, 0x673139, 0x5B4244, 0x3C565B, 0x006C7A, 0x008298, 0x725C5E, 0x705E60, 0x666666, 0x507278,
4118 0x00818F, 0x0094A8, 0x838B8D, 0x818C8E, 0x7B9094, 0x6B97A0, 0x46A2B0, 0x00B0C4, 0x9AB8BF, 0x99B9C0, 0x94BCC4,
4119 0x88C1CC, 0x71C9D8, 0x3CD4E7, 0xB5E6F0, 0xB4E7F1, 0xB0E9F4, 0xA7ECFA, 0x97F3FF, 0x7AFBFF, 0x9B0031, 0x990035,
4120 0x933041, 0x854D54, 0x686969, 0x1C808C, 0x9C293F, 0x9A2E42, 0x943F4C, 0x86565B, 0x6B6E6F, 0x288591, 0xA15B63,
4121 0xA05D65, 0x9A656A, 0x8D7275, 0x758387, 0x4496A2, 0xAC8B8E, 0xAA8C8F, 0xA59092, 0x999999, 0x86A4AA, 0x63B2BF,
4122 0xBABABA, 0xB9BABB, 0xB5BDBF, 0xADC2C7, 0x9DCAD3, 0x83D5E3, 0xD0E7EC, 0xCFE8ED, 0xCBEAF0, 0xC4EDF6, 0xB7F3FF,
4123 0xA3FCFF, 0xCE0042, 0xCD0044, 0xC92A4E, 0xC04A5D, 0xB1676F, 0x978284, 0xCF214C, 0xCE284E, 0xCA3C56, 0xC15463,
4124 0xB26D75, 0x988788, 0xD3596B, 0xD25B6C, 0xCE6371, 0xC5717B, 0xB68388, 0x9E9899, 0xDA8A92, 0xD98B93, 0xD58F97,
4125 0xCD989D, 0xBFA5A7, 0xAAB4B6, 0xE5B9BD, 0xE4BABE, 0xE0BDC0, 0xD9C3C5, 0xCCCCCC, 0xBBD6DD, 0xF3E8E9, 0xF2E9E9,
4126 0xEFEBEB, 0xE9EFF0, 0xDFF5FA, 0xD0FDFF, 0xFF0052, 0xFF0054, 0xFE205B, 0xF84668, 0xED6478, 0xDD818B, 0xFF095A,
4127 0xFF1B5C, 0xFF3662, 0xF8506E, 0xEE6B7D, 0xDE858F, 0xFF5674, 0xFF5875, 0xFF607A, 0xFB6F83, 0xF1818F, 0xE1979E,
4128 0xFF8898, 0xFF8999, 0xFF8E9C, 0xFF96A3, 0xF7A3AC, 0xE8B3B8, 0xFFB8C1, 0xFFB9C2, 0xFFBCC4, 0xFFC2C9, 0xFFCBD0,
4129 0xF2D7D9, 0xFFE7EC, 0xFFE8ED, 0xFFEAEE, 0xFFEFF2, 0xFFF6F7, 0xFFFFFF> csWStritanoptiaAlt;
4130 //@}
4131 //========================================================================================================================================================
4132 /** @name Interesting Pallets */
4133 //@{
4134 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4135 /** @class csFPcircular12
4136 @ingroup cs
4137 @extends csFP_tpl */
4138 typedef csFP_tpl<0xFF0000, 0xFF7D00, 0xFFFF00, 0x7DFF00, 0x66CC00, 0x66FFB2, 0x00FFFF,
4139 0x007DFF, 0x0000FF, 0x7D00FF, 0xFF00FF, 0xFF007D> csFPcircular12;
4140 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4141 /** @class csFPcircular24
4142 @ingroup cs
4143 @extends csFP_tpl */
4144 typedef csFP_tpl<0xFF0000, 0xFF3F00, 0xFF7D00, 0xFFBE00, 0xFFE100, 0xFFFF00, 0x7DFF00, 0x7DCC00, 0x009600, 0x00BE00, 0x00FF5A,
4145 0x00FFBE, 0x00FFFF, 0x00BEFF, 0x007DFF, 0x003FFF, 0x0000FF, 0x3F00FF, 0x7D00FF, 0xBE00FF, 0xFF00FF, 0xFF00BE,
4146 0xFF007D, 0xFF003F> csFPcircular24;
4147 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4148 /** @class csFPblAqGrYeOrReVi200
4149 @ingroup cs
4150 @extends csFP_tpl */
4151 typedef csFP_tpl<0x0000FF, 0x0008FF, 0x000FFF, 0x0017FF, 0x001FFF, 0x0027FF, 0x002EFF, 0x0036FF, 0x003EFF, 0x0046FF, 0x004DFF,
4152 0x0055FF, 0x005DFF, 0x0064FF, 0x006CFF, 0x0074FF, 0x007CFF, 0x0083FF, 0x008BFF, 0x0093FF, 0x009BFF, 0x00A2FF,
4153 0x00AAFF, 0x00B2FF, 0x00B9FF, 0x00C1FF, 0x00C9FF, 0x00D1FF, 0x00D8FF, 0x00E0FF, 0x00E8FF, 0x00F0FF, 0x00F7FF,
4154 0x00FFFF, 0x00FDF8, 0x00FAF0, 0x01F8E9, 0x01F6E2, 0x01F3DB, 0x01F1D3, 0x02EFCC, 0x02EDC5, 0x02EABE, 0x02E8B6,
4155 0x03E6AF, 0x03E3A8, 0x03E1A0, 0x03DF99, 0x04DC92, 0x04DA8B, 0x04D883, 0x04D67C, 0x05D375, 0x05D16E, 0x05CF66,
4156 0x05CC5F, 0x06CA58, 0x06C850, 0x06C549, 0x06C342, 0x07C13B, 0x07BF33, 0x07BC2C, 0x07BA25, 0x08B81E, 0x08B516,
4157 0x08B30F, 0x0FB50F, 0x17B70E, 0x1EBA0E, 0x25BC0D, 0x2CBE0D, 0x34C00C, 0x3BC30C, 0x42C50B, 0x49C70B, 0x51C90B,
4158 0x58CC0A, 0x5FCE0A, 0x66D009, 0x6ED209, 0x75D508, 0x7CD708, 0x84D908, 0x8BDB07, 0x92DD07, 0x99E006, 0xA1E206,
4159 0xA8E405, 0xAFE605, 0xB6E904, 0xBEEB04, 0xC5ED04, 0xCCEF03, 0xD3F203, 0xDBF402, 0xE2F602, 0xE9F801, 0xF0FB01,
4160 0xF8FD00, 0xFFFF00, 0xFFFC00, 0xFFFA00, 0xFFF700, 0xFFF400, 0xFFF100, 0xFFEF00, 0xFFEC00, 0xFFE900, 0xFFE600,
4161 0xFFE400, 0xFFE100, 0xFFDE00, 0xFFDC00, 0xFFD900, 0xFFD600, 0xFFD300, 0xFFD100, 0xFFCE00, 0xFFCB00, 0xFFC800,
4162 0xFFC600, 0xFFC300, 0xFFC000, 0xFFBE00, 0xFFBB00, 0xFFB800, 0xFFB500, 0xFFB300, 0xFFB000, 0xFFAD00, 0xFFAA00,
4163 0xFFA800, 0xFFA500, 0xFFA000, 0xFF9B00, 0xFF9600, 0xFF9100, 0xFF8C00, 0xFF8700, 0xFF8200, 0xFF7D00, 0xFF7800,
4164 0xFF7300, 0xFF6E00, 0xFF6900, 0xFF6400, 0xFF5F00, 0xFF5A00, 0xFF5500, 0xFF5000, 0xFF4B00, 0xFF4600, 0xFF4100,
4165 0xFF3C00, 0xFF3700, 0xFF3200, 0xFF2D00, 0xFF2800, 0xFF2300, 0xFF1E00, 0xFF1900, 0xFF1400, 0xFF0F00, 0xFF0A00,
4166 0xFF0500, 0xFF0000, 0xFA0004, 0xF50008, 0xF0000C, 0xEB0010, 0xE60015, 0xE00019, 0xDB001D, 0xD60021, 0xD10025,
4167 0xCC0029, 0xC7002D, 0xC20031, 0xBD0036, 0xB8003A, 0xB3003E, 0xAE0042, 0xA80046, 0xA3004A, 0x9E004E, 0x990052,
4168 0x940057, 0x8F005B, 0x8A005F, 0x850063, 0x800067, 0x7B006B, 0x76006F, 0x700073, 0x6B0078, 0x66007C, 0x610080,
4169 0x5C0084, 0x570088> csFPblAqGrYeOrReVi200;
4170 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4171 /** @class csFPcmoceanAlgae
4172 @ingroup cs
4173 @extends csFP_tpl */
4174 typedef csFP_tpl<0xD7F9D0, 0xD6F8CE, 0xD4F7CD, 0xD3F6CB, 0xD2F5CA, 0xD1F4C8, 0xCFF4C7, 0xCEF3C5, 0xCDF2C4, 0xCCF1C3, 0xCAF0C1,
4175 0xC9EFC0, 0xC8EEBE, 0xC7EDBD, 0xC5ECBB, 0xC4EBBA, 0xC3EBB9, 0xC2EAB7, 0xC0E9B6, 0xBFE8B4, 0xBEE7B3, 0xBDE6B1,
4176 0xBBE5B0, 0xBAE4AF, 0xB9E4AD, 0xB8E3AC, 0xB6E2AB, 0xB5E1A9, 0xB4E0A8, 0xB2DFA6, 0xB1DEA5, 0xB0DEA4, 0xAFDDA2,
4177 0xADDCA1, 0xACDBA0, 0xABDA9E, 0xAADA9D, 0xA8D99C, 0xA7D89A, 0xA6D799, 0xA4D698, 0xA3D596, 0xA2D595, 0xA0D494,
4178 0x9FD392, 0x9ED291, 0x9DD190, 0x9BD18F, 0x9AD08D, 0x99CF8C, 0x97CE8B, 0x96CD8A, 0x95CD88, 0x93CC87, 0x92CB86,
4179 0x91CA85, 0x8FCA83, 0x8EC982, 0x8CC881, 0x8BC780, 0x8AC77E, 0x88C67D, 0x87C57C, 0x85C47B, 0x84C47A, 0x83C379,
4180 0x81C277, 0x80C176, 0x7EC175, 0x7DC074, 0x7BBF73, 0x7ABE72, 0x78BE71, 0x77BD6F, 0x75BC6E, 0x74BB6D, 0x72BB6C,
4181 0x71BA6B, 0x6FB96A, 0x6EB969, 0x6CB868, 0x6BB767, 0x69B666, 0x67B665, 0x66B564, 0x64B463, 0x62B462, 0x61B361,
4182 0x5FB260, 0x5DB25F, 0x5BB15E, 0x5AB05D, 0x58AF5D, 0x56AF5C, 0x54AE5B, 0x52AD5A, 0x50AD59, 0x4EAC59, 0x4CAB58,
4183 0x4AAB57, 0x48AA57, 0x46A956, 0x44A855, 0x42A855, 0x3FA754, 0x3DA654, 0x3BA654, 0x39A553, 0x37A453, 0x34A353,
4184 0x32A352, 0x30A252, 0x2EA152, 0x2CA052, 0x2AA052, 0x289F51, 0x269E51, 0x249D51, 0x229C51, 0x209C51, 0x1E9B51,
4185 0x1C9A51, 0x1B9951, 0x199851, 0x189750, 0x169650, 0x159650, 0x139550, 0x129450, 0x109350, 0x0F9250, 0x0E9150,
4186 0x0D904F, 0x0C8F4F, 0x0B8F4F, 0x0A8E4F, 0x098D4F, 0x098C4F, 0x088B4E, 0x088A4E, 0x07894E, 0x07884E, 0x07874D,
4187 0x07864D, 0x07864D, 0x07854D, 0x07844D, 0x07834C, 0x07824C, 0x08814C, 0x08804B, 0x087F4B, 0x097E4B, 0x097D4B,
4188 0x0A7C4A, 0x0A7C4A, 0x0B7B4A, 0x0B7A49, 0x0C7949, 0x0C7849, 0x0D7748, 0x0D7648, 0x0E7548, 0x0E7447, 0x0F7347,
4189 0x0F7347, 0x107246, 0x107146, 0x117045, 0x116F45, 0x126E45, 0x126D44, 0x126C44, 0x136B43, 0x136A43, 0x146A43,
4190 0x146942, 0x146842, 0x156741, 0x156641, 0x156540, 0x166440, 0x166340, 0x16623F, 0x17623F, 0x17613E, 0x17603E,
4191 0x175F3D, 0x185E3D, 0x185D3C, 0x185C3C, 0x185B3B, 0x185B3B, 0x195A3A, 0x19593A, 0x195839, 0x195739, 0x195638,
4192 0x195538, 0x195437, 0x195437, 0x1A5336, 0x1A5235, 0x1A5135, 0x1A5034, 0x1A4F34, 0x1A4E33, 0x1A4D33, 0x1A4D32,
4193 0x1A4C32, 0x1A4B31, 0x1A4A30, 0x1A4930, 0x1A482F, 0x1A472F, 0x1A472E, 0x1A462E, 0x1A452D, 0x1A442C, 0x1A432C,
4194 0x19422B, 0x19412B, 0x19402A, 0x194029, 0x193F29, 0x193E28, 0x193D27, 0x193C27, 0x183B26, 0x183B26, 0x183A25,
4195 0x183924, 0x183824, 0x183723, 0x173622, 0x173522, 0x173521, 0x173420, 0x173320, 0x16321F, 0x16311E, 0x16301E,
4196 0x162F1D, 0x152F1C, 0x152E1C, 0x152D1B, 0x142C1A, 0x142B1A, 0x142A19, 0x142918, 0x132918, 0x132817, 0x132716,
4197 0x122616, 0x122515, 0x122414> csFPcmoceanAlgae;
4198 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4199 /** @class csFPcmoceanAmp
4200 @ingroup cs
4201 @extends csFP_tpl */
4202 typedef csFP_tpl<0xF1EDEC, 0xF1ECEB, 0xF0EBE9, 0xEFE9E8, 0xEFE8E7, 0xEEE7E5, 0xEEE6E4, 0xEDE5E3, 0xEDE3E1, 0xECE2E0, 0xECE1DE,
4203 0xEBE0DD, 0xEBDFDC, 0xEADDDA, 0xEADCD9, 0xE9DBD7, 0xE9DAD6, 0xE9D9D4, 0xE8D8D3, 0xE8D6D2, 0xE7D5D0, 0xE7D4CF,
4204 0xE6D3CD, 0xE6D2CC, 0xE6D1CA, 0xE5CFC9, 0xE5CEC8, 0xE4CDC6, 0xE4CCC5, 0xE4CBC3, 0xE3C9C2, 0xE3C8C0, 0xE2C7BF,
4205 0xE2C6BD, 0xE2C5BC, 0xE1C4BB, 0xE1C3B9, 0xE1C1B8, 0xE0C0B6, 0xE0BFB5, 0xDFBEB3, 0xDFBDB2, 0xDFBCB0, 0xDEBAAF,
4206 0xDEB9AE, 0xDEB8AC, 0xDDB7AB, 0xDDB6A9, 0xDDB5A8, 0xDCB4A6, 0xDCB2A5, 0xDCB1A3, 0xDBB0A2, 0xDBAFA1, 0xDBAE9F,
4207 0xDAAD9E, 0xDAAC9C, 0xD9AA9B, 0xD9A999, 0xD9A898, 0xD8A796, 0xD8A695, 0xD8A594, 0xD7A492, 0xD7A291, 0xD7A18F,
4208 0xD6A08E, 0xD69F8C, 0xD69E8B, 0xD59D89, 0xD59C88, 0xD59A87, 0xD49985, 0xD49884, 0xD49782, 0xD39681, 0xD3957F,
4209 0xD3947E, 0xD2927D, 0xD2917B, 0xD2907A, 0xD18F78, 0xD18E77, 0xD18D76, 0xD08C74, 0xD08B73, 0xD08971, 0xCF8870,
4210 0xCF876F, 0xCF866D, 0xCE856C, 0xCE846A, 0xCD8369, 0xCD8168, 0xCD8066, 0xCC7F65, 0xCC7E64, 0xCC7D62, 0xCB7C61,
4211 0xCB7A60, 0xCB795E, 0xCA785D, 0xCA775B, 0xC9765A, 0xC97559, 0xC97457, 0xC87256, 0xC87155, 0xC87054, 0xC76F52,
4212 0xC76E51, 0xC66D50, 0xC66B4E, 0xC66A4D, 0xC5694C, 0xC5684A, 0xC56749, 0xC46548, 0xC46447, 0xC36346, 0xC36244,
4213 0xC36143, 0xC25F42, 0xC25E41, 0xC15D3F, 0xC15C3E, 0xC05B3D, 0xC0593C, 0xC0583B, 0xBF573A, 0xBF5639, 0xBE5438,
4214 0xBE5336, 0xBD5235, 0xBD5134, 0xBD4F33, 0xBC4E32, 0xBC4D31, 0xBB4C30, 0xBB4A30, 0xBA492F, 0xBA482E, 0xB9462D,
4215 0xB9452C, 0xB8442B, 0xB8422B, 0xB7412A, 0xB74029, 0xB63F29, 0xB53D28, 0xB53C27, 0xB43B27, 0xB43926, 0xB33826,
4216 0xB23726, 0xB23525, 0xB13425, 0xB03325, 0xB03125, 0xAF3024, 0xAE2F24, 0xAE2D24, 0xAD2C24, 0xAC2B24, 0xAB2A24,
4217 0xAA2824, 0xAA2724, 0xA92624, 0xA82524, 0xA72424, 0xA62225, 0xA52125, 0xA42025, 0xA31F25, 0xA21E25, 0xA11D25,
4218 0xA01C26, 0x9F1B26, 0x9E1A26, 0x9D1926, 0x9C1827, 0x9B1727, 0x9A1627, 0x991527, 0x981527, 0x971428, 0x951328,
4219 0x941328, 0x931228, 0x921128, 0x911129, 0x901029, 0x8E1029, 0x8D1029, 0x8C0F29, 0x8B0F29, 0x890F29, 0x880F29,
4220 0x870E29, 0x850E29, 0x840E29, 0x830E29, 0x810E29, 0x800E29, 0x7F0E29, 0x7D0E29, 0x7C0E29, 0x7B0E29, 0x790E29,
4221 0x780E28, 0x770E28, 0x750E28, 0x740E28, 0x730E27, 0x710E27, 0x700E27, 0x6F0E26, 0x6D0E26, 0x6C0F26, 0x6B0F25,
4222 0x690F25, 0x680F25, 0x670F24, 0x650F24, 0x640E23, 0x630E23, 0x610E22, 0x600E22, 0x5F0E21, 0x5D0E21, 0x5C0E21,
4223 0x5B0E20, 0x5A0E1F, 0x580E1F, 0x570E1E, 0x560E1E, 0x540D1D, 0x530D1D, 0x520D1C, 0x510D1C, 0x4F0D1B, 0x4E0D1A,
4224 0x4D0C1A, 0x4B0C19, 0x4A0C19, 0x490C18, 0x480B17, 0x460B17, 0x450B16, 0x440B16, 0x430A15, 0x410A14, 0x400A14,
4225 0x3F0A13, 0x3D0912, 0x3C0912> csFPcmoceanAmp;
4226 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4227 /** @class csFPcmoceanBalance
4228 @ingroup cs
4229 @extends csFP_tpl */
4230 typedef csFP_tpl<0x181C43, 0x191E46, 0x1A1F49, 0x1B214C, 0x1C224F, 0x1D2352, 0x1E2555, 0x1F2658, 0x20275B, 0x21295F, 0x212A62,
4231 0x222B65, 0x232D69, 0x242E6C, 0x252F6F, 0x253073, 0x263276, 0x27337A, 0x27347D, 0x283681, 0x283784, 0x293888,
4232 0x293A8C, 0x293B8F, 0x293C93, 0x293E97, 0x293F9A, 0x29409E, 0x2942A2, 0x2843A5, 0x2745A9, 0x2647AC, 0x2548B0,
4233 0x234AB3, 0x214CB6, 0x1F4EB8, 0x1C50BA, 0x1952BC, 0x1655BD, 0x1357BE, 0x1059BE, 0x0D5BBE, 0x0C5EBE, 0x0A60BE,
4234 0x0A62BE, 0x0A64BE, 0x0B66BD, 0x0D68BD, 0x0F6ABD, 0x116CBC, 0x136EBC, 0x1670BC, 0x1972BB, 0x1B74BB, 0x1E76BB,
4235 0x2178BB, 0x237ABA, 0x267BBA, 0x297DBA, 0x2B7FBA, 0x2E81BA, 0x3083BA, 0x3384BA, 0x3686BA, 0x3888BA, 0x3B89BA,
4236 0x3E8BBA, 0x408DBA, 0x438FBA, 0x4690BA, 0x4892BA, 0x4B94BA, 0x4E95BA, 0x5197BA, 0x5399BA, 0x569ABB, 0x599CBB,
4237 0x5C9DBB, 0x5F9FBB, 0x62A0BB, 0x65A2BC, 0x68A4BC, 0x6BA5BC, 0x6EA7BD, 0x71A8BD, 0x75AABE, 0x78ABBE, 0x7BACBF,
4238 0x7EAEBF, 0x81AFC0, 0x85B1C0, 0x88B2C1, 0x8BB4C2, 0x8EB5C3, 0x91B7C3, 0x94B8C4, 0x98BAC5, 0x9BBBC6, 0x9EBCC7,
4239 0xA1BEC8, 0xA4BFC9, 0xA7C1CA, 0xAAC2CB, 0xADC4CC, 0xB0C5CD, 0xB3C7CE, 0xB6C9CF, 0xB9CAD0, 0xBCCCD2, 0xBFCDD3,
4240 0xC1CFD4, 0xC4D0D5, 0xC7D2D7, 0xCAD4D8, 0xCDD5D9, 0xD0D7DA, 0xD3D9DC, 0xD5DADD, 0xD8DCDE, 0xDBDEE0, 0xDEE0E1,
4241 0xE1E1E3, 0xE3E3E4, 0xE6E5E6, 0xE9E7E7, 0xEBE9E9, 0xEEEAEA, 0xF1ECEC, 0xF1ECEB, 0xF0EAE9, 0xEFE8E6, 0xEEE5E3,
4242 0xEDE3E0, 0xECE0DE, 0xEBDEDB, 0xEADCD8, 0xE9D9D5, 0xE8D7D2, 0xE7D5CF, 0xE6D2CD, 0xE5D0CA, 0xE5CEC7, 0xE4CBC4,
4243 0xE3C9C1, 0xE2C7BE, 0xE1C4BB, 0xE1C2B8, 0xE0C0B5, 0xDFBDB2, 0xDFBBB0, 0xDEB9AD, 0xDDB6AA, 0xDCB4A7, 0xDCB2A4,
4244 0xDBAFA1, 0xDAAD9E, 0xDAAB9B, 0xD9A998, 0xD8A696, 0xD8A493, 0xD7A290, 0xD69F8D, 0xD69D8A, 0xD59B87, 0xD49984,
4245 0xD39681, 0xD3947F, 0xD2927C, 0xD18F79, 0xD18D76, 0xD08B73, 0xCF8970, 0xCF866E, 0xCE846B, 0xCD8268, 0xCD7F65,
4246 0xCC7D63, 0xCB7B60, 0xCA795D, 0xCA765B, 0xC97458, 0xC87255, 0xC76F53, 0xC76D50, 0xC66B4D, 0xC5684B, 0xC46648,
4247 0xC36346, 0xC36143, 0xC25F41, 0xC15C3F, 0xC05A3C, 0xBF573A, 0xBE5538, 0xBE5236, 0xBD5034, 0xBC4D32, 0xBB4B30,
4248 0xBA482E, 0xB9452C, 0xB8432B, 0xB74029, 0xB63D28, 0xB43B27, 0xB33826, 0xB23525, 0xB13325, 0xAF3024, 0xAE2E24,
4249 0xAC2B24, 0xAB2924, 0xA92624, 0xA72424, 0xA52125, 0xA31F25, 0xA11D25, 0x9F1B26, 0x9D1926, 0x9B1727, 0x991627,
4250 0x971428, 0x941328, 0x921228, 0x901029, 0x8D1029, 0x8B0F29, 0x880F29, 0x860E29, 0x830E29, 0x800E29, 0x7E0E29,
4251 0x7B0E29, 0x780E28, 0x760E28, 0x730E27, 0x700E27, 0x6D0E26, 0x6B0F25, 0x680F25, 0x650F24, 0x630E23, 0x600E22,
4252 0x5E0E21, 0x5B0E20, 0x580E1F, 0x560E1E, 0x530D1D, 0x510D1C, 0x4E0D1B, 0x4B0C19, 0x490C18, 0x460B17, 0x440B16,
4253 0x410A14, 0x3F0A13, 0x3C0912> csFPcmoceanBalance;
4254 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4255 /** @class csFPcmoceanCurl
4256 @ingroup cs
4257 @extends csFP_tpl */
4258 typedef csFP_tpl<0x151D44, 0x151F45, 0x162146, 0x162347, 0x172548, 0x172749, 0x18294A, 0x182B4B, 0x182D4C, 0x192F4D, 0x19314F,
4259 0x1A3350, 0x1A3551, 0x1A3652, 0x1B3853, 0x1B3A54, 0x1B3C56, 0x1B3E57, 0x1C4058, 0x1C4259, 0x1C435A, 0x1C455B,
4260 0x1C475D, 0x1C495E, 0x1C4B5F, 0x1C4C60, 0x1C4E61, 0x1C5062, 0x1C5263, 0x1C5465, 0x1B5666, 0x1B5867, 0x1B5968,
4261 0x1A5B69, 0x1A5D6A, 0x1A5F6B, 0x19616C, 0x19636D, 0x18656E, 0x17666F, 0x176870, 0x166A71, 0x156C72, 0x146E73,
4262 0x147074, 0x137275, 0x127476, 0x127676, 0x117777, 0x117978, 0x117B79, 0x117D79, 0x117F7A, 0x12817B, 0x13837B,
4263 0x14847C, 0x16867C, 0x17887D, 0x1A8A7D, 0x1C8C7E, 0x1F8D7E, 0x228F7E, 0x25917F, 0x29937F, 0x2C947F, 0x309680,
4264 0x349880, 0x389981, 0x3B9B81, 0x3F9C81, 0x439E82, 0x479F82, 0x4BA183, 0x50A284, 0x54A484, 0x57A585, 0x5BA686,
4265 0x5FA887, 0x63A988, 0x67AB89, 0x6BAC8A, 0x6FAD8B, 0x72AF8C, 0x76B08D, 0x7AB18E, 0x7DB390, 0x81B491, 0x85B593,
4266 0x88B794, 0x8BB896, 0x8FBA97, 0x92BB99, 0x96BC9B, 0x99BE9D, 0x9CBF9F, 0xA0C0A0, 0xA3C2A2, 0xA6C3A4, 0xA9C5A6,
4267 0xACC6A9, 0xB0C8AB, 0xB3C9AD, 0xB6CBAF, 0xB9CCB2, 0xBCCEB4, 0xBFCFB6, 0xC2D1B9, 0xC5D2BB, 0xC8D4BE, 0xCBD5C0,
4268 0xCED7C3, 0xD1D8C5, 0xD3DAC8, 0xD6DCCB, 0xD9DDCD, 0xDCDFD0, 0xDFE1D3, 0xE2E2D6, 0xE4E4D8, 0xE7E6DB, 0xEAE8DE,
4269 0xEDEAE1, 0xF0EBE4, 0xF2EDE7, 0xF5EFEA, 0xF8F1ED, 0xFBF3F0, 0xFDF5F3, 0xFEF6F5, 0xFCF4F1, 0xFBF1EE, 0xFAEFEB,
4270 0xF9ECE7, 0xF8EAE4, 0xF6E7E1, 0xF5E5DD, 0xF4E2DA, 0xF3E0D6, 0xF2DDD3, 0xF2DBD0, 0xF1D8CC, 0xF0D6C9, 0xEFD3C6,
4271 0xEED1C3, 0xEDCFBF, 0xECCCBC, 0xECCAB9, 0xEBC7B6, 0xEAC5B3, 0xE9C2AF, 0xE9C0AC, 0xE8BDA9, 0xE7BBA6, 0xE7B8A3,
4272 0xE6B6A0, 0xE5B39D, 0xE5B19A, 0xE4AE98, 0xE3AC95, 0xE3A992, 0xE2A78F, 0xE1A48D, 0xE1A28A, 0xE09F88, 0xE09D85,
4273 0xDF9A83, 0xDE9880, 0xDE957E, 0xDD937C, 0xDC907A, 0xDB8E78, 0xDB8B76, 0xDA8974, 0xD98672, 0xD88471, 0xD7816F,
4274 0xD67F6E, 0xD67C6C, 0xD57A6B, 0xD4776A, 0xD37569, 0xD27268, 0xD07067, 0xCF6E66, 0xCE6B65, 0xCD6964, 0xCC6764,
4275 0xCA6463, 0xC96263, 0xC86062, 0xC65D62, 0xC55B61, 0xC35961, 0xC25761, 0xC05561, 0xBF5360, 0xBD5160, 0xBB4E60,
4276 0xBA4C60, 0xB84A60, 0xB64860, 0xB44660, 0xB34460, 0xB14260, 0xAF4160, 0xAD3F60, 0xAB3D60, 0xA93B60, 0xA73960,
4277 0xA53760, 0xA33660, 0xA13460, 0x9F3260, 0x9D3060, 0x9B2F60, 0x992D61, 0x972B61, 0x952A61, 0x922861, 0x902760,
4278 0x8E2560, 0x8C2460, 0x892260, 0x872160, 0x852060, 0x821F60, 0x801D5F, 0x7D1C5F, 0x7B1B5E, 0x781A5E, 0x76195D,
4279 0x73195D, 0x71185C, 0x6E175B, 0x6C175A, 0x691659, 0x661658, 0x641557, 0x611556, 0x5E1455, 0x5C1453, 0x591452,
4280 0x571350, 0x54134E, 0x51134D, 0x4F124B, 0x4C1249, 0x491247, 0x471145, 0x441143, 0x421041, 0x3F103F, 0x3D0F3D,
4281 0x3A0F3B, 0x380E39, 0x350D36> csFPcmoceanCurl;
4282 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4283 /** @class csFPcmoceanDeep
4284 @ingroup cs
4285 @extends csFP_tpl */
4286 typedef csFP_tpl<0xFDFECC, 0xFBFDCB, 0xF9FCCA, 0xF7FBC8, 0xF5FAC7, 0xF3FAC6, 0xF1F9C5, 0xEFF8C4, 0xEDF7C3, 0xEBF7C1, 0xE9F6C0,
4287 0xE7F5BF, 0xE5F4BE, 0xE3F4BD, 0xE1F3BC, 0xDFF2BB, 0xDDF2BA, 0xDBF1B9, 0xD9F0B8, 0xD7EFB7, 0xD4EFB6, 0xD2EEB5,
4288 0xD0EDB4, 0xCEECB3, 0xCCECB3, 0xCAEBB2, 0xC8EAB1, 0xC6EAB0, 0xC4E9AF, 0xC1E8AF, 0xBFE7AE, 0xBDE7AD, 0xBBE6AC,
4289 0xB9E5AC, 0xB7E5AB, 0xB5E4AA, 0xB2E3AA, 0xB0E2A9, 0xAEE2A9, 0xACE1A8, 0xAAE0A8, 0xA7E0A7, 0xA5DFA7, 0xA3DEA6,
4290 0xA1DDA6, 0x9FDDA5, 0x9CDCA5, 0x9ADBA5, 0x98DAA4, 0x96DAA4, 0x94D9A4, 0x92D8A4, 0x90D7A4, 0x8DD7A3, 0x8BD6A3,
4291 0x89D5A3, 0x87D4A3, 0x85D3A3, 0x83D3A3, 0x81D2A3, 0x7FD1A3, 0x7DD0A3, 0x7CCFA3, 0x7ACEA3, 0x78CEA3, 0x76CDA3,
4292 0x75CCA3, 0x73CBA3, 0x71CAA3, 0x70C9A3, 0x6EC8A3, 0x6DC7A3, 0x6BC6A3, 0x6AC5A4, 0x69C4A4, 0x67C3A4, 0x66C2A4,
4293 0x65C2A4, 0x64C1A4, 0x63C0A4, 0x62BFA4, 0x61BEA4, 0x60BDA4, 0x5FBCA4, 0x5EBBA4, 0x5DBAA4, 0x5CB9A4, 0x5BB8A4,
4294 0x5AB7A4, 0x5AB6A4, 0x59B4A4, 0x58B3A4, 0x58B2A4, 0x57B1A4, 0x56B0A4, 0x56AFA4, 0x55AEA3, 0x55ADA3, 0x54ACA3,
4295 0x53ABA3, 0x53AAA3, 0x52A9A3, 0x52A8A3, 0x51A7A3, 0x51A6A2, 0x51A5A2, 0x50A4A2, 0x50A3A2, 0x4FA2A2, 0x4FA1A2,
4296 0x4FA0A2, 0x4E9FA1, 0x4E9EA1, 0x4D9DA1, 0x4D9CA1, 0x4D9BA1, 0x4C9AA0, 0x4C99A0, 0x4B98A0, 0x4B97A0, 0x4B96A0,
4297 0x4A959F, 0x4A949F, 0x4A939F, 0x49929F, 0x49919E, 0x49909E, 0x488F9E, 0x488E9E, 0x488D9D, 0x478C9D, 0x478B9D,
4298 0x478A9D, 0x46899D, 0x46889C, 0x46879C, 0x45869C, 0x45859C, 0x45849B, 0x44839B, 0x44829B, 0x44819B, 0x44809B,
4299 0x437F9A, 0x437E9A, 0x437D9A, 0x427C9A, 0x427B99, 0x427A99, 0x427999, 0x417899, 0x417799, 0x417698, 0x407598,
4300 0x407498, 0x407398, 0x407298, 0x407197, 0x3F7097, 0x3F6F97, 0x3F6E97, 0x3F6D97, 0x3F6C96, 0x3E6B96, 0x3E6A96,
4301 0x3E6996, 0x3E6896, 0x3E6795, 0x3E6695, 0x3E6595, 0x3E6495, 0x3E6394, 0x3E6294, 0x3E6194, 0x3E6094, 0x3E5F93,
4302 0x3E5E93, 0x3E5C93, 0x3E5B93, 0x3E5A92, 0x3E5992, 0x3E5892, 0x3E5791, 0x3E5691, 0x3F5590, 0x3F5490, 0x3F538F,
4303 0x3F528F, 0x3F508E, 0x404F8D, 0x404E8D, 0x404D8C, 0x404C8B, 0x414B8A, 0x414A89, 0x414988, 0x414887, 0x414785,
4304 0x414684, 0x414583, 0x414481, 0x424380, 0x41427E, 0x41417D, 0x41407B, 0x41407A, 0x413F78, 0x413E76, 0x413D75,
4305 0x403C73, 0x403C71, 0x403B70, 0x403A6E, 0x3F396C, 0x3F386B, 0x3F3869, 0x3E3767, 0x3E3666, 0x3D3564, 0x3D3562,
4306 0x3D3461, 0x3C335F, 0x3C325D, 0x3B325C, 0x3B315A, 0x3A3058, 0x3A3057, 0x392F55, 0x392E54, 0x382D52, 0x382D51,
4307 0x372C4F, 0x362B4D, 0x362A4C, 0x352A4A, 0x352949, 0x342847, 0x342846, 0x332744, 0x322643, 0x322541, 0x312540,
4308 0x30243E, 0x30233D, 0x2F223B, 0x2F223A, 0x2E2139, 0x2D2037, 0x2D1F36, 0x2C1F34, 0x2B1E33, 0x2B1D32, 0x2A1C30,
4309 0x291C2F, 0x281B2D, 0x281A2C> csFPcmoceanDeep;
4310 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4311 /** @class csFPcmoceanDense
4312 @ingroup cs
4313 @extends csFP_tpl */
4314 typedef csFP_tpl<0xE6F1F1, 0xE4F0F0, 0xE3EFEF, 0xE1EEEF, 0xDFEDEE, 0xDDEDED, 0xDCECED, 0xDAEBEC, 0xD8EAEC, 0xD7E9EB, 0xD5E9EB,
4315 0xD3E8EA, 0xD1E7EA, 0xD0E6E9, 0xCEE5E9, 0xCCE4E8, 0xCBE4E8, 0xC9E3E8, 0xC7E2E7, 0xC6E1E7, 0xC4E0E6, 0xC2DFE6,
4316 0xC1DFE6, 0xBFDEE6, 0xBEDDE5, 0xBCDCE5, 0xBADBE5, 0xB9DAE4, 0xB7DAE4, 0xB6D9E4, 0xB4D8E4, 0xB2D7E4, 0xB1D6E3,
4317 0xAFD5E3, 0xAED4E3, 0xACD4E3, 0xABD3E3, 0xA9D2E3, 0xA8D1E3, 0xA6D0E3, 0xA5CFE2, 0xA3CEE2, 0xA2CEE2, 0xA0CDE2,
4318 0x9FCCE2, 0x9ECBE2, 0x9CCAE2, 0x9BC9E2, 0x9AC8E2, 0x98C7E2, 0x97C6E2, 0x96C5E2, 0x94C5E2, 0x93C4E2, 0x92C3E2,
4319 0x90C2E2, 0x8FC1E2, 0x8EC0E2, 0x8DBFE2, 0x8CBEE2, 0x8ABDE3, 0x89BCE3, 0x88BBE3, 0x87BAE3, 0x86B9E3, 0x85B8E3,
4320 0x84B7E3, 0x83B6E3, 0x82B5E3, 0x81B4E3, 0x80B3E3, 0x7FB2E3, 0x7FB1E4, 0x7EB0E4, 0x7DAFE4, 0x7CAEE4, 0x7BADE4,
4321 0x7BACE4, 0x7AABE4, 0x79AAE4, 0x79A9E4, 0x78A8E4, 0x78A7E4, 0x77A6E4, 0x77A5E4, 0x76A4E5, 0x76A3E5, 0x75A1E5,
4322 0x75A0E5, 0x759FE5, 0x759EE5, 0x749DE5, 0x749CE4, 0x749BE4, 0x749AE4, 0x7498E4, 0x7397E4, 0x7396E4, 0x7395E4,
4323 0x7394E4, 0x7393E3, 0x7391E3, 0x7390E3, 0x738FE3, 0x738EE2, 0x748DE2, 0x748BE2, 0x748AE2, 0x7489E1, 0x7488E1,
4324 0x7487E0, 0x7485E0, 0x7584DF, 0x7583DF, 0x7582DE, 0x7581DE, 0x757FDD, 0x757EDD, 0x767DDC, 0x767CDC, 0x767BDB,
4325 0x7679DA, 0x7678DA, 0x7777D9, 0x7776D8, 0x7775D7, 0x7773D7, 0x7772D6, 0x7871D5, 0x7870D4, 0x786FD3, 0x786ED2,
4326 0x786CD2, 0x786BD1, 0x786AD0, 0x7969CF, 0x7968CE, 0x7966CD, 0x7965CC, 0x7964CB, 0x7963CA, 0x7962C9, 0x7961C8,
4327 0x7960C7, 0x795EC5, 0x795DC4, 0x795CC3, 0x795BC2, 0x795AC1, 0x7959C0, 0x7958BF, 0x7957BD, 0x7956BC, 0x7954BB,
4328 0x7953BA, 0x7952B8, 0x7951B7, 0x7950B6, 0x794FB5, 0x784EB3, 0x784DB2, 0x784CB1, 0x784BAF, 0x784AAE, 0x7849AD,
4329 0x7748AB, 0x7747AA, 0x7746A9, 0x7745A7, 0x7743A6, 0x7642A5, 0x7641A3, 0x7640A2, 0x763FA0, 0x753E9F, 0x753D9D,
4330 0x753C9C, 0x743B9B, 0x743B99, 0x743A98, 0x733996, 0x733895, 0x733793, 0x723692, 0x723590, 0x72348F, 0x71338D,
4331 0x71328C, 0x70318A, 0x703088, 0x6F2F87, 0x6F2E85, 0x6E2D84, 0x6E2D82, 0x6D2C81, 0x6D2B7F, 0x6C2A7E, 0x6C297C,
4332 0x6B287A, 0x6B2879, 0x6A2777, 0x6A2675, 0x692574, 0x682472, 0x682471, 0x67236F, 0x67226D, 0x66216C, 0x65216A,
4333 0x652068, 0x641F67, 0x631F65, 0x621E63, 0x621D62, 0x611D60, 0x601C5E, 0x5F1B5D, 0x5F1B5B, 0x5E1A59, 0x5D1A58,
4334 0x5C1956, 0x5B1954, 0x5A1853, 0x5A1851, 0x591750, 0x58174E, 0x57164C, 0x56164B, 0x551649, 0x541548, 0x531546,
4335 0x521544, 0x511443, 0x501441, 0x4F1440, 0x4E133E, 0x4D133D, 0x4B133B, 0x4A133A, 0x491238, 0x481237, 0x471236,
4336 0x461234, 0x451133, 0x441132, 0x421130, 0x41112F, 0x40102E, 0x3F102D, 0x3E102B, 0x3C102A, 0x3B0F29, 0x3A0F28,
4337 0x390F27, 0x380F25, 0x360E24> csFPcmoceanDense;
4338 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4339 /** @class csFPcmoceanHaline
4340 @ingroup cs
4341 @extends csFP_tpl */
4342 typedef csFP_tpl<0x2A186C, 0x2A196E, 0x2A1971, 0x2B1973, 0x2B1975, 0x2C1A78, 0x2C1A7A, 0x2D1A7D, 0x2D1A7F, 0x2D1B82, 0x2E1B84,
4343 0x2E1B87, 0x2E1C89, 0x2E1C8C, 0x2E1C8E, 0x2E1D91, 0x2E1D93, 0x2E1E95, 0x2E1E98, 0x2E1F9A, 0x2D209C, 0x2D219D,
4344 0x2C229F, 0x2B24A0, 0x2A25A1, 0x2927A2, 0x2829A3, 0x262BA3, 0x252DA3, 0x242EA3, 0x2230A3, 0x2132A2, 0x2034A2,
4345 0x1E35A1, 0x1D37A1, 0x1C39A0, 0x1B3AA0, 0x193C9F, 0x183D9E, 0x173F9E, 0x16409D, 0x15419C, 0x14439C, 0x13449B,
4346 0x12459B, 0x11479A, 0x104899, 0x0F4999, 0x0F4A98, 0x0E4C97, 0x0D4D97, 0x0D4E96, 0x0D4F96, 0x0C5095, 0x0C5195,
4347 0x0C5294, 0x0C5394, 0x0C5493, 0x0D5593, 0x0D5692, 0x0D5792, 0x0E5891, 0x0E5991, 0x0F5A91, 0x0F5B90, 0x105C90,
4348 0x115D8F, 0x115E8F, 0x125F8F, 0x13608E, 0x14618E, 0x14628E, 0x15638E, 0x16638D, 0x17648D, 0x18658D, 0x18668C,
4349 0x19678C, 0x1A688C, 0x1B698C, 0x1C6A8C, 0x1D6B8B, 0x1D6B8B, 0x1E6C8B, 0x1F6D8B, 0x206E8B, 0x216F8B, 0x22708A,
4350 0x22718A, 0x23718A, 0x24728A, 0x25738A, 0x26748A, 0x26758A, 0x27768A, 0x287689, 0x297789, 0x297889, 0x2A7989,
4351 0x2B7A89, 0x2B7B89, 0x2C7C89, 0x2D7C89, 0x2D7D89, 0x2E7E89, 0x2F7F89, 0x2F8089, 0x308189, 0x318289, 0x318288,
4352 0x328388, 0x338488, 0x338588, 0x348688, 0x348788, 0x358888, 0x358988, 0x368988, 0x378A88, 0x378B88, 0x388C88,
4353 0x388D88, 0x398E88, 0x398F88, 0x3A9087, 0x3A9087, 0x3B9187, 0x3B9287, 0x3C9387, 0x3C9487, 0x3D9587, 0x3D9687,
4354 0x3E9787, 0x3E9886, 0x3F9986, 0x3F9986, 0x409A86, 0x419B86, 0x419C85, 0x429D85, 0x429E85, 0x439F85, 0x43A084,
4355 0x44A184, 0x44A284, 0x45A384, 0x46A483, 0x46A483, 0x47A583, 0x48A682, 0x48A782, 0x49A882, 0x4AA981, 0x4AAA81,
4356 0x4BAB81, 0x4CAC80, 0x4CAD80, 0x4DAE7F, 0x4EAE7F, 0x4FAF7E, 0x50B07E, 0x51B17D, 0x51B27D, 0x52B37C, 0x53B47C,
4357 0x54B57B, 0x55B67B, 0x56B77A, 0x57B879, 0x58B879, 0x5AB978, 0x5BBA77, 0x5CBB77, 0x5DBC76, 0x5EBD75, 0x5FBE75,
4358 0x61BF74, 0x62BF73, 0x63C072, 0x65C172, 0x66C271, 0x68C370, 0x69C46F, 0x6BC46E, 0x6CC56E, 0x6EC66D, 0x70C76C,
4359 0x71C86B, 0x73C86A, 0x75C969, 0x77CA68, 0x78CB68, 0x7ACB67, 0x7CCC66, 0x7ECD65, 0x80CE64, 0x82CE63, 0x84CF62,
4360 0x86D062, 0x89D061, 0x8BD160, 0x8DD25F, 0x8FD25F, 0x92D35E, 0x94D35D, 0x97D45D, 0x99D45D, 0x9BD55C, 0x9ED65C,
4361 0xA0D65C, 0xA3D75C, 0xA5D75C, 0xA8D85C, 0xAAD85C, 0xADD85C, 0xAFD95D, 0xB1D95D, 0xB4DA5E, 0xB6DA5F, 0xB8DB60,
4362 0xBBDB61, 0xBDDC62, 0xBFDC63, 0xC1DD64, 0xC4DD65, 0xC6DE66, 0xC8DE67, 0xCADF69, 0xCCDF6A, 0xCEE06C, 0xD0E06D,
4363 0xD2E16F, 0xD4E170, 0xD6E272, 0xD8E273, 0xDAE375, 0xDCE377, 0xDEE479, 0xE0E57A, 0xE1E57C, 0xE3E67E, 0xE5E680,
4364 0xE7E781, 0xE9E783, 0xEBE885, 0xECE987, 0xEEE989, 0xF0EA8A, 0xF2EA8C, 0xF3EB8E, 0xF5EC90, 0xF7EC92, 0xF8ED94,
4365 0xFAEE96, 0xFCEE98, 0xFDEF9A> csFPcmoceanHaline;
4366 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4367 /** @class csFPcmoceanIce
4368 @ingroup cs
4369 @extends csFP_tpl */
4370 typedef csFP_tpl<0x040613, 0x050614, 0x050715, 0x060817, 0x070918, 0x080A1A, 0x090B1B, 0x0A0C1D, 0x0B0D1E, 0x0C0D1F, 0x0D0E21,
4371 0x0E0F22, 0x0F1024, 0x101125, 0x111227, 0x121328, 0x13132A, 0x14142B, 0x15152C, 0x16162E, 0x17172F, 0x171831,
4372 0x181832, 0x191934, 0x1A1A35, 0x1B1B37, 0x1C1C38, 0x1D1C3A, 0x1E1D3B, 0x1F1E3D, 0x1F1F3E, 0x201F40, 0x212041,
4373 0x222143, 0x232244, 0x242246, 0x252347, 0x252449, 0x26254A, 0x27254C, 0x28264E, 0x29274F, 0x292851, 0x2A2852,
4374 0x2B2954, 0x2C2A55, 0x2C2B57, 0x2D2B59, 0x2E2C5A, 0x2F2D5C, 0x2F2E5E, 0x302F5F, 0x312F61, 0x313062, 0x323164,
4375 0x333266, 0x333267, 0x343369, 0x35346B, 0x35356C, 0x36356E, 0x363670, 0x373771, 0x383873, 0x383975, 0x393976,
4376 0x393A78, 0x3A3B7A, 0x3A3C7B, 0x3A3D7D, 0x3B3E7F, 0x3B3E80, 0x3C3F82, 0x3C4084, 0x3C4185, 0x3D4287, 0x3D4389,
4377 0x3D448A, 0x3E458C, 0x3E468D, 0x3E478F, 0x3E4890, 0x3E4992, 0x3E4993, 0x3F4A95, 0x3F4B96, 0x3F4C97, 0x3F4E99,
4378 0x3F4F9A, 0x3F509B, 0x3F519D, 0x3F529E, 0x3F539F, 0x3F54A0, 0x3F55A1, 0x3F56A2, 0x3F57A3, 0x3F58A4, 0x3F59A5,
4379 0x3E5AA6, 0x3E5CA7, 0x3E5DA8, 0x3E5EA9, 0x3E5FAA, 0x3E60AB, 0x3E61AB, 0x3E62AC, 0x3E63AD, 0x3E65AD, 0x3E66AE,
4380 0x3E67AF, 0x3E68AF, 0x3E69B0, 0x3E6AB0, 0x3F6BB1, 0x3F6CB2, 0x3F6EB2, 0x3F6FB3, 0x3F70B3, 0x3F71B4, 0x4072B4,
4381 0x4073B4, 0x4074B5, 0x4075B5, 0x4176B6, 0x4178B6, 0x4279B7, 0x427AB7, 0x427BB7, 0x437CB8, 0x437DB8, 0x447EB9,
4382 0x447FB9, 0x4580B9, 0x4581BA, 0x4682BA, 0x4684BB, 0x4785BB, 0x4786BB, 0x4887BC, 0x4988BC, 0x4989BC, 0x4A8ABD,
4383 0x4B8BBD, 0x4B8CBD, 0x4C8DBE, 0x4D8EBE, 0x4E8FBF, 0x4E90BF, 0x4F91BF, 0x5092C0, 0x5194C0, 0x5195C0, 0x5296C1,
4384 0x5397C1, 0x5498C2, 0x5599C2, 0x559AC2, 0x569BC3, 0x579CC3, 0x589DC3, 0x599EC4, 0x5A9FC4, 0x5BA0C5, 0x5CA1C5,
4385 0x5DA2C5, 0x5EA3C6, 0x5FA4C6, 0x5FA6C7, 0x60A7C7, 0x61A8C7, 0x62A9C8, 0x63AAC8, 0x64ABC9, 0x65ACC9, 0x67ADC9,
4386 0x68AECA, 0x69AFCA, 0x6AB0CB, 0x6BB1CB, 0x6CB2CB, 0x6DB3CC, 0x6EB4CC, 0x6FB5CD, 0x71B6CD, 0x72B8CE, 0x73B9CE,
4387 0x74BACE, 0x75BBCF, 0x77BCCF, 0x78BDD0, 0x79BED0, 0x7BBFD0, 0x7CC0D1, 0x7DC1D1, 0x7FC2D2, 0x80C3D2, 0x82C4D3,
4388 0x83C5D3, 0x85C6D3, 0x86C7D4, 0x88C8D4, 0x89C9D5, 0x8BCAD5, 0x8CCBD6, 0x8ECCD6, 0x90CDD7, 0x92CED7, 0x93CFD8,
4389 0x95D0D8, 0x97D1D9, 0x99D2D9, 0x9AD3DA, 0x9CD4DA, 0x9ED5DB, 0xA0D6DC, 0xA2D6DC, 0xA4D7DD, 0xA6D8DE, 0xA8D9DE,
4390 0xA9DADF, 0xABDBE0, 0xADDCE0, 0xAFDDE1, 0xB1DEE2, 0xB3DFE3, 0xB5E0E3, 0xB7E1E4, 0xB9E2E5, 0xBAE3E6, 0xBCE4E7,
4391 0xBEE5E7, 0xC0E6E8, 0xC2E6E9, 0xC4E7EA, 0xC6E8EB, 0xC8E9EC, 0xC9EAED, 0xCBEBEE, 0xCDECEF, 0xCFEDEF, 0xD1EEF0,
4392 0xD3EFF1, 0xD5F0F2, 0xD6F1F3, 0xD8F2F4, 0xDAF3F5, 0xDCF4F6, 0xDEF5F7, 0xE0F6F8, 0xE1F7F9, 0xE3F9FA, 0xE5FAFB,
4393 0xE7FBFB, 0xE8FCFC, 0xEAFDFD> csFPcmoceanIce;
4394 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4395 /** @class csFPcmoceanTempo
4396 @ingroup cs
4397 @extends csFP_tpl */
4398 typedef csFP_tpl<0xFFF6F4, 0xFDF5F3, 0xFCF4F1, 0xFBF3F0, 0xF9F2EE, 0xF8F1ED, 0xF7F0EB, 0xF5EFEA, 0xF4EEE8, 0xF2EDE7, 0xF1ECE5,
4399 0xF0EBE4, 0xEEEAE2, 0xEDEAE1, 0xEBE9DF, 0xEAE8DE, 0xE9E7DD, 0xE7E6DB, 0xE6E5DA, 0xE4E4D8, 0xE3E3D7, 0xE2E2D6,
4400 0xE0E2D4, 0xDFE1D3, 0xDDE0D1, 0xDCDFD0, 0xDBDECF, 0xD9DDCD, 0xD8DDCC, 0xD6DCCB, 0xD5DBC9, 0xD3DAC8, 0xD2D9C7,
4401 0xD1D8C5, 0xCFD8C4, 0xCED7C3, 0xCCD6C1, 0xCBD5C0, 0xC9D4BF, 0xC8D4BE, 0xC6D3BC, 0xC5D2BB, 0xC3D1BA, 0xC2D1B9,
4402 0xC0D0B7, 0xBFCFB6, 0xBDCEB5, 0xBCCEB4, 0xBACDB3, 0xB9CCB2, 0xB7CBB0, 0xB6CBAF, 0xB4CAAE, 0xB3C9AD, 0xB1C8AC,
4403 0xB0C8AB, 0xAEC7AA, 0xACC6A9, 0xABC5A8, 0xA9C5A6, 0xA8C4A5, 0xA6C3A4, 0xA4C3A3, 0xA3C2A2, 0xA1C1A1, 0xA0C0A0,
4404 0x9EC09F, 0x9CBF9F, 0x9BBE9E, 0x99BE9D, 0x97BD9C, 0x96BC9B, 0x94BC9A, 0x92BB99, 0x91BA98, 0x8FBA97, 0x8DB997,
4405 0x8BB896, 0x8AB795, 0x88B794, 0x86B693, 0x85B593, 0x83B592, 0x81B491, 0x7FB390, 0x7DB390, 0x7CB28F, 0x7AB18E,
4406 0x78B18E, 0x76B08D, 0x74AF8D, 0x72AF8C, 0x71AE8B, 0x6FAD8B, 0x6DAD8A, 0x6BAC8A, 0x69AB89, 0x67AB89, 0x65AA88,
4407 0x63A988, 0x61A987, 0x5FA887, 0x5DA786, 0x5BA686, 0x59A685, 0x57A585, 0x56A485, 0x54A484, 0x52A384, 0x50A284,
4408 0x4EA183, 0x4BA183, 0x49A083, 0x479F82, 0x459F82, 0x439E82, 0x419D82, 0x3F9C81, 0x3D9C81, 0x3B9B81, 0x3A9A81,
4409 0x389981, 0x369880, 0x349880, 0x329780, 0x309680, 0x2E9580, 0x2C947F, 0x2A937F, 0x29937F, 0x27927F, 0x25917F,
4410 0x24907F, 0x228F7E, 0x218E7E, 0x1F8D7E, 0x1E8D7E, 0x1C8C7E, 0x1B8B7D, 0x1A8A7D, 0x19897D, 0x17887D, 0x16877C,
4411 0x16867C, 0x15857C, 0x14847C, 0x13847B, 0x13837B, 0x12827B, 0x12817B, 0x11807A, 0x117F7A, 0x117E7A, 0x117D79,
4412 0x117C79, 0x117B79, 0x117A78, 0x117978, 0x117878, 0x117777, 0x117677, 0x127676, 0x127576, 0x127476, 0x137375,
4413 0x137275, 0x137174, 0x147074, 0x146F73, 0x146E73, 0x156D73, 0x156C72, 0x166B72, 0x166A71, 0x166971, 0x176870,
4414 0x176770, 0x17666F, 0x18656F, 0x18656E, 0x18646E, 0x19636D, 0x19626D, 0x19616C, 0x19606C, 0x1A5F6B, 0x1A5E6B,
4415 0x1A5D6A, 0x1A5C6A, 0x1A5B69, 0x1B5A68, 0x1B5968, 0x1B5867, 0x1B5867, 0x1B5766, 0x1B5666, 0x1C5565, 0x1C5465,
4416 0x1C5364, 0x1C5263, 0x1C5163, 0x1C5062, 0x1C4F62, 0x1C4E61, 0x1C4D61, 0x1C4C60, 0x1C4C5F, 0x1C4B5F, 0x1C4A5E,
4417 0x1C495E, 0x1C485D, 0x1C475D, 0x1C465C, 0x1C455B, 0x1C445B, 0x1C435A, 0x1C425A, 0x1C4259, 0x1C4158, 0x1C4058,
4418 0x1B3F57, 0x1B3E57, 0x1B3D56, 0x1B3C56, 0x1B3B55, 0x1B3A54, 0x1B3954, 0x1B3853, 0x1A3753, 0x1A3652, 0x1A3651,
4419 0x1A3551, 0x1A3450, 0x1A3350, 0x19324F, 0x19314F, 0x19304E, 0x192F4D, 0x192E4D, 0x182D4C, 0x182C4C, 0x182B4B,
4420 0x182A4B, 0x18294A, 0x17284A, 0x172749, 0x172648, 0x172548, 0x172447, 0x162347, 0x162246, 0x162146, 0x162045,
4421 0x151F45, 0x151E44, 0x151D44> csFPcmoceanTempo;
4422 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4423 /** @class csFPmplBrBG
4424 @ingroup cs
4425 @extends csFP_tpl */
4426 typedef csFP_tpl<0x563105, 0x5A3305, 0x5E3605, 0x633906, 0x673B06, 0x6C3E07, 0x704007, 0x744307, 0x794608, 0x7B4708, 0x824B09,
4427 0x844C09, 0x8A5009, 0x8C510A, 0x93570E, 0x955910, 0x9A5F14, 0x9E6217, 0xA16418, 0xA76A1C, 0xAA6E1F, 0xAF7122,
4428 0xB17323, 0xB67927, 0xBA7D2A, 0xBF802D, 0xC08330, 0xC48B39, 0xC6903F, 0xC99546, 0xCA9749, 0xCE9F52, 0xD0A458,
4429 0xD3A95F, 0xD5AE65, 0xD8B36B, 0xDAB972, 0xDBBB75, 0xDFC27E, 0xE1C583, 0xE3C889, 0xE4CB8E, 0xE6CE94, 0xE8D199,
4430 0xEAD49F, 0xEBD6A2, 0xEDDAAA, 0xEFDDAF, 0xF1E0B5, 0xF3E3BA, 0xF5E6C0, 0xF5E8C4, 0xF5E9C8, 0xF5EACA, 0xF5EBD0,
4431 0xF5ECD4, 0xF5EDD8, 0xF5EEDC, 0xF5EFE0, 0xF5F0E4, 0xF5F1E8, 0xF5F2EA, 0xF5F3F0, 0xF5F4F4, 0xF2F4F4, 0xEEF3F2,
4432 0xEBF2F1, 0xE7F1F0, 0xE3F0EF, 0xE0F0ED, 0xDCEFEC, 0xD9EEEB, 0xD5EDEA, 0xD1ECE8, 0xCEEBE7, 0xCCEBE6, 0xC6E9E4,
4433 0xC1E7E2, 0xBBE5DF, 0xB6E3DC, 0xB0E0D9, 0xABDED6, 0xA5DCD4, 0xA0DAD1, 0x9AD7CE, 0x94D5CB, 0x8FD3C8, 0x89D0C5,
4434 0x84CEC3, 0x7ECBC0, 0x78C7BC, 0x75C5BA, 0x6CBFB4, 0x67BAB0, 0x61B6AC, 0x5BB2A8, 0x55AEA4, 0x4FAAA0, 0x49A59C,
4435 0x43A198, 0x3D9D94, 0x379990, 0x32958D, 0x2E9189, 0x2A8D85, 0x268981, 0x22857D, 0x20837B, 0x1A7E76, 0x167A72,
4436 0x12766E, 0x0E726A, 0x0A6E66, 0x066A62, 0x02665E, 0x00635B, 0x006057, 0x005C54, 0x005950, 0x00564C, 0x005349,
4437 0x004F45, 0x004C42, 0x004A40, 0x00453A, 0x004237, 0x003F33, 0x003B2F> csFPmplBrBG;
4438 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4439 /** @class csFPmplOcean
4440 @ingroup cs
4441 @extends csFP_tpl */
4442 typedef csFP_tpl<0x007E01, 0x007B03, 0x007705, 0x007507, 0x007208, 0x006E0A, 0x006B0C, 0x00690F, 0x006611, 0x006411, 0x006015,
4443 0x005E16, 0x005918, 0x00581A, 0x00541C, 0x00521D, 0x004D21, 0x004B23, 0x004923, 0x004426, 0x004228, 0x003F2A,
4444 0x003D2B, 0x00382F, 0x003631, 0x003333, 0x003134, 0x002D36, 0x002A38, 0x00263B, 0x00253B, 0x00213F, 0x001D41,
4445 0x001A42, 0x001844, 0x001546, 0x001149, 0x001049, 0x000C4D, 0x00084F, 0x000550, 0x000352, 0x000054, 0x000356,
4446 0x000559, 0x000759, 0x000C5D, 0x000F5E, 0x001160, 0x001562, 0x001864, 0x001A67, 0x001D69, 0x001F69, 0x00236D,
4447 0x00266E, 0x002A70, 0x002D72, 0x002F75, 0x003377, 0x003679, 0x003779, 0x003B7C, 0x003F7E, 0x004280, 0x004482,
4448 0x004885, 0x004B87, 0x004D89, 0x00508A, 0x00548C, 0x00568E, 0x005990, 0x005D93, 0x006095, 0x006195, 0x006699,
4449 0x00699A, 0x006B9C, 0x006E9E, 0x0072A1, 0x0075A3, 0x0077A5, 0x007BA7, 0x007EA8, 0x0380AA, 0x0883AC, 0x0F87AF,
4450 0x1589B1, 0x1A8CB3, 0x2190B5, 0x2391B5, 0x2D95B8, 0x3399BA, 0x389CBC, 0x3F9EBF, 0x44A1C1, 0x4BA5C3, 0x50A8C4,
4451 0x56AAC6, 0x5DAEC8, 0x62B1CA, 0x69B3CD, 0x6EB6CF, 0x75BAD1, 0x7BBCD3, 0x80BFD4, 0x83C1D6, 0x8CC6D8, 0x93C8DB,
4452 0x99CCDD, 0x9ECFDF, 0xA5D1E1, 0xAAD4E2, 0xB1D8E4, 0xB6DBE6, 0xBCDDE8, 0xC3E1EB, 0xC8E4ED, 0xCFE6EF, 0xD4E9F0,
4453 0xDBEDF2, 0xE1EFF4, 0xE4F1F6, 0xEDF6F9, 0xF2F9FB, 0xF9FBFD, 0xFFFFFF> csFPmplOcean;
4454 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4455 /** @class csFPmplOranges
4456 @ingroup cs
4457 @extends csFP_tpl */
4458 typedef csFP_tpl<0xFEF4EA, 0xFEF3E8, 0xFEF2E6, 0xFEF1E4, 0xFEF0E2, 0xFEEFE0, 0xFEEEDF, 0xFEEDDD, 0xFEEDDB, 0xFEECDA, 0xFEEBD7,
4459 0xFEEAD6, 0xFEE9D4, 0xFEE8D3, 0xFEE7D0, 0xFEE6CF, 0xFDE5CC, 0xFDE3C9, 0xFDE3C8, 0xFDE1C4, 0xFDDFC1, 0xFDDEBE,
4460 0xFDDDBD, 0xFDDBB9, 0xFDDAB6, 0xFDD8B3, 0xFDD8B2, 0xFDD6AE, 0xFDD4AB, 0xFDD3A8, 0xFDD2A7, 0xFDD0A3, 0xFDCE9F,
4461 0xFDCC9C, 0xFDCA98, 0xFDC895, 0xFDC692, 0xFDC590, 0xFDC18B, 0xFDBF87, 0xFDBD84, 0xFDBB80, 0xFDB97D, 0xFDB779,
4462 0xFDB576, 0xFDB374, 0xFDB06F, 0xFDAE6C, 0xFDAC68, 0xFDAA66, 0xFDA863, 0xFDA660, 0xFDA45D, 0xFDA35B, 0xFDA057,
4463 0xFD9E54, 0xFD9C51, 0xFD994E, 0xFD974B, 0xFD9548, 0xFD9345, 0xFD9244, 0xFD8F3F, 0xFD8D3C, 0xFC8B3A, 0xFB8937,
4464 0xFA8634, 0xFA8432, 0xF9822F, 0xF8802D, 0xF77D2A, 0xF77B28, 0xF67925, 0xF57622, 0xF47420, 0xF4731F, 0xF3701B,
4465 0xF26D18, 0xF16B16, 0xF16913, 0xEF6712, 0xEE6510, 0xEC630F, 0xEB610E, 0xE95F0D, 0xE85C0C, 0xE65A0B, 0xE5580A,
4466 0xE35609, 0xE25407, 0xE05206, 0xDF5106, 0xDD4E04, 0xDC4C03, 0xDA4A02, 0xD94801, 0xD64701, 0xD34501, 0xCF4401,
4467 0xCC4301, 0xC94201, 0xC64101, 0xC34001, 0xBF3F01, 0xBC3D02, 0xB93C02, 0xB63B02, 0xB43B02, 0xAF3902, 0xAC3802,
4468 0xA93702, 0xA63602, 0xA33503, 0xA13403, 0x9E3303, 0x9C3203, 0x993103, 0x973003, 0x952F03, 0x922E03, 0x902D03,
4469 0x8D2C03, 0x8B2B03, 0x8A2B03, 0x862903, 0x832803, 0x812703, 0x7E2603> csFPmplOranges;
4470 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4471 /** @class csFPneoDdivVegetationA
4472 @ingroup cs
4473 @extends csFP_tpl */
4474 typedef csFP_tpl<0x530000, 0x540000, 0x540000, 0x550000, 0x560000, 0x560000, 0x570000, 0x580000, 0x5A0000, 0x5A0000, 0x5B0000,
4475 0x5B0000, 0x5D0000, 0x5E0000, 0x5F0000, 0x600000, 0x610000, 0x610000, 0x620000, 0x630000, 0x640000, 0x650000,
4476 0x670000, 0x670000, 0x690000, 0x6A0000, 0x6B0000, 0x6C0000, 0x6D0000, 0x6E0000, 0x700000, 0x710000, 0x720000,
4477 0x740000, 0x740000, 0x760000, 0x770000, 0x790000, 0x790000, 0x7B0000, 0x7C0000, 0x7D0000, 0x7F0000, 0x800000,
4478 0x830401, 0x830702, 0x860B04, 0x870D05, 0x8A1106, 0x8C1507, 0x8E1908, 0x901D0A, 0x921F0B, 0x93220C, 0x96270D,
4479 0x972A0E, 0x992E0F, 0x9C3211, 0x9E3512, 0x9F3913, 0xA13C14, 0xA23F15, 0xA54417, 0xA74818, 0xA94B19, 0xAB501A,
4480 0xAD531B, 0xB0571D, 0xB25B1E, 0xB35D1F, 0xB66321, 0xB86722, 0xBB6C24, 0xBD6F25, 0xBF7326, 0xC0762A, 0xC1782D,
4481 0xC2792F, 0xC37C33, 0xC57F37, 0xC6813A, 0xC7843E, 0xC88641, 0xC98945, 0xCB8C49, 0xCC8E4C, 0xCC904F, 0xCE9252,
4482 0xCF9656, 0xD09859, 0xD19B5D, 0xD29D60, 0xD49F64, 0xD5A368, 0xD6A56B, 0xD7A86F, 0xD9AA73, 0xD9AC75, 0xDBB07A,
4483 0xDCB27D, 0xDDB581, 0xDFB885, 0xE0BA88, 0xE1BD8D, 0xE2C090, 0xE3C293, 0xE5C597, 0xE6C79A, 0xE7CA9E, 0xE9CDA3,
4484 0xEAD0A6, 0xEBD2A9, 0xECD5AC, 0xEDD7B0, 0xEFDAB4, 0xF0DDB8, 0xF1E1BD, 0xF2E3C0, 0xF3E5C3, 0xF5E8C7, 0xF6EBCB,
4485 0xF7EDCE, 0xF8EFD1, 0xFAF4D6, 0xFBF5D9, 0xFCF8DD, 0xFDFBE1, 0xFFFFE5, 0xFEFFE5, 0xFAFDE0, 0xF8FBDD, 0xF6FBDB,
4486 0xF4F9D7, 0xF1F8D4, 0xEFF7D1, 0xECF6CD, 0xEAF4CA, 0xE7F3C6, 0xE5F2C3, 0xE2F1BF, 0xE0EFBB, 0xDDEEB9, 0xDAEDB5,
4487 0xD8ECB1, 0xD6EAAF, 0xD2E9AB, 0xD0E8A8, 0xCDE7A5, 0xCBE5A1, 0xC8E49F, 0xC6E39B, 0xC3E297, 0xC1E194, 0xBFDF91,
4488 0xBCDE8D, 0xBADD8B, 0xB7DB86, 0xB5DA83, 0xB3D981, 0xB0D87D, 0xAED77A, 0xABD576, 0xA9D574, 0xA6D371, 0xA3D26D,
4489 0xA1D16A, 0x9ED066, 0x9CCE64, 0x9ACD60, 0x97CC5D, 0x96CB5B, 0x93CA57, 0x90C954, 0x8EC750, 0x8CC74E, 0x89C54A,
4490 0x87C448, 0x85C344, 0x83C242, 0x80C03D, 0x7FC03C, 0x7BBE39, 0x77BC37, 0x72B935, 0x6EB733, 0x6BB532, 0x67B331,
4491 0x63B02F, 0x5FAE2D, 0x5BAC2C, 0x58AB2B, 0x54A829, 0x51A628, 0x4DA426, 0x4AA325, 0x46A124, 0x429F22, 0x409D20,
4492 0x3B9A1E, 0x38991D, 0x34971C, 0x31951A, 0x2D9319, 0x299118, 0x278F17, 0x238D15, 0x1F8B13, 0x1B8913, 0x198711,
4493 0x168510, 0x13840F, 0x0F810D, 0x0C800C, 0x0C7E0C, 0x0C7D0C, 0x0B7B0B, 0x0B790B, 0x0B780B, 0x0B770B, 0x0B750B,
4494 0x0B750B, 0x0A730A, 0x0A710A, 0x0A700A, 0x0A6E0A, 0x0A6D0A, 0x0A6C0A, 0x0A6B0A, 0x096909, 0x096709, 0x096609,
4495 0x096609, 0x096409, 0x096309, 0x086108, 0x086108, 0x085F08, 0x085F08, 0x085D08, 0x085C08, 0x085A08, 0x085A08,
4496 0x075907, 0x075807, 0x075607, 0x075507, 0x075507, 0x075407, 0x075207, 0x075107, 0x065106, 0x065006, 0x064F06,
4497 0x064E06, 0x064D06, 0x064C06> csFPneoDdivVegetationA;
4498 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4499 /** @class csFPneoDivVegetationC
4500 @ingroup cs
4501 @extends csFP_tpl */
4502 typedef csFP_tpl<0x795B13, 0x865614, 0x8A5513, 0x8A5513, 0x875715, 0x875715, 0x895A0A, 0x8C590A, 0x935711, 0x945812, 0x945812,
4503 0x955913, 0x965A14, 0x975B15, 0x985C16, 0x985C16, 0x9B5F19, 0x9B5F19, 0x9C601A, 0x9C601A, 0x9D611B, 0x9E621C,
4504 0x9F631D, 0x9F631D, 0xAA681A, 0xAA681A, 0xAA681A, 0xAB691B, 0xAC6A1C, 0xAD6B1D, 0xAE6C1E, 0xAE6C1E, 0xB47224,
4505 0xB57325, 0xB67426, 0xB87628, 0xBA782A, 0xBB792B, 0xBD7B2D, 0xBD7B2D, 0xBB8231, 0xBB8231, 0xBD8433, 0xBF8635,
4506 0xC28737, 0xC38838, 0xC58A3A, 0xC58A3A, 0xC38A3B, 0xC48B3C, 0xC48D3D, 0xC68F3F, 0xC49140, 0xC69342, 0xC59543,
4507 0xC69548, 0xC89E52, 0xC99F53, 0xC9A255, 0xCAA356, 0xCDA65B, 0xCFA85D, 0xCFA95E, 0xD0AA5F, 0xD5AF66, 0xD6B067,
4508 0xD7B26B, 0xD8B36C, 0xD9B76F, 0xDBB971, 0xDCBA72, 0xDDBB73, 0xDCBE78, 0xDDBF79, 0xDEC07A, 0xE0C27C, 0xE1C47E,
4509 0xE3C684, 0xE4C785, 0xE5C789, 0xE6CA89, 0xE7CA8E, 0xE6CC8F, 0xE7CC94, 0xE9CE96, 0xEACF97, 0xEBD098, 0xECD199,
4510 0xEAD9A5, 0xEBD9A9, 0xEBDBAA, 0xEDDDAC, 0xEEDDAF, 0xF0DFB1, 0xEFE1B2, 0xF0E1B6, 0xECDFB3, 0xECDEB7, 0xEEE0B9,
4511 0xEFE1BA, 0xF0E4BE, 0xF2E6C0, 0xF3E7C1, 0xF4E8C2, 0xF0EAD0, 0xF0EAD4, 0xF1EBD5, 0xF1EBD5, 0xF1EBD5, 0xF2ECD6,
4512 0xF1ECD6, 0xF1ECD9, 0xF0EDDA, 0xF1EEDF, 0xF0EEDF, 0xF0EEDF, 0xF1EFE0, 0xF1EFE0, 0xF1EFE0, 0xF1EFE3, 0xF1F1E9,
4513 0xF1F0EC, 0xF2F1ED, 0xF2F1ED, 0xF2F3EE, 0xF2F3EE, 0xF2F4F1, 0xF2F4F1, 0xF1F3F2, 0xF1F3F2, 0xEEF2F1, 0xEEF2F1,
4514 0xEDF1F2, 0xECF0F1, 0xEBF1F1, 0xEBF1F1, 0xE5EEED, 0xE5EEED, 0xE4EDEC, 0xE4EDEC, 0xE2ECED, 0xE2ECED, 0xE0ECEC,
4515 0xE0ECEC, 0xD9E7E7, 0xD9E7E7, 0xD7E7E7, 0xD7E7E7, 0xD4E6E6, 0xD3E5E5, 0xD3E5E5, 0xD3E5E5, 0xC3EEE5, 0xC3EEE5,
4516 0xC2EDE4, 0xC0EBE2, 0xBDEBE1, 0xBBE9DF, 0xB7E9DE, 0xB7E9DE, 0xB0E4D8, 0xAFE3D7, 0xADE3D6, 0xABE1D4, 0xA8E0D3,
4517 0xA6DED1, 0xA4DED0, 0xA3DDCF, 0x9BDDCF, 0x9ADCCE, 0x97DBCC, 0x94D8C9, 0x92D6C7, 0x8FD3C4, 0x8BD2C2, 0x8AD1C1,
4518 0x8BD4C3, 0x8AD3C2, 0x89D2C1, 0x87D0BF, 0x84CEBD, 0x82CCBB, 0x81CBBA, 0x80CAB9, 0x74C7B5, 0x74C7B5, 0x71C6B3,
4519 0x6FC4B1, 0x6DC2AF, 0x6BC0AD, 0x68BFAC, 0x67BEAB, 0x60B7A6, 0x5FB6A5, 0x5CB5A3, 0x5BB4A2, 0x57B2A0, 0x55B09E,
4520 0x53AE9C, 0x53AE9C, 0x52A9A0, 0x51A89F, 0x4FA69D, 0x4EA59C, 0x4AA49A, 0x48A298, 0x47A197, 0x46A096, 0x3E9A8F,
4521 0x3D998E, 0x3B988D, 0x39968B, 0x379489, 0x369388, 0x359287, 0x349186, 0x2C9183, 0x2C9183, 0x2A8F81, 0x298E80,
4522 0x278C7E, 0x258A7C, 0x24897B, 0x23887A, 0x1F8476, 0x1F8476, 0x1E8375, 0x1D8274, 0x1C8173, 0x1C8173, 0x1B8072,
4523 0x1B8072, 0x197D71, 0x187C70, 0x177B6F, 0x167A6E, 0x14786C, 0x13776B, 0x12766A, 0x117569, 0x0F7367, 0x0F7367,
4524 0x0F7367, 0x0E7266, 0x0D7165, 0x0D7165, 0x0C7064, 0x0C7064, 0x066B5B, 0x066B5B, 0x066B59, 0x086958, 0x0B6655,
4525 0x0B6655, 0x056951, 0x056951> csFPneoDivVegetationC;
4526 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4527 /** @class csFPneoModisNdvi
4528 @ingroup cs
4529 @extends csFP_tpl */
4530 typedef csFP_tpl<0xECE0D7, 0xEBDFD6, 0xEADED4, 0xEADDD3, 0xE9DDD1, 0xE8DCD0, 0xE7DBCE, 0xE7DACD, 0xE6D9CC, 0xE5D8CA, 0xE4D7C9,
4531 0xE3D6C7, 0xE3D6C6, 0xE2D5C5, 0xE1D4C3, 0xE0D3C2, 0xE0D2C0, 0xDFD1BF, 0xDED0BD, 0xDDCFBC, 0xDDCFBB, 0xDCCEB9,
4532 0xDBCDB8, 0xDACCB6, 0xD9CBB5, 0xD9CAB4, 0xD8C9B2, 0xD7C8B1, 0xD6C8AF, 0xD6C7AE, 0xD5C6AC, 0xD4C5AB, 0xD3C4AA,
4533 0xD2C3A8, 0xD1C3A7, 0xD1C2A5, 0xD0C1A4, 0xCFC0A2, 0xCEC0A1, 0xCDBF9F, 0xCCBE9E, 0xCCBD9C, 0xCBBC9B, 0xCABC99,
4534 0xC9BB98, 0xC8BA96, 0xC7B995, 0xC7B994, 0xC6B892, 0xC5B791, 0xC4B68F, 0xC3B58E, 0xC2B58C, 0xC1B48B, 0xC1B389,
4535 0xC0B288, 0xBFB186, 0xBEB185, 0xBDB083, 0xBCAF82, 0xBCAE80, 0xBBAE7F, 0xBAAD7D, 0xB9AC7C, 0xB8AB7A, 0xB7AB79,
4536 0xB6AA77, 0xB5A975, 0xB4A974, 0xB3A872, 0xB2A770, 0xB1A76F, 0xB0A66D, 0xAFA56B, 0xAEA469, 0xADA468, 0xACA366,
4537 0xABA264, 0xAAA263, 0xAAA161, 0xA9A05F, 0xA8A05E, 0xA79F5C, 0xA69E5A, 0xA59E59, 0xA49D57, 0xA39C55, 0xA29C54,
4538 0xA19B52, 0xA09A50, 0x9F994E, 0x9E994D, 0x9D984B, 0x9C9749, 0x9B9748, 0x9A9646, 0x999545, 0x989544, 0x979442,
4539 0x969341, 0x959340, 0x93923F, 0x92913D, 0x91913C, 0x90903B, 0x8F8F3A, 0x8E8E38, 0x8D8E37, 0x8C8D36, 0x8B8C35,
4540 0x8A8C33, 0x898B32, 0x878A31, 0x868A30, 0x85892E, 0x84882D, 0x83882C, 0x82872B, 0x818629, 0x808628, 0x7F8527,
4541 0x7E8426, 0x7C8324, 0x7B8323, 0x7A8222, 0x798121, 0x78811F, 0x77801E, 0x767F1E, 0x757F1E, 0x747E1E, 0x737D1E,
4542 0x727C1E, 0x717C1F, 0x707B1F, 0x6F7A1F, 0x6E791F, 0x6D791F, 0x6C781F, 0x6B771F, 0x6A761F, 0x69761F, 0x68751F,
4543 0x677420, 0x667320, 0x657320, 0x647220, 0x637120, 0x627020, 0x617020, 0x606F20, 0x5F6E20, 0x5E6D20, 0x5D6D20,
4544 0x5C6C21, 0x5B6B21, 0x5A6A21, 0x596A21, 0x586921, 0x576821, 0x566721, 0x556621, 0x556621, 0x546521, 0x536421,
4545 0x526321, 0x516321, 0x516221, 0x506121, 0x4F6021, 0x4E5F21, 0x4D5F21, 0x4C5E21, 0x4C5D21, 0x4B5C21, 0x4A5C21,
4546 0x495B21, 0x485A21, 0x485921, 0x475821, 0x465821, 0x455721, 0x445621, 0x445521, 0x435421, 0x425421, 0x415321,
4547 0x405221, 0x3F5121, 0x3F5121, 0x3E5021, 0x3D4F21, 0x3C4E20, 0x3B4E1F, 0x3A4D1E, 0x394C1D, 0x384C1C, 0x374B1B,
4548 0x364A1A, 0x354A19, 0x344918, 0x334817, 0x324816, 0x314715, 0x304614, 0x2F4613, 0x2E4512, 0x2E4511, 0x2D440F,
4549 0x2C430E, 0x2B430D, 0x2A420C, 0x29410B, 0x28410A, 0x274009, 0x263F08, 0x253F07, 0x243E06, 0x233D05, 0x223D04,
4550 0x213C03, 0x203B02, 0x1F3B01, 0x1E3A00, 0x1D3900, 0x1D3900, 0x1C3800, 0x1C3700, 0x1B3600, 0x1A3601, 0x1A3501,
4551 0x193401, 0x183401, 0x183301, 0x173201, 0x173101, 0x163101, 0x153001, 0x152F01, 0x142F02, 0x132E02, 0x132D02,
4552 0x122C02, 0x122C02, 0x112B02, 0x102A02, 0x102902, 0x0F2902, 0x0E2802, 0x0E2702, 0x0D2703, 0x0D2603, 0x0C2503,
4553 0x0B2403, 0x0B2403, 0x000000> csFPneoModisNdvi;
4554 //@}
4555
4556
4557 //========================================================================================================================================================
4558 /** @name ColorBrewer2 Color Schemes */
4559 //@{
4560 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4561 /** @class csCBSpectral
4562 @ingroup cs
4563 @extends csCB_tpl
4564 ColorBrewer2 "Spectral" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4565 typedef csCB_tpl<11,
4566 0xFC8D59, 0xFFFFBF, 0x99D594,
4567 0xD7191C, 0xFDAE61, 0xABDDA4, 0x2B83BA,
4568 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xABDDA4, 0x2B83BA,
4569 0xD53E4F, 0xFC8D59, 0xFEE08B, 0xE6F598, 0x99D594, 0x3288BD,
4570 0xD53E4F, 0xFC8D59, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0x99D594, 0x3288BD,
4571 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD,
4572 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD,
4573 0x9E0142, 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD, 0x5E4FA2,
4574 0x9E0142, 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD, 0x5E4FA2> csCBSpectral;
4575 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4576 /** @class csCBRdYlGn
4577 @ingroup cs
4578 @extends csCB_tpl
4579 ColorBrewer2 "RdYlGn" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4580 typedef csCB_tpl<11,
4581 0xFC8D59, 0xFFFFBF, 0x91CF60,
4582 0xD7191C, 0xFDAE61, 0xA6D96A, 0x1A9641,
4583 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xA6D96A, 0x1A9641,
4584 0xD73027, 0xFC8D59, 0xFEE08B, 0xD9EF8B, 0x91CF60, 0x1A9850,
4585 0xD73027, 0xFC8D59, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0x91CF60, 0x1A9850,
4586 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850,
4587 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850,
4588 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850, 0x006837,
4589 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850, 0x006837> csCBRdYlGn;
4590 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4591 /** @class csCBRdBu
4592 @ingroup cs
4593 @extends csCB_tpl
4594 ColorBrewer2 "RdBu" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4595 typedef csCB_tpl<11,
4596 0xEF8A62, 0xF7F7F7, 0x67A9CF,
4597 0xCA0020, 0xF4A582, 0x92C5DE, 0x0571B0,
4598 0xCA0020, 0xF4A582, 0xF7F7F7, 0x92C5DE, 0x0571B0,
4599 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xD1E5F0, 0x67A9CF, 0x2166AC,
4600 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x67A9CF, 0x2166AC,
4601 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC,
4602 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC,
4603 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC, 0x053061,
4604 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC, 0x053061> csCBRdBu;
4605 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4606 /** @class csCBPiYG
4607 @ingroup cs
4608 @extends csCB_tpl
4609 ColorBrewer2 "PiYG" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4610 typedef csCB_tpl<11,
4611 0xE9A3C9, 0xF7F7F7, 0xA1D76A,
4612 0xD01C8B, 0xF1B6DA, 0xB8E186, 0x4DAC26,
4613 0xD01C8B, 0xF1B6DA, 0xF7F7F7, 0xB8E186, 0x4DAC26,
4614 0xC51B7D, 0xE9A3C9, 0xFDE0EF, 0xE6F5D0, 0xA1D76A, 0x4D9221,
4615 0xC51B7D, 0xE9A3C9, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xA1D76A, 0x4D9221,
4616 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221,
4617 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221,
4618 0x8E0152, 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221, 0x276419,
4619 0x8E0152, 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221, 0x276419> csCBPiYG;
4620 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4621 /** @class csCBPRGn
4622 @ingroup cs
4623 @extends csCB_tpl
4624 ColorBrewer2 "PRGn" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4625 typedef csCB_tpl<11,
4626 0xAF8DC3, 0xF7F7F7, 0x7FBF7B,
4627 0x7B3294, 0xC2A5CF, 0xA6DBA0, 0x008837,
4628 0x7B3294, 0xC2A5CF, 0xF7F7F7, 0xA6DBA0, 0x008837,
4629 0x762A83, 0xAF8DC3, 0xE7D4E8, 0xD9F0D3, 0x7FBF7B, 0x1B7837,
4630 0x762A83, 0xAF8DC3, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0x7FBF7B, 0x1B7837,
4631 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837,
4632 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837,
4633 0x40004B, 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837, 0x00441B,
4634 0x40004B, 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837, 0x00441B> csCBPRGn;
4635 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4636 /** @class csCBRdYlBu
4637 @ingroup cs
4638 @extends csCB_tpl
4639 ColorBrewer2 "RdYlBu" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4640 typedef csCB_tpl<11,
4641 0xFC8D59, 0xFFFFBF, 0x91BFDB,
4642 0xD7191C, 0xFDAE61, 0xABD9E9, 0x2C7BB6,
4643 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xABD9E9, 0x2C7BB6,
4644 0xD73027, 0xFC8D59, 0xFEE090, 0xE0F3F8, 0x91BFDB, 0x4575B4,
4645 0xD73027, 0xFC8D59, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0x91BFDB, 0x4575B4,
4646 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4,
4647 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4,
4648 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4, 0x313695,
4649 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4, 0x313695> csCBRdYlBu;
4650 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4651 /** @class csCBBrBG
4652 @ingroup cs
4653 @extends csCB_tpl
4654 ColorBrewer2 "BrBG" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4655 typedef csCB_tpl<11,
4656 0xD8B365, 0xF5F5F5, 0x5AB4AC,
4657 0xA6611A, 0xDFC27D, 0x80CDC1, 0x018571,
4658 0xA6611A, 0xDFC27D, 0xF5F5F5, 0x80CDC1, 0x018571,
4659 0x8C510A, 0xD8B365, 0xF6E8C3, 0xC7EAE5, 0x5AB4AC, 0x01665E,
4660 0x8C510A, 0xD8B365, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x5AB4AC, 0x01665E,
4661 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E,
4662 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E,
4663 0x543005, 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E, 0x003C30,
4664 0x543005, 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E, 0x003C30> csCBBrBG;
4665 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4666 /** @class csCBRdGy
4667 @ingroup cs
4668 @extends csCB_tpl
4669 ColorBrewer2 "RdGy" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4670 typedef csCB_tpl<11,
4671 0xEF8A62, 0xFFFFFF, 0x999999,
4672 0xCA0020, 0xF4A582, 0xBABABA, 0x404040,
4673 0xCA0020, 0xF4A582, 0xFFFFFF, 0xBABABA, 0x404040,
4674 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xE0E0E0, 0x999999, 0x4D4D4D,
4675 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0x999999, 0x4D4D4D,
4676 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D,
4677 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D,
4678 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D, 0x1A1A1A,
4679 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D, 0x1A1A1A> csCBRdGy;
4680 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4681 /** @class csCBPuOr
4682 @ingroup cs
4683 @extends csCB_tpl
4684 ColorBrewer2 "PuOr" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4685 typedef csCB_tpl<11,
4686 0xF1A340, 0xF7F7F7, 0x998EC3,
4687 0xE66101, 0xFDB863, 0xB2ABD2, 0x5E3C99,
4688 0xE66101, 0xFDB863, 0xF7F7F7, 0xB2ABD2, 0x5E3C99,
4689 0xB35806, 0xF1A340, 0xFEE0B6, 0xD8DAEB, 0x998EC3, 0x542788,
4690 0xB35806, 0xF1A340, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0x998EC3, 0x542788,
4691 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788,
4692 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788,
4693 0x7F3B08, 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788, 0x2D004B,
4694 0x7F3B08, 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788, 0x2D004B> csCBPuOr;
4695 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4696 /** @class csCBSet2
4697 @ingroup cs
4698 @extends csCB_tpl
4699 ColorBrewer2 "Set2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4700 typedef csCB_tpl<8,
4701 0x66C2A5, 0xFC8D62, 0x8DA0CB,
4702 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3,
4703 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854,
4704 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F,
4705 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F, 0xE5C494,
4706 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F, 0xE5C494, 0xB3B3B3> csCBSet2;
4707 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4708 /** @class csCBAccent
4709 @ingroup cs
4710 @extends csCB_tpl
4711 ColorBrewer2 "Accent" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4712 typedef csCB_tpl<8,
4713 0x7FC97F, 0xBEAED4, 0xFDC086,
4714 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99,
4715 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0,
4716 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F,
4717 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F, 0xBF5B17,
4718 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F, 0xBF5B17, 0x666666> csCBAccent;
4719 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4720 /** @class csCBSet1
4721 @ingroup cs
4722 @extends csCB_tpl
4723 ColorBrewer2 "Set1" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4724 typedef csCB_tpl<9,
4725 0xE41A1C, 0x377EB8, 0x4DAF4A,
4726 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3,
4727 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00,
4728 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33,
4729 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628,
4730 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628, 0xF781BF,
4731 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628, 0xF781BF, 0x999999> csCBSet1;
4732 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4733 /** @class csCBSet3
4734 @ingroup cs
4735 @extends csCB_tpl
4736 ColorBrewer2 "Set3" color scheme of 3 to 12 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4737 typedef csCB_tpl<12,
4738 0x8DD3C7, 0xFFFFB3, 0xBEBADA,
4739 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072,
4740 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3,
4741 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462,
4742 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69,
4743 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5,
4744 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9,
4745 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD,
4746 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD, 0xCCEBC5,
4747 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD, 0xCCEBC5, 0xFFED6F> csCBSet3;
4748 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4749 /** @class csCBDark2
4750 @ingroup cs
4751 @extends csCB_tpl
4752 ColorBrewer2 "Dark2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4753 typedef csCB_tpl<8,
4754 0x1B9E77, 0xD95F02, 0x7570B3,
4755 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A,
4756 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E,
4757 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02,
4758 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02, 0xA6761D,
4759 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02, 0xA6761D, 0x666666> csCBDark2;
4760 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4761 /** @class csCBPaired
4762 @ingroup cs
4763 @extends csCB_tpl
4764 ColorBrewer2 "Paired" color scheme of 3 to 12 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4765 typedef csCB_tpl<12,
4766 0xA6CEE3, 0x1F78B4, 0xB2DF8A,
4767 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C,
4768 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99,
4769 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C,
4770 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F,
4771 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00,
4772 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6,
4773 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A,
4774 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A, 0xFFFF99,
4775 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A, 0xFFFF99, 0xB15928> csCBPaired;
4776 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4777 /** @class csCBPastel2
4778 @ingroup cs
4779 @extends csCB_tpl
4780 ColorBrewer2 "Pastel2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4781 typedef csCB_tpl<8,
4782 0xB3E2CD, 0xFDCDAC, 0xCBD5E8,
4783 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4,
4784 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9,
4785 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE,
4786 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE, 0xF1E2CC,
4787 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE, 0xF1E2CC, 0xCCCCCC> csCBPastel2;
4788 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4789 /** @class csCBPastel1
4790 @ingroup cs
4791 @extends csCB_tpl
4792 ColorBrewer2 "Pastel1" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4793 typedef csCB_tpl<9,
4794 0xFBB4AE, 0xB3CDE3, 0xCCEBC5,
4795 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4,
4796 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6,
4797 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC,
4798 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD,
4799 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD, 0xFDDAEC,
4800 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD, 0xFDDAEC, 0xF2F2F2> csCBPastel1;
4801 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4802 /** @class csCBOrRd
4803 @ingroup cs
4804 @extends csCB_tpl
4805 ColorBrewer2 "RdYlGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4806 typedef csCB_tpl<9,
4807 0xFEE8C8, 0xFDBB84, 0xE34A33,
4808 0xFEF0D9, 0xFDCC8A, 0xFC8D59, 0xD7301F,
4809 0xFEF0D9, 0xFDCC8A, 0xFC8D59, 0xE34A33, 0xB30000,
4810 0xFEF0D9, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xE34A33, 0xB30000,
4811 0xFEF0D9, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0x990000,
4812 0xFFF7EC, 0xFEE8C8, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0x990000,
4813 0xFFF7EC, 0xFEE8C8, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0xB30000, 0x7F0000> csCBOrRd;
4814 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4815 /** @class csCBPuBu
4816 @ingroup cs
4817 @extends csCB_tpl
4818 ColorBrewer2 "PuBu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4819 typedef csCB_tpl<9,
4820 0xECE7F2, 0xA6BDDB, 0x2B8CBE,
4821 0xF1EEF6, 0xBDC9E1, 0x74A9CF, 0x0570B0,
4822 0xF1EEF6, 0xBDC9E1, 0x74A9CF, 0x2B8CBE, 0x045A8D,
4823 0xF1EEF6, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x2B8CBE, 0x045A8D,
4824 0xF1EEF6, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x034E7B,
4825 0xFFF7FB, 0xECE7F2, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x034E7B,
4826 0xFFF7FB, 0xECE7F2, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x045A8D, 0x023858> csCBPuBu;
4827 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4828 /** @class csCBBuPu
4829 @ingroup cs
4830 @extends csCB_tpl
4831 ColorBrewer2 "CbBuPu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4832 typedef csCB_tpl<9,
4833 0xE0ECF4, 0x9EBCDA, 0x8856A7,
4834 0xEDF8FB, 0xB3CDE3, 0x8C96C6, 0x88419D,
4835 0xEDF8FB, 0xB3CDE3, 0x8C96C6, 0x8856A7, 0x810F7C,
4836 0xEDF8FB, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8856A7, 0x810F7C,
4837 0xEDF8FB, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x6E016B,
4838 0xF7FCFD, 0xE0ECF4, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x6E016B,
4839 0xF7FCFD, 0xE0ECF4, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x810F7C, 0x4D004B> csCBBuPu;
4840 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4841 /** @class csCBOranges
4842 @ingroup cs
4843 @extends csCB_tpl
4844 ColorBrewer2 "Oranges" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4845 typedef csCB_tpl<9,
4846 0xFEE6CE, 0xFDAE6B, 0xE6550D,
4847 0xFEEDDE, 0xFDBE85, 0xFD8D3C, 0xD94701,
4848 0xFEEDDE, 0xFDBE85, 0xFD8D3C, 0xE6550D, 0xA63603,
4849 0xFEEDDE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xE6550D, 0xA63603,
4850 0xFEEDDE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0x8C2D04,
4851 0xFFF5EB, 0xFEE6CE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0x8C2D04,
4852 0xFFF5EB, 0xFEE6CE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0xA63603, 0x7F2704> csCBOranges;
4853 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4854 /** @class csCBBuGn
4855 @ingroup cs
4856 @extends csCB_tpl
4857 ColorBrewer2 "BuGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4858 typedef csCB_tpl<9,
4859 0xE5F5F9, 0x99D8C9, 0x2CA25F,
4860 0xEDF8FB, 0xB2E2E2, 0x66C2A4, 0x238B45,
4861 0xEDF8FB, 0xB2E2E2, 0x66C2A4, 0x2CA25F, 0x006D2C,
4862 0xEDF8FB, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x2CA25F, 0x006D2C,
4863 0xEDF8FB, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x005824,
4864 0xF7FCFD, 0xE5F5F9, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x005824,
4865 0xF7FCFD, 0xE5F5F9, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x006D2C, 0x00441B> csCBBuGn;
4866 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4867 /** @class csCBYlOrBr
4868 @ingroup cs
4869 @extends csCB_tpl
4870 ColorBrewer2 "YlOrBr" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4871 typedef csCB_tpl<9,
4872 0xFFF7BC, 0xFEC44F, 0xD95F0E,
4873 0xFFFFD4, 0xFED98E, 0xFE9929, 0xCC4C02,
4874 0xFFFFD4, 0xFED98E, 0xFE9929, 0xD95F0E, 0x993404,
4875 0xFFFFD4, 0xFEE391, 0xFEC44F, 0xFE9929, 0xD95F0E, 0x993404,
4876 0xFFFFD4, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x8C2D04,
4877 0xFFFFE5, 0xFFF7BC, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x8C2D04,
4878 0xFFFFE5, 0xFFF7BC, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x993404, 0x662506> csCBYlOrBr;
4879 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4880 /** @class csCBYlGn
4881 @ingroup cs
4882 @extends csCB_tpl
4883 ColorBrewer2 "csCBYlGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4884 typedef csCB_tpl<9,
4885 0xF7FCB9, 0xADDD8E, 0x31A354,
4886 0xFFFFCC, 0xC2E699, 0x78C679, 0x238443,
4887 0xFFFFCC, 0xC2E699, 0x78C679, 0x31A354, 0x006837,
4888 0xFFFFCC, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x31A354, 0x006837,
4889 0xFFFFCC, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x005A32,
4890 0xFFFFE5, 0xF7FCB9, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x005A32,
4891 0xFFFFE5, 0xF7FCB9, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x006837, 0x004529> csCBYlGn;
4892 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4893 /** @class csCBReds
4894 @ingroup cs
4895 @extends csCB_tpl
4896 ColorBrewer2 "Reds" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4897 typedef csCB_tpl<9,
4898 0xFEE0D2, 0xFC9272, 0xDE2D26,
4899 0xFEE5D9, 0xFCAE91, 0xFB6A4A, 0xCB181D,
4900 0xFEE5D9, 0xFCAE91, 0xFB6A4A, 0xDE2D26, 0xA50F15,
4901 0xFEE5D9, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xDE2D26, 0xA50F15,
4902 0xFEE5D9, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0x99000D,
4903 0xFFF5F0, 0xFEE0D2, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0x99000D,
4904 0xFFF5F0, 0xFEE0D2, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0xA50F15, 0x67000D> csCBReds;
4905 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4906 /** @class csCBRdPu
4907 @ingroup cs
4908 @extends csCB_tpl
4909 ColorBrewer2 "RdPu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4910 typedef csCB_tpl<9,
4911 0xFDE0DD, 0xFA9FB5, 0xC51B8A,
4912 0xFEEBE2, 0xFBB4B9, 0xF768A1, 0xAE017E,
4913 0xFEEBE2, 0xFBB4B9, 0xF768A1, 0xC51B8A, 0x7A0177,
4914 0xFEEBE2, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xC51B8A, 0x7A0177,
4915 0xFEEBE2, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177,
4916 0xFFF7F3, 0xFDE0DD, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177,
4917 0xFFF7F3, 0xFDE0DD, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177, 0x49006A> csCBRdPu;
4918 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4919 /** @class csCBGreens
4920 @ingroup cs
4921 @extends csCB_tpl
4922 ColorBrewer2 "Greens" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4923 typedef csCB_tpl<9,
4924 0xE5F5E0, 0xA1D99B, 0x31A354,
4925 0xEDF8E9, 0xBAE4B3, 0x74C476, 0x238B45,
4926 0xEDF8E9, 0xBAE4B3, 0x74C476, 0x31A354, 0x006D2C,
4927 0xEDF8E9, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x31A354, 0x006D2C,
4928 0xEDF8E9, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x005A32,
4929 0xF7FCF5, 0xE5F5E0, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x005A32,
4930 0xF7FCF5, 0xE5F5E0, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x006D2C, 0x00441B> csCBGreens;
4931 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4932 /** @class csCBYlGnBu
4933 @ingroup cs
4934 @extends csCB_tpl
4935 ColorBrewer2 "YlGnBu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4936 typedef csCB_tpl<9,
4937 0xEDF8B1, 0x7FCDBB, 0x2C7FB8,
4938 0xFFFFCC, 0xA1DAB4, 0x41B6C4, 0x225EA8,
4939 0xFFFFCC, 0xA1DAB4, 0x41B6C4, 0x2C7FB8, 0x253494,
4940 0xFFFFCC, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x2C7FB8, 0x253494,
4941 0xFFFFCC, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x0C2C84,
4942 0xFFFFD9, 0xEDF8B1, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x0C2C84,
4943 0xFFFFD9, 0xEDF8B1, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x253494, 0x081D58> csCBYlGnBu;
4944 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4945 /** @class csCBPurples
4946 @ingroup cs
4947 @extends csCB_tpl
4948 ColorBrewer2 "Purples" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4949 typedef csCB_tpl<9,
4950 0xEFEDF5, 0xBCBDDC, 0x756BB1,
4951 0xF2F0F7, 0xCBC9E2, 0x9E9AC8, 0x6A51A3,
4952 0xF2F0F7, 0xCBC9E2, 0x9E9AC8, 0x756BB1, 0x54278F,
4953 0xF2F0F7, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x756BB1, 0x54278F,
4954 0xF2F0F7, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x4A1486,
4955 0xFCFBFD, 0xEFEDF5, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x4A1486,
4956 0xFCFBFD, 0xEFEDF5, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x54278F, 0x3F007D> csCBPurples;
4957 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4958 /** @class csCBGnBu
4959 @ingroup cs
4960 @extends csCB_tpl
4961 ColorBrewer2 "GnBu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4962 typedef csCB_tpl<9,
4963 0xE0F3DB, 0xA8DDB5, 0x43A2CA,
4964 0xF0F9E8, 0xBAE4BC, 0x7BCCC4, 0x2B8CBE,
4965 0xF0F9E8, 0xBAE4BC, 0x7BCCC4, 0x43A2CA, 0x0868AC,
4966 0xF0F9E8, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x43A2CA, 0x0868AC,
4967 0xF0F9E8, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x08589E,
4968 0xF7FCF0, 0xE0F3DB, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x08589E,
4969 0xF7FCF0, 0xE0F3DB, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x0868AC, 0x084081> csCBGnBu;
4970 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4971 /** @class csCBGreys
4972 @ingroup cs
4973 @extends csCB_tpl
4974 ColorBrewer2 "Greys" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4975 typedef csCB_tpl<9,
4976 0xF0F0F0, 0xBDBDBD, 0x636363,
4977 0xF7F7F7, 0xCCCCCC, 0x969696, 0x525252,
4978 0xF7F7F7, 0xCCCCCC, 0x969696, 0x636363, 0x252525,
4979 0xF7F7F7, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x636363, 0x252525,
4980 0xF7F7F7, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525,
4981 0xFFFFFF, 0xF0F0F0, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525,
4982 0xFFFFFF, 0xF0F0F0, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525, 0x000000> csCBGreys;
4983 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4984 /** @class csCBYlOrRd
4985 @ingroup cs
4986 @extends csCB_tpl
4987 ColorBrewer2 "YlOrRd" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4988 typedef csCB_tpl<8,
4989 0xFFEDA0, 0xFEB24C, 0xF03B20,
4990 0xFFFFB2, 0xFECC5C, 0xFD8D3C, 0xE31A1C,
4991 0xFFFFB2, 0xFECC5C, 0xFD8D3C, 0xF03B20, 0xBD0026,
4992 0xFFFFB2, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xF03B20, 0xBD0026,
4993 0xFFFFB2, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xFC4E2A, 0xE31A1C, 0xB10026,
4994 0xFFFFCC, 0xFFEDA0, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xFC4E2A, 0xE31A1C, 0xB10026> csCBYlOrRd;
4995 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4996 /** @class csCBPuRd
4997 @ingroup cs
4998 @extends csCB_tpl
4999 ColorBrewer2 "PuRd" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
5000 typedef csCB_tpl<9,
5001 0xE7E1EF, 0xC994C7, 0xDD1C77,
5002 0xF1EEF6, 0xD7B5D8, 0xDF65B0, 0xCE1256,
5003 0xF1EEF6, 0xD7B5D8, 0xDF65B0, 0xDD1C77, 0x980043,
5004 0xF1EEF6, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xDD1C77, 0x980043,
5005 0xF1EEF6, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x91003F,
5006 0xF7F4F9, 0xE7E1EF, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x91003F,
5007 0xF7F4F9, 0xE7E1EF, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x980043, 0x67001F> csCBPuRd;
5008 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5009 /** @class csCBBlues
5010 @ingroup cs
5011 @extends csCB_tpl
5012 ColorBrewer2 "Blues" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
5013 typedef csCB_tpl<9,
5014 0xDEEBF7, 0x9ECAE1, 0x3182BD,
5015 0xEFF3FF, 0xBDD7E7, 0x6BAED6, 0x2171B5,
5016 0xEFF3FF, 0xBDD7E7, 0x6BAED6, 0x3182BD, 0x08519C,
5017 0xEFF3FF, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x3182BD, 0x08519C,
5018 0xEFF3FF, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x084594,
5019 0xF7FBFF, 0xDEEBF7, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x084594,
5020 0xF7FBFF, 0xDEEBF7, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x08519C, 0x08306B> csCBBlues;
5021 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5022 /** @class csCBPuBuGn
5023 @ingroup cs
5024 @extends csCB_tpl
5025 ColorBrewer2 "PuBuGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
5026 typedef csCB_tpl<9,
5027 0xECE2F0, 0xA6BDDB, 0x1C9099,
5028 0xF6EFF7, 0xBDC9E1, 0x67A9CF, 0x02818A,
5029 0xF6EFF7, 0xBDC9E1, 0x67A9CF, 0x1C9099, 0x016C59,
5030 0xF6EFF7, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x1C9099, 0x016C59,
5031 0xF6EFF7, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016450,
5032 0xFFF7FB, 0xECE2F0, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016450,
5033 0xFFF7FB, 0xECE2F0, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016C59, 0x014636> csCBPuBuGn;
5034 //@}
5035
5036 /** @endcond */
5037
5038 //========================================================================================================================================================
5039 /** @name 2D Color Schemes */
5040 //@{
5041#if !(MISSING_P1907R1)
5042 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5043 /** Compute a color from Richardson's 2D complex number coloring scheme.
5044 See: Richardson (1991); Visualizing quantum scattering on the CM-2 supercomputer; Computer Physics Communications 63; pp 84-94"
5045 This is a continuous, 2D color scheme!
5046 @tparam cutDepth See: tfrmComplexCut()
5047 @tparam argCuts See: tfrmComplexCut()
5048 @tparam absCuts See: tfrmComplexCut()
5049 @tparam logAbs See: tfrmComplexCut() */
5050 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5052 public:
5053 /** Set given colorTpl instance to the selected color in the color scheme.
5054 @param aColor color object to set.
5055 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5056 @param csY A value that, along with csX, identifies the color in the scheme.
5057 @return Returns a reference to \a aColor. */
5058 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5059 csFltType c_abs2 = csX*csX+csY*csY;
5060 csFltType c_abs = std::sqrt(c_abs2);
5061 csFltType c_abs2p1 = 1 + c_abs2;
5062 csFltType x_scl = csX / std::sqrt(30.0/5.0);
5063 csFltType y_scl = csY / std::sqrt(2.0);
5064 csFltType ofs = (c_abs<1 ? -1.0 : 1.0) * (0.5 - c_abs/c_abs2p1);
5065 aColor.setChansRGB_dbl(std::clamp(ofs + (0.5 + (std::sqrt(2.0/3.0) * csX) / c_abs2p1), 0.0, 1.0),
5066 std::clamp(ofs + (0.5 - (x_scl - y_scl) / c_abs2p1), 0.0, 1.0),
5067 std::clamp(ofs + (0.5 - (x_scl + y_scl) / c_abs2p1), 0.0, 1.0));
5068 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5069 }
5070 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5071 @param csX A value that, along with csY, identifies the color in the scheme.
5072 @param csY A value that, along with csX, identifies the color in the scheme.
5073 @return Returns a colorTpl value */
5074 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5075 /** Set given colorTpl instance to the selected color in the color scheme.
5076 @param aColor color object to set.
5077 @param csZ A value that identifies the color in the scheme.
5078 @return Returns a reference to \a aColor. */
5079 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5080 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5081 @param csZ A value that identifies the color in the scheme.
5082 @return Returns a colorTpl value */
5083 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5084 };
5085 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5086 /** Compute a color for a point in @f$\mathbb{R}^2@f$ using a discrete color scheme for the phase angle.
5087 This is a continuous, 2D color scheme!
5088 @tparam colorScheme Integer indexed color scheme to use for the argument. csCColdeRainbow is a traditional choice.
5089 @tparam argWrap Number of times to wrap around the color ramp for arg
5090 @tparam cutDepth See: tfrmComplexCut()
5091 @tparam argCuts See: tfrmComplexCut()
5092 @tparam absCuts See: tfrmComplexCut()
5093 @tparam logAbs See: tfrmComplexCut() */
5094 template<typename colorScheme, int argWrap, double cutDepth, double argCuts, double absCuts, bool logAbs>
5096 public:
5097 /** Set given colorTpl instance to the selected color in the color scheme.
5098 @param aColor color object to set.
5099 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5100 @param csY A value that, along with csX, identifies the color in the scheme.
5101 @return Returns a reference to \a aColor. */
5102 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5103 csIntType numC = colorScheme::numC;
5104 double tau = std::numbers::pi * 2; // 2*Pi
5105 double zArg = std::atan2(csY, csX); // Arg
5106 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
5107 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)));
5108 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5109 }
5110 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5111 @param csX A value that, along with csY, identifies the color in the scheme.
5112 @param csY A value that, along with csX, identifies the color in the scheme.
5113 @return Returns a colorTpl value */
5114 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5115 /** Set given colorTpl instance to the selected color in the color scheme.
5116 @param aColor color object to set.
5117 @param csZ A value that identifies the color in the scheme.
5118 @return Returns a reference to \a aColor. */
5119 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5120 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5121 @param csZ A value that identifies the color in the scheme.
5122 @return Returns a colorTpl value */
5123 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5124 };
5125 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5126 /** Compute a color for a point in @f$\mathbb{R}^2@f$ using a continuous color scheme for the phase angle.
5127 This is a continuous, 2D color scheme!
5128 @tparam colorScheme Integer indexed color scheme to use for the argument. csCColdeRainbow is a traditional choice.
5129 @tparam argWrap Number of times to wrap around the color ramp for arg
5130 @tparam cutDepth See: tfrmComplexCut()
5131 @tparam argCuts See: tfrmComplexCut()
5132 @tparam absCuts See: tfrmComplexCut()
5133 @tparam logAbs See: tfrmComplexCut() */
5134 template<typename colorScheme, int argWrap, double cutDepth, double argCuts, double absCuts, bool logAbs>
5136 public:
5137 /** Set given colorTpl instance to the selected color in the color scheme.
5138 @param aColor color object to set.
5139 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5140 @param csY A value that, along with csX, identifies the color in the scheme.
5141 @return Returns a reference to \a aColor. */
5142 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5143 double tau = std::numbers::pi * 2; // 2*Pi
5144 double zArg = std::atan2(csY, csX); // Arg
5145 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
5146 aColor.csSet<colorScheme>(static_cast<csFltType>(mjr::math::ivl::wrapCC(mjr::math::ivl::unit_clamp(pzArg)*argWrap, 1.0)));
5147 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5148 }
5149 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5150 @param csX A value that, along with csY, identifies the color in the scheme.
5151 @param csY A value that, along with csX, identifies the color in the scheme.
5152 @return Returns a colorTpl value */
5153 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5154 /** Set given colorTpl instance to the selected color in the color scheme.
5155 @param aColor color object to set.
5156 @param csZ A value that identifies the color in the scheme.
5157 @return Returns a reference to \a aColor. */
5158 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5159 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5160 @param csZ A value that identifies the color in the scheme.
5161 @return Returns a colorTpl value */
5162 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5163 };
5164 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5165 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSL.
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 maximum 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 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5185 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSV and dynamic value.
5186 See: Bernd Thaller (2000); Visual Quantum Mechanics; pp 2-8
5187 This is a continuous, 2D color scheme!
5188 @tparam cutDepth See: tfrmComplexCut()
5189 @tparam argCuts See: tfrmComplexCut()
5190 @tparam absCuts See: tfrmComplexCut()
5191 @tparam logAbs See: tfrmComplexCut() */
5192 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5194#endif
5195 //@}
5196
5197 template <class csT, class csAT> colorTpl& csSet(csAT csArg) { return csT::c(*this, csArg); }
5198 template <class csT, class csAT> colorTpl& csSet(csAT csArg1, csAT csArg2) { return csT::c(*this, csArg1, csArg2); }
5199
5200 };
5201
5202////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5203 /** i/O stream output operator for colorTpl types. */
5204 template <class clrChanT, int numChan, int redChanIdx = -1, int blueChanIdx = -1, int greenChanIdx = -1, int alphaChanIdx = -1>
5205 requires ((numChan>0) && // Must have at least 1 chan
5206 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
5207 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
5208 (redChanIdx < numChan) &&
5209 (blueChanIdx < numChan) &&
5210 (greenChanIdx < numChan) &&
5211 (alphaChanIdx < numChan) &&
5212 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
5213 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
5214 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
5215 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
5216 (redChanIdx != blueChanIdx) &&
5217 (redChanIdx != alphaChanIdx) &&
5218 (greenChanIdx != blueChanIdx) &&
5219 (greenChanIdx != alphaChanIdx) &&
5220 (blueChanIdx != alphaChanIdx)))) // Chans can't be the same if non-negative
5221 inline std::ostream&
5222 operator<< (std::ostream &out, colorTpl<clrChanT, numChan> const& color) {
5223 // 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..
5224 out << "<";
5225 if (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) > sizeof(uint64_t))) {
5226 for(int i=0; i<(numChan-1); i++)
5227 out << color.getChan(i) << ", ";
5228 out << color.getChan(numChan-1) << ">";
5229 } else {
5230 for(int i=0; i<(numChan-1); i++)
5231 out << static_cast<uint64_t>(color.getChan(i)) << ", ";
5232 out << static_cast<uint64_t>(color.getChan(numChan-1)) << ">";
5233 }
5234 return out;
5235 }
5236
5237////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5238 /** Inequality operator for colorTpl types. */
5239 template <class clrChanT, int numChan, int redChanIdx = -1, int blueChanIdx = -1, int greenChanIdx = -1, int alphaChanIdx = -1>
5240 requires ((numChan>0) && // Must have at least 1 chan
5241 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
5242 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
5243 (redChanIdx < numChan) &&
5244 (blueChanIdx < numChan) &&
5245 (greenChanIdx < numChan) &&
5246 (alphaChanIdx < numChan) &&
5247 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
5248 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
5249 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
5250 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
5251 (redChanIdx != blueChanIdx) &&
5252 (redChanIdx != alphaChanIdx) &&
5253 (greenChanIdx != blueChanIdx) &&
5254 (greenChanIdx != alphaChanIdx) &&
5255 (blueChanIdx != alphaChanIdx)))) // Chans can't be the same if non-negative
5256 inline bool
5257 operator!= (colorTpl<clrChanT, numChan> const& color1, colorTpl<clrChanT, numChan> const& color2) {
5258 return color1.isNotEqual(color2);
5259 }
5260
5261} // end namespace mjr
5262
5263#define MJR_INCLUDE_MRcolorTpl
5264#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.
std::function< void(colorTpl &)> cr2void_func_t
color reference to void (transform)
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].
std::function< colorTpl &(colorTpl &)> cr2cr_func_t
color reference to color reference (transform)
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.
std::function< colorTpl(colorTpl)> co2co_func_t
color to color (transform)
clrChanT channelType
Type for the channels (clrChanT)
colorTpl & setC3_dbl(double cVal)
std::function< colorTpl(colorTpl &)> cr2co_func_t
color reference to color (transform)
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 ...