MRaster lib 22.0.0.0
Image Processing Library
Loading...
Searching...
No Matches
MRcolorTpl.hpp
Go to the documentation of this file.
1// -*- Mode:C++; Coding:us-ascii-unix; fill-column:158 -*-
2/*******************************************************************************************************************************************************.H.S.**/
3/**
4 @file MRcolorTpl.hpp
5 @author Mitch Richling <https://www.mitchr.me>
6 @brief Header for the ramColor class@EOL
7 @copyright
8 @parblock
9 Copyright (c) 1988-2015, Mitchell Jay Richling <https://www.mitchr.me> All rights reserved.
10
11 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
12
13 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.
14
15 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation
16 and/or other materials provided with the distribution.
17
18 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software
19 without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 DAMAGE.
27 @endparblock
28*/
29/*******************************************************************************************************************************************************.H.E.**/
30
31////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32#ifndef MJR_INCLUDE_MRcolorTpl
33
34#include "MRMathFC.hpp"
35#include "MRMathIVL.hpp"
36#include "MRMathLINM.hpp"
37#include "MRMathODR.hpp"
38
39////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
40#include <algorithm> /* STL algorithm C++11 */
41#include <array> /* array template C++11 */
42#include <bit> /* STL bit manipulation C++20 */
43#include <climits> /* std:: C limits.h C++11 */
44#include <cmath> /* std:: C math.h C++11 */
45#include <complex> /* Complex Numbers C++11 */
46#include <concepts> /* Concepts library C++20 */
47#include <cstring> /* std:: C string.h C++11 */
48#include <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)> co2coType; //!< color to color (transform)
246 typedef std::function<colorTpl&(colorTpl&)> cr2crType; //!< color reference to color reference (transform)
247 typedef std::function<colorTpl(colorTpl&)> cr2coType; //!< color reference to color (transform)
248 typedef std::function<void(colorTpl&)> cr2voidType; //!< 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)
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 with native mjr::colorTpl::clrChanT inputs.
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)
678 setChansRGBA(r, g, b, a);
679 }
680 colorTpl(clrChanT r, clrChanT g, clrChanT b) {
681 if constexpr (numChan > 3)
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; }
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; }
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 Channel Transformations.*/
1901 //@{
1902 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1903 /** Adds the value to the give channel.
1904 @warning No bounds checking on the value of chan!!!
1905 @param chan The channel number. Default: 0
1906 @param v The value to add. Default: 1
1907 @return Returns a reference to the current color object.*/
1908 // theColor.thePartsA[chan] += v; is faster, but not idiomatic.
1909 inline colorTpl& tfrmChanIncr(int chan = 0, clrChanT v = 1) { setChanNC(chan, getChanNC(chan) + v); return *this; }
1910 //@}
1911
1912 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1913 /** @name Logical Operators */
1914 //@{
1915 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1916 /** Performs a logical OR with the current object and the given object and places the value in the current object.
1917 @param aCol The color to use in the computation.
1918 @return Returns a reference to the current color object.*/
1919 inline colorTpl& tfrmOr(colorArgType aCol) requires (std::integral<clrChanT>) {
1920 if constexpr (goodMask)
1921 setMaskNC(getMaskNC() | aCol.getMaskNC());
1922 else
1923 for(int i=0; i<numChan; i++)
1924 setChanNC(i, getChanNC(i) | aCol.getChanNC(i));
1925 return *this;
1926 }
1927#if !(MISSING_P0476R2)
1928 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1929 /** Template specialization member function differing from the above function only in supported template conditions. */
1930 inline colorTpl& tfrmOr(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1931 /* Performance: Yep. Sometimes floating point colors get a goodMask. */
1932 if constexpr (goodMask)
1933 setMaskNC(getMaskNC() | aCol.getMaskNC());
1934 else
1935 for(int i=0; i<numChan; i++)
1936 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) | std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
1937 return *this;
1938 }
1939#endif
1940 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1941 /** Performs a logical NOR with the current object and the given object and places the value in the current object.
1942 @param aCol The color to use in the computation.
1943 @return Returns a reference to the current color object.*/
1944 inline colorTpl& tfrmNor(colorArgType aCol) requires (std::integral<clrChanT>) {
1945 if constexpr (goodMask)
1946 setMaskNC(~(getMaskNC() | aCol.getMaskNC()));
1947 else
1948 for(int i=0; i<numChan; i++)
1949 setChanNC(i, ~(getChanNC(i) | aCol.getChanNC(i)));
1950 return *this;
1951 }
1952#if !(MISSING_P0476R2)
1953 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1954 /** Template specialization member function differing from the above function only in supported template conditions. */
1955 inline colorTpl& tfrmNor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1956 if constexpr (goodMask)
1957 setMaskNC(~(getMaskNC() | aCol.getMaskNC()));
1958 else
1959 for(int i=0; i<numChan; i++)
1960 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) | std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
1961 return *this;
1962 }
1963#endif
1964 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1965 /** Performs a logical AND with the current object and the given object and places the value in the current object.
1966 @param aCol The color to use in the computation.
1967 @return Returns a reference to the current color object.*/
1968 inline colorTpl& tfrmAnd(colorArgType aCol) requires (std::integral<clrChanT>) {
1969 if constexpr (goodMask)
1970 setMaskNC(getMaskNC() & aCol.getMaskNC());
1971 else
1972 for(int i=0; i<numChan; i++)
1973 setChanNC(i, getChanNC(i) & aCol.getChanNC(i));
1974 return *this;
1975 }
1976#if !(MISSING_P0476R2)
1977 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1978 /** Template specialization member function differing from the above function only in supported template conditions. */
1979 inline colorTpl& tfrmAnd(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1980 if constexpr (goodMask)
1981 setMaskNC(getMaskNC() & aCol.getMaskNC());
1982 else
1983 for(int i=0; i<numChan; i++)
1984 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) & std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
1985 return *this;
1986 }
1987#endif
1988 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1989 /** Performs a logical NAND with the current object and the given object and places the value in the current object.
1990 @param aCol The color to use in the computation.
1991 @return Returns a reference to the current color object.*/
1992 inline colorTpl& tfrmNand(colorArgType aCol) requires (std::integral<clrChanT>) {
1993 if constexpr (goodMask)
1994 setMaskNC(~(getMaskNC() & aCol.getMaskNC()));
1995 else
1996 for(int i=0; i<numChan; i++)
1997 setChanNC(i, ~(getChanNC(i) & aCol.getChanNC(i)));
1998 return *this;
1999 }
2000#if !(MISSING_P0476R2)
2001 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2002 /** Template specialization member function differing from the above function only in supported template conditions. */
2003 inline colorTpl& tfrmNand(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2004 if constexpr (goodMask)
2005 setMaskNC(~(getMaskNC() & aCol.getMaskNC()));
2006 else
2007 for(int i=0; i<numChan; i++)
2008 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) & std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
2009 return *this;
2010 }
2011#endif
2012 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2013 /** Performs a logical EXCLUSIVE OR (XOR) with the current object and the given object and places the value in the current object.
2014 @param aCol The color to use in the computation.
2015 @return Returns a reference to the current color object.*/
2016 inline colorTpl& tfrmXor(colorArgType aCol) requires (std::integral<clrChanT>) {
2017 if constexpr (goodMask)
2018 setMaskNC(getMaskNC() ^ aCol.getMaskNC());
2019 else
2020 for(int i=0; i<numChan; i++)
2021 setChanNC(i, getChanNC(i) ^ aCol.getChanNC(i));
2022 return *this;
2023 }
2024#if !(MISSING_P0476R2)
2025 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2026 /** Template specialization member function differing from the above function only in supported template conditions. */
2027 inline colorTpl& tfrmXor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2028 if constexpr (goodMask)
2029 setMaskNC(getMaskNC() ^ aCol.getMaskNC());
2030 else
2031 for(int i=0; i<numChan; i++)
2032 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) ^ std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
2033 return *this;
2034 }
2035#endif
2036 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2037 /** Performs a logical NOT EXCLUSIVE OR (NXOR) with the current object and the given object and places the value in the current object.
2038 @param aCol The color to use in the computation.
2039 @return Returns a reference to the current color object.*/
2040 inline colorTpl& tfrmNxor(colorArgType aCol) requires (std::integral<clrChanT>) {
2041 if constexpr (goodMask)
2042 setMaskNC(~(getMaskNC() ^ aCol.getMaskNC()));
2043 else
2044 for(int i=0; i<numChan; i++)
2045 setChanNC(i, ~(getChanNC(i) ^ aCol.getChanNC(i)));
2046 return *this;
2047 }
2048#if !(MISSING_P0476R2)
2049 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2050 /** Template specialization member function differing from the above function only in supported template conditions. */
2051 inline colorTpl& tfrmNxor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2052 if constexpr (goodMask)
2053 setMaskNC(~(getMaskNC() ^ aCol.getMaskNC()));
2054 else
2055 for(int i=0; i<numChan; i++)
2056 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) ^ std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
2057 return *this;
2058 }
2059#endif
2060 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2061 /** Performs logical (bit-wise) negation of current object.
2062 @return Returns a reference to the current color object.*/
2063 inline colorTpl& tfrmNot(void) requires (std::integral<clrChanT>) {
2064 if constexpr (goodMask)
2065 setMaskNC(~(getMaskNC()));
2066 else
2067 for(int i=0; i<numChan; i++)
2068 setChanNC(i, ~(getChanNC(i)));
2069 return *this;
2070 }
2071#if !(MISSING_P0476R2)
2072 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2073 /** Template specialization member function differing from the above function only in supported template conditions. */
2074 inline colorTpl& tfrmNot(void) requires (std::floating_point<clrChanT>) {
2075 if constexpr (goodMask)
2076 setMaskNC(~(getMaskNC()));
2077 else
2078 for(int i=0; i<numChan; i++)
2079 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)))));
2080 return *this;
2081 }
2082#endif
2083 //@}
2084
2085 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2086 /** @name Arithmetic Operators */
2087 //@{
2088 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2089 /** Computes the square of the difference for each channel between the given color and the current color object.
2090 @param aCol The color to use in the computation.
2091 @return Returns a reference to the current color object.*/
2093 for(int i=0; i<numChan; i++)
2094 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithSDPType>(getChanNC(i)) - static_cast<channelArithSDPType>(aCol.getChanNC(i))) *
2095 (static_cast<channelArithSDPType>(getChanNC(i)) - static_cast<channelArithSDPType>(aCol.getChanNC(i)))));
2096 return *this;
2097 }
2098 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2099 /** Computes the absolute value of the difference for each channel between the given color and the current color object.
2100 @param aCol The color to use in the computation.
2101 @return Returns the absolute value of the difference for each channel.*/
2103 for(int i=0; i<numChan; i++)
2104 setChanNC(i, static_cast<clrChanT>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i)))));
2105 return *this;
2106 }
2107 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2108 /** Computes the arithmetic sum of the given color and the current one.
2109 @param aCol The color to use in the computation.
2110 @return Returns a reference to the current color object.*/
2112 for(int i=0; i<numChan; i++)
2113 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))));
2114 return *this;
2115 }
2116 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2117 /** Computes the arithmetic division of the current color by the given color.
2118 If a channel of aCol is zero, then the corresponding channel of the current color object will be left untouched.
2119 @param aCol The color to use in the computation.
2120 @return Returns a reference to the current color object.*/
2121 inline colorTpl& tfrmDiv(colorArgType aCol) requires (std::integral<clrChanT>) {
2122 for(int i=0; i<numChan; i++)
2123 if (aCol.getChanNC(i) != 0)
2124 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) / static_cast<channelArithSPType>(aCol.getChanNC(i))));
2125 return *this;
2126 }
2127 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2128 /** Template specialization member function differing from the above function only in supported template conditions. */
2129 inline colorTpl& tfrmDiv(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2130 for(int i=0; i<numChan; i++)
2131 if (mjr::math::fc::not_near_zero(aCol.getChanNC(i), static_cast<clrChanT>(1.0e-8)))
2132 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) / static_cast<channelArithSPType>(aCol.getChanNC(i))));
2133 return *this;
2134 }
2135 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2136 /** Computes the arithmetic product of the given color and the current one.
2137 @param aCol The color to use in the computation.
2138 @return Returns a reference to the current color object.*/
2140 for(int i=0; i<numChan; i++)
2141 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(aCol.getChanNC(i))));
2142 return *this;
2143 }
2144 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2145 /** Computes the product of the given color and the current one.
2146 If the result of a multiplication is too large, it will be set to the maximum component value.
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 setChanNC(i, clampTop(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(aCol.getChanNC(i))));
2152 return *this;
2153 }
2154 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2155 /** Computes the component wise scaled sign of the difference between the current color and the given one.
2156 As an example of the computation, the red component of the current color is computed like this:
2157 - R=#minChanVal iff(R<color.R)
2158 - R=#meanChanVal iff(R==color.R)
2159 - R=#maxChanVal iff(R>color.R)
2160 @param aCol The color to use in the computation.
2161 @return Returns a reference to the current color object.*/
2163 for(int i=0; i<numChan; i++) {
2164 if(getChanNC(i) < aCol.getChanNC(i)) {
2166 } else if(getChanNC(i) > aCol.getChanNC(i)) {
2168 } else {
2170 }
2171 }
2172 return *this;
2173 }
2174 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2175 /** Computes the arithmetic difference of the given color from the current one.
2176 If the result a differences is negative, then that component will be set to zero.
2177 @param aCol The color to use in the computation.
2178 @return Returns a reference to the current color object.*/
2180 for(int i=0; i<numChan; i++)
2181 setChanNC(i, clampBot(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i))));
2182 return *this;
2183 }
2184 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2185 /** Computes the negative of the arithmetic difference of the given color from the current one.
2186 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
2187 component will be set to zero.
2188 @param aCol The color to use in the computation.
2189 @return Returns a reference to the current color object.*/
2191 for(int i=0; i<numChan; i++)
2192 setChanNC(i, clampBot(static_cast<channelArithDType>(aCol.getChanNC(i)) - static_cast<channelArithDType>(getChanNC(i))));
2193 return *this;
2194 }
2195 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2196 /** Computes the arithmetic sum of the given color from the current one.
2197 If the result of a sum is greater than the maximum value, then that component will be set to the maximum value.
2198 @param aCol The color to use in the computation.
2199 @return Returns a reference to the current color object.*/
2201 for(int i=0; i<numChan; i++)
2202 setChanNC(i, clampTop(static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))));
2203 return *this;
2204 }
2205 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2206 /** Computes the arithmetic sum of the current color and aCol, then divids by dCol.
2207 If the result is greater than the maximum value, then that component will be set to the maximum value.
2208 If a channel of dCol is zero, then the corresponding channel of the current color object will be left untouched.
2209 @param aCol The color to use for initial add.
2210 @param dCol The color to use for final division.
2211 @return Returns a reference to the current color object.*/
2212 inline colorTpl& tfrmAddDivClamp(colorArgType aCol, colorArgType dCol) requires (std::integral<clrChanT>) {
2213 for(int i=0; i<numChan; i++)
2214 if (dCol.getChanNC(i) != 0)
2215 setChanNC(i, clampTop((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) /
2216 static_cast<channelArithSPType>(dCol.getChanNC(i))));
2217 return *this;
2218 }
2219 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2220 /** Template specialization member function differing from the above function only in supported template conditions. */
2221 inline colorTpl& tfrmAddDivClamp(colorArgType aCol, colorArgType dCol) requires (std::floating_point<clrChanT>) {
2222 for(int i=0; i<numChan; i++)
2223 if (mjr::math::fc::not_near_zero(dCol.getChanNC(i), static_cast<clrChanT>(1.0e-8)))
2224 setChanNC(i, clampTop((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) /
2225 static_cast<channelArithSPType>(dCol.getChanNC(i))));
2226 return *this;
2227 }
2228 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2229 /** Computes the arithmetic difference of the given color from the current one.
2230 @param aCol The color to use in the computation.
2231 @return Returns a reference to the current color object.*/
2233 for(int i=0; i<numChan; i++)
2234 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i))));
2235 return *this;
2236 }
2237 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2238 /** Computes the arithmetic modulus of the current by the given one.
2239 If a channel of aCol is zero, then the corresponding channel of the current object is left untouched.
2240 @param aCol The color to use in the computation.
2241 @return Returns a reference to the current color object.*/
2242 inline colorTpl& tfrmMod(colorArgType aCol) requires (std::integral<clrChanT>) {
2243 for(int i=0; i<numChan; i++)
2244 if (aCol.getChanNC(i) != 0)
2245 setChanNC(i, getChanNC(i) % aCol.getChanNC(i));
2246 return *this;
2247 }
2248 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2249 /** Template specialization member function differing from the above function only in supported template conditions. */
2250 inline colorTpl& tfrmMod(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2251 for(int i=0; i<numChan; i++)
2252 if (mjr::math::fc::not_near_zero(aCol.getChanNC(i), static_cast<clrChanT>(1.0e-8)))
2253 setChanNC(i, static_cast<clrChanT>(std::fmod(static_cast<double>(getChanNC(i)), static_cast<double>(aCol.getChanNC(i)))));
2254 return *this;
2255 }
2256 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2257 /** Transforms the color: r=#maxChanVal-r, g=#maxChanVal-r, and b=#maxChanVal-b
2258 @return Returns a reference to the current color object.*/
2260 // MJR TODO NOTE tfrmInvert: This is just as fast as array refs...
2261 // MJR TODO NOTE tfrmInvert: We should use this universally across the library -- to isolate the code from the array specifics...
2262 for(int i=0; i<numChan; i++)
2264 return *this;
2265 }
2266 //@}
2267
2268 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2269 /** @name Named Operators */
2270 //@{
2271 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2272 /** Power: c=maxChanVal*(c/maxChanVal)^p.
2273 Floating point Numbers are used for intermediate values and the result cast to a colorT at the end.
2274 Take care when negative values for p -- this can cause undefined behavior!!
2275 @return Returns a reference to the current color object.*/
2276 inline colorTpl& tfrmPow(double p) {
2277 for(int i=0; i<numChan; i++)
2278 setChanNC(i, static_cast<clrChanT>(static_cast<double>(maxChanVal) * std::pow(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal), p)));
2279 return *this;
2280 }
2281 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2282 /** Adds 1.0 and takes the natural logarithm of each channel.
2283 Floating point Numbers are used for intermediate values and the result cast to a colorT at the end.
2284 If a channel value would result in an undefined result, then the value is left untouched.
2285 @return Returns a reference to the current color object.*/
2286 inline colorTpl& tfrmLn1() requires (std::integral<clrChanT>) {
2287 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2288 for(int i=0; i<numChan; i++)
2289 setChanNC(i, static_cast<clrChanT>(std::log(1.0 + static_cast<double>(getChanNC(i)))));
2290 return *this;
2291 }
2292 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2293 /** Template specialization member function differing from the above function only in supported template conditions. */
2294 inline colorTpl& tfrmLn1() requires (std::floating_point<clrChanT>) {
2295 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2296 for(int i=0; i<numChan; i++) {
2297 clrChanT cVal = getChanNC(i);
2298 if (cVal > static_cast<clrChanT>(-1.0))
2299 setChanNC(i, static_cast<clrChanT>(std::log(1.0 + static_cast<double>(cVal))));
2300 }
2301 return *this;
2302 }
2303 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2304 /** Computes ln(c)*scale for each channel value c. If c==0, then the value is left undisturbed.
2305 Floating point Numbers are used for intermediate values and the result cast to a colorT at the end.
2306 If a channel value would result in an undefined result, then the value is left untouched.
2307 @param scale The scale value to multiply by the final result.
2308 @return Returns a reference to the current color object.*/
2309 inline colorTpl& tfrmLn(double scale) requires (std::integral<clrChanT>) {
2310 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2311 for(int i=0; i<numChan; i++) {
2312 clrChanT cVal = getChanNC(i);
2313 if(cVal != 0)
2314 setChanNC(i, static_cast<clrChanT>(std::log(static_cast<double>(cVal)) * scale));
2315 }
2316 return *this;
2317 }
2318 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2319 /** Template specialization member function differing from the above function only in supported template conditions. */
2320 inline colorTpl& tfrmLn(double scale) requires (std::floating_point<clrChanT>) {
2321 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2322 for(int i=0; i<numChan; i++) {
2323 clrChanT cVal = getChanNC(i);
2324 if (cVal > static_cast<clrChanT>(0.0))
2325 setChanNC(i, static_cast<clrChanT>(std::log(static_cast<double>(cVal)) * scale));
2326 }
2327 return *this;
2328 }
2329 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2330 /** Linearly interpolate between the current color and the given color (at a point scaled the unit interval).
2331 If \a aDouble is 0, then the current color will not change. If \a aDouble is 1, then the current color will be tooCol.
2332 @param aDouble Distance from the current color (on a unit interval)
2333 @param tooCol The color we are interpolating with.
2334 @return Returns a reference to the current color object.*/
2335 inline colorTpl& tfrmMix(double aDouble, colorArgType tooCol) {
2336 if( (aDouble >= 0.0) && (aDouble <= 1.0) )
2337 for(int i=0; i<numChan; i++)
2338 setChanNC(i, static_cast<clrChanT>(mjr::math::linm::interpolate(static_cast<double>(getChanNC(i)), static_cast<double>(tooCol.getChanNC(i)), aDouble)));
2339 return *this;
2340 }
2341 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2342 /** Copies the given argument into the current color object.
2343 Scan as copy() -- just with a name more suited to transformation code.
2344 @return Returns a reference to the current color object.*/
2345 inline colorTpl& tfrmCopy(colorArgType aCol) { return copy(aCol); }
2346 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2347 /** Makes the current color the maximum of the current color or the given color.
2348 Colors are ordered by intensity (thus the 'I' in the name)
2349 @param aCol The color to use in the computation.
2350 @return Returns a reference to the current color object.*/
2352 channelArithSPType thisSum = 0;
2353 channelArithSPType thatSum = 0;
2354 for(int i=0; i<numChan; i++) {
2355 thisSum += static_cast<channelArithSPType>(getChanNC(i));
2356 thatSum += static_cast<channelArithSPType>(aCol.getChanNC(i));
2357 }
2358 if(thisSum < thatSum)
2359 tfrmCopy(aCol);
2360 return *this;
2361 }
2362 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2363 /** Makes the current color the minimum of the current color or the given color.
2364 Colors are ordered by intensity (thus the 'I' in the name)
2365 @param aCol The color to use in the computation.
2366 @return Returns a reference to the current color object.*/
2368 /* Performance: Finding the max of two arrays in parallel with one loop is faster than calling max twice, once for each array. */
2369 channelArithSPType thisSum = 0;
2370 channelArithSPType thatSum = 0;
2371 for(int i=0; i<numChan; i++) {
2372 thisSum += static_cast<channelArithSPType>(getChanNC(i));
2373 thatSum += static_cast<channelArithSPType>(aCol.getChanNC(i));
2374 }
2375 if(thisSum > thatSum)
2376 tfrmCopy(aCol);
2377 return *this;
2378 }
2379 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2380 /** Makes each component of the current color the maximum of that component and the corresponding component of the given color.
2381 @param aCol The color to use in the computation.
2382 @return Returns a reference to the current color object.*/
2384 for(int i=0; i<numChan; i++)
2385 if(getChanNC(i) < aCol.getChanNC(i))
2386 setChanNC(i, aCol.getChanNC(i));
2387 return *this;
2388 }
2389 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2390 /** Makes each component of the current color the minimum of that component and the corresponding component of the given color.
2391 @param aCol The color to use in the computation.
2392 @return Returns a reference to the current color object.*/
2394 for(int i=0; i<numChan; i++)
2395 if(getChanNC(i) > aCol.getChanNC(i))
2396 setChanNC(i, aCol.getChanNC(i));
2397 return *this;
2398 }
2399 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2400 /** The Shift Left Transform modifies the current color.
2401 @param aCol Number of bits to shift left
2402 @return Returns a reference to the current color object.*/
2403 inline colorTpl& tfrmShiftL(colorArgType aCol) requires (std::integral<clrChanT>) {
2404 for(int i=0; i<numChan; i++)
2405 setChanNC(i, getChanNC(i) << aCol.getChanNC(i));
2406 return *this;
2407 }
2408#if !(MISSING_P0476R2)
2409 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2410 /** Template specialization member function differing from the above function only in supported template conditions. */
2411 inline colorTpl& tfrmShiftL(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2412 for(int i=0; i<numChan; i++)
2413 /* 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. */
2414 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) << static_cast<uint64_t>(aCol.getChanNC(i))));
2415 return *this;
2416 }
2417#endif
2418 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2419 /** The Shift Right Transform modifies the current color.
2420 @param aCol How many bits to shift.
2421 @return Returns a reference to the current color object.*/
2422 inline colorTpl& tfrmShiftR(colorArgType aCol) requires (std::integral<clrChanT>) {
2423 for(int i=0; i<numChan; i++)
2424 setChanNC(i, getChanNC(i) >> aCol.getChanNC(i));
2425 return *this;
2426 }
2427#if !(MISSING_P0476R2)
2428 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2429 /** Template specialization member function differing from the above function only in supported template conditions. */
2430 inline colorTpl& tfrmShiftR(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2431 for(int i=0; i<numChan; i++)
2432 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) >> static_cast<uint64_t>(aCol.getChanNC(i))));
2433 return *this;
2434 }
2435#endif
2436 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2437 /** The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, C_i, 0)
2438 @param lowCol lower cutoff value
2439 @param highCol upper cutoff value
2440 @return Returns a reference to the current color object.*/
2441 inline colorTpl& tfrmSaw(colorArgType lowCol, colorArgType highCol) {
2442 for(int i=0; i<numChan; i++)
2443 setChanNC(i, ((lowCol.getChanNC(i) <= getChanNC(i)) && (highCol.getChanNC(i) >= getChanNC(i)) ? getChanNC(i) : 0));
2444 return *this;
2445 }
2446 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2447 /** The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, maxChanVal, 0)
2448 @param lowCol lower cutoff value
2449 @param highCol upper cutoff value
2450 @return Returns a reference to the current color object.*/
2451 inline colorTpl& tfrmStep(colorArgType lowCol, colorArgType highCol) {
2452 for(int i=0; i<numChan; i++)
2453 setChanNC(i, ((lowCol.getChanNC(i) <= getChanNC(i)) && (highCol.getChanNC(i) >= getChanNC(i)) ? maxChanVal : 0));
2454 return *this;
2455 }
2456 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2457 /** The DiracTot (total) Transform modifies the current color: Set current color to white if it equals aCol, and black otherwise.
2458 @param aCol Dirac trigger value
2459 @return Returns a reference to the current color object.*/
2461 for(int i=0; i<numChan; i++)
2462 if(aCol.getChanNC(i) != getChanNC(i))
2463 return setToBlack();
2464 return setToWhite();
2465 }
2466 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2467 /** The Dirac Transform modifies the current color: C_i = ifelse(C_i==aCol.C_i, maxChanVal, 0)
2468 @param aCol Dirac trigger value
2469 @return Returns a reference to the current color object.*/
2471 for(int i=0; i<numChan; i++)
2472 setChanNC(i, ((aCol.getChanNC(i) == getChanNC(i)) ? maxChanVal : 0));
2473 return *this;
2474 }
2475 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2476 /** The Fuzzy Dirac Transform modifies the current color: C_i=ifelse(|R-ctrCol.R|<=radCol.R), maxChanVal, 0)
2477 @param ctrCol Center Color
2478 @param radCol Radius Color
2479 @return Returns a reference to the current color object.*/
2481 for(int i=0; i<numChan; i++)
2482 setChanNC(i, ((std::abs(ctrCol.getChanNC(i) - getChanNC(i)) <= radCol.getChanNC(i)) ? maxChanVal : 0));
2483 return *this;
2484 }
2485 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2486 /** Computes the arithmetic mean of the given color and the current one.
2487 @param aCol The color to use in the computation.
2488 @return Returns a reference to the current color object.*/
2490 for(int i=0; i<numChan; i++)
2491 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) / 2));
2492 return *this;
2493 }
2494 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2495 /** Computes the geometric mean of the given color and the current one.
2496 Floating point Numbers re used for intermediate values and the result cast to a colorT at the end.
2497 @param aCol The color to use in the computation.
2498 @return Returns a reference to the current color object.*/
2500 for(int i=0; i<numChan; i++)
2501 setChanNC(i, static_cast<clrChanT>(std::sqrt(static_cast<channelArithFltType>(getChanNC(i)) * static_cast<channelArithFltType>(aCol.getChanNC(i)))));
2502 return *this;
2503 }
2504 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2505 /** Transform the current color by rendering it into a true grey via the same method used by the luminanceRGB() function.
2506 This function only sets the red, blue, and green channels -- all other channels are left untouched.
2507 @return Returns a reference to the current color object.*/
2509 /* Requires: Inherits numChan>2 from getC2. */
2510 double lumU = static_cast<double>(luminanceRGB());
2511 setRed_dbl( lumU);
2512 setGreen_dbl(lumU);
2513 setBlue_dbl( lumU);
2514 return *this;
2515 }
2516 //@}
2517
2518 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2519 /** @name Color Reduction Transformations */
2520 //@{
2521 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2522 /** The 216 Palate Web Safe Transform modifies the current color into the closest web safe color from the 216 color web safe pallet.
2523 This function only sets the red, blue, and green channels -- all other channels are left untouched.
2524 @return Returns a reference to the current color object.*/
2525 inline colorTpl& tfrmWebSafeRGB() requires (redChan>=0) {
2526 for (int c : {redChan, blueChan, greenChan}) {
2527 int charCompVal = convertChanToByte(getChanNC(c));
2528 int minDist = 256;
2529 int minCol;
2530 for(int pv : { 0x0, 0x33, 0x66, 0x99, 0xCC, 0xFF }) {
2531 int curDist = std::abs(charCompVal - pv);
2532 if( curDist < minDist ) {
2533 minDist = curDist;
2534 minCol = pv;
2535 }
2536 }
2537 setChanNC(c, convertByteToChan(static_cast<uint8_t>(minCol)));
2538 }
2539 return *this;
2540 }
2541 //@}
2542
2543 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2544 /** @name Alternate Color Space Stuff */
2545 //@{
2546 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2547 /** Compute channels for given color space coordinates for the current color.
2548 Note RGB returns float RGB normalized to 1.0.
2549 @param space The color space to convert to
2550 @return An RGB color with double channels. */
2552 /* Requires: Inherits numChan>2 from getBlue. */
2553
2554 double redF = getRed_dbl();
2555 double greenF = getGreen_dbl();
2556 double blueF = getBlue_dbl();
2557
2558 if (space == colorSpaceEnum::RGB)
2559 return colConDbl3(redF, greenF, blueF);
2560
2561 if ((space == colorSpaceEnum::HSL) || (space == colorSpaceEnum::HSV)) {
2562 clrChanT rgbMaxI = getMaxRGB();
2563 clrChanT rgbMinI = getMinRGB();
2564
2565 channelArithSDPType rangeI = rgbMaxI - rgbMinI;
2566
2567 double rgbMaxF = static_cast<double>(rgbMaxI) / static_cast<double>(maxChanVal);
2568 double rgbMinF = static_cast<double>(rgbMinI) / static_cast<double>(maxChanVal);
2569
2570 double rangeF = rgbMaxF - rgbMinF;
2571 double sumF = rgbMaxF + rgbMinF;
2572
2573 // Compute L
2574 double L = sumF / 2.0;
2575 double V = rgbMaxF;
2576
2577 // Compute H & S
2578 double S, H;
2579 if((rgbMaxI == 0) || (rangeI == 0)) {
2580 S = 0.0;
2581 H = 0.0;
2582 } else {
2583
2584 if (space == colorSpaceEnum::HSL) {
2585 if(L <= 0.5)
2586 S = rangeF / sumF;
2587 else
2588 S = rangeF / ( 2.0 - sumF);
2589 } else {
2590 S = rangeF / rgbMaxF;
2591 }
2592
2593 H = 0.0;
2594 if(getRed() == rgbMaxI)
2595 H = 0.0 + (greenF - blueF) / rangeF;
2596 else if(getGreen() == rgbMaxI)
2597 H = 2.0 + (blueF - redF) / rangeF;
2598 else if(getBlue() == rgbMaxI)
2599 H = 4.0 + (redF - greenF) / rangeF;
2600 H = mjr::math::ivl::wrapCO(H * 60.0, 360.0);
2601 }
2602 if (space == colorSpaceEnum::HSL)
2603 return colConDbl3(H, S, L);
2604 else
2605 return colConDbl3(H, S, V);
2606 } else {
2607 redF = 100.0 * ((redF > 0.04045) ? std::pow((redF + 0.055) / 1.055, 2.4) : redF / 12.92);
2608 greenF = 100.0 * ((greenF > 0.04045) ? std::pow((greenF + 0.055) / 1.055, 2.4) : greenF / 12.92);
2609 blueF = 100.0 * ((blueF > 0.04045) ? std::pow((blueF + 0.055) / 1.055, 2.4) : blueF / 12.92);
2610
2611 double X = (0.4124 * redF + 0.3576 * greenF + 0.1805 * blueF);
2612 double Y = (0.2126 * redF + 0.7152 * greenF + 0.0722 * blueF); // luminance with weights RGBluminanceWeightR, RGBluminanceWeightG, RGBluminanceWeightB
2613 double Z = (0.0193 * redF + 0.1192 * greenF + 0.9505 * blueF);
2614
2615 if (space == colorSpaceEnum::XYZ)
2616 return colConDbl3(X, Y, Z);
2617
2618 X /= 95.0429;
2619 Y /= 100.0;
2620 Z /= 108.89;
2621
2622 X = (X > 0.008856 ? std::pow(X, 1.0 / 3.0) : (7.787 * X) + (16.0 / 116.0));
2623 Y = (Y > 0.008856 ? std::pow(Y, 1.0 / 3.0) : (7.787 * Y) + (16.0 / 116.0));
2624 Z = (Z > 0.008856 ? std::pow(Z, 1.0 / 3.0) : (7.787 * Z) + (16.0 / 116.0));
2625
2626 double L = (116.0 * Y) - 16.0;
2627 double A = 500.0 * (X - Y);
2628 double B = 200.0 * (Y - Z);
2629
2630 if (space == colorSpaceEnum::LAB)
2631 return colConDbl3(L, A, B);
2632
2633 double C = std::hypot(A, B);
2634
2635 double H = 0.0;
2636 if ( std::abs(A) > 1.0e-5) // Not Grey
2637 H = mjr::math::ivl::wrapCO(atan2(B,A) * 180.0 / std::numbers::pi, 360.0);
2638
2639 if (space == colorSpaceEnum::LCH)
2640 return colConDbl3(L, C, H);
2641 }
2642
2643 return colConDbl3(0.0, 0.0, 0.0);
2644 }
2645 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2646 /** Compute channels for given color space coordinates for the current color.
2647 Note RGB returns float RGB normalized to 1.0.
2648 @param space The color space to stringify
2649 @return A string representing the color space. */
2650 inline std::string colorSpaceToString(colorSpaceEnum space) {
2651 switch (space) {
2652 case colorSpaceEnum::RGB : return std::string("rgb");
2653 case colorSpaceEnum::HSL : return std::string("HSL");
2654 case colorSpaceEnum::HSV : return std::string("HSV");
2655 case colorSpaceEnum::LAB : return std::string("Lab");
2656 case colorSpaceEnum::XYZ : return std::string("XYZ");
2657 case colorSpaceEnum::LCH : return std::string("Lch");
2658 default: return std::string("ERROR");
2659 }
2660 }
2661 //@}
2662
2663 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2664 /** @name Color Transformation Functions */
2665 //@{
2666 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2667 /** The Linear Grey Level Scale transform modifies the current color such that: C_n=c*C_n+b.
2668 This function transforms all channels --- not just RGBA.
2669 @param c The "contrast" value
2670 @param b The "brightness" value
2671 @return Returns a reference to the current color object.*/
2672 inline colorTpl& tfrmLinearGreyLevelScale(double c, double b) {
2673 for(int i=0; i<numChan; i++)
2674 setChanNC(i, static_cast<clrChanT>(c * static_cast<double>(getChanNC(i)) + b));
2675 return *this;
2676 }
2677 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2678 /** The Linear Grey Level Scale transform modifies the current color such that: R=rc*R+rb, G=gc*G+gb, B=bc*B+bb.
2679 This function ONLY transforms the red, green, and blue channels.
2680 @param rc The "contrast" value for red
2681 @param rb The "brightness" value for red
2682 @param gc The "contrast" value for green
2683 @param gb The "brightness" value for green
2684 @param bc The "contrast" value for blue
2685 @param bb The "brightness" value for blue
2686 @return Returns a reference to the current color object.*/
2687 inline colorTpl& tfrmLinearGreyLevelScaleRGB(double rc, double rb, double gc, double gb, double bc, double bb) {
2688 /* Requires: Inherits numChan>3 from setAlpha & getC3. */
2689 setRed( static_cast<clrChanT>(rc * static_cast<double>(getRed()) + rb));
2690 setGreen(static_cast<clrChanT>(gc * static_cast<double>(getGreen()) + gb));
2691 setBlue( static_cast<clrChanT>(bc * static_cast<double>(getBlue()) + bb));
2692 return *this;
2693 }
2694 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2695 /** Perform a tfrmLinearGreyLevelScale based on a complex number.
2696 @param z The complex number
2697 @param cutDepth Range: @f$[1, ~30]@f$ Smaller means more contrast on cuts.
2698 @param argCuts Number of grey cuts for arg
2699 @param absCuts Number of grey cuts for abs
2700 @param logAbs If true, then take the logorithm of abs for cuts. */
2701 inline colorTpl& tfrmComplexCut(std::complex<double> z, double cutDepth, double argCuts, double absCuts, bool logAbs = true) {
2702 double tau = std::numbers::pi * 2; // 2*Pi
2703 double zArg = std::arg(z); // Arg
2704 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
2705 if (argCuts > 0)
2706 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(pzArg*argCuts) - pzArg*argCuts)/cutDepth, 0);
2707 if (absCuts > 0) {
2708 double zAbs = std::abs(z); // Abs
2709 if (logAbs) {
2710 double lzAbs = std::log(zAbs);
2711 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(lzAbs*absCuts) - lzAbs*absCuts)/cutDepth, 0);
2712 } else {
2713 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(zAbs*absCuts) - zAbs*absCuts)/cutDepth, 0);
2714 }
2715 }
2716 return *this;
2717 }
2718 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2719 /** The Standard Power Transform modifies the current color such that: C_i = maxChanVal*(C_i / maxChanVal)**p.
2720 @return Returns a reference to the current color object.*/
2721 inline colorTpl& tfrmStdPow(double p) {
2722 for(int i=0; i<numChan; i++)
2723 setChanNC(i, static_cast<clrChanT>(std::pow(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal), p) * static_cast<double>(maxChanVal)));
2724 return *this;
2725 }
2726 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2727 /** The Standard Power Transform modifies the current color such that:
2728 R=#maxChanVal*(R/#maxChanVal)**rp, B=#maxChanVal*(B/#maxChanVal)**gp, B=#maxChanVal*(B/#maxChanVal)**bp
2729 @return Returns a reference to the current color object.*/
2730 inline colorTpl& tfrmStdPowRGB(double rp, double gp, double bp) {
2731 /* Requires: Inherits numChan>2 from setBlue & getC2. */
2732 setRed( static_cast<clrChanT>(std::pow(static_cast<double>(getRed()) / static_cast<double>(maxChanVal), rp) * static_cast<double>(maxChanVal)));
2733 setGreen(static_cast<clrChanT>(std::pow(static_cast<double>(getGreen()) / static_cast<double>(maxChanVal), gp) * static_cast<double>(maxChanVal)));
2734 setBlue( static_cast<clrChanT>(std::pow(static_cast<double>(getBlue()) / static_cast<double>(maxChanVal), bp) * static_cast<double>(maxChanVal)));
2735 return *this;
2736 }
2737 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2738 /** The Standard Power Transform with p=2. The new color will be: C_i = C_i * C_i / maxChanVal == (C_i/maxChanVal)^2*maxChanVal
2739 This computation is done with integer math if clrChanT is integral.
2740 @return Returns a reference to the current color object.*/
2741 inline colorTpl& tfrmStdPowSqr(void) {
2742 for(int i=0; i<numChan; i++)
2743 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(getChanNC(i)) /
2744 static_cast<channelArithSPType>(maxChanVal)));
2745 return *this;
2746 }
2747 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2748 /** The Standard Power Transform with p=1/2. The new color will be: C_i = sqrt(C_i / maxChanVal) * maxChanVal
2749 @return Returns a reference to the current color object.*/
2750 inline colorTpl& tfrmStdPowSqrt(void) {
2751 for(int i=0; i<numChan; i++)
2752 setChanNC(i, static_cast<clrChanT>(std::sqrt(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal)) * static_cast<double>(maxChanVal)));
2753 return *this;
2754 }
2755 //@}
2756
2757 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2758 /** @name Mathematical Operations On Color(s)
2759 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
2760 result. */
2761 //@{
2762 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2763 /** Use the R, G, & B channels to compute a floating point value representing a grey scale.
2764 What is returned is the dot product of the given color and the three scalars: R*redWt+G*greenWt+B*blueWt.
2765 @param redWt The red weight
2766 @param greenWt The green weight
2767 @param blueWt The blue weight
2768 @return The integer representing grey value for the given color. */
2769 inline channelArithFltType rgb2GreyDotProd(channelArithFltType redWt = RGBluminanceWeightR,
2770 channelArithFltType greenWt = RGBluminanceWeightG,
2771 channelArithFltType blueWt = RGBluminanceWeightB) const {
2772 /* Requires: Inherits numChan>2 from getC2. */
2773 return (static_cast<channelArithFltType>(getRed()) * static_cast<channelArithFltType>(redWt) +
2774 static_cast<channelArithFltType>(getGreen()) * static_cast<channelArithFltType>(greenWt) +
2775 static_cast<channelArithFltType>(getBlue()) * static_cast<channelArithFltType>(blueWt));
2776 }
2777 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2778 /** Compute the luminance of the current color via the definition given in the ITU-R Recommendation BT.709.
2779 The output value will be between 0 and 1, and is given by: (RGBluminanceWeightR*R+RGBluminanceWeightG*G+RGBluminanceWeightB*B)/#maxChanVal.
2780 @return The luminance for the current object. */
2781 inline channelArithFltType luminanceRGB(void) const {
2782 /* Requires: Inherits numChan>2 from getC2. */
2783 return ((static_cast<channelArithFltType>(getRed()) * static_cast<channelArithFltType>(RGBluminanceWeightR) +
2784 static_cast<channelArithFltType>(getGreen()) * static_cast<channelArithFltType>(RGBluminanceWeightG) +
2785 static_cast<channelArithFltType>(getBlue()) * static_cast<channelArithFltType>(RGBluminanceWeightB)) / static_cast<channelArithFltType>(maxChanVal));
2786 }
2787 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2788 /** Compute the unscaled intensity (sum of the R, G, & B components) of the current color
2789 @return The unscaled intensity for the current object. */
2790 inline channelArithSPType intensityRGB(void) const {
2791 /* Requires: Inherits numChan>2 from getC2. */
2792 return static_cast<channelArithSPType>(static_cast<channelArithSPType>(getRed()) +
2793 static_cast<channelArithSPType>(getGreen()) +
2794 static_cast<channelArithSPType>(getC2()));
2795 }
2796 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2797 /** Compute the sum of the components.
2798 @return Sum of components. */
2799 inline channelArithSPType intensity() const {
2800 channelArithSPType sum = 0;
2801 for(int i=0; i<numChan; i++)
2802 sum += getChan(i);
2803 return (sum);
2804 }
2805 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2806 /** Compute the scaled intensity (sum of the first three components divided by the maximum intensity possible) of the current color
2807 @return The scaled intensity for the current object. */
2808 inline channelArithFltType intensityScaledRGB() const {
2809 return (static_cast<channelArithFltType>(intensityRGB()) / static_cast<channelArithFltType>(3) / static_cast<channelArithFltType>(maxChanVal));
2810 }
2811 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2812 /** Compute the scaled intensity (sum of the components divided by the maximum intensity possible) of the current color
2813 @return Sum of components. */
2814 inline channelArithFltType intensityScaled() const {
2815 return (static_cast<channelArithFltType>(intensity()) / static_cast<channelArithFltType>(numChan) / static_cast<channelArithFltType>(maxChanVal));
2816 }
2817 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2818 /** Returns the value of the largest component.
2819 @return The value of the largest color component currently stored.*/
2820 inline clrChanT getMaxC() const {
2821 /* 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.
2822 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
2823 code. */
2824 if constexpr (numChan == 1) { // 1 channel
2825 return getChanNC(0);
2826 } else if constexpr (numChan == 2) { // 2 channels
2827 return std::max(getChanNC(0), getChanNC(1));
2828 } else if constexpr (numChan == 3) { // 3 channels
2829 return mjr::math::odr::max3(getChanNC(0), getChanNC(1), getChanNC(2));
2830 } else if constexpr (numChan == 4) { // 4 channels
2831 return mjr::math::odr::max4(getChanNC(0), getChanNC(1), getChanNC(2), getChanNC(3));
2832 } else { // More than 3 channels
2833 clrChanT theMax = minChanVal;
2834 for(int i=0; i<numChan; i++)
2835 if(theMax < getChanNC(i))
2836 theMax = getChanNC(i);
2837 return theMax;
2838 }
2839 }
2840 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2841 /** Returns the value of the smallest component.
2842 @return The value of the smallest color component currently stored.*/
2843 inline clrChanT getMinC() const {
2844 if constexpr (numChan == 1) { // 1 channel
2845 return getChanNC(0);
2846 } else if constexpr (numChan == 2) { // 2 channels
2847 return std::min(getChanNC(0), getChanNC(1));
2848 } else if constexpr (numChan == 3) { // 3 channels
2849 return mjr::math::odr::min3(getChanNC(0), getChanNC(1), getChanNC(2));
2850 } else if constexpr (numChan == 4) { // 4 channels
2851 return mjr::math::odr::min4(getChanNC(0), getChanNC(1), getChanNC(2), getChanNC(3));
2852 } else {
2853 clrChanT theMin = maxChanVal;
2854 for(int i=0; i<numChan; i++)
2855 if(theMin > getChanNC(i))
2856 theMin = getChanNC(i);
2857 return theMin;
2858 }
2859 }
2860 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2861 /** Returns the value of the largest component from R, G, and B. This function is highly optimized.
2862 @return The value of the largest color component.*/
2863 inline clrChanT getMaxRGB() const { return mjr::math::odr::max3(getRed(), getGreen(), getBlue()); } /* Requires: Inherits numChan>2 from getC2. */
2864 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2865 /** Returns the value of the smallest component from R, G, and B. This function is highly optimized.
2866 @return The value of the smallest color component.*/
2867 inline clrChanT getMinRGB() const { return mjr::math::odr::min3(getRed(), getGreen(), getBlue()); } /* Requires: Inherits numChan>2 from getC2. */
2868 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2869 /** Compute the dot product between the current color and the given color. i.e. c1.r*c2.r+c1.g*c2.g+...
2870 @param aColor the given color
2871 @return Returns dot product.*/
2872 inline channelArithFltType dotProd(colorArgType aColor) const {
2873 channelArithFltType daProd = 0;
2874 for(int i=0; i<numChan; i++)
2875 daProd += static_cast<channelArithFltType>(static_cast<channelArithFltType>(getChanNC(i)) * static_cast<channelArithFltType>(aColor.getChanNC(i)));
2876 return daProd;
2877 }
2878 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2879 /** Distance between current color and given one (sum squares of channel differences -- Euclidean distance squared).
2880 @param aColor The given color
2881 @return Returns Distance */
2882 inline channelArithFltType distHypot(colorArgType aColor) const {
2883 channelArithFltType daDist = 0;
2884 for(int i=0; i<numChan; i++)
2885 daDist += (static_cast<channelArithFltType>((static_cast<channelArithFltType>(getChanNC(i)) - static_cast<channelArithFltType>(aColor.getChanNC(i))) *
2886 (static_cast<channelArithFltType>(getChanNC(i)) - static_cast<channelArithFltType>(aColor.getChanNC(i)))));
2887 return static_cast<channelArithFltType>(std::sqrt(daDist));
2888 }
2889 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2890 /** Distance between current color and given one (sum of absolute channel differences).
2891 @param aColor the given color
2892 @return Returns Distance */
2893 inline channelArithSPType distSumAbs(colorArgType aColor) const {
2894 channelArithSPType daDist = 0;
2895 for(int i=0; i<numChan; i++)
2896 daDist += static_cast<channelArithSPType>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))));
2897 return daDist;
2898 }
2899 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2900 /** Distance between current color and given one (maximum of absolute value of channel differences).
2901 @param aColor the given color
2902 @return Returns Distance */
2903 inline channelArithSPType distMaxAbs(colorArgType aColor) const {
2904 channelArithSPType daDist = 0;
2905 for(int i=0; i<numChan; i++) {
2906 channelArithSPType tmp = static_cast<channelArithSPType>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))));
2907 if (daDist < tmp)
2908 daDist = tmp;
2909 }
2910 return daDist;
2911 }
2912 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2913 /** LAB Delta E* distance between current color and given one.
2914 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.
2915 @param aColor the given color
2916 @return Returns Distance -- note return is a double not a channelArithFltType. */
2917 inline double distDeltaE1976(colorArgType aColor) const {
2918 colConDbl3 acol1 = rgb2colorSpace(colorSpaceEnum::LAB);
2919 colConDbl3 acol2 = aColor.rgb2colorSpace(colorSpaceEnum::LAB);
2920 double daDist = 0;
2921 for (int c=0; c<3; c++)
2922 daDist += std::pow(acol1.getChanNC(c) - acol2.getChanNC(c), 2);
2923 daDist = std::sqrt(daDist);
2924 return daDist;
2925 }
2926 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2927 /** LAB Delta E* 1994 (graphic arts) distance between current color and given one.
2928 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.
2929 Note: The Delta E* 1994 distance measurement is NOT symetric -- the 1976 one is!
2930 @param aColor the given color
2931 @return Returns Distance -- note return is a double not a channelArithFltType. */
2932 inline double distDeltaE1994(colorArgType aColor) const {
2933 colConDbl3 acol1 = rgb2colorSpace(colorSpaceEnum::LAB);
2934 colConDbl3 acol2 = aColor.rgb2colorSpace(colorSpaceEnum::LAB);
2935 double k1 = 0.045;
2936 double k2 = 0.015;
2937 double kL = 1.000;
2938 double kC = 1.000;
2939 double kH = 1.000;
2940 double sL = 1.000;
2941 double dL = acol1.getC0() - acol2.getC0();
2942 double da = acol1.getC1() - acol2.getC1();
2943 double db = acol1.getC2() - acol2.getC2();
2944 double c1 = std::sqrt(std::pow(acol1.getC1(), 2) + std::pow(acol1.getC2(), 2));
2945 double c2 = std::sqrt(std::pow(acol2.getC1(), 2) + std::pow(acol2.getC2(), 2));
2946 double sH = 1.000 + k2 * c1;
2947 double sC = 1.000 + k1 * c1;
2948 double dC = c2 - c2;
2949 double dH2 = std::pow(da, 2) + std::pow(db, 2) - std::pow(dC, 2);
2950 if (dH2 < 0.0)
2951 dH2 = 0.000;
2952 double dE = std::sqrt(std::pow(dL/kL/sL, 2) + std::pow(dC/kC/sC, 2) + dH2/std::pow(kH*sH, 2));
2953 return dE;
2954 }
2955 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2956 /** 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).
2957 Note the implications for floating point clrChanT.
2958 @return non-zero if the given color is logically the same as the current color*/
2959 inline bool isClose(colorArgType aColor, clrChanT epsilon) const {
2960 for(int i=0; i<numChan; i++)
2961 if (std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))) > epsilon)
2962 return false;
2963 return true;
2964 }
2965 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2966 /** Like isClose(), but only checks the R, G, & B channels.
2967 @return non-zero if the given RGB color is the same as the current color*/
2968 inline bool isCloseRGB(colorArgType aColor, clrChanT epsilon) const requires(blueChan >= 0) {
2969 for (int i : {redChan, blueChan, greenChan})
2970 if (std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))) > epsilon)
2971 return false;
2972 return true;
2973 }
2974 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2975 /** Returns non-zero if the current color is precicely equal to aColor.
2976 Note the implications for floating point clrChanT.
2977 @return non-zero if the given color is logically the same as the current color*/
2978 inline bool isEqual(colorArgType aColor) const {
2979 if constexpr (perfectMask)
2980 return (getMaskNC() == aColor.getMaskNC());
2981 else
2982 for(int i=0; i<numChan; i++)
2983 if(getChanNC(i) != aColor.getChanNC(i))
2984 return false;
2985 return true;
2986 }
2987 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2988 /** Like isEqual(), but only checks the R, G, & B channels.
2989 @return non-zero if the given RGB color is the same as the current color*/
2990 inline bool isEqualRGB(colorArgType aColor) const {
2991 /* Requires: Inherits RGB channel requirements from getRed/getGreen/getBlue. */
2992 return ((getRed() == aColor.getRed() ) &&
2993 (getGreen() == aColor.getGreen()) &&
2994 (getBlue() == aColor.getBlue()));
2995 }
2996 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2997 /** Returns non-zero if the given color is logically NOT the same as the current color.
2998 Note the implications for floating point clrChanT.
2999 @return non-zero if the given color is logically the same as the current color*/
3000 inline bool isNotEqual(colorArgType aColor) const { return !(isEqual(aColor)); }
3001 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3002 /** Returns non-zero if the given color is black (all componnets are zero)
3003 @return non-zero if the given color is black (all componnets are zero) */
3004 inline bool isBlack() {
3005 if constexpr (perfectMask)
3006 return (getMaskNC() == maskAllZero);
3007 else
3008 for(int i=0; i<numChan; i++)
3009 if(getChanNC(i) != 0)
3010 return false;
3011 return true;
3012 }
3013 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3014 /** LIke isBlack(), but only checks the R, G, & B channels
3015 @return non-zero if the given color is black (R, G, & B are are zero) */
3016 inline bool isBlackRGB() const { return ((getRed() == 0) && (getGreen() == 0) && (getBlue() == 0)); } /* Requires: Inherits RGB channel requirements from getRed/getGreen/getBlue. */
3017 //@}
3018
3019 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3020 /** @name Channel Clipping Functions */
3021 //@{
3022 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3023 /** Clamp a value to (infinity, maxChanVal].
3024 Input values larger than maxChanVal are mapped to maxChanVal. Values less than minChanVal are not changed.
3025 @param arithValue The value to clamp */
3026 template <typename iT>
3027 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>)
3028 inline clrChanT clampTop(iT arithValue) {
3029 if(arithValue > static_cast<iT>(maxChanVal))
3030 return static_cast<clrChanT>(maxChanVal);
3031 else
3032 return static_cast<clrChanT>(arithValue);
3033 }
3034 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3035 /** Clamp a value to [minChanVal, infinity).
3036 @param arithValue The value to clamp */
3037 template <typename iT>
3038 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>)
3039 inline clrChanT clampBot(iT arithValue) {
3040 if(arithValue < static_cast<iT>(minChanVal))
3041 return static_cast<clrChanT>(minChanVal);
3042 else
3043 return static_cast<clrChanT>(arithValue);
3044 }
3045 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3046 /** Clamp a value to [minChanVal, maxChanVal].
3047 @param arithValue The value to clamp */
3048 template <typename iT>
3049 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>)
3050 inline clrChanT clampAll(iT arithValue) {
3051 if (arithValue > static_cast<iT>(maxChanVal))
3052 return static_cast<clrChanT>(maxChanVal);
3053 else if(arithValue < static_cast<iT>(minChanVal))
3054 return static_cast<clrChanT>(minChanVal);
3055 else
3056 return static_cast<clrChanT>(arithValue);
3057 }
3058 //@}
3059
3060 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3061 /** @name Meta Color Schemes */
3062 //@{
3063 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3064#if !(MISSING_P1907R1)
3065 /** Compute a color from a polynomial space curve in the RGB color space. This is a continuous color scheme!
3066 @tparam coefs Polynomial coefficients*/
3067 template<double...coefs>
3069 public:
3070 /** Set given colorTpl instance to the selected color in the color scheme.
3071 @param aColor color object to set.
3072 @param csX A value in [0, 1] that identifies the color in the scheme.
3073 @return Returns a reference to \a aColor. */
3074 static inline colorTpl& c(colorRefType aColor, csFltType csX) {
3075 double pR = pcoff[0 * psize];
3076 double pG = pcoff[1 * psize];
3077 double pB = pcoff[2 * psize];
3078 for (unsigned int i=1; i<psize; i++) {
3079 pR = pR * csX + pcoff[i + 0 * psize];
3080 pG = pG * csX + pcoff[i + 1 * psize];
3081 pB = pB * csX + pcoff[i + 2 * psize];
3082 }
3083 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));
3084 }
3085 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3086 @param csX A value in [0, 1] that identifies the color in the scheme.
3087 @return Returns a colorTpl value */
3088 static inline colorTpl c(csFltType csX) { colorTpl tmp; return c(tmp, csX); }
3089 private:
3090 constexpr static int psize = (sizeof...(coefs)) / 3;
3091 constexpr static double pcoff[] = { coefs... };
3092 };
3093#endif
3094#if !(MISSING_P1907R1)
3095 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3096 /** 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.
3097 This is a continous color scheme!
3098 @tparam start colour (1=red, 2=green, 3=blue; ex: 0.5=purple;
3099 @tparam rots Rotations in colour in [-1.5, 1.5]. ex: -1.0 is one blue->green->red cycle;
3100 @tparam hue Hue intensity scaling in [0, 1] (0 == greyscale).
3101 @tparam gamma Gamma correction for intensity. */
3102 template<double start, double rots, double hue, double gamma>
3104 public:
3105 /** Set given colorTpl instance to the selected color in the color scheme.
3106 @param aColor color object to set.
3107 @param csX A value in [0, 1] that identifies the color in the scheme.
3108 @return Returns a reference to \a aColor. */
3109 static inline colorTpl& c(colorRefType aColor, csFltType csX) {
3110 //csX=mjr::math::ivl::wrapCC(csX, 0.0, 1.0);
3111 double angle=2*std::numbers::pi*(start/3.0+1.0+rots*csX);
3112 csX=std::pow(csX, gamma);
3113 double ampl=hue*csX*(1-csX)/2.0;
3114 return aColor.setChansRGB_dbl(std::clamp(csX+ampl*(-0.14861*std::cos(angle)+1.78277*std::sin(angle)), 0.0, 1.0),
3115 std::clamp(csX+ampl*(-0.29227*std::cos(angle)-0.90649*std::sin(angle)), 0.0, 1.0),
3116 std::clamp(csX+ampl*(+1.97294*std::cos(angle)), 0.0, 1.0));
3117 }
3118 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3119 @param csX A value in [0, 1] that identifies the color in the scheme.
3120 @return Returns a colorTpl value */
3121 static inline colorTpl c(csFltType csX) { colorTpl tmp; return c(tmp, csX); }
3122 };
3123#endif
3124 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3125 /** Template for HSL color schemes.
3126 If clrChanT is integral, this is a discrete color scheme, otherwise it is continuous.. */
3127 template<cornerColorEnum corner>
3129 public:
3130 constexpr static csIntType numC = (chanIsInt ? meanChanVal : 0);
3131 /** Set given colorTpl instance to the selected color in the color scheme.
3132 @param aColor color object to set.
3133 @param csVal Index of color in pallet. Wrapped to [0, meanChanVal].
3134 @return Returns a reference to \a aColor. */
3135 static inline colorTpl& c(colorRefType aColor, csNatType csVal) {
3136 clrChanT cVal = static_cast<clrChanT>(mjr::math::ivl::wrapCC(csVal, meanChanVal));
3137 colorTpl cc(corner);
3138 return aColor.setChansRGB(static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getRed() ? cVal : -cVal)),
3139 static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getGreen() ? cVal : -cVal)),
3140 static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getBlue() ? cVal : -cVal)));
3141 }
3142 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3143 @param csVal Index of color in pallet. Wrapped to [0, meanChanVal].
3144 @return Returns a colorTpl value */
3145 static inline colorTpl c(csNatType csVal) { colorTpl tmp; return c(tmp, csVal); }
3146 };
3147 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3148 /** Template providing RGB color cube gradiant color schemes */
3149 template<cornerColorEnum...corners>
3150 class csCC_tpl {
3151 public:
3152 constexpr static csIntType numC = ((sizeof...(corners)) - 1) * chanStepMax + 1;
3153 /** Set given colorTpl instance to the selected color in the color scheme.
3154 @param aColor color object to set.
3155 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3156 @return Returns a reference to \a aColor. */
3157 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) {
3158 csFltType csX = static_cast<csFltType>(csG);
3159 return aColor.cmpRGBcornerCGradiant(csX, numA, cols);
3160 }
3161 /** Set given colorTpl instance to the selected color in the color scheme.
3162 @param aColor color object to set.
3163 @param csG Integer used to select a color from the discrete gradiaant.
3164 @return Returns a reference to \a aColor. */
3165 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) {
3166 csIntType csIdx = static_cast<csIntType>(csG);
3167 return aColor.cmpRGBcornerDGradiant(csIdx % numC, numA, cols);
3168 }
3169 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3170 @param csG color scheme selector
3171 @return Returns a colorTpl value */
3172 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) {
3173 colorTpl tmp;
3174 return c(tmp, csG);
3175 }
3176 private:
3177 constexpr static int numA = (sizeof...(corners));
3178 constexpr static cornerColorEnum cols[] = { corners... };
3179 };
3180 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3181 /** Binary color scheme. First color for even inputs and second color for odd. */
3182 template<cornerColorEnum a, cornerColorEnum b>
3184 public:
3185 constexpr static csIntType numC = 2;
3186 /** Set given colorTpl instance to the selected color in the color scheme.
3187 @param aColor color object to set.
3188 @param csIdx Index of color in pallet. Not wrapped or clipped. Even values get color \a a, while odd values get color \a b.
3189 @return Returns a reference to \a aColor. */
3190 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) { if (csIdx % 2) return aColor.setToCorner(b); else return aColor.setToCorner(a); }
3191 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3192 @param csIdx Index of color in pallet. Not wrapped or clipped. Even values get color \a a, while odd values get color \a b.
3193 @return Returns a colorTpl value */
3194 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3195 };
3196 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3197 /** Template for fixed size pallets. */
3198 template<uint32_t...colors>
3199 class csFP_tpl {
3200 public:
3201 constexpr static csIntType numC = (sizeof...(colors));
3202 /** Set given colorTpl instance to the selected color in the color scheme.
3203 @param aColor color object to set.
3204 @param csG Integer used to select a color from the discrete gradiaant.
3205 @return Returns a reference to \a aColor. */
3206 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) {
3207 csFltType csX = static_cast<csFltType>(csG);
3208 return aColor.cmpGradiant(mjr::math::ivl::wrapCC(csX, 1.0), numC, d);
3209 }
3210 /** Set given colorTpl instance to the selected color in the color scheme.
3211 @param aColor color object to set.
3212 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3213 @return Returns a reference to \a aColor. */
3214 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) {
3215 csIntType csIdx = static_cast<csIntType>(csG);
3216 return aColor.setRGBfromLogPackIntARGB(d[csIdx % numC]);
3217 }
3218 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3219 @param csG color scheme color selector
3220 @return Returns a colorTpl value */
3221 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) {
3222 colorTpl tmp;
3223 return c(tmp, csG);
3224 }
3225 private:
3226 constexpr static uint32_t d[] = { colors... };
3227 };
3228 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3229 /** Template for Color Brewer 2 variable sized pallets. */
3230 template<csIntType mx, uint32_t...colors>
3231 class csCB_tpl {
3232 public:
3233 constexpr static csIntType minNumC = 3;
3234 constexpr static csIntType maxNumC = mx;
3235 /** Set given colorTpl instance to the selected color in the color scheme.
3236 @param aColor color object to set.
3237 @param csG Integer used to select a color from the discrete gradiaant.
3238 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3239 @return Returns a reference to \a aColor. */
3240 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG, csIntType numC=maxNumC) requires (std::floating_point<saT>) {
3241 csFltType csX = static_cast<csFltType>(csG);
3242 csIntType b = std::clamp(numC, minNumC, maxNumC);
3243 return aColor.cmpGradiant(mjr::math::ivl::wrapCC(csX, 1.0), b, &d[b*(b-1)/2-3+0]);
3244 }
3245 /** Set given colorTpl instance to the selected color in the color scheme.
3246 @param aColor color object to set.
3247 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3248 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3249 @return Returns a reference to \a aColor. */
3250 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG, csIntType numC=maxNumC) requires (std::integral<saT>) {
3251 csIntType csIdx = static_cast<csIntType>(csG);
3252 csIntType b = std::clamp(numC, minNumC, maxNumC);
3253 csIntType i = csIdx % b;
3254 return aColor.setRGBfromLogPackIntARGB(d[b*(b-1)/2-3+i]);
3255 }
3256 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3257 @param csG color scheme color selector
3258 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3259 @return Returns a colorTpl value */
3260 template<typename saT> static inline colorTpl c(saT csG, csIntType numC=maxNumC) requires (std::integral<saT> || std::floating_point<saT>) {
3261 colorTpl tmp;
3262 return c(tmp, csG, numC);
3263 }
3264 private:
3265 constexpr static uint32_t d[] = { colors... };
3266 };
3267 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3268 /** Wrapper for Color Brewer 2 variable sized pallet template to produce a simple fixed color scheme with a numC member.
3269 @tparam varColorScheme A color brewer variable sized color scheme
3270 @tparam numClr The number of colors wanted in the fixed sized scheme.*/
3271 template<class varColorScheme, csIntType numClr>
3272 requires((varColorScheme::minNumC <= numClr) && (varColorScheme::maxNumC >= numClr))
3274 public:
3275 constexpr static csIntType numC = numClr;
3276 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) { return varColorScheme::c(aColor, csG, numClr); }
3277 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) { return varColorScheme::c(aColor, csG, numClr); }
3278 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) { return varColorScheme::c(csG, numC); }
3279 };
3280 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3281 /** Template for web safe 216 pallets. */
3282 template<uint32_t...colors>
3283 class csWS_tpl {
3284 public:
3285 constexpr static csIntType numC = (sizeof...(colors));
3286 /** Set given colorTpl instance to the selected color in the color scheme.
3287 @param aColor color object to set.
3288 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3289 @return Returns a reference to \a aColor. */
3290 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) { return aColor.setRGBfromLogPackIntARGB(d[csIdx % numC]); }
3291 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3292 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3293 @return Returns a reference a colorTpl value. */
3294 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3295 /** Set given colorTpl instance to the selected color in the color scheme.
3296 @param aColor color object to set.
3297 @param csCol input color to convert to a web safe color.
3298 @return Returns a reference to \a aColor. */
3299 static colorTpl& c(colorRefType aColor, colorRefType csCol) {
3300 aColor.copy(csCol);
3301 aColor.tfrmWebSafeRGB();
3302 int colIdx = 36 * (aColor.getRed_byte() / 0x33) + 6 * (aColor.getGreen_byte() / 0x33) + 1 * (aColor.getBlue_byte() / 0x33) + 1;
3303 return aColor.setRGBfromLogPackIntARGB(d[colIdx]);
3304 }
3305 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3306 @param csCol input color to convert to a web safe color.
3307 @return Returns a reference a colorTpl value. */
3308 static colorTpl c(colorRefType csCol) { colorTpl tmp; return c(tmp, csCol); }
3309 private:
3310 constexpr static uint32_t d[] = { colors... };
3311 };
3312 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3313 /** Template for Thaller 2D color schemes. */
3314 template<bool useHSL, bool maxV, double cutDepth, double argCuts, double absCuts, bool logAbs>
3315 requires( !(useHSL && maxV))
3317 public:
3318 /** Set given colorTpl instance to the selected color in the color scheme.
3319 @param aColor color object to set.
3320 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
3321 @param csY A value that, along with csX, identifies the color in the scheme.
3322 @return Returns a reference to \a aColor. */
3323 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
3324 double tau = std::numbers::pi * 2; // 2*Pi
3325 double zAbs = std::sqrt(csX*csX+csY*csY); // Abs
3326 double zArg = std::atan2(csY, csX); // Arg
3327 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
3328 double val = (maxV ? 1 : 4.0*std::atan(zAbs)/tau); // V for HSV
3329 if (useHSL)
3330 aColor.setRGBfromUnitHSL(pzArg, 1.0, val);
3331 else
3332 aColor.setRGBfromUnitHSV(pzArg, 1.0, val);
3333 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
3334 }
3335 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3336 @param csX A value that, along with csY, identifies the color in the scheme.
3337 @param csY A value that, along with csX, identifies the color in the scheme.
3338 @return Returns a colorTpl value */
3339 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
3340 /** Set given colorTpl instance to the selected color in the color scheme.
3341 @param aColor color object to set.
3342 @param csZ A value that identifies the color in the scheme.
3343 @return Returns a reference to \a aColor. */
3344 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
3345 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3346 @param csZ A value that identifies the color in the scheme.
3347 @return Returns a colorTpl value */
3348 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
3349 };
3350 //@}
3351
3352 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3353 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3354 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3355
3356 /** @cond color-schemes */
3357 /* Doxygen is pretty bad at formatting these bits... */
3358
3359 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3360 /** @defgroup cs Color Schemes */
3361
3362#if !(MISSING_P1907R1)
3363 //========================================================================================================================================================
3364 /** @name Color Schemes: Polynomial */
3365 //@{
3366 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3367 /*- @class csPLYgrey
3368 @ingroup cs
3369 @extends csPLY_tpl
3370 Greyscale */
3371 typedef csPLY_tpl<1.0, 0.0,
3372 1.0, 0.0,
3373 1.0, 0.0> csPLYgrey;
3374 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3375 /** @class csPLYquad
3376 @ingroup cs
3377 @extends csPLY_tpl
3378 Quadratic */
3379 typedef csPLY_tpl<1.0, 0.0, 0.0,
3380 1.0, 0.0, 0.0,
3381 1.0, 0.0, 0.0> csPLYquad;
3382 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3383 /** @class csPLYturbo
3384 @ingroup cs
3385 @extends csPLY_tpl
3386 Similar to the Google turbo colormap.
3387 Note this colormap is not identical to turbo, and lacks some of it's more sophisticated characteristics; however, it looks nice.
3388 See: https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html */
3389 typedef csPLY_tpl< 40703.92740, -218720.2701, 492368.2177, -590441.1804, 384271.9078, -101352.6555, -30425.81099,
3390 32619.05953, -10529.162296, 1625.5688083, -124.13217495, 4.867108400, 0.15787894011,
3391 20766.64723, -122258.4886, 315808.0723, -470687.9792, 447662.9929, -283594.9850, 121141.42864,
3392 -34482.96363, 6288.268231, -682.8118257, 37.74849512, 2.025549368, 0.06643490255,
3393 -94331.85477, 587011.8043, -1597312.2220, 2495306.9899, -2470958.0510, 1616523.3372, -706621.97816,
3394 204052.57726, -37536.525321, 4109.7062335, -257.68681737, 13.750387410, 0.16179522842> csPLYturbo;
3395 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3396 /** @class csPLYparula
3397 @ingroup cs
3398 @extends csPLY_tpl
3399 Similar to the Matlab parula colormap.
3400 Note this colormap is not identical to parula, and lacks some of it's more sophisticated characteristics; however, it looks nice.
3401 See: https://www.mathworks.com/help/matlab/ref/parula.html */
3402 typedef csPLY_tpl< 62043.87545, -399037.6523, 1122946.9120, -1812238.5254, 1846100.4184, -1230398.5816, 537273.93047,
3403 -149254.730651, 24535.019552, -2015.3894764, 44.825447931, 0.6772663755, 0.2018889435,
3404 -17121.77553, 108751.1007, -300422.7570, 473217.4661, -468061.6834, 301522.8593, -126770.41694,
3405 33776.781210, -5288.933402, 404.6316583, -7.800267203, 1.3431462881, 0.1677335602,
3406 -17004.66127, 100139.7442, -255248.5285, 366029.9549, -319570.5392, 169195.6211, -48015.67328,
3407 2478.369459, 2717.762128, -795.8032035, 72.119793045, 1.1497391882, 0.5347179324> csPLYparula;
3408 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3409 /** @class csPLYmagma
3410 @ingroup cs
3411 @extends csPLY_tpl
3412 Similar, but not identical, to the matplotlib magma colormap.
3413 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3414 typedef csPLY_tpl<746.7387907, -3433.588054, 6464.361262, -6369.328232, 3470.981211, -1010.528460, 141.7946515,
3415 -15.78575778, 6.066078845, 0.2765580349, 0.000406276347,
3416 885.3555317, -5488.721941, 14347.739660, -20613.711506, 17758.797775, -9380.063372, 2976.8215781,
3417 -529.56166374, 45.254936301, -0.9276250448, 0.006923020887,
3418 -3360.6362774, 17553.826465, -38851.355442, 47349.901018, -34548.072322, 15336.155184, -3997.3017542,
3419 548.12480687, -32.540585926, 2.6406562133, 0.006263758764> csPLYmagma;
3420 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3421 /** @class csPLYinferno
3422 @ingroup cs
3423 @extends csPLY_tpl
3424 Similar, but not identical, to the matplotlib inferno colormap.
3425 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3426 typedef csPLY_tpl<-19.63292067, 452.2107953, -1685.008066, 2775.510486, -2442.279827, 1181.312494, -280.5809421,
3427 10.74924866, 8.60430465, 0.1030211659, 0.002048171596,
3428 1970.76446015, -10379.8617699, 23277.924908, -28925.873437, 21688.815122, -10002.539645, 2763.0755166,
3429 -419.99828889, 28.92908793, -0.2365793129, 0.001175881895,
3430 2525.53763382, -12168.1567723, 24862.266312, -28273.600973, 19817.598983, -8983.810158, 2683.7805375,
3431 -515.72960422, 52.67809976, 0.0641022894, 0.024051180021> csPLYinferno;
3432 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3433 /** @class csPLYplasma
3434 @ingroup cs
3435 @extends csPLY_tpl
3436 Similar, but not identical, to the matplotlib plasma colormap.
3437 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3438 typedef csPLY_tpl<-43.8322257, 285.8375115, -806.7514473, 1301.765273, -1325.274751, 878.0715655, -374.7228293,
3439 98.20716947, -15.31425214, 2.899584724, 0.05309687850,
3440 1014.1378090, -5599.3136737, 13256.9879694, -17529.001879, 14102.556299, -7032.4501033, 2110.7323912,
3441 -350.31653834, 28.69509557, -1.086029536, 0.03452846048,
3442 -829.5844973, 4029.2020771, -8461.6295286, 10078.322085, -7471.246818, 3531.4365043, -1036.2596994,
3443 175.24253651, -17.51426724, 1.646647586, 0.52562476199> csPLYplasma;
3444 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3445 /** @class csPLYviridis
3446 @ingroup cs
3447 @extends csPLY_tpl
3448 Similar, but not identical, to the matplotlib viridis colormap.
3449 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3450 typedef csPLY_tpl<-5.432077171, 4.751786889, 6.203735901, -4.599931518, -0.32724109679, 0.1077083262, 0.274455424454,
3451 4.641571316, -13.749439404, 14.153964947, -5.758238189, 0.21481356454, 1.3964696839, 0.005767962397,
3452 26.272107604, -65.320967828, 56.656299565, -19.291808950, 0.09197688076, 1.3867705979, 0.332663881113> csPLYviridis;
3453 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3454 /** @class csPLYcividis
3455 @ingroup cs
3456 @extends csPLY_tpl
3457 Similar, but not identical, to the cividis colormap.
3458 Note this map dosen't have the flat red and sharp increase in blue at the start of the map.
3459 See: https://github.com/marcosci/cividis and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3460 typedef csPLY_tpl<-10.6296994279, 27.5479183452, -25.1086313881, 9.3401209056, -0.1385953043, -0.0177903167,
3461 -0.2641767638, 0.6924831686, -0.5155427716, 0.2071305342, 0.6695454456, 0.1273928107,
3462 9.7085048454, -25.9409393982, 24.1852720215, -9.7350011883, 1.7347333905, 0.3185822998> csPLYcividis;
3463 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3464 /** @class csPLYhsvRB
3465 @ingroup cs
3466 @extends csPLY_tpl
3467 Similar to csCColdeRainbow, but a little softer. */
3468 typedef csPLY_tpl<8.746561257e-11, 4.285714286, -4.285714286, 1.166666667e+00,
3469 1.200000000e+01, -21.000000000, 9.023809524, -2.161907281e-13,
3470 -1.200000000e+01, 15.000000000, -3.023809524, 2.380952381e-02> csPLYhsvRB;
3471 //@}
3472#endif
3473
3474#if !(MISSING_P1907R1)
3475 //========================================================================================================================================================
3476 /** @name Color Schemes: CubeHelix */
3477 //@{
3478 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3479 /** @class csCHstd
3480 @ingroup cs
3481 @extends csCubeHelix_tpl
3482 The "standard" cubehelix color scheme with start=0.5, rots=-1.5, hue=1, and gamma=1. */
3483 typedef csCubeHelix_tpl<0.5, -1.5, 1.0, 1.0> csCHstd;
3484 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3485 /** @class csCHblu
3486 @ingroup cs
3487 @extends csCubeHelix_tpl
3488 The "blues" cubehelix color scheme with start=0.5, rots=-0.5, hue=1, and gamma=1. */
3489 typedef csCubeHelix_tpl<0.5, -0.5, 1.0, 1.0> csCHblu;
3490 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3491 /** @class csCHvio
3492 @ingroup cs
3493 @extends csCubeHelix_tpl
3494 The "violets" cubehelix color scheme with start=0.5, rots=0.0, hue=1, and gamma=1. */
3495 typedef csCubeHelix_tpl<0.5, 0.0, 1.0, 1.0> csCHvio;
3496 //@}
3497#endif
3498
3499 //========================================================================================================================================================
3500 /** @name Color Schemes: White In Center Circular Gradients */
3501 //@{
3502 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3503 /** @class csCCwicR
3504 @ingroup cs
3505 @extends csCC_tpl
3506 Color cycle starting and ending with red with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3507 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::WHITE, cornerColorEnum::RED> csCCwicR;
3508 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3509 /** @class csCCwicG
3510 @ingroup cs
3511 @extends csCC_tpl
3512 Color cycle starting and ending with green with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3513 typedef csCC_tpl<cornerColorEnum::GREEN, cornerColorEnum::WHITE, cornerColorEnum::GREEN> csCCwicG;
3514 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3515 /** @class csCCwicB
3516 @ingroup cs
3517 @extends csCC_tpl
3518 Color cycle starting and ending with blue with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3519 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::WHITE, cornerColorEnum::BLUE> csCCwicB;
3520 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3521 /** @class csCCwicM
3522 @ingroup cs
3523 @extends csCC_tpl
3524 Color cycle starting and ending with magenta with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3525 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::WHITE, cornerColorEnum::MAGENTA> csCCwicM;
3526 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3527 /** @class csCCwicY
3528 @ingroup cs
3529 @extends csCC_tpl
3530 Color cycle starting and ending with yellow with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3531 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::WHITE, cornerColorEnum::YELLOW> csCCwicY;
3532 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3533 /** @class csCCwicC
3534 @ingroup cs
3535 @extends csCC_tpl
3536 Color cycle starting and ending with cyan with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3537 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::WHITE, cornerColorEnum::CYAN> csCCwicC;
3538 //@}
3539
3540 //========================================================================================================================================================
3541 /** @name Color Schemes: RGB Constant Brightness Ramps */
3542 //@{
3543 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3544 /** @class csCCconsTwo
3545 @ingroup cs
3546 @extends csCC_tpl
3547 Color cycle around the cube with constant brightness of two. Provides (mjr::colorTpl::chanStepMax*3+1) unique colors. */
3548 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csCCconsTwo;
3549 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3550 /** @class csCCconsOne
3551 @ingroup cs
3552 @extends csCC_tpl
3553 Color cycle around the cube with constant brightness of one. Provides (mjr::colorTpl::chanStepMax*3+1) unique colors. */
3554 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::RED, cornerColorEnum::GREEN, cornerColorEnum::BLUE> csCCconsOne;
3555 //@}
3556
3557 //========================================================================================================================================================
3558 /** @name Color Schemes: Start and end with a primary with the secondary mixed from the primaries in the middle. */
3559 //@{
3560 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3561 /** @class csCCmixRYG
3562 @ingroup cs
3563 @extends csCC_tpl
3564 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3565 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::GREEN> csCCmixRYG;
3566 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3567 /** @class csCCmixRMB
3568 @ingroup cs
3569 @extends csCC_tpl
3570 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3571 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::MAGENTA, cornerColorEnum::BLUE> csCCmixRMB;
3572 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3573 /** @class csCCmixGCB
3574 @ingroup cs
3575 @extends csCC_tpl
3576 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3577 typedef csCC_tpl<cornerColorEnum::GREEN, cornerColorEnum::CYAN, cornerColorEnum::BLUE> csCCmixGCB;
3578 //@}
3579
3580 //========================================================================================================================================================
3581 /** @name Color Schemes: RGB Divergent Ramps */
3582 //@{
3583 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3584 /** @class csCCdivBWR
3585 @ingroup cs
3586 @extends csCC_tpl
3587 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. */
3588 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::WHITE, cornerColorEnum::RED> csCCdivBWR;
3589 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3590 /** @class csCCdivCWM
3591 @ingroup cs
3592 @extends csCC_tpl
3593 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. */
3594 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::WHITE, cornerColorEnum::MAGENTA> csCCdivCWM;
3595 //@}
3596
3597 //========================================================================================================================================================
3598 /** @name Color Schemes: RGB Cube Diagional Ramps */
3599 //@{
3600 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3601 /** @class csCCdiag01
3602 @ingroup cs
3603 @extends csCC_tpl
3604 Gradient across the diagonal of the RGB color cube from black to white. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3605 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csCCdiag01;
3606 /** @class csCCdiag10
3607 @ingroup cs
3608 @extends csCC_tpl
3609 Gradient across the diagonal of the RGB color cube from white to black. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3610 typedef csCC_tpl<cornerColorEnum::WHITE, cornerColorEnum::BLACK> csCCdiag10;
3611 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3612 /** @class csCCdiagCR
3613 @ingroup cs
3614 @extends csCC_tpl
3615 Gradient across the diagonal of the RGB color cube from cyan to red. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3616 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::RED> csCCdiagCR;
3617 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3618 /** @class csCCdiagMG
3619 @ingroup cs
3620 @extends csCC_tpl
3621 Gradient across the diagonal of the RGB color cube from magenta to green. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3622 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::GREEN> csCCdiagMG;
3623 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3624 /** @class csCCdiagYB
3625 @ingroup cs
3626 @extends csCC_tpl
3627 Gradient across the diagonal of the RGB color cube from yellow to blue. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3628 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::BLUE> csCCdiagYB;
3629 //@}
3630
3631 //========================================================================================================================================================
3632 /** @name Color Schemes: Classic RGB Ramps */
3633 //@{
3634 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3635 /** @class csCColdeFireRamp
3636 @ingroup cs
3637 @extends csCC_tpl
3638 Classic color cube "Fire Ramp". */
3639 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCColdeFireRamp;
3640 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3641 /** @class csCColdeColdToHot
3642 @ingroup cs
3643 @extends csCC_tpl
3644 Classical cold to hot color cube ramp. Provides (mjr::colorTpl::chanStepMax*4+1) unique colors. */
3645 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::GREEN,
3646 cornerColorEnum::YELLOW, cornerColorEnum::RED> csCColdeColdToHot;
3647 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3648 /** @class csCColdeIceToWaterToHot
3649 @ingroup cs
3650 @extends csCC_tpl
3651 Modified version of the classical cold to hot color cube ramp.ramp. It starts at white (ice), moves up to blue (cold),
3652 then yellow through red (hot). Provides (mjr::colorTpl::chanStepMax*4+1) unique colors. */
3653 typedef csCC_tpl<cornerColorEnum::WHITE, cornerColorEnum::CYAN, cornerColorEnum::BLUE,
3654 cornerColorEnum::YELLOW, cornerColorEnum::RED> csCColdeIceToWaterToHot;
3655 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3656 /** @class csCColdeRainbow
3657 @ingroup cs
3658 @extends csCC_tpl
3659 The classic HSV rainbow color scheme based upon an edge traversal of the RGB color cube. Provides (6 * mjr::colorTpl::chanStepMax + 1) colors. */
3660 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::GREEN, cornerColorEnum::CYAN,
3661 cornerColorEnum::BLUE, cornerColorEnum::MAGENTA, cornerColorEnum::RED> csCColdeRainbow;
3662 //@}
3663
3664 //========================================================================================================================================================
3665 /** @name Color Schemes: Classic Fractal RGB Gradients.
3666 Gradients frequently used to color fractal images. */
3667 //@{
3668 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3669 /** @class csCCfractal0RYBCW
3670 @ingroup cs
3671 @extends csCC_tpl
3672 Provides (5 * mjr::colorTpl::chanStepMax + 1) colors. */
3673 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW,
3674 cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCfractal0RYBCW;
3675 /** @class csCCfractalYR
3676 @ingroup cs
3677 @extends csCC_tpl
3678 Provides (mjr::colorTpl::chanStepMax + 1) colors. */
3679 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::RED> csCCfractalYR;
3680 /** @class csCCfractalYB
3681 @ingroup cs
3682 @extends csCC_tpl
3683 Provides (mjr::colorTpl::chanStepMax + 1) colors. */
3684 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::BLUE> csCCfractalYB;
3685 //@}
3686
3687 //========================================================================================================================================================
3688 /** @name Color Schemes: RGB Sum Ramps */
3689 //@{
3690 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3691 /** @class csCCsumRGB
3692 @ingroup cs
3693 @extends csCC_tpl
3694 RGB cube sum-ramp: RGB == Black -> Red -> Yellow -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3695 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCCsumRGB;
3696 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3697 /** @class csCCsumBGR
3698 @ingroup cs
3699 @extends csCC_tpl
3700 RGB cube sum-ramp: BGR == Black -> Blue -> cyan -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3701 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCsumBGR;
3702 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3703 /** @class csCCsumGRB
3704 @ingroup cs
3705 @extends csCC_tpl
3706 RGB cube sum-ramp: GRB == Black -> Green -> yellow -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3707 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCCsumGRB;
3708 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3709 /** @class csCCsumGBR
3710 @ingroup cs
3711 @extends csCC_tpl
3712 RGB cube sum-ramp: GBR == Black -> Green -> cyan -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3713 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCsumGBR;
3714 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3715 /** @class csCCsumBRG
3716 @ingroup cs
3717 @extends csCC_tpl
3718 RGB cube sum-ramp: BRG == Black -> Blue -> magenta -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3719 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE, cornerColorEnum::MAGENTA, cornerColorEnum::WHITE> csCCsumBRG;
3720 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3721 /** @class csCCsumRBG
3722 @ingroup cs
3723 @extends csCC_tpl
3724 RGB cube sum-ramp: RBG Black -> Red -> Magenta -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3725 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::MAGENTA, cornerColorEnum::WHITE> csCCsumRBG;
3726 //@}
3727
3728 //========================================================================================================================================================
3729 /** @name Color Schemes: RGB Up-Down Ramps */
3730 //@{
3731 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3732 /** @class csCCudRg
3733 @ingroup cs
3734 @extends csCC_tpl
3735 RGB Up-Down Ramp: Rg == Red Up and Green Down == cyan -> magenta. Provides chanStepMax different colors.*/
3736 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::MAGENTA> csCCudRg;
3737 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3738 /** @class csCCudRb
3739 @ingroup cs
3740 @extends csCC_tpl
3741 RGB Up-Down Ramp: Rb == Red Up and Blue Down == cyan -> yellow. Provides chanStepMax different colors.*/
3742 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::YELLOW> csCCudRb;
3743 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3744 /** @class csCCudGr
3745 @ingroup cs
3746 @extends csCC_tpl
3747 RGB Up-Down Ramp: Gr == Green Up and Red Down == magenta -> cyan. Provides chanStepMax different colors. */
3748 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::CYAN> csCCudGr;
3749 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3750 /** @class csCCudGb
3751 @ingroup cs
3752 @extends csCC_tpl
3753 RGB Up-Down Ramp: Gb == Green Up and Blue Down == magenta -> yellow. Provides chanStepMax different colors. */
3754 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW> csCCudGb;
3755 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3756 /** @class csCCudBr
3757 @ingroup cs
3758 @extends csCC_tpl
3759 RGB Up-Down Ramp: Br == Blue Up and Red Down == yellow -> cyan. Provides chanStepMax different colors. */
3760 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csCCudBr;
3761 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3762 /** @class csCCudBg
3763 @ingroup cs
3764 @extends csCC_tpl
3765 RGB Up-Down Ramp: Bg == Blue Up and Green Down == yellow -> magenta. Provides chanStepMax different colors. */
3766 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::MAGENTA> csCCudBg;
3767 //@}
3768
3769 //========================================================================================================================================================
3770 /** @name Color Schemes: Ramp from black to corner */
3771 //@{
3772 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csCCu0W; //!< Ramp from black to white
3773 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED> csCCu0R; //!< Ramp from black to red
3774 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE> csCCu0B; //!< Ramp from black to blue
3775 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN> csCCu0G; //!< Ramp from black to green
3776 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::CYAN> csCCu0C; //!< Ramp from black to cyan
3777 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::MAGENTA> csCCu0M; //!< Ramp from black to magenta
3778 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::YELLOW> csCCu0Y; //!< Ramp from black to yellow
3779 //@}
3780
3781 //========================================================================================================================================================
3782 /** @name Color Schemes: Binary */
3783 //@{
3784 typedef csBin_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csBin01; //!< Binary Black-White color scheme. First color for even inputs and second color for odd.
3785 typedef csBin_tpl<cornerColorEnum::GREEN, cornerColorEnum::BLUE> csBinGB; //!< Binary Green-Blue color scheme. First color for even inputs and second color for odd.
3786 typedef csBin_tpl<cornerColorEnum::RED, cornerColorEnum::BLUE> csBinRB; //!< Binary Red-Blue color scheme. First color for even inputs and second color for odd.
3787 typedef csBin_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::CYAN> csBinMC; //!< Binary Magenta-Cyan color scheme. First color for even inputs and second color for odd.
3788 typedef csBin_tpl<cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csBinYC; //!< Binary Yellow-Cyan color scheme. First color for even inputs and second color for odd.
3789 typedef csBin_tpl<cornerColorEnum::RED, cornerColorEnum::GREEN> csBinRG; //!< Binary Red-Green color scheme. First color for even inputs and second color for odd.
3790 typedef csBin_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW> csBinMY; //!< Binary Magenta-Yellow color scheme. First color for even inputs and second color for odd.
3791 //@}
3792
3793 //========================================================================================================================================================
3794 /** @name Color Schemes: Pseudo-Grey
3795 These color schemes start with black and move toward white trying to increase perceptional brightness, they don't stay precisely on the diagonal. */
3796 //@{
3797 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3798 /** @class csPGrey3x
3799 @ingroup cs
3800 A Pseudo-Grey color scheme with 3 * mjr::colorTpl::chanStepMax colors. */
3801 class csPGrey3x {
3802 public:
3803 constexpr static csIntType numC = 3*chanStepMax;
3804 /** Set given colorTpl instance to the selected color in the color scheme.
3805 @param aColor color object to set.
3806 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3807 @return Returns a reference to \a aColor. */
3808 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) {
3809 csIdx = csIdx % numC;
3810 return aColor.setChansRGB(static_cast<clrChanT>(csIdx / 3 + (csIdx%3==0?1:0)),
3811 static_cast<clrChanT>(csIdx / 3 + (csIdx%3==1?1:0)),
3812 static_cast<clrChanT>(csIdx / 3 + (csIdx%3==2?1:0)));
3813 }
3814 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3815 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3816 @return Returns a colorTpl value */
3817 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3818 };
3819 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3820 /** @class csPGrey4x
3821 @ingroup cs
3822 A Pseudo-Grey color scheme with 4 * mjr::colorTpl::chanStepMax colors. */
3823 class csPGrey4x {
3824 public:
3825 constexpr static csIntType numC = 4*chanStepMax;
3826 /** Set given colorTpl instance to the selected color in the color scheme.
3827 @param aColor color object to set.
3828 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3829 @return Returns a reference to \a aColor. */
3830 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) {
3831 csIdx = csIdx % numC;
3832 return aColor.setChansRGB(static_cast<clrChanT>(csIdx / 4 + ((csIdx+1)%4==0?1:0)),
3833 static_cast<clrChanT>(csIdx / 4 + ((csIdx+2)%4==0?1:0)),
3834 static_cast<clrChanT>(csIdx / 4 + ((csIdx+3)%4==0?1:0)));
3835 }
3836 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3837 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3838 @return Returns a colorTpl value */
3839 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3840 };
3841 //@}
3842
3843 //========================================================================================================================================================
3844 /** @name Color Schemes: HSL Saturation Ramps */
3845 //@{
3846 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3847 /** @class csHSLhR
3848 @ingroup cs
3849 @extends csHSLh_tpl
3850 HSL color scheme extending from the center of the HSL color space to the red vertex.
3851 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3852 typedef csHSLh_tpl<cornerColorEnum::RED> csHSLhR;
3853 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3854 /** @class csHSLhG
3855 @ingroup cs
3856 @extends csHSLh_tpl
3857 HSL color scheme extending from the center of the HSL color space to the green vertex.
3858 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3859 typedef csHSLh_tpl<cornerColorEnum::GREEN> csHSLhG;
3860 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3861 /** @class csHSLhB
3862 @ingroup cs
3863 @extends csHSLh_tpl
3864 HSL color scheme extending from the center of the HSL color space to the blue vertex.
3865 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3866 typedef csHSLh_tpl<cornerColorEnum::BLUE> csHSLhB;
3867 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3868 /** @class csHSLhC
3869 @ingroup cs
3870 @extends csHSLh_tpl
3871 HSL color scheme extending from the center of the HSL color space to the cyan vertex.
3872 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3873 typedef csHSLh_tpl<cornerColorEnum::CYAN> csHSLhC;
3874 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3875 /** @class csHSLhM
3876 @ingroup cs
3877 @extends csHSLh_tpl
3878 HSL color scheme extending from the center of the HSL color space to the magenta vertex.
3879 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3880 typedef csHSLh_tpl<cornerColorEnum::MAGENTA> csHSLhM;
3881 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3882 /** @class csHSLhY
3883 @ingroup cs
3884 @extends csHSLh_tpl
3885 HSL color scheme extending from the center of the HSL color space to the yellow vertex.
3886 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3887 typedef csHSLh_tpl<cornerColorEnum::YELLOW> csHSLhY;
3888 //@}
3889
3890 //========================================================================================================================================================
3891 /** @name Color Schemes: Rainbows */
3892 //@{
3893 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3894 /** @class csRainbowLA
3895 @ingroup cs
3896 Computes a color value based upon a linear approximation of the color match functions used to approximate wavelength to RGB conversion.
3897 The linear color function approximation is not very accurate, but it is quite attractive. */
3898 class csRainbowLA {
3899 public:
3900 /** Set given colorTpl instance to the selected color in the color scheme.
3901 @param aColor color object to set.
3902 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3903 @param numC Number of colors to provide
3904 @return Returns a reference to \a aColor. */
3905 static inline colorTpl& c(colorRefType aColor, csIntType csIdx, csIntType numC) {
3906 csIdx = mjr::math::ivl::wrapCC(csIdx, numC);
3907 return aColor.setRGBfromWavelengthLA(mjr::math::linm::gen_map(static_cast<double>(csIdx),
3908 static_cast<double>(0),
3909 static_cast<double>(numC),
3910 static_cast<double>(minWavelength),
3911 static_cast<double>(maxWavelength)));
3912 }
3913 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3914 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3915 @param numC Number of colors to provide
3916 @return Returns a reference a colorTpl value. */
3917 static inline colorTpl c(csIntType csIdx, csIntType numC) {
3918 colorTpl tmp;
3919 return c(tmp, numC, csIdx);
3920 }
3921 };
3922 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3923 /** @class csRainbowCM
3924 @ingroup cs
3925 Computes a color value based upon an algorithm to convert wavelength to RGB that uses the Color Matching functions.
3926 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum) */
3927 class csRainbowCM {
3928 public:
3929 /** Set given colorTpl instance to the selected color in the color scheme.
3930 @param aColor color object to set.
3931 @param numC Number of colors to provide.
3932 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3933 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
3934 @return Returns a reference to \a aColor. */
3935 static inline colorTpl& c(colorRefType aColor, csIntType csIdx, csIntType numC, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
3936 csIdx = mjr::math::ivl::wrapCC(csIdx, numC);
3937 return aColor.setRGBfromWavelengthCM(mjr::math::linm::gen_map(static_cast<double>(csIdx),
3938 static_cast<double>(0),
3939 static_cast<double>(numC),
3940 static_cast<double>(minWavelength),
3941 static_cast<double>(maxWavelength)),
3942 interpMethod);
3943 }
3944 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3945 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3946 @param numC Number of colors to provide.
3947 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
3948 @return Returns a reference a colorTpl value. */
3949 static inline colorTpl c(csIntType csIdx, csIntType numC, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
3950 colorTpl tmp;
3951 return c(tmp, numC, csIdx, interpMethod);
3952 }
3953 };
3954 //@}
3955
3956 //========================================================================================================================================================
3957 /** @name "Web Safe" Color Schemes */
3958 //@{
3959 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3960 /** @class csWSnormalVision
3961 @ingroup cs
3962 @extends csWS_tpl
3963 The "web safe" color pallet of 216 colors as seen by someone with normal color vision.
3964 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)
3965 pallet for color reduction. The colors are ordered in lexicographical ordering based upon the hexadecimal web-based color name scheme "#RRGGBB" --
3966 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(). */
3967 typedef csWS_tpl<0x000000, 0x000033, 0x000066, 0x000099, 0x0000CC, 0x0000FF, 0x003300, 0x003333, 0x003366, 0x003399, 0x0033CC,
3968 0x0033FF, 0x006600, 0x006633, 0x006666, 0x006699, 0x0066CC, 0x0066FF, 0x009900, 0x009933, 0x009966, 0x009999,
3969 0x0099CC, 0x0099FF, 0x00CC00, 0x00CC33, 0x00CC66, 0x00CC99, 0x00CCCC, 0x00CCFF, 0x00FF00, 0x00FF33, 0x00FF66,
3970 0x00FF99, 0x00FFCC, 0x00FFFF, 0x330000, 0x330033, 0x330066, 0x330099, 0x3300CC, 0x3300FF, 0x333300, 0x333333,
3971 0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336600, 0x336633, 0x336666, 0x336699, 0x3366CC, 0x3366FF, 0x339900,
3972 0x339933, 0x339966, 0x339999, 0x3399CC, 0x3399FF, 0x33CC00, 0x33CC33, 0x33CC66, 0x33CC99, 0x33CCCC, 0x33CCFF,
3973 0x33FF00, 0x33FF33, 0x33FF66, 0x33FF99, 0x33FFCC, 0x33FFFF, 0x660000, 0x660033, 0x660066, 0x660099, 0x6600CC,
3974 0x6600FF, 0x663300, 0x663333, 0x663366, 0x663399, 0x6633CC, 0x6633FF, 0x666600, 0x666633, 0x666666, 0x666699,
3975 0x6666CC, 0x6666FF, 0x669900, 0x669933, 0x669966, 0x669999, 0x6699CC, 0x6699FF, 0x66CC00, 0x66CC33, 0x66CC66,
3976 0x66CC99, 0x66CCCC, 0x66CCFF, 0x66FF00, 0x66FF33, 0x66FF66, 0x66FF99, 0x66FFCC, 0x66FFFF, 0x990000, 0x990033,
3977 0x990066, 0x990099, 0x9900CC, 0x9900FF, 0x993300, 0x993333, 0x993366, 0x993399, 0x9933CC, 0x9933FF, 0x996600,
3978 0x996633, 0x996666, 0x996699, 0x9966CC, 0x9966FF, 0x999900, 0x999933, 0x999966, 0x999999, 0x9999CC, 0x9999FF,
3979 0x99CC00, 0x99CC33, 0x99CC66, 0x99CC99, 0x99CCCC, 0x99CCFF, 0x99FF00, 0x99FF33, 0x99FF66, 0x99FF99, 0x99FFCC,
3980 0x99FFFF, 0xCC0000, 0xCC0033, 0xCC0066, 0xCC0099, 0xCC00CC, 0xCC00FF, 0xCC3300, 0xCC3333, 0xCC3366, 0xCC3399,
3981 0xCC33CC, 0xCC33FF, 0xCC6600, 0xCC6633, 0xCC6666, 0xCC6699, 0xCC66CC, 0xCC66FF, 0xCC9900, 0xCC9933, 0xCC9966,
3982 0xCC9999, 0xCC99CC, 0xCC99FF, 0xCCCC00, 0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCCC, 0xCCCCFF, 0xCCFF00, 0xCCFF33,
3983 0xCCFF66, 0xCCFF99, 0xCCFFCC, 0xCCFFFF, 0xFF0000, 0xFF0033, 0xFF0066, 0xFF0099, 0xFF00CC, 0xFF00FF, 0xFF3300,
3984 0xFF3333, 0xFF3366, 0xFF3399, 0xFF33CC, 0xFF33FF, 0xFF6600, 0xFF6633, 0xFF6666, 0xFF6699, 0xFF66CC, 0xFF66FF,
3985 0xFF9900, 0xFF9933, 0xFF9966, 0xFF9999, 0xFF99CC, 0xFF99FF, 0xFFCC00, 0xFFCC33, 0xFFCC66, 0xFFCC99, 0xFFCCCC,
3986 0xFFCCFF, 0xFFFF00, 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFFFFFF> csWSnormalVision;
3987 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3988 /** @class csWSprotanopia
3989 @ingroup cs
3990 @extends csWS_tpl
3991 The "web safe" color pallet of 216 colors as seen by someone with Protanopia.
3992 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSprotanopiaAlt. */
3993 typedef csWS_tpl<0x000000, 0x002346, 0x004487, 0x0060C1, 0x0078F0, 0x719CFF, 0x312C00, 0x2E2E30, 0x0D3366, 0x0053A6,
3994 0x006FDE, 0x5B91FF, 0x635800, 0x61592E, 0x5C5B5F, 0x4E5F93, 0x1A66CC, 0x007EFE, 0x948500, 0x93852D, 0x90865E,
3995 0x8A898F, 0x7E8DC2, 0x6792F8, 0xC5B000, 0xC5B12B, 0xC3B25D, 0xBFB38D, 0xB8B6BF, 0xADBAF2, 0xF6DC00, 0xF6DD29,
3996 0xF5DD5C, 0xF2DF8C, 0xEDE1BD, 0xE6E4EE, 0x1E1B08, 0x002448, 0x00468B, 0x0062C4, 0x0079F2, 0x739DFF, 0x373200,
3997 0x343333, 0x19376A, 0x0054AA, 0x0070E1, 0x6094FF, 0x655B00, 0x645B2F, 0x5E5D61, 0x506195, 0x2067CD, 0x2581FF,
3998 0x958600, 0x95862E, 0x92875E, 0x8C8A90, 0x7F8EC3, 0x6993FA, 0xC6B100, 0xC6B22C, 0xC4B25D, 0xC0B48E, 0xB9B7BF,
3999 0xAEBBF2, 0xF7DD00, 0xF7DD29, 0xF5DE5C, 0xF3DF8C, 0xEEE2BD, 0xE7E5EF, 0x3C360F, 0x323748, 0x00478E, 0x0065CA,
4000 0x007CF8, 0x7AA1FF, 0x4A420B, 0x46433A, 0x324676, 0x0059B4, 0x0074EA, 0x6E9AFF, 0x6F6300, 0x6D6432, 0x686666,
4001 0x59699C, 0x326ED5, 0x518DFF, 0x9B8B00, 0x9B8B2F, 0x988C61, 0x918F93, 0x8593C7, 0x6E98FE, 0xCAB500, 0xCAB52D,
4002 0xC8B65E, 0xC4B88F, 0xBDBBC1, 0xB2BEF5, 0xFAE000, 0xFAE02A, 0xF8E15D, 0xF6E28D, 0xF1E4BF, 0xEAE7F0, 0x5A5117,
4003 0x55514A, 0x39538F, 0x0067D0, 0x2782FF, 0x83A6FF, 0x635913, 0x5F5941, 0x505B80, 0x005EBF, 0x007AF6, 0x7DA2FF,
4004 0x7F720D, 0x7E7237, 0x78746D, 0x6A77A5, 0x497BDF, 0x709BFF, 0xA69500, 0xA59532, 0xA29665, 0x9B9899, 0x8F9CCE,
4005 0x83A4FF, 0xD2BC00, 0xD1BC2F, 0xCFBD61, 0xCBBF93, 0xC4C1C6, 0xB9C5FA, 0xFFE41C, 0xFFE532, 0xFEE65E, 0xFBE790,
4006 0xF7E9C1, 0xEFECF4, 0x786C1E, 0x746C4C, 0x646D90, 0x356FD5, 0x5D91FF, 0x8CABFF, 0x7E711B, 0x7B7146, 0x707387,
4007 0x5275C8, 0x4387FF, 0x8AAAFF, 0x948415, 0x92853C, 0x8C8675, 0x7F88AF, 0x648CEB, 0x87A7FF, 0xB5A20E, 0xB5A336,
4008 0xB1A46A, 0xAAA5A0, 0x9EA8D7, 0x98B1FF, 0xDDC600, 0xDDC631, 0xDBC764, 0xD7C997, 0xCFCBCB, 0xC4CEFF, 0xFFE655,
4009 0xFFE75C, 0xFFE873, 0xFFEB97, 0xFFF1C5, 0xF8F4F8, 0x968726, 0x93874E, 0x888892, 0x6E89D7, 0x7BA0FF, 0x96B1FF,
4010 0x9A8B23, 0x988B4A, 0x8F8C8B, 0x7A8ECE, 0x779DFF, 0x96B1FF, 0xAC9A1E, 0xAA9A42, 0xA59B7C, 0x999DB9, 0x82A0F6,
4011 0x98B2FF, 0xC8B317, 0xC7B43A, 0xC4B470, 0xBDB6A8, 0xB1B8E0, 0xAABDFF, 0xECD30F, 0xECD435, 0xE9D469, 0xE5D69D,
4012 0xDED8D2, 0xCFD7FF, 0xFFE871, 0xFFE975, 0xFFEA86, 0xFFEDA2, 0xFFF2C8, 0xFFFAFA> csWSprotanopia;
4013 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4014 /** @class csWSdeutanopia
4015 @ingroup cs
4016 @extends csWS_tpl
4017 The "web safe" color pallet of 216 colors as seen by someone with Deutanopia.
4018 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSdeutanopiaAlt. */
4019 typedef csWS_tpl<0x000000, 0x002135, 0x004168, 0x005E97, 0x0076BE, 0x008BDF, 0x362A0C, 0x2F2D34, 0x003E68, 0x005E9A, 0x0078C2,
4020 0x008CE2, 0x6D5418, 0x6A5538, 0x5E5A69, 0x3D629A, 0x0078C9, 0x0090EC, 0xA37E25, 0xA27E3D, 0x9B816C, 0x8D869D,
4021 0x728ECF, 0x3398FF, 0xDAA831, 0xD9A844, 0xD4AA6F, 0xCBAEA0, 0xBBB3D1, 0xA5BBFF, 0xFFCD72, 0xFFCD77, 0xFFCF87,
4022 0xFFD3A6, 0xFBDAD4, 0xE6DCFF, 0x221A00, 0x131E30, 0x003F67, 0x005D96, 0x0076BF, 0x008BDF, 0x3D2F09, 0x373133,
4023 0x003B65, 0x005D99, 0x0078C2, 0x008CE2, 0x705617, 0x6D5737, 0x615B68, 0x43639A, 0x0078C9, 0x0090EC, 0xA58600,
4024 0xA4803C, 0x9D826B, 0x8F879D, 0x758FCE, 0x3999FF, 0xDBA830, 0xDAA943, 0xD6AB6F, 0xCCAEA0, 0xBDB4D1, 0xA7BBFF,
4025 0xFFCD74, 0xFFCD78, 0xFFCF88, 0xFFD4A6, 0xFCDBD4, 0xE7DDFF, 0x453500, 0x3F352F, 0x253D60, 0x005A94, 0x0076BF,
4026 0x008BE1, 0x534000, 0x4F4031, 0x3D4763, 0x005995, 0x0076C2, 0x008CE4, 0x7B5E11, 0x795F35, 0x6F6367, 0x586A98,
4027 0x0076C9, 0x0090EE, 0xAC8421, 0xAA853B, 0xA4876A, 0x978C9C, 0x8093CD, 0x519CFE, 0xE0AC2E, 0xDFAC42, 0xDAAE6E,
4028 0xD2B29F, 0xC3B7D1, 0xADBEFF, 0xFFCE79, 0xFFCF7C, 0xFFD08B, 0xFFD5A7, 0xFFDDD3, 0xEBDFFF, 0x674F00, 0x634E2C,
4029 0x57535F, 0x385B90, 0x0073C0, 0x008CE5, 0x705600, 0x6C552D, 0x625961, 0x496192, 0x0073C2, 0x008DE8, 0x8E6C00,
4030 0x8C6D31, 0x847064, 0x737696, 0x507FC7, 0x0090F3, 0xA69500, 0xB78E37, 0xB29068, 0xA6949A, 0x929BCC, 0x6FA4FD,
4031 0xE9B22A, 0xE8B33F, 0xE4B56C, 0xDBB89D, 0xCEBDCF, 0xB9C4FF, 0xFFD080, 0xFFD184, 0xFFD291, 0xFFD6A9, 0xFFDDD0,
4032 0xF4E4FF, 0x886900, 0x856726, 0x7E6A5E, 0x6E7190, 0x4B7AC0, 0x008CEC, 0x8F6D00, 0x8C6C27, 0x856F5F, 0x767591,
4033 0x577EC2, 0x008DEF, 0xA67F00, 0xA47E2B, 0x9E8161, 0x918694, 0x7B8DC5, 0x4C97F6, 0xCA9A00, 0xC99B32, 0xC49D65,
4034 0xBAA198, 0xAAA7C9, 0x8FAEFB, 0xF6C600, 0xF5BC3B, 0xF1BE6A, 0xEAC19B, 0xDEC6CD, 0xCBCCFF, 0xFFD389, 0xFFD38C,
4035 0xFFD497, 0xFFD8AB, 0xFFDECC, 0xFFEAFD, 0xA98200, 0xA8801A, 0xA2835B, 0x97888E, 0x838FC0, 0x5E98F1, 0xAE8600,
4036 0xAD841C, 0xA7875C, 0x9D8B8F, 0x8A92C1, 0x679BF2, 0xC09300, 0xBF9322, 0xBB955E, 0xB19992, 0xA09FC3, 0x85A7F5,
4037 0xDFAA00, 0xDEAB2A, 0xDAAC62, 0xD2B095, 0xC5B5C7, 0xB0BCF9, 0xFFC750, 0xFFC857, 0xFFCA6F, 0xFCCD99, 0xF1D2CB,
4038 0xE1D8FD, 0xFFD592, 0xFFD594, 0xFFD79D, 0xFFDAAD, 0xFFDFC8, 0xFFE8EF> csWSdeutanopia;
4039 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4040 /** @class csWStritanoptia
4041 @ingroup cs
4042 @extends csWS_tpl
4043 The "web safe" color pallet of 216 colors as seen by someone with Tritanoptia.
4044 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWStritanoptiaAlt. */
4045 typedef csWS_tpl<0x000000, 0x001C1D, 0x003739, 0x005155, 0x006A6E, 0x007F85, 0x173033, 0x0A3236, 0x004347, 0x00595E, 0x006F74,
4046 0x008389, 0x2D5F66, 0x2A6068, 0x15656D, 0x00727A, 0x00828A, 0x00929A, 0x448F9A, 0x42909A, 0x39929D, 0x1F97A3,
4047 0x00A1AC, 0x00ACB7, 0x5ABFCD, 0x59BFCD, 0x54C1CF, 0x47C4D3, 0x29CAD9, 0x00D0DF, 0x73EDFF, 0x73EDFF, 0x73EEFF,
4048 0x72EEFF, 0x70EFFF, 0x6EEFFF, 0x330600, 0x301517, 0x212A2D, 0x00474B, 0x006469, 0x007C82, 0x363033, 0x333236,
4049 0x263C41, 0x005056, 0x006A70, 0x008187, 0x415F66, 0x3F6068, 0x35656D, 0x146D76, 0x007F87, 0x009099, 0x518F9A,
4050 0x4F909A, 0x49929D, 0x3997A3, 0x00A0AC, 0x00ABB7, 0x64BFD7, 0x63BFCD, 0x5EC1CF, 0x54C4D3, 0x3ECAD9, 0x00D1E0,
4051 0x7AEDFF, 0x7AEDFF, 0x79EEFF, 0x78EEFF, 0x76EFFF, 0x74EFFF, 0x660B00, 0x651615, 0x602B2D, 0x563F44, 0x42545B,
4052 0x006B73, 0x673033, 0x663336, 0x623D41, 0x584C51, 0x445D64, 0x007179, 0x6C5F66, 0x6B6067, 0x67656C, 0x5E6D75,
4053 0x4D7982, 0x228791, 0x758F9A, 0x74909A, 0x71929D, 0x6997A3, 0x5A9FAB, 0x3EA9B6, 0x82BECD, 0x81BFCD, 0x7EC1CF,
4054 0x77C4D3, 0x6BCAD9, 0x57D1E1, 0x92EDFF, 0x92EDFF, 0x90EEFF, 0x8EEEFF, 0x8BEFFF, 0x88EFFF, 0x991100, 0x981612,
4055 0x962B2C, 0x904044, 0x87555B, 0x796A71, 0x9A3032, 0x993335, 0x963D40, 0x914C51, 0x885D64, 0x7A7078, 0x9D5F66,
4056 0x9C6067, 0x9A656C, 0x946D75, 0x8C7982, 0x7E8791, 0xA28F99, 0xA2909A, 0x9F929D, 0x9A97A3, 0x929FAB, 0x86A9B6,
4057 0xABBECD, 0xAABFCD, 0xA8C1CF, 0xA3C4D3, 0x9CCAD9, 0x91D1E1, 0xB6EDFF, 0xB5EDFF, 0xB4EEFF, 0xB0EEFF, 0xACEFFF,
4058 0xA6EFFF, 0xCC1600, 0xCB170B, 0xCA2B2B, 0xC64043, 0xC0555A, 0xB76A71, 0xCC3030, 0xCC3334, 0xCA3D3F, 0xC64C50,
4059 0xC15E64, 0xB87178, 0xCF5F65, 0xCE6067, 0xCC656C, 0xC96E75, 0xC37982, 0xBB8791, 0xD38F99, 0xD2909A, 0xD0929D,
4060 0xCD98A2, 0xC79FAB, 0xBFA9B6, 0xD9BECC, 0xD8BFCD, 0xD7C1CF, 0xD3C4D3, 0xCECAD9, 0xC6D1E1, 0xE0EEFF, 0xE0EEFF,
4061 0xDDEEFF, 0xD9EEFF, 0xD3EFFF, 0xCBEFFF, 0xFE1C00, 0xFE1A00, 0xFD2B28, 0xFA4042, 0xF6555A, 0xF06A71, 0xFF3331,
4062 0xFF3332, 0xFE3D3E, 0xFB4C4F, 0xF75E63, 0xF07178, 0xFF6569, 0xFF656A, 0xFF666C, 0xFD6E74, 0xF87981, 0xF28791,
4063 0xFF949C, 0xFF949D, 0xFF959E, 0xFF99A2, 0xFC9FAA, 0xF6A9B5, 0xFFBECA, 0xFFBFCA, 0xFFC0CD, 0xFFC4D1, 0xFFCAD8,
4064 0xFBD1E1, 0xFFE4F2, 0xFFE5F3, 0xFFE6F5, 0xFFEAF9, 0xFDEFFF, 0xF4F0FF> csWStritanoptia;
4065 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4066 /** @class csWSprotanopiaAlt
4067 @ingroup cs
4068 @extends csWS_tpl
4069 The "web safe" color pallet of 216 colors as seen by someone with Protanopia.
4070 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSprotanopia. */
4071 typedef csWS_tpl<0x000000, 0x000E33, 0x001D66, 0x002B99, 0x003ACC, 0x0048FF, 0x422F00, 0x303133, 0x003566, 0x003D99, 0x0047CC,
4072 0x0053FF, 0x845D00, 0x7E5E33, 0x606266, 0x266699, 0x006BCC, 0x0072FF, 0xC68C00, 0xC38D33, 0xB38F66, 0x909399,
4073 0x6896CC, 0x009BFF, 0xFFBB00, 0xFFBB32, 0xFCBD66, 0xE6C099, 0xC0C4CC, 0x9DC7FF, 0xFFE900, 0xFFEA31, 0xFFEB65,
4074 0xFFED99, 0xFFF1CC, 0xF0F5FF, 0x1A1202, 0x001633, 0x002166, 0x002E99, 0x003BCC, 0x0049FF, 0x453100, 0x333333,
4075 0x003766, 0x003F99, 0x0048CC, 0x0053FF, 0x855E00, 0x7F5F33, 0x616366, 0x2A6699, 0x006CCC, 0x0072FF, 0xC78C00,
4076 0xC38D33, 0xB48F66, 0x919499, 0x6997CC, 0x009BFF, 0xFFBB00, 0xFFBB32, 0xFCBD66, 0xE6C099, 0xC0C5CC, 0x9DC8FF,
4077 0xFFEA00, 0xFFEA31, 0xFFEB65, 0xFFED99, 0xFFF1CC, 0xF0F6FF, 0x332405, 0x1D2733, 0x002D66, 0x003699, 0x0042CC,
4078 0x004EFF, 0x4F3804, 0x413A33, 0x003E66, 0x004499, 0x004DCC, 0x0057FF, 0x8A6100, 0x846233, 0x666666, 0x376999,
4079 0x006ECC, 0x0075FF, 0xC98E00, 0xC68F33, 0xB79166, 0x939599, 0x6E99CC, 0x009DFF, 0xFFBC00, 0xFFBD32, 0xFEBE66,
4080 0xE8C199, 0xC2C6CC, 0xA0C9FF, 0xFFEA00, 0xFFEB32, 0xFFEC65, 0xFFEE99, 0xFFF2CC, 0xF2F6FF, 0x4D3607, 0x3E3833,
4081 0x003C66, 0x004399, 0x004CCC, 0x0057FF, 0x604407, 0x564533, 0x2E4966, 0x004E99, 0x0056CC, 0x005FFF, 0x926703,
4082 0x8D6833, 0x726C66, 0x496F99, 0x0074CC, 0x007AFF, 0xCE9200, 0xCB9233, 0xBD9566, 0x999999, 0x769CCC, 0x00A0FF,
4083 0xFFBF00, 0xFFBF32, 0xFFC166, 0xEDC499, 0xC6C8CC, 0xA5CBFF, 0xFFEC00, 0xFFED32, 0xFFEE66, 0xFFF099, 0xFFF4CC,
4084 0xF4F8FF, 0x66490A, 0x5E4A33, 0x3A4E66, 0x005299, 0x0059CC, 0x0062FF, 0x745209, 0x6D5333, 0x4D5766, 0x005B99,
4085 0x0061CC, 0x0069FF, 0x9E7008, 0x9A7133, 0x837466, 0x5E7899, 0x007CCC, 0x0081FF, 0xD69700, 0xD39833, 0xC59A66,
4086 0xA59E99, 0x82A1CC, 0x16A5FF, 0xFFC300, 0xFFC333, 0xFFC466, 0xF3C799, 0xCCCCCC, 0xACCFFF, 0xFFEF00, 0xFFEF32,
4087 0xFFF166, 0xFFF399, 0xFFF6CC, 0xF9FBFF, 0x805B0C, 0x7A5C34, 0x5C6066, 0x006399, 0x0069CC, 0x0070FF, 0x8A620C,
4088 0x856334, 0x676766, 0x396A99, 0x006FCC, 0x0076FF, 0xAE7B0B, 0xAA7C34, 0x967E66, 0x738299, 0x2786CC, 0x008BFF,
4089 0xE19F08, 0xDE9F33, 0xD1A166, 0xB3A599, 0x90A9CC, 0x4FACFF, 0xFFC800, 0xFFC833, 0xFFCA66, 0xFCCC99, 0xD7D1CC,
4090 0xB7D4FF, 0xFFF300, 0xFFF332, 0xFFF466, 0xFFF799, 0xFFFACC, 0xFFFFFF> csWSprotanopiaAlt;
4091 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4092 /** @class csWSdeutanopiaAlt
4093 @ingroup cs
4094 @extends csWS_tpl
4095 The "web safe" color pallet of 216 colors as seen by someone with Deutanopia.
4096 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSdeutanopia. */
4097 typedef csWS_tpl<0x000000, 0x001433, 0x002866, 0x003C99, 0x0050CB, 0x0064FE, 0x3A2A0B, 0x2C2F33, 0x003866, 0x004699, 0x0057CB,
4098 0x0069FE, 0x755316, 0x6F5635, 0x585D67, 0x226599, 0x0070CC, 0x007EFF, 0xAF7D20, 0xAC7E39, 0x9E8468, 0x848C9A,
4099 0x5F93CC, 0x009DFF, 0xEAA72B, 0xE8A83F, 0xDFAB6B, 0xCBB29B, 0xAFBBCD, 0x8FC2FF, 0xFFD036, 0xFFD146, 0xFFD46E,
4100 0xFFD99D, 0xF7E1CE, 0xDBE9FF, 0x231800, 0x001F33, 0x002D66, 0x003F99, 0x0052CB, 0x0065FE, 0x412E09, 0x333333,
4101 0x003C66, 0x004999, 0x0059CB, 0x006BFE, 0x775515, 0x725735, 0x5B5F66, 0x2C6799, 0x0072CC, 0x007FFE, 0xB17E20,
4102 0xAE7F39, 0xA08568, 0x858D9A, 0x6294CC, 0x009EFF, 0xEBA72B, 0xE9A83F, 0xE0AC6B, 0xCCB39B, 0xB0BBCD, 0x91C2FF,
4103 0xFFD136, 0xFFD246, 0xFFD46E, 0xFFDA9D, 0xF8E2CE, 0xDCEAFF, 0x453000, 0x393532, 0x003E65, 0x004B98, 0x005ACB,
4104 0x006CFE, 0x563C00, 0x4D4032, 0x2C4865, 0x005398, 0x0061CB, 0x0071FE, 0x825C11, 0x7D5E34, 0x666666, 0x446D99,
4105 0x0077CC, 0x0084FE, 0xB7821E, 0xB48338, 0xA78968, 0x8C9199, 0x6C98CC, 0x00A1FF, 0xEFAA2A, 0xEDAB3E, 0xE4AF6A,
4106 0xD2B69B, 0xB5BECD, 0x97C5FF, 0xFFD335, 0xFFD445, 0xFFD66E, 0xFFDC9D, 0xFCE4CE, 0xE0ECFF, 0x684900, 0x624B2F,
4107 0x485364, 0x005C98, 0x0069CB, 0x0077FE, 0x725000, 0x6D5230, 0x545A64, 0x106398, 0x006ECB, 0x007CFE, 0x946800,
4108 0x906A32, 0x7E7165, 0x617898, 0x0081CB, 0x008DFE, 0xC38A1A, 0xC08B37, 0xB49067, 0x999999, 0x7E9FCC, 0x38A8FF,
4109 0xF7B027, 0xF5B13D, 0xEDB46A, 0xDBBB9B, 0xBEC4CD, 0xA3CAFF, 0xFFD733, 0xFFD844, 0xFFDA6D, 0xFFE09D, 0xFFE7CE,
4110 0xE7F0FF, 0x8B6100, 0x87632C, 0x736A63, 0x537297, 0x007BCA, 0x0087FE, 0x926600, 0x8E682C, 0x7B6F63, 0x5E7697,
4111 0x007FCA, 0x008BFE, 0xAC7900, 0xA97A2F, 0x9A8064, 0x7F8897, 0x5790CB, 0x009AFE, 0xD4960E, 0xD19734, 0xC79B66,
4112 0xB0A398, 0x94ABCB, 0x68B2FE, 0xFFB822, 0xFFB93A, 0xFABC68, 0xEAC39A, 0xCCCCCC, 0xB3D2FF, 0xFFDE30, 0xFFDE42,
4113 0xFFE16C, 0xFFE69C, 0xFFEDCD, 0xF1F6FF, 0xAE7900, 0xAB7A26, 0x9D8061, 0x818996, 0x5B90CA, 0x009AFD, 0xB37D00,
4114 0xB07E27, 0xA38461, 0x878C96, 0x6494CA, 0x009DFD, 0xC78C00, 0xC58D2A, 0xB99162, 0x9F9A96, 0x83A1CA, 0x47AAFD,
4115 0xE9A400, 0xE7A52F, 0xDEA964, 0xCAB097, 0xAEB9CA, 0x8DC0FE, 0xFFC319, 0xFFC436, 0xFFC767, 0xFDCD99, 0xE2D6CB,
4116 0xC8DDFE, 0xFFE62B, 0xFFE73F, 0xFFE96B, 0xFFEE9B, 0xFFF5CD, 0xFFFFFF> csWSdeutanopiaAlt;
4117 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4118 /** @class csWStritanoptiaAlt
4119 @ingroup cs
4120 @extends csWS_tpl
4121 The "web safe" color pallet of 216 colors as seen by someone with Tritanoptia.
4122 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWStritanoptia. */
4123 typedef csWS_tpl<0x000000, 0x00191E, 0x00323D, 0x004B5B, 0x00647A, 0x007C98, 0x202E31, 0x113237, 0x00404A, 0x005463, 0x006A7F,
4124 0x00819C, 0x415C61, 0x3C5D63, 0x21646D, 0x00707E, 0x008093, 0x0093AC, 0x618A92, 0x5F8B93, 0x548F99, 0x3296A4,
4125 0x00A1B4, 0x00AFC7, 0x82B8C2, 0x80B8C3, 0x79BBC7, 0x69C0CF, 0x42C8DA, 0x00D3EA, 0xA2E6F3, 0xA1E6F3, 0x9CE8F6,
4126 0x91ECFC, 0x7DF2FF, 0x53FAFF, 0x340010, 0x2C1A1C, 0x00333A, 0x004B5A, 0x006479, 0x007D98, 0x392E2F, 0x333333,
4127 0x004147, 0x005462, 0x006A7E, 0x00819C, 0x4D5C5F, 0x4A5E62, 0x39646C, 0x00707D, 0x008093, 0x0093AB, 0x698A91,
4128 0x678B92, 0x5D8F98, 0x4296A3, 0x00A1B3, 0x00AFC6, 0x87B8C1, 0x85B8C2, 0x7FBBC6, 0x70C0CE, 0x4FC8DA, 0x00D3E9,
4129 0xA6E6F2, 0xA5E6F3, 0xA0E8F6, 0x95ECFC, 0x82F2FF, 0x5CFAFF, 0x670021, 0x651527, 0x583338, 0x364E52, 0x006674,
4130 0x007E94, 0x692C35, 0x673139, 0x5B4244, 0x3C565B, 0x006C7A, 0x008298, 0x725C5E, 0x705E60, 0x666666, 0x507278,
4131 0x00818F, 0x0094A8, 0x838B8D, 0x818C8E, 0x7B9094, 0x6B97A0, 0x46A2B0, 0x00B0C4, 0x9AB8BF, 0x99B9C0, 0x94BCC4,
4132 0x88C1CC, 0x71C9D8, 0x3CD4E7, 0xB5E6F0, 0xB4E7F1, 0xB0E9F4, 0xA7ECFA, 0x97F3FF, 0x7AFBFF, 0x9B0031, 0x990035,
4133 0x933041, 0x854D54, 0x686969, 0x1C808C, 0x9C293F, 0x9A2E42, 0x943F4C, 0x86565B, 0x6B6E6F, 0x288591, 0xA15B63,
4134 0xA05D65, 0x9A656A, 0x8D7275, 0x758387, 0x4496A2, 0xAC8B8E, 0xAA8C8F, 0xA59092, 0x999999, 0x86A4AA, 0x63B2BF,
4135 0xBABABA, 0xB9BABB, 0xB5BDBF, 0xADC2C7, 0x9DCAD3, 0x83D5E3, 0xD0E7EC, 0xCFE8ED, 0xCBEAF0, 0xC4EDF6, 0xB7F3FF,
4136 0xA3FCFF, 0xCE0042, 0xCD0044, 0xC92A4E, 0xC04A5D, 0xB1676F, 0x978284, 0xCF214C, 0xCE284E, 0xCA3C56, 0xC15463,
4137 0xB26D75, 0x988788, 0xD3596B, 0xD25B6C, 0xCE6371, 0xC5717B, 0xB68388, 0x9E9899, 0xDA8A92, 0xD98B93, 0xD58F97,
4138 0xCD989D, 0xBFA5A7, 0xAAB4B6, 0xE5B9BD, 0xE4BABE, 0xE0BDC0, 0xD9C3C5, 0xCCCCCC, 0xBBD6DD, 0xF3E8E9, 0xF2E9E9,
4139 0xEFEBEB, 0xE9EFF0, 0xDFF5FA, 0xD0FDFF, 0xFF0052, 0xFF0054, 0xFE205B, 0xF84668, 0xED6478, 0xDD818B, 0xFF095A,
4140 0xFF1B5C, 0xFF3662, 0xF8506E, 0xEE6B7D, 0xDE858F, 0xFF5674, 0xFF5875, 0xFF607A, 0xFB6F83, 0xF1818F, 0xE1979E,
4141 0xFF8898, 0xFF8999, 0xFF8E9C, 0xFF96A3, 0xF7A3AC, 0xE8B3B8, 0xFFB8C1, 0xFFB9C2, 0xFFBCC4, 0xFFC2C9, 0xFFCBD0,
4142 0xF2D7D9, 0xFFE7EC, 0xFFE8ED, 0xFFEAEE, 0xFFEFF2, 0xFFF6F7, 0xFFFFFF> csWStritanoptiaAlt;
4143 //@}
4144 //========================================================================================================================================================
4145 /** @name Interesting Pallets */
4146 //@{
4147 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4148 /** @class csFPcircular12
4149 @ingroup cs
4150 @extends csFP_tpl */
4151 typedef csFP_tpl<0xFF0000, 0xFF7D00, 0xFFFF00, 0x7DFF00, 0x66CC00, 0x66FFB2, 0x00FFFF,
4152 0x007DFF, 0x0000FF, 0x7D00FF, 0xFF00FF, 0xFF007D> csFPcircular12;
4153 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4154 /** @class csFPcircular24
4155 @ingroup cs
4156 @extends csFP_tpl */
4157 typedef csFP_tpl<0xFF0000, 0xFF3F00, 0xFF7D00, 0xFFBE00, 0xFFE100, 0xFFFF00, 0x7DFF00, 0x7DCC00, 0x009600, 0x00BE00, 0x00FF5A,
4158 0x00FFBE, 0x00FFFF, 0x00BEFF, 0x007DFF, 0x003FFF, 0x0000FF, 0x3F00FF, 0x7D00FF, 0xBE00FF, 0xFF00FF, 0xFF00BE,
4159 0xFF007D, 0xFF003F> csFPcircular24;
4160 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4161 /** @class csFPblAqGrYeOrReVi200
4162 @ingroup cs
4163 @extends csFP_tpl */
4164 typedef csFP_tpl<0x0000FF, 0x0008FF, 0x000FFF, 0x0017FF, 0x001FFF, 0x0027FF, 0x002EFF, 0x0036FF, 0x003EFF, 0x0046FF, 0x004DFF,
4165 0x0055FF, 0x005DFF, 0x0064FF, 0x006CFF, 0x0074FF, 0x007CFF, 0x0083FF, 0x008BFF, 0x0093FF, 0x009BFF, 0x00A2FF,
4166 0x00AAFF, 0x00B2FF, 0x00B9FF, 0x00C1FF, 0x00C9FF, 0x00D1FF, 0x00D8FF, 0x00E0FF, 0x00E8FF, 0x00F0FF, 0x00F7FF,
4167 0x00FFFF, 0x00FDF8, 0x00FAF0, 0x01F8E9, 0x01F6E2, 0x01F3DB, 0x01F1D3, 0x02EFCC, 0x02EDC5, 0x02EABE, 0x02E8B6,
4168 0x03E6AF, 0x03E3A8, 0x03E1A0, 0x03DF99, 0x04DC92, 0x04DA8B, 0x04D883, 0x04D67C, 0x05D375, 0x05D16E, 0x05CF66,
4169 0x05CC5F, 0x06CA58, 0x06C850, 0x06C549, 0x06C342, 0x07C13B, 0x07BF33, 0x07BC2C, 0x07BA25, 0x08B81E, 0x08B516,
4170 0x08B30F, 0x0FB50F, 0x17B70E, 0x1EBA0E, 0x25BC0D, 0x2CBE0D, 0x34C00C, 0x3BC30C, 0x42C50B, 0x49C70B, 0x51C90B,
4171 0x58CC0A, 0x5FCE0A, 0x66D009, 0x6ED209, 0x75D508, 0x7CD708, 0x84D908, 0x8BDB07, 0x92DD07, 0x99E006, 0xA1E206,
4172 0xA8E405, 0xAFE605, 0xB6E904, 0xBEEB04, 0xC5ED04, 0xCCEF03, 0xD3F203, 0xDBF402, 0xE2F602, 0xE9F801, 0xF0FB01,
4173 0xF8FD00, 0xFFFF00, 0xFFFC00, 0xFFFA00, 0xFFF700, 0xFFF400, 0xFFF100, 0xFFEF00, 0xFFEC00, 0xFFE900, 0xFFE600,
4174 0xFFE400, 0xFFE100, 0xFFDE00, 0xFFDC00, 0xFFD900, 0xFFD600, 0xFFD300, 0xFFD100, 0xFFCE00, 0xFFCB00, 0xFFC800,
4175 0xFFC600, 0xFFC300, 0xFFC000, 0xFFBE00, 0xFFBB00, 0xFFB800, 0xFFB500, 0xFFB300, 0xFFB000, 0xFFAD00, 0xFFAA00,
4176 0xFFA800, 0xFFA500, 0xFFA000, 0xFF9B00, 0xFF9600, 0xFF9100, 0xFF8C00, 0xFF8700, 0xFF8200, 0xFF7D00, 0xFF7800,
4177 0xFF7300, 0xFF6E00, 0xFF6900, 0xFF6400, 0xFF5F00, 0xFF5A00, 0xFF5500, 0xFF5000, 0xFF4B00, 0xFF4600, 0xFF4100,
4178 0xFF3C00, 0xFF3700, 0xFF3200, 0xFF2D00, 0xFF2800, 0xFF2300, 0xFF1E00, 0xFF1900, 0xFF1400, 0xFF0F00, 0xFF0A00,
4179 0xFF0500, 0xFF0000, 0xFA0004, 0xF50008, 0xF0000C, 0xEB0010, 0xE60015, 0xE00019, 0xDB001D, 0xD60021, 0xD10025,
4180 0xCC0029, 0xC7002D, 0xC20031, 0xBD0036, 0xB8003A, 0xB3003E, 0xAE0042, 0xA80046, 0xA3004A, 0x9E004E, 0x990052,
4181 0x940057, 0x8F005B, 0x8A005F, 0x850063, 0x800067, 0x7B006B, 0x76006F, 0x700073, 0x6B0078, 0x66007C, 0x610080,
4182 0x5C0084, 0x570088> csFPblAqGrYeOrReVi200;
4183 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4184 /** @class csFPcmoceanAlgae
4185 @ingroup cs
4186 @extends csFP_tpl */
4187 typedef csFP_tpl<0xD7F9D0, 0xD6F8CE, 0xD4F7CD, 0xD3F6CB, 0xD2F5CA, 0xD1F4C8, 0xCFF4C7, 0xCEF3C5, 0xCDF2C4, 0xCCF1C3, 0xCAF0C1,
4188 0xC9EFC0, 0xC8EEBE, 0xC7EDBD, 0xC5ECBB, 0xC4EBBA, 0xC3EBB9, 0xC2EAB7, 0xC0E9B6, 0xBFE8B4, 0xBEE7B3, 0xBDE6B1,
4189 0xBBE5B0, 0xBAE4AF, 0xB9E4AD, 0xB8E3AC, 0xB6E2AB, 0xB5E1A9, 0xB4E0A8, 0xB2DFA6, 0xB1DEA5, 0xB0DEA4, 0xAFDDA2,
4190 0xADDCA1, 0xACDBA0, 0xABDA9E, 0xAADA9D, 0xA8D99C, 0xA7D89A, 0xA6D799, 0xA4D698, 0xA3D596, 0xA2D595, 0xA0D494,
4191 0x9FD392, 0x9ED291, 0x9DD190, 0x9BD18F, 0x9AD08D, 0x99CF8C, 0x97CE8B, 0x96CD8A, 0x95CD88, 0x93CC87, 0x92CB86,
4192 0x91CA85, 0x8FCA83, 0x8EC982, 0x8CC881, 0x8BC780, 0x8AC77E, 0x88C67D, 0x87C57C, 0x85C47B, 0x84C47A, 0x83C379,
4193 0x81C277, 0x80C176, 0x7EC175, 0x7DC074, 0x7BBF73, 0x7ABE72, 0x78BE71, 0x77BD6F, 0x75BC6E, 0x74BB6D, 0x72BB6C,
4194 0x71BA6B, 0x6FB96A, 0x6EB969, 0x6CB868, 0x6BB767, 0x69B666, 0x67B665, 0x66B564, 0x64B463, 0x62B462, 0x61B361,
4195 0x5FB260, 0x5DB25F, 0x5BB15E, 0x5AB05D, 0x58AF5D, 0x56AF5C, 0x54AE5B, 0x52AD5A, 0x50AD59, 0x4EAC59, 0x4CAB58,
4196 0x4AAB57, 0x48AA57, 0x46A956, 0x44A855, 0x42A855, 0x3FA754, 0x3DA654, 0x3BA654, 0x39A553, 0x37A453, 0x34A353,
4197 0x32A352, 0x30A252, 0x2EA152, 0x2CA052, 0x2AA052, 0x289F51, 0x269E51, 0x249D51, 0x229C51, 0x209C51, 0x1E9B51,
4198 0x1C9A51, 0x1B9951, 0x199851, 0x189750, 0x169650, 0x159650, 0x139550, 0x129450, 0x109350, 0x0F9250, 0x0E9150,
4199 0x0D904F, 0x0C8F4F, 0x0B8F4F, 0x0A8E4F, 0x098D4F, 0x098C4F, 0x088B4E, 0x088A4E, 0x07894E, 0x07884E, 0x07874D,
4200 0x07864D, 0x07864D, 0x07854D, 0x07844D, 0x07834C, 0x07824C, 0x08814C, 0x08804B, 0x087F4B, 0x097E4B, 0x097D4B,
4201 0x0A7C4A, 0x0A7C4A, 0x0B7B4A, 0x0B7A49, 0x0C7949, 0x0C7849, 0x0D7748, 0x0D7648, 0x0E7548, 0x0E7447, 0x0F7347,
4202 0x0F7347, 0x107246, 0x107146, 0x117045, 0x116F45, 0x126E45, 0x126D44, 0x126C44, 0x136B43, 0x136A43, 0x146A43,
4203 0x146942, 0x146842, 0x156741, 0x156641, 0x156540, 0x166440, 0x166340, 0x16623F, 0x17623F, 0x17613E, 0x17603E,
4204 0x175F3D, 0x185E3D, 0x185D3C, 0x185C3C, 0x185B3B, 0x185B3B, 0x195A3A, 0x19593A, 0x195839, 0x195739, 0x195638,
4205 0x195538, 0x195437, 0x195437, 0x1A5336, 0x1A5235, 0x1A5135, 0x1A5034, 0x1A4F34, 0x1A4E33, 0x1A4D33, 0x1A4D32,
4206 0x1A4C32, 0x1A4B31, 0x1A4A30, 0x1A4930, 0x1A482F, 0x1A472F, 0x1A472E, 0x1A462E, 0x1A452D, 0x1A442C, 0x1A432C,
4207 0x19422B, 0x19412B, 0x19402A, 0x194029, 0x193F29, 0x193E28, 0x193D27, 0x193C27, 0x183B26, 0x183B26, 0x183A25,
4208 0x183924, 0x183824, 0x183723, 0x173622, 0x173522, 0x173521, 0x173420, 0x173320, 0x16321F, 0x16311E, 0x16301E,
4209 0x162F1D, 0x152F1C, 0x152E1C, 0x152D1B, 0x142C1A, 0x142B1A, 0x142A19, 0x142918, 0x132918, 0x132817, 0x132716,
4210 0x122616, 0x122515, 0x122414> csFPcmoceanAlgae;
4211 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4212 /** @class csFPcmoceanAmp
4213 @ingroup cs
4214 @extends csFP_tpl */
4215 typedef csFP_tpl<0xF1EDEC, 0xF1ECEB, 0xF0EBE9, 0xEFE9E8, 0xEFE8E7, 0xEEE7E5, 0xEEE6E4, 0xEDE5E3, 0xEDE3E1, 0xECE2E0, 0xECE1DE,
4216 0xEBE0DD, 0xEBDFDC, 0xEADDDA, 0xEADCD9, 0xE9DBD7, 0xE9DAD6, 0xE9D9D4, 0xE8D8D3, 0xE8D6D2, 0xE7D5D0, 0xE7D4CF,
4217 0xE6D3CD, 0xE6D2CC, 0xE6D1CA, 0xE5CFC9, 0xE5CEC8, 0xE4CDC6, 0xE4CCC5, 0xE4CBC3, 0xE3C9C2, 0xE3C8C0, 0xE2C7BF,
4218 0xE2C6BD, 0xE2C5BC, 0xE1C4BB, 0xE1C3B9, 0xE1C1B8, 0xE0C0B6, 0xE0BFB5, 0xDFBEB3, 0xDFBDB2, 0xDFBCB0, 0xDEBAAF,
4219 0xDEB9AE, 0xDEB8AC, 0xDDB7AB, 0xDDB6A9, 0xDDB5A8, 0xDCB4A6, 0xDCB2A5, 0xDCB1A3, 0xDBB0A2, 0xDBAFA1, 0xDBAE9F,
4220 0xDAAD9E, 0xDAAC9C, 0xD9AA9B, 0xD9A999, 0xD9A898, 0xD8A796, 0xD8A695, 0xD8A594, 0xD7A492, 0xD7A291, 0xD7A18F,
4221 0xD6A08E, 0xD69F8C, 0xD69E8B, 0xD59D89, 0xD59C88, 0xD59A87, 0xD49985, 0xD49884, 0xD49782, 0xD39681, 0xD3957F,
4222 0xD3947E, 0xD2927D, 0xD2917B, 0xD2907A, 0xD18F78, 0xD18E77, 0xD18D76, 0xD08C74, 0xD08B73, 0xD08971, 0xCF8870,
4223 0xCF876F, 0xCF866D, 0xCE856C, 0xCE846A, 0xCD8369, 0xCD8168, 0xCD8066, 0xCC7F65, 0xCC7E64, 0xCC7D62, 0xCB7C61,
4224 0xCB7A60, 0xCB795E, 0xCA785D, 0xCA775B, 0xC9765A, 0xC97559, 0xC97457, 0xC87256, 0xC87155, 0xC87054, 0xC76F52,
4225 0xC76E51, 0xC66D50, 0xC66B4E, 0xC66A4D, 0xC5694C, 0xC5684A, 0xC56749, 0xC46548, 0xC46447, 0xC36346, 0xC36244,
4226 0xC36143, 0xC25F42, 0xC25E41, 0xC15D3F, 0xC15C3E, 0xC05B3D, 0xC0593C, 0xC0583B, 0xBF573A, 0xBF5639, 0xBE5438,
4227 0xBE5336, 0xBD5235, 0xBD5134, 0xBD4F33, 0xBC4E32, 0xBC4D31, 0xBB4C30, 0xBB4A30, 0xBA492F, 0xBA482E, 0xB9462D,
4228 0xB9452C, 0xB8442B, 0xB8422B, 0xB7412A, 0xB74029, 0xB63F29, 0xB53D28, 0xB53C27, 0xB43B27, 0xB43926, 0xB33826,
4229 0xB23726, 0xB23525, 0xB13425, 0xB03325, 0xB03125, 0xAF3024, 0xAE2F24, 0xAE2D24, 0xAD2C24, 0xAC2B24, 0xAB2A24,
4230 0xAA2824, 0xAA2724, 0xA92624, 0xA82524, 0xA72424, 0xA62225, 0xA52125, 0xA42025, 0xA31F25, 0xA21E25, 0xA11D25,
4231 0xA01C26, 0x9F1B26, 0x9E1A26, 0x9D1926, 0x9C1827, 0x9B1727, 0x9A1627, 0x991527, 0x981527, 0x971428, 0x951328,
4232 0x941328, 0x931228, 0x921128, 0x911129, 0x901029, 0x8E1029, 0x8D1029, 0x8C0F29, 0x8B0F29, 0x890F29, 0x880F29,
4233 0x870E29, 0x850E29, 0x840E29, 0x830E29, 0x810E29, 0x800E29, 0x7F0E29, 0x7D0E29, 0x7C0E29, 0x7B0E29, 0x790E29,
4234 0x780E28, 0x770E28, 0x750E28, 0x740E28, 0x730E27, 0x710E27, 0x700E27, 0x6F0E26, 0x6D0E26, 0x6C0F26, 0x6B0F25,
4235 0x690F25, 0x680F25, 0x670F24, 0x650F24, 0x640E23, 0x630E23, 0x610E22, 0x600E22, 0x5F0E21, 0x5D0E21, 0x5C0E21,
4236 0x5B0E20, 0x5A0E1F, 0x580E1F, 0x570E1E, 0x560E1E, 0x540D1D, 0x530D1D, 0x520D1C, 0x510D1C, 0x4F0D1B, 0x4E0D1A,
4237 0x4D0C1A, 0x4B0C19, 0x4A0C19, 0x490C18, 0x480B17, 0x460B17, 0x450B16, 0x440B16, 0x430A15, 0x410A14, 0x400A14,
4238 0x3F0A13, 0x3D0912, 0x3C0912> csFPcmoceanAmp;
4239 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4240 /** @class csFPcmoceanBalance
4241 @ingroup cs
4242 @extends csFP_tpl */
4243 typedef csFP_tpl<0x181C43, 0x191E46, 0x1A1F49, 0x1B214C, 0x1C224F, 0x1D2352, 0x1E2555, 0x1F2658, 0x20275B, 0x21295F, 0x212A62,
4244 0x222B65, 0x232D69, 0x242E6C, 0x252F6F, 0x253073, 0x263276, 0x27337A, 0x27347D, 0x283681, 0x283784, 0x293888,
4245 0x293A8C, 0x293B8F, 0x293C93, 0x293E97, 0x293F9A, 0x29409E, 0x2942A2, 0x2843A5, 0x2745A9, 0x2647AC, 0x2548B0,
4246 0x234AB3, 0x214CB6, 0x1F4EB8, 0x1C50BA, 0x1952BC, 0x1655BD, 0x1357BE, 0x1059BE, 0x0D5BBE, 0x0C5EBE, 0x0A60BE,
4247 0x0A62BE, 0x0A64BE, 0x0B66BD, 0x0D68BD, 0x0F6ABD, 0x116CBC, 0x136EBC, 0x1670BC, 0x1972BB, 0x1B74BB, 0x1E76BB,
4248 0x2178BB, 0x237ABA, 0x267BBA, 0x297DBA, 0x2B7FBA, 0x2E81BA, 0x3083BA, 0x3384BA, 0x3686BA, 0x3888BA, 0x3B89BA,
4249 0x3E8BBA, 0x408DBA, 0x438FBA, 0x4690BA, 0x4892BA, 0x4B94BA, 0x4E95BA, 0x5197BA, 0x5399BA, 0x569ABB, 0x599CBB,
4250 0x5C9DBB, 0x5F9FBB, 0x62A0BB, 0x65A2BC, 0x68A4BC, 0x6BA5BC, 0x6EA7BD, 0x71A8BD, 0x75AABE, 0x78ABBE, 0x7BACBF,
4251 0x7EAEBF, 0x81AFC0, 0x85B1C0, 0x88B2C1, 0x8BB4C2, 0x8EB5C3, 0x91B7C3, 0x94B8C4, 0x98BAC5, 0x9BBBC6, 0x9EBCC7,
4252 0xA1BEC8, 0xA4BFC9, 0xA7C1CA, 0xAAC2CB, 0xADC4CC, 0xB0C5CD, 0xB3C7CE, 0xB6C9CF, 0xB9CAD0, 0xBCCCD2, 0xBFCDD3,
4253 0xC1CFD4, 0xC4D0D5, 0xC7D2D7, 0xCAD4D8, 0xCDD5D9, 0xD0D7DA, 0xD3D9DC, 0xD5DADD, 0xD8DCDE, 0xDBDEE0, 0xDEE0E1,
4254 0xE1E1E3, 0xE3E3E4, 0xE6E5E6, 0xE9E7E7, 0xEBE9E9, 0xEEEAEA, 0xF1ECEC, 0xF1ECEB, 0xF0EAE9, 0xEFE8E6, 0xEEE5E3,
4255 0xEDE3E0, 0xECE0DE, 0xEBDEDB, 0xEADCD8, 0xE9D9D5, 0xE8D7D2, 0xE7D5CF, 0xE6D2CD, 0xE5D0CA, 0xE5CEC7, 0xE4CBC4,
4256 0xE3C9C1, 0xE2C7BE, 0xE1C4BB, 0xE1C2B8, 0xE0C0B5, 0xDFBDB2, 0xDFBBB0, 0xDEB9AD, 0xDDB6AA, 0xDCB4A7, 0xDCB2A4,
4257 0xDBAFA1, 0xDAAD9E, 0xDAAB9B, 0xD9A998, 0xD8A696, 0xD8A493, 0xD7A290, 0xD69F8D, 0xD69D8A, 0xD59B87, 0xD49984,
4258 0xD39681, 0xD3947F, 0xD2927C, 0xD18F79, 0xD18D76, 0xD08B73, 0xCF8970, 0xCF866E, 0xCE846B, 0xCD8268, 0xCD7F65,
4259 0xCC7D63, 0xCB7B60, 0xCA795D, 0xCA765B, 0xC97458, 0xC87255, 0xC76F53, 0xC76D50, 0xC66B4D, 0xC5684B, 0xC46648,
4260 0xC36346, 0xC36143, 0xC25F41, 0xC15C3F, 0xC05A3C, 0xBF573A, 0xBE5538, 0xBE5236, 0xBD5034, 0xBC4D32, 0xBB4B30,
4261 0xBA482E, 0xB9452C, 0xB8432B, 0xB74029, 0xB63D28, 0xB43B27, 0xB33826, 0xB23525, 0xB13325, 0xAF3024, 0xAE2E24,
4262 0xAC2B24, 0xAB2924, 0xA92624, 0xA72424, 0xA52125, 0xA31F25, 0xA11D25, 0x9F1B26, 0x9D1926, 0x9B1727, 0x991627,
4263 0x971428, 0x941328, 0x921228, 0x901029, 0x8D1029, 0x8B0F29, 0x880F29, 0x860E29, 0x830E29, 0x800E29, 0x7E0E29,
4264 0x7B0E29, 0x780E28, 0x760E28, 0x730E27, 0x700E27, 0x6D0E26, 0x6B0F25, 0x680F25, 0x650F24, 0x630E23, 0x600E22,
4265 0x5E0E21, 0x5B0E20, 0x580E1F, 0x560E1E, 0x530D1D, 0x510D1C, 0x4E0D1B, 0x4B0C19, 0x490C18, 0x460B17, 0x440B16,
4266 0x410A14, 0x3F0A13, 0x3C0912> csFPcmoceanBalance;
4267 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4268 /** @class csFPcmoceanCurl
4269 @ingroup cs
4270 @extends csFP_tpl */
4271 typedef csFP_tpl<0x151D44, 0x151F45, 0x162146, 0x162347, 0x172548, 0x172749, 0x18294A, 0x182B4B, 0x182D4C, 0x192F4D, 0x19314F,
4272 0x1A3350, 0x1A3551, 0x1A3652, 0x1B3853, 0x1B3A54, 0x1B3C56, 0x1B3E57, 0x1C4058, 0x1C4259, 0x1C435A, 0x1C455B,
4273 0x1C475D, 0x1C495E, 0x1C4B5F, 0x1C4C60, 0x1C4E61, 0x1C5062, 0x1C5263, 0x1C5465, 0x1B5666, 0x1B5867, 0x1B5968,
4274 0x1A5B69, 0x1A5D6A, 0x1A5F6B, 0x19616C, 0x19636D, 0x18656E, 0x17666F, 0x176870, 0x166A71, 0x156C72, 0x146E73,
4275 0x147074, 0x137275, 0x127476, 0x127676, 0x117777, 0x117978, 0x117B79, 0x117D79, 0x117F7A, 0x12817B, 0x13837B,
4276 0x14847C, 0x16867C, 0x17887D, 0x1A8A7D, 0x1C8C7E, 0x1F8D7E, 0x228F7E, 0x25917F, 0x29937F, 0x2C947F, 0x309680,
4277 0x349880, 0x389981, 0x3B9B81, 0x3F9C81, 0x439E82, 0x479F82, 0x4BA183, 0x50A284, 0x54A484, 0x57A585, 0x5BA686,
4278 0x5FA887, 0x63A988, 0x67AB89, 0x6BAC8A, 0x6FAD8B, 0x72AF8C, 0x76B08D, 0x7AB18E, 0x7DB390, 0x81B491, 0x85B593,
4279 0x88B794, 0x8BB896, 0x8FBA97, 0x92BB99, 0x96BC9B, 0x99BE9D, 0x9CBF9F, 0xA0C0A0, 0xA3C2A2, 0xA6C3A4, 0xA9C5A6,
4280 0xACC6A9, 0xB0C8AB, 0xB3C9AD, 0xB6CBAF, 0xB9CCB2, 0xBCCEB4, 0xBFCFB6, 0xC2D1B9, 0xC5D2BB, 0xC8D4BE, 0xCBD5C0,
4281 0xCED7C3, 0xD1D8C5, 0xD3DAC8, 0xD6DCCB, 0xD9DDCD, 0xDCDFD0, 0xDFE1D3, 0xE2E2D6, 0xE4E4D8, 0xE7E6DB, 0xEAE8DE,
4282 0xEDEAE1, 0xF0EBE4, 0xF2EDE7, 0xF5EFEA, 0xF8F1ED, 0xFBF3F0, 0xFDF5F3, 0xFEF6F5, 0xFCF4F1, 0xFBF1EE, 0xFAEFEB,
4283 0xF9ECE7, 0xF8EAE4, 0xF6E7E1, 0xF5E5DD, 0xF4E2DA, 0xF3E0D6, 0xF2DDD3, 0xF2DBD0, 0xF1D8CC, 0xF0D6C9, 0xEFD3C6,
4284 0xEED1C3, 0xEDCFBF, 0xECCCBC, 0xECCAB9, 0xEBC7B6, 0xEAC5B3, 0xE9C2AF, 0xE9C0AC, 0xE8BDA9, 0xE7BBA6, 0xE7B8A3,
4285 0xE6B6A0, 0xE5B39D, 0xE5B19A, 0xE4AE98, 0xE3AC95, 0xE3A992, 0xE2A78F, 0xE1A48D, 0xE1A28A, 0xE09F88, 0xE09D85,
4286 0xDF9A83, 0xDE9880, 0xDE957E, 0xDD937C, 0xDC907A, 0xDB8E78, 0xDB8B76, 0xDA8974, 0xD98672, 0xD88471, 0xD7816F,
4287 0xD67F6E, 0xD67C6C, 0xD57A6B, 0xD4776A, 0xD37569, 0xD27268, 0xD07067, 0xCF6E66, 0xCE6B65, 0xCD6964, 0xCC6764,
4288 0xCA6463, 0xC96263, 0xC86062, 0xC65D62, 0xC55B61, 0xC35961, 0xC25761, 0xC05561, 0xBF5360, 0xBD5160, 0xBB4E60,
4289 0xBA4C60, 0xB84A60, 0xB64860, 0xB44660, 0xB34460, 0xB14260, 0xAF4160, 0xAD3F60, 0xAB3D60, 0xA93B60, 0xA73960,
4290 0xA53760, 0xA33660, 0xA13460, 0x9F3260, 0x9D3060, 0x9B2F60, 0x992D61, 0x972B61, 0x952A61, 0x922861, 0x902760,
4291 0x8E2560, 0x8C2460, 0x892260, 0x872160, 0x852060, 0x821F60, 0x801D5F, 0x7D1C5F, 0x7B1B5E, 0x781A5E, 0x76195D,
4292 0x73195D, 0x71185C, 0x6E175B, 0x6C175A, 0x691659, 0x661658, 0x641557, 0x611556, 0x5E1455, 0x5C1453, 0x591452,
4293 0x571350, 0x54134E, 0x51134D, 0x4F124B, 0x4C1249, 0x491247, 0x471145, 0x441143, 0x421041, 0x3F103F, 0x3D0F3D,
4294 0x3A0F3B, 0x380E39, 0x350D36> csFPcmoceanCurl;
4295 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4296 /** @class csFPcmoceanDeep
4297 @ingroup cs
4298 @extends csFP_tpl */
4299 typedef csFP_tpl<0xFDFECC, 0xFBFDCB, 0xF9FCCA, 0xF7FBC8, 0xF5FAC7, 0xF3FAC6, 0xF1F9C5, 0xEFF8C4, 0xEDF7C3, 0xEBF7C1, 0xE9F6C0,
4300 0xE7F5BF, 0xE5F4BE, 0xE3F4BD, 0xE1F3BC, 0xDFF2BB, 0xDDF2BA, 0xDBF1B9, 0xD9F0B8, 0xD7EFB7, 0xD4EFB6, 0xD2EEB5,
4301 0xD0EDB4, 0xCEECB3, 0xCCECB3, 0xCAEBB2, 0xC8EAB1, 0xC6EAB0, 0xC4E9AF, 0xC1E8AF, 0xBFE7AE, 0xBDE7AD, 0xBBE6AC,
4302 0xB9E5AC, 0xB7E5AB, 0xB5E4AA, 0xB2E3AA, 0xB0E2A9, 0xAEE2A9, 0xACE1A8, 0xAAE0A8, 0xA7E0A7, 0xA5DFA7, 0xA3DEA6,
4303 0xA1DDA6, 0x9FDDA5, 0x9CDCA5, 0x9ADBA5, 0x98DAA4, 0x96DAA4, 0x94D9A4, 0x92D8A4, 0x90D7A4, 0x8DD7A3, 0x8BD6A3,
4304 0x89D5A3, 0x87D4A3, 0x85D3A3, 0x83D3A3, 0x81D2A3, 0x7FD1A3, 0x7DD0A3, 0x7CCFA3, 0x7ACEA3, 0x78CEA3, 0x76CDA3,
4305 0x75CCA3, 0x73CBA3, 0x71CAA3, 0x70C9A3, 0x6EC8A3, 0x6DC7A3, 0x6BC6A3, 0x6AC5A4, 0x69C4A4, 0x67C3A4, 0x66C2A4,
4306 0x65C2A4, 0x64C1A4, 0x63C0A4, 0x62BFA4, 0x61BEA4, 0x60BDA4, 0x5FBCA4, 0x5EBBA4, 0x5DBAA4, 0x5CB9A4, 0x5BB8A4,
4307 0x5AB7A4, 0x5AB6A4, 0x59B4A4, 0x58B3A4, 0x58B2A4, 0x57B1A4, 0x56B0A4, 0x56AFA4, 0x55AEA3, 0x55ADA3, 0x54ACA3,
4308 0x53ABA3, 0x53AAA3, 0x52A9A3, 0x52A8A3, 0x51A7A3, 0x51A6A2, 0x51A5A2, 0x50A4A2, 0x50A3A2, 0x4FA2A2, 0x4FA1A2,
4309 0x4FA0A2, 0x4E9FA1, 0x4E9EA1, 0x4D9DA1, 0x4D9CA1, 0x4D9BA1, 0x4C9AA0, 0x4C99A0, 0x4B98A0, 0x4B97A0, 0x4B96A0,
4310 0x4A959F, 0x4A949F, 0x4A939F, 0x49929F, 0x49919E, 0x49909E, 0x488F9E, 0x488E9E, 0x488D9D, 0x478C9D, 0x478B9D,
4311 0x478A9D, 0x46899D, 0x46889C, 0x46879C, 0x45869C, 0x45859C, 0x45849B, 0x44839B, 0x44829B, 0x44819B, 0x44809B,
4312 0x437F9A, 0x437E9A, 0x437D9A, 0x427C9A, 0x427B99, 0x427A99, 0x427999, 0x417899, 0x417799, 0x417698, 0x407598,
4313 0x407498, 0x407398, 0x407298, 0x407197, 0x3F7097, 0x3F6F97, 0x3F6E97, 0x3F6D97, 0x3F6C96, 0x3E6B96, 0x3E6A96,
4314 0x3E6996, 0x3E6896, 0x3E6795, 0x3E6695, 0x3E6595, 0x3E6495, 0x3E6394, 0x3E6294, 0x3E6194, 0x3E6094, 0x3E5F93,
4315 0x3E5E93, 0x3E5C93, 0x3E5B93, 0x3E5A92, 0x3E5992, 0x3E5892, 0x3E5791, 0x3E5691, 0x3F5590, 0x3F5490, 0x3F538F,
4316 0x3F528F, 0x3F508E, 0x404F8D, 0x404E8D, 0x404D8C, 0x404C8B, 0x414B8A, 0x414A89, 0x414988, 0x414887, 0x414785,
4317 0x414684, 0x414583, 0x414481, 0x424380, 0x41427E, 0x41417D, 0x41407B, 0x41407A, 0x413F78, 0x413E76, 0x413D75,
4318 0x403C73, 0x403C71, 0x403B70, 0x403A6E, 0x3F396C, 0x3F386B, 0x3F3869, 0x3E3767, 0x3E3666, 0x3D3564, 0x3D3562,
4319 0x3D3461, 0x3C335F, 0x3C325D, 0x3B325C, 0x3B315A, 0x3A3058, 0x3A3057, 0x392F55, 0x392E54, 0x382D52, 0x382D51,
4320 0x372C4F, 0x362B4D, 0x362A4C, 0x352A4A, 0x352949, 0x342847, 0x342846, 0x332744, 0x322643, 0x322541, 0x312540,
4321 0x30243E, 0x30233D, 0x2F223B, 0x2F223A, 0x2E2139, 0x2D2037, 0x2D1F36, 0x2C1F34, 0x2B1E33, 0x2B1D32, 0x2A1C30,
4322 0x291C2F, 0x281B2D, 0x281A2C> csFPcmoceanDeep;
4323 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4324 /** @class csFPcmoceanDense
4325 @ingroup cs
4326 @extends csFP_tpl */
4327 typedef csFP_tpl<0xE6F1F1, 0xE4F0F0, 0xE3EFEF, 0xE1EEEF, 0xDFEDEE, 0xDDEDED, 0xDCECED, 0xDAEBEC, 0xD8EAEC, 0xD7E9EB, 0xD5E9EB,
4328 0xD3E8EA, 0xD1E7EA, 0xD0E6E9, 0xCEE5E9, 0xCCE4E8, 0xCBE4E8, 0xC9E3E8, 0xC7E2E7, 0xC6E1E7, 0xC4E0E6, 0xC2DFE6,
4329 0xC1DFE6, 0xBFDEE6, 0xBEDDE5, 0xBCDCE5, 0xBADBE5, 0xB9DAE4, 0xB7DAE4, 0xB6D9E4, 0xB4D8E4, 0xB2D7E4, 0xB1D6E3,
4330 0xAFD5E3, 0xAED4E3, 0xACD4E3, 0xABD3E3, 0xA9D2E3, 0xA8D1E3, 0xA6D0E3, 0xA5CFE2, 0xA3CEE2, 0xA2CEE2, 0xA0CDE2,
4331 0x9FCCE2, 0x9ECBE2, 0x9CCAE2, 0x9BC9E2, 0x9AC8E2, 0x98C7E2, 0x97C6E2, 0x96C5E2, 0x94C5E2, 0x93C4E2, 0x92C3E2,
4332 0x90C2E2, 0x8FC1E2, 0x8EC0E2, 0x8DBFE2, 0x8CBEE2, 0x8ABDE3, 0x89BCE3, 0x88BBE3, 0x87BAE3, 0x86B9E3, 0x85B8E3,
4333 0x84B7E3, 0x83B6E3, 0x82B5E3, 0x81B4E3, 0x80B3E3, 0x7FB2E3, 0x7FB1E4, 0x7EB0E4, 0x7DAFE4, 0x7CAEE4, 0x7BADE4,
4334 0x7BACE4, 0x7AABE4, 0x79AAE4, 0x79A9E4, 0x78A8E4, 0x78A7E4, 0x77A6E4, 0x77A5E4, 0x76A4E5, 0x76A3E5, 0x75A1E5,
4335 0x75A0E5, 0x759FE5, 0x759EE5, 0x749DE5, 0x749CE4, 0x749BE4, 0x749AE4, 0x7498E4, 0x7397E4, 0x7396E4, 0x7395E4,
4336 0x7394E4, 0x7393E3, 0x7391E3, 0x7390E3, 0x738FE3, 0x738EE2, 0x748DE2, 0x748BE2, 0x748AE2, 0x7489E1, 0x7488E1,
4337 0x7487E0, 0x7485E0, 0x7584DF, 0x7583DF, 0x7582DE, 0x7581DE, 0x757FDD, 0x757EDD, 0x767DDC, 0x767CDC, 0x767BDB,
4338 0x7679DA, 0x7678DA, 0x7777D9, 0x7776D8, 0x7775D7, 0x7773D7, 0x7772D6, 0x7871D5, 0x7870D4, 0x786FD3, 0x786ED2,
4339 0x786CD2, 0x786BD1, 0x786AD0, 0x7969CF, 0x7968CE, 0x7966CD, 0x7965CC, 0x7964CB, 0x7963CA, 0x7962C9, 0x7961C8,
4340 0x7960C7, 0x795EC5, 0x795DC4, 0x795CC3, 0x795BC2, 0x795AC1, 0x7959C0, 0x7958BF, 0x7957BD, 0x7956BC, 0x7954BB,
4341 0x7953BA, 0x7952B8, 0x7951B7, 0x7950B6, 0x794FB5, 0x784EB3, 0x784DB2, 0x784CB1, 0x784BAF, 0x784AAE, 0x7849AD,
4342 0x7748AB, 0x7747AA, 0x7746A9, 0x7745A7, 0x7743A6, 0x7642A5, 0x7641A3, 0x7640A2, 0x763FA0, 0x753E9F, 0x753D9D,
4343 0x753C9C, 0x743B9B, 0x743B99, 0x743A98, 0x733996, 0x733895, 0x733793, 0x723692, 0x723590, 0x72348F, 0x71338D,
4344 0x71328C, 0x70318A, 0x703088, 0x6F2F87, 0x6F2E85, 0x6E2D84, 0x6E2D82, 0x6D2C81, 0x6D2B7F, 0x6C2A7E, 0x6C297C,
4345 0x6B287A, 0x6B2879, 0x6A2777, 0x6A2675, 0x692574, 0x682472, 0x682471, 0x67236F, 0x67226D, 0x66216C, 0x65216A,
4346 0x652068, 0x641F67, 0x631F65, 0x621E63, 0x621D62, 0x611D60, 0x601C5E, 0x5F1B5D, 0x5F1B5B, 0x5E1A59, 0x5D1A58,
4347 0x5C1956, 0x5B1954, 0x5A1853, 0x5A1851, 0x591750, 0x58174E, 0x57164C, 0x56164B, 0x551649, 0x541548, 0x531546,
4348 0x521544, 0x511443, 0x501441, 0x4F1440, 0x4E133E, 0x4D133D, 0x4B133B, 0x4A133A, 0x491238, 0x481237, 0x471236,
4349 0x461234, 0x451133, 0x441132, 0x421130, 0x41112F, 0x40102E, 0x3F102D, 0x3E102B, 0x3C102A, 0x3B0F29, 0x3A0F28,
4350 0x390F27, 0x380F25, 0x360E24> csFPcmoceanDense;
4351 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4352 /** @class csFPcmoceanHaline
4353 @ingroup cs
4354 @extends csFP_tpl */
4355 typedef csFP_tpl<0x2A186C, 0x2A196E, 0x2A1971, 0x2B1973, 0x2B1975, 0x2C1A78, 0x2C1A7A, 0x2D1A7D, 0x2D1A7F, 0x2D1B82, 0x2E1B84,
4356 0x2E1B87, 0x2E1C89, 0x2E1C8C, 0x2E1C8E, 0x2E1D91, 0x2E1D93, 0x2E1E95, 0x2E1E98, 0x2E1F9A, 0x2D209C, 0x2D219D,
4357 0x2C229F, 0x2B24A0, 0x2A25A1, 0x2927A2, 0x2829A3, 0x262BA3, 0x252DA3, 0x242EA3, 0x2230A3, 0x2132A2, 0x2034A2,
4358 0x1E35A1, 0x1D37A1, 0x1C39A0, 0x1B3AA0, 0x193C9F, 0x183D9E, 0x173F9E, 0x16409D, 0x15419C, 0x14439C, 0x13449B,
4359 0x12459B, 0x11479A, 0x104899, 0x0F4999, 0x0F4A98, 0x0E4C97, 0x0D4D97, 0x0D4E96, 0x0D4F96, 0x0C5095, 0x0C5195,
4360 0x0C5294, 0x0C5394, 0x0C5493, 0x0D5593, 0x0D5692, 0x0D5792, 0x0E5891, 0x0E5991, 0x0F5A91, 0x0F5B90, 0x105C90,
4361 0x115D8F, 0x115E8F, 0x125F8F, 0x13608E, 0x14618E, 0x14628E, 0x15638E, 0x16638D, 0x17648D, 0x18658D, 0x18668C,
4362 0x19678C, 0x1A688C, 0x1B698C, 0x1C6A8C, 0x1D6B8B, 0x1D6B8B, 0x1E6C8B, 0x1F6D8B, 0x206E8B, 0x216F8B, 0x22708A,
4363 0x22718A, 0x23718A, 0x24728A, 0x25738A, 0x26748A, 0x26758A, 0x27768A, 0x287689, 0x297789, 0x297889, 0x2A7989,
4364 0x2B7A89, 0x2B7B89, 0x2C7C89, 0x2D7C89, 0x2D7D89, 0x2E7E89, 0x2F7F89, 0x2F8089, 0x308189, 0x318289, 0x318288,
4365 0x328388, 0x338488, 0x338588, 0x348688, 0x348788, 0x358888, 0x358988, 0x368988, 0x378A88, 0x378B88, 0x388C88,
4366 0x388D88, 0x398E88, 0x398F88, 0x3A9087, 0x3A9087, 0x3B9187, 0x3B9287, 0x3C9387, 0x3C9487, 0x3D9587, 0x3D9687,
4367 0x3E9787, 0x3E9886, 0x3F9986, 0x3F9986, 0x409A86, 0x419B86, 0x419C85, 0x429D85, 0x429E85, 0x439F85, 0x43A084,
4368 0x44A184, 0x44A284, 0x45A384, 0x46A483, 0x46A483, 0x47A583, 0x48A682, 0x48A782, 0x49A882, 0x4AA981, 0x4AAA81,
4369 0x4BAB81, 0x4CAC80, 0x4CAD80, 0x4DAE7F, 0x4EAE7F, 0x4FAF7E, 0x50B07E, 0x51B17D, 0x51B27D, 0x52B37C, 0x53B47C,
4370 0x54B57B, 0x55B67B, 0x56B77A, 0x57B879, 0x58B879, 0x5AB978, 0x5BBA77, 0x5CBB77, 0x5DBC76, 0x5EBD75, 0x5FBE75,
4371 0x61BF74, 0x62BF73, 0x63C072, 0x65C172, 0x66C271, 0x68C370, 0x69C46F, 0x6BC46E, 0x6CC56E, 0x6EC66D, 0x70C76C,
4372 0x71C86B, 0x73C86A, 0x75C969, 0x77CA68, 0x78CB68, 0x7ACB67, 0x7CCC66, 0x7ECD65, 0x80CE64, 0x82CE63, 0x84CF62,
4373 0x86D062, 0x89D061, 0x8BD160, 0x8DD25F, 0x8FD25F, 0x92D35E, 0x94D35D, 0x97D45D, 0x99D45D, 0x9BD55C, 0x9ED65C,
4374 0xA0D65C, 0xA3D75C, 0xA5D75C, 0xA8D85C, 0xAAD85C, 0xADD85C, 0xAFD95D, 0xB1D95D, 0xB4DA5E, 0xB6DA5F, 0xB8DB60,
4375 0xBBDB61, 0xBDDC62, 0xBFDC63, 0xC1DD64, 0xC4DD65, 0xC6DE66, 0xC8DE67, 0xCADF69, 0xCCDF6A, 0xCEE06C, 0xD0E06D,
4376 0xD2E16F, 0xD4E170, 0xD6E272, 0xD8E273, 0xDAE375, 0xDCE377, 0xDEE479, 0xE0E57A, 0xE1E57C, 0xE3E67E, 0xE5E680,
4377 0xE7E781, 0xE9E783, 0xEBE885, 0xECE987, 0xEEE989, 0xF0EA8A, 0xF2EA8C, 0xF3EB8E, 0xF5EC90, 0xF7EC92, 0xF8ED94,
4378 0xFAEE96, 0xFCEE98, 0xFDEF9A> csFPcmoceanHaline;
4379 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4380 /** @class csFPcmoceanIce
4381 @ingroup cs
4382 @extends csFP_tpl */
4383 typedef csFP_tpl<0x040613, 0x050614, 0x050715, 0x060817, 0x070918, 0x080A1A, 0x090B1B, 0x0A0C1D, 0x0B0D1E, 0x0C0D1F, 0x0D0E21,
4384 0x0E0F22, 0x0F1024, 0x101125, 0x111227, 0x121328, 0x13132A, 0x14142B, 0x15152C, 0x16162E, 0x17172F, 0x171831,
4385 0x181832, 0x191934, 0x1A1A35, 0x1B1B37, 0x1C1C38, 0x1D1C3A, 0x1E1D3B, 0x1F1E3D, 0x1F1F3E, 0x201F40, 0x212041,
4386 0x222143, 0x232244, 0x242246, 0x252347, 0x252449, 0x26254A, 0x27254C, 0x28264E, 0x29274F, 0x292851, 0x2A2852,
4387 0x2B2954, 0x2C2A55, 0x2C2B57, 0x2D2B59, 0x2E2C5A, 0x2F2D5C, 0x2F2E5E, 0x302F5F, 0x312F61, 0x313062, 0x323164,
4388 0x333266, 0x333267, 0x343369, 0x35346B, 0x35356C, 0x36356E, 0x363670, 0x373771, 0x383873, 0x383975, 0x393976,
4389 0x393A78, 0x3A3B7A, 0x3A3C7B, 0x3A3D7D, 0x3B3E7F, 0x3B3E80, 0x3C3F82, 0x3C4084, 0x3C4185, 0x3D4287, 0x3D4389,
4390 0x3D448A, 0x3E458C, 0x3E468D, 0x3E478F, 0x3E4890, 0x3E4992, 0x3E4993, 0x3F4A95, 0x3F4B96, 0x3F4C97, 0x3F4E99,
4391 0x3F4F9A, 0x3F509B, 0x3F519D, 0x3F529E, 0x3F539F, 0x3F54A0, 0x3F55A1, 0x3F56A2, 0x3F57A3, 0x3F58A4, 0x3F59A5,
4392 0x3E5AA6, 0x3E5CA7, 0x3E5DA8, 0x3E5EA9, 0x3E5FAA, 0x3E60AB, 0x3E61AB, 0x3E62AC, 0x3E63AD, 0x3E65AD, 0x3E66AE,
4393 0x3E67AF, 0x3E68AF, 0x3E69B0, 0x3E6AB0, 0x3F6BB1, 0x3F6CB2, 0x3F6EB2, 0x3F6FB3, 0x3F70B3, 0x3F71B4, 0x4072B4,
4394 0x4073B4, 0x4074B5, 0x4075B5, 0x4176B6, 0x4178B6, 0x4279B7, 0x427AB7, 0x427BB7, 0x437CB8, 0x437DB8, 0x447EB9,
4395 0x447FB9, 0x4580B9, 0x4581BA, 0x4682BA, 0x4684BB, 0x4785BB, 0x4786BB, 0x4887BC, 0x4988BC, 0x4989BC, 0x4A8ABD,
4396 0x4B8BBD, 0x4B8CBD, 0x4C8DBE, 0x4D8EBE, 0x4E8FBF, 0x4E90BF, 0x4F91BF, 0x5092C0, 0x5194C0, 0x5195C0, 0x5296C1,
4397 0x5397C1, 0x5498C2, 0x5599C2, 0x559AC2, 0x569BC3, 0x579CC3, 0x589DC3, 0x599EC4, 0x5A9FC4, 0x5BA0C5, 0x5CA1C5,
4398 0x5DA2C5, 0x5EA3C6, 0x5FA4C6, 0x5FA6C7, 0x60A7C7, 0x61A8C7, 0x62A9C8, 0x63AAC8, 0x64ABC9, 0x65ACC9, 0x67ADC9,
4399 0x68AECA, 0x69AFCA, 0x6AB0CB, 0x6BB1CB, 0x6CB2CB, 0x6DB3CC, 0x6EB4CC, 0x6FB5CD, 0x71B6CD, 0x72B8CE, 0x73B9CE,
4400 0x74BACE, 0x75BBCF, 0x77BCCF, 0x78BDD0, 0x79BED0, 0x7BBFD0, 0x7CC0D1, 0x7DC1D1, 0x7FC2D2, 0x80C3D2, 0x82C4D3,
4401 0x83C5D3, 0x85C6D3, 0x86C7D4, 0x88C8D4, 0x89C9D5, 0x8BCAD5, 0x8CCBD6, 0x8ECCD6, 0x90CDD7, 0x92CED7, 0x93CFD8,
4402 0x95D0D8, 0x97D1D9, 0x99D2D9, 0x9AD3DA, 0x9CD4DA, 0x9ED5DB, 0xA0D6DC, 0xA2D6DC, 0xA4D7DD, 0xA6D8DE, 0xA8D9DE,
4403 0xA9DADF, 0xABDBE0, 0xADDCE0, 0xAFDDE1, 0xB1DEE2, 0xB3DFE3, 0xB5E0E3, 0xB7E1E4, 0xB9E2E5, 0xBAE3E6, 0xBCE4E7,
4404 0xBEE5E7, 0xC0E6E8, 0xC2E6E9, 0xC4E7EA, 0xC6E8EB, 0xC8E9EC, 0xC9EAED, 0xCBEBEE, 0xCDECEF, 0xCFEDEF, 0xD1EEF0,
4405 0xD3EFF1, 0xD5F0F2, 0xD6F1F3, 0xD8F2F4, 0xDAF3F5, 0xDCF4F6, 0xDEF5F7, 0xE0F6F8, 0xE1F7F9, 0xE3F9FA, 0xE5FAFB,
4406 0xE7FBFB, 0xE8FCFC, 0xEAFDFD> csFPcmoceanIce;
4407 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4408 /** @class csFPcmoceanTempo
4409 @ingroup cs
4410 @extends csFP_tpl */
4411 typedef csFP_tpl<0xFFF6F4, 0xFDF5F3, 0xFCF4F1, 0xFBF3F0, 0xF9F2EE, 0xF8F1ED, 0xF7F0EB, 0xF5EFEA, 0xF4EEE8, 0xF2EDE7, 0xF1ECE5,
4412 0xF0EBE4, 0xEEEAE2, 0xEDEAE1, 0xEBE9DF, 0xEAE8DE, 0xE9E7DD, 0xE7E6DB, 0xE6E5DA, 0xE4E4D8, 0xE3E3D7, 0xE2E2D6,
4413 0xE0E2D4, 0xDFE1D3, 0xDDE0D1, 0xDCDFD0, 0xDBDECF, 0xD9DDCD, 0xD8DDCC, 0xD6DCCB, 0xD5DBC9, 0xD3DAC8, 0xD2D9C7,
4414 0xD1D8C5, 0xCFD8C4, 0xCED7C3, 0xCCD6C1, 0xCBD5C0, 0xC9D4BF, 0xC8D4BE, 0xC6D3BC, 0xC5D2BB, 0xC3D1BA, 0xC2D1B9,
4415 0xC0D0B7, 0xBFCFB6, 0xBDCEB5, 0xBCCEB4, 0xBACDB3, 0xB9CCB2, 0xB7CBB0, 0xB6CBAF, 0xB4CAAE, 0xB3C9AD, 0xB1C8AC,
4416 0xB0C8AB, 0xAEC7AA, 0xACC6A9, 0xABC5A8, 0xA9C5A6, 0xA8C4A5, 0xA6C3A4, 0xA4C3A3, 0xA3C2A2, 0xA1C1A1, 0xA0C0A0,
4417 0x9EC09F, 0x9CBF9F, 0x9BBE9E, 0x99BE9D, 0x97BD9C, 0x96BC9B, 0x94BC9A, 0x92BB99, 0x91BA98, 0x8FBA97, 0x8DB997,
4418 0x8BB896, 0x8AB795, 0x88B794, 0x86B693, 0x85B593, 0x83B592, 0x81B491, 0x7FB390, 0x7DB390, 0x7CB28F, 0x7AB18E,
4419 0x78B18E, 0x76B08D, 0x74AF8D, 0x72AF8C, 0x71AE8B, 0x6FAD8B, 0x6DAD8A, 0x6BAC8A, 0x69AB89, 0x67AB89, 0x65AA88,
4420 0x63A988, 0x61A987, 0x5FA887, 0x5DA786, 0x5BA686, 0x59A685, 0x57A585, 0x56A485, 0x54A484, 0x52A384, 0x50A284,
4421 0x4EA183, 0x4BA183, 0x49A083, 0x479F82, 0x459F82, 0x439E82, 0x419D82, 0x3F9C81, 0x3D9C81, 0x3B9B81, 0x3A9A81,
4422 0x389981, 0x369880, 0x349880, 0x329780, 0x309680, 0x2E9580, 0x2C947F, 0x2A937F, 0x29937F, 0x27927F, 0x25917F,
4423 0x24907F, 0x228F7E, 0x218E7E, 0x1F8D7E, 0x1E8D7E, 0x1C8C7E, 0x1B8B7D, 0x1A8A7D, 0x19897D, 0x17887D, 0x16877C,
4424 0x16867C, 0x15857C, 0x14847C, 0x13847B, 0x13837B, 0x12827B, 0x12817B, 0x11807A, 0x117F7A, 0x117E7A, 0x117D79,
4425 0x117C79, 0x117B79, 0x117A78, 0x117978, 0x117878, 0x117777, 0x117677, 0x127676, 0x127576, 0x127476, 0x137375,
4426 0x137275, 0x137174, 0x147074, 0x146F73, 0x146E73, 0x156D73, 0x156C72, 0x166B72, 0x166A71, 0x166971, 0x176870,
4427 0x176770, 0x17666F, 0x18656F, 0x18656E, 0x18646E, 0x19636D, 0x19626D, 0x19616C, 0x19606C, 0x1A5F6B, 0x1A5E6B,
4428 0x1A5D6A, 0x1A5C6A, 0x1A5B69, 0x1B5A68, 0x1B5968, 0x1B5867, 0x1B5867, 0x1B5766, 0x1B5666, 0x1C5565, 0x1C5465,
4429 0x1C5364, 0x1C5263, 0x1C5163, 0x1C5062, 0x1C4F62, 0x1C4E61, 0x1C4D61, 0x1C4C60, 0x1C4C5F, 0x1C4B5F, 0x1C4A5E,
4430 0x1C495E, 0x1C485D, 0x1C475D, 0x1C465C, 0x1C455B, 0x1C445B, 0x1C435A, 0x1C425A, 0x1C4259, 0x1C4158, 0x1C4058,
4431 0x1B3F57, 0x1B3E57, 0x1B3D56, 0x1B3C56, 0x1B3B55, 0x1B3A54, 0x1B3954, 0x1B3853, 0x1A3753, 0x1A3652, 0x1A3651,
4432 0x1A3551, 0x1A3450, 0x1A3350, 0x19324F, 0x19314F, 0x19304E, 0x192F4D, 0x192E4D, 0x182D4C, 0x182C4C, 0x182B4B,
4433 0x182A4B, 0x18294A, 0x17284A, 0x172749, 0x172648, 0x172548, 0x172447, 0x162347, 0x162246, 0x162146, 0x162045,
4434 0x151F45, 0x151E44, 0x151D44> csFPcmoceanTempo;
4435 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4436 /** @class csFPmplBrBG
4437 @ingroup cs
4438 @extends csFP_tpl */
4439 typedef csFP_tpl<0x563105, 0x5A3305, 0x5E3605, 0x633906, 0x673B06, 0x6C3E07, 0x704007, 0x744307, 0x794608, 0x7B4708, 0x824B09,
4440 0x844C09, 0x8A5009, 0x8C510A, 0x93570E, 0x955910, 0x9A5F14, 0x9E6217, 0xA16418, 0xA76A1C, 0xAA6E1F, 0xAF7122,
4441 0xB17323, 0xB67927, 0xBA7D2A, 0xBF802D, 0xC08330, 0xC48B39, 0xC6903F, 0xC99546, 0xCA9749, 0xCE9F52, 0xD0A458,
4442 0xD3A95F, 0xD5AE65, 0xD8B36B, 0xDAB972, 0xDBBB75, 0xDFC27E, 0xE1C583, 0xE3C889, 0xE4CB8E, 0xE6CE94, 0xE8D199,
4443 0xEAD49F, 0xEBD6A2, 0xEDDAAA, 0xEFDDAF, 0xF1E0B5, 0xF3E3BA, 0xF5E6C0, 0xF5E8C4, 0xF5E9C8, 0xF5EACA, 0xF5EBD0,
4444 0xF5ECD4, 0xF5EDD8, 0xF5EEDC, 0xF5EFE0, 0xF5F0E4, 0xF5F1E8, 0xF5F2EA, 0xF5F3F0, 0xF5F4F4, 0xF2F4F4, 0xEEF3F2,
4445 0xEBF2F1, 0xE7F1F0, 0xE3F0EF, 0xE0F0ED, 0xDCEFEC, 0xD9EEEB, 0xD5EDEA, 0xD1ECE8, 0xCEEBE7, 0xCCEBE6, 0xC6E9E4,
4446 0xC1E7E2, 0xBBE5DF, 0xB6E3DC, 0xB0E0D9, 0xABDED6, 0xA5DCD4, 0xA0DAD1, 0x9AD7CE, 0x94D5CB, 0x8FD3C8, 0x89D0C5,
4447 0x84CEC3, 0x7ECBC0, 0x78C7BC, 0x75C5BA, 0x6CBFB4, 0x67BAB0, 0x61B6AC, 0x5BB2A8, 0x55AEA4, 0x4FAAA0, 0x49A59C,
4448 0x43A198, 0x3D9D94, 0x379990, 0x32958D, 0x2E9189, 0x2A8D85, 0x268981, 0x22857D, 0x20837B, 0x1A7E76, 0x167A72,
4449 0x12766E, 0x0E726A, 0x0A6E66, 0x066A62, 0x02665E, 0x00635B, 0x006057, 0x005C54, 0x005950, 0x00564C, 0x005349,
4450 0x004F45, 0x004C42, 0x004A40, 0x00453A, 0x004237, 0x003F33, 0x003B2F> csFPmplBrBG;
4451 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4452 /** @class csFPmplOcean
4453 @ingroup cs
4454 @extends csFP_tpl */
4455 typedef csFP_tpl<0x007E01, 0x007B03, 0x007705, 0x007507, 0x007208, 0x006E0A, 0x006B0C, 0x00690F, 0x006611, 0x006411, 0x006015,
4456 0x005E16, 0x005918, 0x00581A, 0x00541C, 0x00521D, 0x004D21, 0x004B23, 0x004923, 0x004426, 0x004228, 0x003F2A,
4457 0x003D2B, 0x00382F, 0x003631, 0x003333, 0x003134, 0x002D36, 0x002A38, 0x00263B, 0x00253B, 0x00213F, 0x001D41,
4458 0x001A42, 0x001844, 0x001546, 0x001149, 0x001049, 0x000C4D, 0x00084F, 0x000550, 0x000352, 0x000054, 0x000356,
4459 0x000559, 0x000759, 0x000C5D, 0x000F5E, 0x001160, 0x001562, 0x001864, 0x001A67, 0x001D69, 0x001F69, 0x00236D,
4460 0x00266E, 0x002A70, 0x002D72, 0x002F75, 0x003377, 0x003679, 0x003779, 0x003B7C, 0x003F7E, 0x004280, 0x004482,
4461 0x004885, 0x004B87, 0x004D89, 0x00508A, 0x00548C, 0x00568E, 0x005990, 0x005D93, 0x006095, 0x006195, 0x006699,
4462 0x00699A, 0x006B9C, 0x006E9E, 0x0072A1, 0x0075A3, 0x0077A5, 0x007BA7, 0x007EA8, 0x0380AA, 0x0883AC, 0x0F87AF,
4463 0x1589B1, 0x1A8CB3, 0x2190B5, 0x2391B5, 0x2D95B8, 0x3399BA, 0x389CBC, 0x3F9EBF, 0x44A1C1, 0x4BA5C3, 0x50A8C4,
4464 0x56AAC6, 0x5DAEC8, 0x62B1CA, 0x69B3CD, 0x6EB6CF, 0x75BAD1, 0x7BBCD3, 0x80BFD4, 0x83C1D6, 0x8CC6D8, 0x93C8DB,
4465 0x99CCDD, 0x9ECFDF, 0xA5D1E1, 0xAAD4E2, 0xB1D8E4, 0xB6DBE6, 0xBCDDE8, 0xC3E1EB, 0xC8E4ED, 0xCFE6EF, 0xD4E9F0,
4466 0xDBEDF2, 0xE1EFF4, 0xE4F1F6, 0xEDF6F9, 0xF2F9FB, 0xF9FBFD, 0xFFFFFF> csFPmplOcean;
4467 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4468 /** @class csFPmplOranges
4469 @ingroup cs
4470 @extends csFP_tpl */
4471 typedef csFP_tpl<0xFEF4EA, 0xFEF3E8, 0xFEF2E6, 0xFEF1E4, 0xFEF0E2, 0xFEEFE0, 0xFEEEDF, 0xFEEDDD, 0xFEEDDB, 0xFEECDA, 0xFEEBD7,
4472 0xFEEAD6, 0xFEE9D4, 0xFEE8D3, 0xFEE7D0, 0xFEE6CF, 0xFDE5CC, 0xFDE3C9, 0xFDE3C8, 0xFDE1C4, 0xFDDFC1, 0xFDDEBE,
4473 0xFDDDBD, 0xFDDBB9, 0xFDDAB6, 0xFDD8B3, 0xFDD8B2, 0xFDD6AE, 0xFDD4AB, 0xFDD3A8, 0xFDD2A7, 0xFDD0A3, 0xFDCE9F,
4474 0xFDCC9C, 0xFDCA98, 0xFDC895, 0xFDC692, 0xFDC590, 0xFDC18B, 0xFDBF87, 0xFDBD84, 0xFDBB80, 0xFDB97D, 0xFDB779,
4475 0xFDB576, 0xFDB374, 0xFDB06F, 0xFDAE6C, 0xFDAC68, 0xFDAA66, 0xFDA863, 0xFDA660, 0xFDA45D, 0xFDA35B, 0xFDA057,
4476 0xFD9E54, 0xFD9C51, 0xFD994E, 0xFD974B, 0xFD9548, 0xFD9345, 0xFD9244, 0xFD8F3F, 0xFD8D3C, 0xFC8B3A, 0xFB8937,
4477 0xFA8634, 0xFA8432, 0xF9822F, 0xF8802D, 0xF77D2A, 0xF77B28, 0xF67925, 0xF57622, 0xF47420, 0xF4731F, 0xF3701B,
4478 0xF26D18, 0xF16B16, 0xF16913, 0xEF6712, 0xEE6510, 0xEC630F, 0xEB610E, 0xE95F0D, 0xE85C0C, 0xE65A0B, 0xE5580A,
4479 0xE35609, 0xE25407, 0xE05206, 0xDF5106, 0xDD4E04, 0xDC4C03, 0xDA4A02, 0xD94801, 0xD64701, 0xD34501, 0xCF4401,
4480 0xCC4301, 0xC94201, 0xC64101, 0xC34001, 0xBF3F01, 0xBC3D02, 0xB93C02, 0xB63B02, 0xB43B02, 0xAF3902, 0xAC3802,
4481 0xA93702, 0xA63602, 0xA33503, 0xA13403, 0x9E3303, 0x9C3203, 0x993103, 0x973003, 0x952F03, 0x922E03, 0x902D03,
4482 0x8D2C03, 0x8B2B03, 0x8A2B03, 0x862903, 0x832803, 0x812703, 0x7E2603> csFPmplOranges;
4483 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4484 /** @class csFPneoDdivVegetationA
4485 @ingroup cs
4486 @extends csFP_tpl */
4487 typedef csFP_tpl<0x530000, 0x540000, 0x540000, 0x550000, 0x560000, 0x560000, 0x570000, 0x580000, 0x5A0000, 0x5A0000, 0x5B0000,
4488 0x5B0000, 0x5D0000, 0x5E0000, 0x5F0000, 0x600000, 0x610000, 0x610000, 0x620000, 0x630000, 0x640000, 0x650000,
4489 0x670000, 0x670000, 0x690000, 0x6A0000, 0x6B0000, 0x6C0000, 0x6D0000, 0x6E0000, 0x700000, 0x710000, 0x720000,
4490 0x740000, 0x740000, 0x760000, 0x770000, 0x790000, 0x790000, 0x7B0000, 0x7C0000, 0x7D0000, 0x7F0000, 0x800000,
4491 0x830401, 0x830702, 0x860B04, 0x870D05, 0x8A1106, 0x8C1507, 0x8E1908, 0x901D0A, 0x921F0B, 0x93220C, 0x96270D,
4492 0x972A0E, 0x992E0F, 0x9C3211, 0x9E3512, 0x9F3913, 0xA13C14, 0xA23F15, 0xA54417, 0xA74818, 0xA94B19, 0xAB501A,
4493 0xAD531B, 0xB0571D, 0xB25B1E, 0xB35D1F, 0xB66321, 0xB86722, 0xBB6C24, 0xBD6F25, 0xBF7326, 0xC0762A, 0xC1782D,
4494 0xC2792F, 0xC37C33, 0xC57F37, 0xC6813A, 0xC7843E, 0xC88641, 0xC98945, 0xCB8C49, 0xCC8E4C, 0xCC904F, 0xCE9252,
4495 0xCF9656, 0xD09859, 0xD19B5D, 0xD29D60, 0xD49F64, 0xD5A368, 0xD6A56B, 0xD7A86F, 0xD9AA73, 0xD9AC75, 0xDBB07A,
4496 0xDCB27D, 0xDDB581, 0xDFB885, 0xE0BA88, 0xE1BD8D, 0xE2C090, 0xE3C293, 0xE5C597, 0xE6C79A, 0xE7CA9E, 0xE9CDA3,
4497 0xEAD0A6, 0xEBD2A9, 0xECD5AC, 0xEDD7B0, 0xEFDAB4, 0xF0DDB8, 0xF1E1BD, 0xF2E3C0, 0xF3E5C3, 0xF5E8C7, 0xF6EBCB,
4498 0xF7EDCE, 0xF8EFD1, 0xFAF4D6, 0xFBF5D9, 0xFCF8DD, 0xFDFBE1, 0xFFFFE5, 0xFEFFE5, 0xFAFDE0, 0xF8FBDD, 0xF6FBDB,
4499 0xF4F9D7, 0xF1F8D4, 0xEFF7D1, 0xECF6CD, 0xEAF4CA, 0xE7F3C6, 0xE5F2C3, 0xE2F1BF, 0xE0EFBB, 0xDDEEB9, 0xDAEDB5,
4500 0xD8ECB1, 0xD6EAAF, 0xD2E9AB, 0xD0E8A8, 0xCDE7A5, 0xCBE5A1, 0xC8E49F, 0xC6E39B, 0xC3E297, 0xC1E194, 0xBFDF91,
4501 0xBCDE8D, 0xBADD8B, 0xB7DB86, 0xB5DA83, 0xB3D981, 0xB0D87D, 0xAED77A, 0xABD576, 0xA9D574, 0xA6D371, 0xA3D26D,
4502 0xA1D16A, 0x9ED066, 0x9CCE64, 0x9ACD60, 0x97CC5D, 0x96CB5B, 0x93CA57, 0x90C954, 0x8EC750, 0x8CC74E, 0x89C54A,
4503 0x87C448, 0x85C344, 0x83C242, 0x80C03D, 0x7FC03C, 0x7BBE39, 0x77BC37, 0x72B935, 0x6EB733, 0x6BB532, 0x67B331,
4504 0x63B02F, 0x5FAE2D, 0x5BAC2C, 0x58AB2B, 0x54A829, 0x51A628, 0x4DA426, 0x4AA325, 0x46A124, 0x429F22, 0x409D20,
4505 0x3B9A1E, 0x38991D, 0x34971C, 0x31951A, 0x2D9319, 0x299118, 0x278F17, 0x238D15, 0x1F8B13, 0x1B8913, 0x198711,
4506 0x168510, 0x13840F, 0x0F810D, 0x0C800C, 0x0C7E0C, 0x0C7D0C, 0x0B7B0B, 0x0B790B, 0x0B780B, 0x0B770B, 0x0B750B,
4507 0x0B750B, 0x0A730A, 0x0A710A, 0x0A700A, 0x0A6E0A, 0x0A6D0A, 0x0A6C0A, 0x0A6B0A, 0x096909, 0x096709, 0x096609,
4508 0x096609, 0x096409, 0x096309, 0x086108, 0x086108, 0x085F08, 0x085F08, 0x085D08, 0x085C08, 0x085A08, 0x085A08,
4509 0x075907, 0x075807, 0x075607, 0x075507, 0x075507, 0x075407, 0x075207, 0x075107, 0x065106, 0x065006, 0x064F06,
4510 0x064E06, 0x064D06, 0x064C06> csFPneoDdivVegetationA;
4511 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4512 /** @class csFPneoDivVegetationC
4513 @ingroup cs
4514 @extends csFP_tpl */
4515 typedef csFP_tpl<0x795B13, 0x865614, 0x8A5513, 0x8A5513, 0x875715, 0x875715, 0x895A0A, 0x8C590A, 0x935711, 0x945812, 0x945812,
4516 0x955913, 0x965A14, 0x975B15, 0x985C16, 0x985C16, 0x9B5F19, 0x9B5F19, 0x9C601A, 0x9C601A, 0x9D611B, 0x9E621C,
4517 0x9F631D, 0x9F631D, 0xAA681A, 0xAA681A, 0xAA681A, 0xAB691B, 0xAC6A1C, 0xAD6B1D, 0xAE6C1E, 0xAE6C1E, 0xB47224,
4518 0xB57325, 0xB67426, 0xB87628, 0xBA782A, 0xBB792B, 0xBD7B2D, 0xBD7B2D, 0xBB8231, 0xBB8231, 0xBD8433, 0xBF8635,
4519 0xC28737, 0xC38838, 0xC58A3A, 0xC58A3A, 0xC38A3B, 0xC48B3C, 0xC48D3D, 0xC68F3F, 0xC49140, 0xC69342, 0xC59543,
4520 0xC69548, 0xC89E52, 0xC99F53, 0xC9A255, 0xCAA356, 0xCDA65B, 0xCFA85D, 0xCFA95E, 0xD0AA5F, 0xD5AF66, 0xD6B067,
4521 0xD7B26B, 0xD8B36C, 0xD9B76F, 0xDBB971, 0xDCBA72, 0xDDBB73, 0xDCBE78, 0xDDBF79, 0xDEC07A, 0xE0C27C, 0xE1C47E,
4522 0xE3C684, 0xE4C785, 0xE5C789, 0xE6CA89, 0xE7CA8E, 0xE6CC8F, 0xE7CC94, 0xE9CE96, 0xEACF97, 0xEBD098, 0xECD199,
4523 0xEAD9A5, 0xEBD9A9, 0xEBDBAA, 0xEDDDAC, 0xEEDDAF, 0xF0DFB1, 0xEFE1B2, 0xF0E1B6, 0xECDFB3, 0xECDEB7, 0xEEE0B9,
4524 0xEFE1BA, 0xF0E4BE, 0xF2E6C0, 0xF3E7C1, 0xF4E8C2, 0xF0EAD0, 0xF0EAD4, 0xF1EBD5, 0xF1EBD5, 0xF1EBD5, 0xF2ECD6,
4525 0xF1ECD6, 0xF1ECD9, 0xF0EDDA, 0xF1EEDF, 0xF0EEDF, 0xF0EEDF, 0xF1EFE0, 0xF1EFE0, 0xF1EFE0, 0xF1EFE3, 0xF1F1E9,
4526 0xF1F0EC, 0xF2F1ED, 0xF2F1ED, 0xF2F3EE, 0xF2F3EE, 0xF2F4F1, 0xF2F4F1, 0xF1F3F2, 0xF1F3F2, 0xEEF2F1, 0xEEF2F1,
4527 0xEDF1F2, 0xECF0F1, 0xEBF1F1, 0xEBF1F1, 0xE5EEED, 0xE5EEED, 0xE4EDEC, 0xE4EDEC, 0xE2ECED, 0xE2ECED, 0xE0ECEC,
4528 0xE0ECEC, 0xD9E7E7, 0xD9E7E7, 0xD7E7E7, 0xD7E7E7, 0xD4E6E6, 0xD3E5E5, 0xD3E5E5, 0xD3E5E5, 0xC3EEE5, 0xC3EEE5,
4529 0xC2EDE4, 0xC0EBE2, 0xBDEBE1, 0xBBE9DF, 0xB7E9DE, 0xB7E9DE, 0xB0E4D8, 0xAFE3D7, 0xADE3D6, 0xABE1D4, 0xA8E0D3,
4530 0xA6DED1, 0xA4DED0, 0xA3DDCF, 0x9BDDCF, 0x9ADCCE, 0x97DBCC, 0x94D8C9, 0x92D6C7, 0x8FD3C4, 0x8BD2C2, 0x8AD1C1,
4531 0x8BD4C3, 0x8AD3C2, 0x89D2C1, 0x87D0BF, 0x84CEBD, 0x82CCBB, 0x81CBBA, 0x80CAB9, 0x74C7B5, 0x74C7B5, 0x71C6B3,
4532 0x6FC4B1, 0x6DC2AF, 0x6BC0AD, 0x68BFAC, 0x67BEAB, 0x60B7A6, 0x5FB6A5, 0x5CB5A3, 0x5BB4A2, 0x57B2A0, 0x55B09E,
4533 0x53AE9C, 0x53AE9C, 0x52A9A0, 0x51A89F, 0x4FA69D, 0x4EA59C, 0x4AA49A, 0x48A298, 0x47A197, 0x46A096, 0x3E9A8F,
4534 0x3D998E, 0x3B988D, 0x39968B, 0x379489, 0x369388, 0x359287, 0x349186, 0x2C9183, 0x2C9183, 0x2A8F81, 0x298E80,
4535 0x278C7E, 0x258A7C, 0x24897B, 0x23887A, 0x1F8476, 0x1F8476, 0x1E8375, 0x1D8274, 0x1C8173, 0x1C8173, 0x1B8072,
4536 0x1B8072, 0x197D71, 0x187C70, 0x177B6F, 0x167A6E, 0x14786C, 0x13776B, 0x12766A, 0x117569, 0x0F7367, 0x0F7367,
4537 0x0F7367, 0x0E7266, 0x0D7165, 0x0D7165, 0x0C7064, 0x0C7064, 0x066B5B, 0x066B5B, 0x066B59, 0x086958, 0x0B6655,
4538 0x0B6655, 0x056951, 0x056951> csFPneoDivVegetationC;
4539 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4540 /** @class csFPneoModisNdvi
4541 @ingroup cs
4542 @extends csFP_tpl */
4543 typedef csFP_tpl<0xECE0D7, 0xEBDFD6, 0xEADED4, 0xEADDD3, 0xE9DDD1, 0xE8DCD0, 0xE7DBCE, 0xE7DACD, 0xE6D9CC, 0xE5D8CA, 0xE4D7C9,
4544 0xE3D6C7, 0xE3D6C6, 0xE2D5C5, 0xE1D4C3, 0xE0D3C2, 0xE0D2C0, 0xDFD1BF, 0xDED0BD, 0xDDCFBC, 0xDDCFBB, 0xDCCEB9,
4545 0xDBCDB8, 0xDACCB6, 0xD9CBB5, 0xD9CAB4, 0xD8C9B2, 0xD7C8B1, 0xD6C8AF, 0xD6C7AE, 0xD5C6AC, 0xD4C5AB, 0xD3C4AA,
4546 0xD2C3A8, 0xD1C3A7, 0xD1C2A5, 0xD0C1A4, 0xCFC0A2, 0xCEC0A1, 0xCDBF9F, 0xCCBE9E, 0xCCBD9C, 0xCBBC9B, 0xCABC99,
4547 0xC9BB98, 0xC8BA96, 0xC7B995, 0xC7B994, 0xC6B892, 0xC5B791, 0xC4B68F, 0xC3B58E, 0xC2B58C, 0xC1B48B, 0xC1B389,
4548 0xC0B288, 0xBFB186, 0xBEB185, 0xBDB083, 0xBCAF82, 0xBCAE80, 0xBBAE7F, 0xBAAD7D, 0xB9AC7C, 0xB8AB7A, 0xB7AB79,
4549 0xB6AA77, 0xB5A975, 0xB4A974, 0xB3A872, 0xB2A770, 0xB1A76F, 0xB0A66D, 0xAFA56B, 0xAEA469, 0xADA468, 0xACA366,
4550 0xABA264, 0xAAA263, 0xAAA161, 0xA9A05F, 0xA8A05E, 0xA79F5C, 0xA69E5A, 0xA59E59, 0xA49D57, 0xA39C55, 0xA29C54,
4551 0xA19B52, 0xA09A50, 0x9F994E, 0x9E994D, 0x9D984B, 0x9C9749, 0x9B9748, 0x9A9646, 0x999545, 0x989544, 0x979442,
4552 0x969341, 0x959340, 0x93923F, 0x92913D, 0x91913C, 0x90903B, 0x8F8F3A, 0x8E8E38, 0x8D8E37, 0x8C8D36, 0x8B8C35,
4553 0x8A8C33, 0x898B32, 0x878A31, 0x868A30, 0x85892E, 0x84882D, 0x83882C, 0x82872B, 0x818629, 0x808628, 0x7F8527,
4554 0x7E8426, 0x7C8324, 0x7B8323, 0x7A8222, 0x798121, 0x78811F, 0x77801E, 0x767F1E, 0x757F1E, 0x747E1E, 0x737D1E,
4555 0x727C1E, 0x717C1F, 0x707B1F, 0x6F7A1F, 0x6E791F, 0x6D791F, 0x6C781F, 0x6B771F, 0x6A761F, 0x69761F, 0x68751F,
4556 0x677420, 0x667320, 0x657320, 0x647220, 0x637120, 0x627020, 0x617020, 0x606F20, 0x5F6E20, 0x5E6D20, 0x5D6D20,
4557 0x5C6C21, 0x5B6B21, 0x5A6A21, 0x596A21, 0x586921, 0x576821, 0x566721, 0x556621, 0x556621, 0x546521, 0x536421,
4558 0x526321, 0x516321, 0x516221, 0x506121, 0x4F6021, 0x4E5F21, 0x4D5F21, 0x4C5E21, 0x4C5D21, 0x4B5C21, 0x4A5C21,
4559 0x495B21, 0x485A21, 0x485921, 0x475821, 0x465821, 0x455721, 0x445621, 0x445521, 0x435421, 0x425421, 0x415321,
4560 0x405221, 0x3F5121, 0x3F5121, 0x3E5021, 0x3D4F21, 0x3C4E20, 0x3B4E1F, 0x3A4D1E, 0x394C1D, 0x384C1C, 0x374B1B,
4561 0x364A1A, 0x354A19, 0x344918, 0x334817, 0x324816, 0x314715, 0x304614, 0x2F4613, 0x2E4512, 0x2E4511, 0x2D440F,
4562 0x2C430E, 0x2B430D, 0x2A420C, 0x29410B, 0x28410A, 0x274009, 0x263F08, 0x253F07, 0x243E06, 0x233D05, 0x223D04,
4563 0x213C03, 0x203B02, 0x1F3B01, 0x1E3A00, 0x1D3900, 0x1D3900, 0x1C3800, 0x1C3700, 0x1B3600, 0x1A3601, 0x1A3501,
4564 0x193401, 0x183401, 0x183301, 0x173201, 0x173101, 0x163101, 0x153001, 0x152F01, 0x142F02, 0x132E02, 0x132D02,
4565 0x122C02, 0x122C02, 0x112B02, 0x102A02, 0x102902, 0x0F2902, 0x0E2802, 0x0E2702, 0x0D2703, 0x0D2603, 0x0C2503,
4566 0x0B2403, 0x0B2403, 0x000000> csFPneoModisNdvi;
4567 //@}
4568
4569
4570 //========================================================================================================================================================
4571 /** @name ColorBrewer2 Color Schemes */
4572 //@{
4573 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4574 /** @class csCBSpectral
4575 @ingroup cs
4576 @extends csCB_tpl
4577 ColorBrewer2 "Spectral" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4578 typedef csCB_tpl<11,
4579 0xFC8D59, 0xFFFFBF, 0x99D594,
4580 0xD7191C, 0xFDAE61, 0xABDDA4, 0x2B83BA,
4581 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xABDDA4, 0x2B83BA,
4582 0xD53E4F, 0xFC8D59, 0xFEE08B, 0xE6F598, 0x99D594, 0x3288BD,
4583 0xD53E4F, 0xFC8D59, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0x99D594, 0x3288BD,
4584 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD,
4585 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD,
4586 0x9E0142, 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD, 0x5E4FA2,
4587 0x9E0142, 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD, 0x5E4FA2> csCBSpectral;
4588 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4589 /** @class csCBRdYlGn
4590 @ingroup cs
4591 @extends csCB_tpl
4592 ColorBrewer2 "RdYlGn" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4593 typedef csCB_tpl<11,
4594 0xFC8D59, 0xFFFFBF, 0x91CF60,
4595 0xD7191C, 0xFDAE61, 0xA6D96A, 0x1A9641,
4596 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xA6D96A, 0x1A9641,
4597 0xD73027, 0xFC8D59, 0xFEE08B, 0xD9EF8B, 0x91CF60, 0x1A9850,
4598 0xD73027, 0xFC8D59, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0x91CF60, 0x1A9850,
4599 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850,
4600 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850,
4601 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850, 0x006837,
4602 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850, 0x006837> csCBRdYlGn;
4603 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4604 /** @class csCBRdBu
4605 @ingroup cs
4606 @extends csCB_tpl
4607 ColorBrewer2 "RdBu" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4608 typedef csCB_tpl<11,
4609 0xEF8A62, 0xF7F7F7, 0x67A9CF,
4610 0xCA0020, 0xF4A582, 0x92C5DE, 0x0571B0,
4611 0xCA0020, 0xF4A582, 0xF7F7F7, 0x92C5DE, 0x0571B0,
4612 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xD1E5F0, 0x67A9CF, 0x2166AC,
4613 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x67A9CF, 0x2166AC,
4614 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC,
4615 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC,
4616 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC, 0x053061,
4617 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC, 0x053061> csCBRdBu;
4618 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4619 /** @class csCBPiYG
4620 @ingroup cs
4621 @extends csCB_tpl
4622 ColorBrewer2 "PiYG" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4623 typedef csCB_tpl<11,
4624 0xE9A3C9, 0xF7F7F7, 0xA1D76A,
4625 0xD01C8B, 0xF1B6DA, 0xB8E186, 0x4DAC26,
4626 0xD01C8B, 0xF1B6DA, 0xF7F7F7, 0xB8E186, 0x4DAC26,
4627 0xC51B7D, 0xE9A3C9, 0xFDE0EF, 0xE6F5D0, 0xA1D76A, 0x4D9221,
4628 0xC51B7D, 0xE9A3C9, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xA1D76A, 0x4D9221,
4629 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221,
4630 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221,
4631 0x8E0152, 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221, 0x276419,
4632 0x8E0152, 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221, 0x276419> csCBPiYG;
4633 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4634 /** @class csCBPRGn
4635 @ingroup cs
4636 @extends csCB_tpl
4637 ColorBrewer2 "PRGn" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4638 typedef csCB_tpl<11,
4639 0xAF8DC3, 0xF7F7F7, 0x7FBF7B,
4640 0x7B3294, 0xC2A5CF, 0xA6DBA0, 0x008837,
4641 0x7B3294, 0xC2A5CF, 0xF7F7F7, 0xA6DBA0, 0x008837,
4642 0x762A83, 0xAF8DC3, 0xE7D4E8, 0xD9F0D3, 0x7FBF7B, 0x1B7837,
4643 0x762A83, 0xAF8DC3, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0x7FBF7B, 0x1B7837,
4644 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837,
4645 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837,
4646 0x40004B, 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837, 0x00441B,
4647 0x40004B, 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837, 0x00441B> csCBPRGn;
4648 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4649 /** @class csCBRdYlBu
4650 @ingroup cs
4651 @extends csCB_tpl
4652 ColorBrewer2 "RdYlBu" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4653 typedef csCB_tpl<11,
4654 0xFC8D59, 0xFFFFBF, 0x91BFDB,
4655 0xD7191C, 0xFDAE61, 0xABD9E9, 0x2C7BB6,
4656 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xABD9E9, 0x2C7BB6,
4657 0xD73027, 0xFC8D59, 0xFEE090, 0xE0F3F8, 0x91BFDB, 0x4575B4,
4658 0xD73027, 0xFC8D59, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0x91BFDB, 0x4575B4,
4659 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4,
4660 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4,
4661 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4, 0x313695,
4662 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4, 0x313695> csCBRdYlBu;
4663 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4664 /** @class csCBBrBG
4665 @ingroup cs
4666 @extends csCB_tpl
4667 ColorBrewer2 "BrBG" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4668 typedef csCB_tpl<11,
4669 0xD8B365, 0xF5F5F5, 0x5AB4AC,
4670 0xA6611A, 0xDFC27D, 0x80CDC1, 0x018571,
4671 0xA6611A, 0xDFC27D, 0xF5F5F5, 0x80CDC1, 0x018571,
4672 0x8C510A, 0xD8B365, 0xF6E8C3, 0xC7EAE5, 0x5AB4AC, 0x01665E,
4673 0x8C510A, 0xD8B365, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x5AB4AC, 0x01665E,
4674 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E,
4675 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E,
4676 0x543005, 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E, 0x003C30,
4677 0x543005, 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E, 0x003C30> csCBBrBG;
4678 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4679 /** @class csCBRdGy
4680 @ingroup cs
4681 @extends csCB_tpl
4682 ColorBrewer2 "RdGy" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4683 typedef csCB_tpl<11,
4684 0xEF8A62, 0xFFFFFF, 0x999999,
4685 0xCA0020, 0xF4A582, 0xBABABA, 0x404040,
4686 0xCA0020, 0xF4A582, 0xFFFFFF, 0xBABABA, 0x404040,
4687 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xE0E0E0, 0x999999, 0x4D4D4D,
4688 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0x999999, 0x4D4D4D,
4689 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D,
4690 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D,
4691 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D, 0x1A1A1A,
4692 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D, 0x1A1A1A> csCBRdGy;
4693 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4694 /** @class csCBPuOr
4695 @ingroup cs
4696 @extends csCB_tpl
4697 ColorBrewer2 "PuOr" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4698 typedef csCB_tpl<11,
4699 0xF1A340, 0xF7F7F7, 0x998EC3,
4700 0xE66101, 0xFDB863, 0xB2ABD2, 0x5E3C99,
4701 0xE66101, 0xFDB863, 0xF7F7F7, 0xB2ABD2, 0x5E3C99,
4702 0xB35806, 0xF1A340, 0xFEE0B6, 0xD8DAEB, 0x998EC3, 0x542788,
4703 0xB35806, 0xF1A340, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0x998EC3, 0x542788,
4704 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788,
4705 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788,
4706 0x7F3B08, 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788, 0x2D004B,
4707 0x7F3B08, 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788, 0x2D004B> csCBPuOr;
4708 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4709 /** @class csCBSet2
4710 @ingroup cs
4711 @extends csCB_tpl
4712 ColorBrewer2 "Set2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4713 typedef csCB_tpl<8,
4714 0x66C2A5, 0xFC8D62, 0x8DA0CB,
4715 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3,
4716 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854,
4717 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F,
4718 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F, 0xE5C494,
4719 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F, 0xE5C494, 0xB3B3B3> csCBSet2;
4720 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4721 /** @class csCBAccent
4722 @ingroup cs
4723 @extends csCB_tpl
4724 ColorBrewer2 "Accent" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4725 typedef csCB_tpl<8,
4726 0x7FC97F, 0xBEAED4, 0xFDC086,
4727 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99,
4728 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0,
4729 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F,
4730 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F, 0xBF5B17,
4731 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F, 0xBF5B17, 0x666666> csCBAccent;
4732 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4733 /** @class csCBSet1
4734 @ingroup cs
4735 @extends csCB_tpl
4736 ColorBrewer2 "Set1" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4737 typedef csCB_tpl<9,
4738 0xE41A1C, 0x377EB8, 0x4DAF4A,
4739 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3,
4740 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00,
4741 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33,
4742 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628,
4743 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628, 0xF781BF,
4744 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628, 0xF781BF, 0x999999> csCBSet1;
4745 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4746 /** @class csCBSet3
4747 @ingroup cs
4748 @extends csCB_tpl
4749 ColorBrewer2 "Set3" color scheme of 3 to 12 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4750 typedef csCB_tpl<12,
4751 0x8DD3C7, 0xFFFFB3, 0xBEBADA,
4752 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072,
4753 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3,
4754 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462,
4755 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69,
4756 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5,
4757 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9,
4758 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD,
4759 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD, 0xCCEBC5,
4760 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD, 0xCCEBC5, 0xFFED6F> csCBSet3;
4761 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4762 /** @class csCBDark2
4763 @ingroup cs
4764 @extends csCB_tpl
4765 ColorBrewer2 "Dark2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4766 typedef csCB_tpl<8,
4767 0x1B9E77, 0xD95F02, 0x7570B3,
4768 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A,
4769 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E,
4770 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02,
4771 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02, 0xA6761D,
4772 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02, 0xA6761D, 0x666666> csCBDark2;
4773 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4774 /** @class csCBPaired
4775 @ingroup cs
4776 @extends csCB_tpl
4777 ColorBrewer2 "Paired" color scheme of 3 to 12 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4778 typedef csCB_tpl<12,
4779 0xA6CEE3, 0x1F78B4, 0xB2DF8A,
4780 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C,
4781 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99,
4782 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C,
4783 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F,
4784 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00,
4785 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6,
4786 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A,
4787 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A, 0xFFFF99,
4788 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A, 0xFFFF99, 0xB15928> csCBPaired;
4789 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4790 /** @class csCBPastel2
4791 @ingroup cs
4792 @extends csCB_tpl
4793 ColorBrewer2 "Pastel2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4794 typedef csCB_tpl<8,
4795 0xB3E2CD, 0xFDCDAC, 0xCBD5E8,
4796 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4,
4797 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9,
4798 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE,
4799 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE, 0xF1E2CC,
4800 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE, 0xF1E2CC, 0xCCCCCC> csCBPastel2;
4801 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4802 /** @class csCBPastel1
4803 @ingroup cs
4804 @extends csCB_tpl
4805 ColorBrewer2 "Pastel1" 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 0xFBB4AE, 0xB3CDE3, 0xCCEBC5,
4808 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4,
4809 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6,
4810 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC,
4811 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD,
4812 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD, 0xFDDAEC,
4813 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD, 0xFDDAEC, 0xF2F2F2> csCBPastel1;
4814 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4815 /** @class csCBOrRd
4816 @ingroup cs
4817 @extends csCB_tpl
4818 ColorBrewer2 "RdYlGn" 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 0xFEE8C8, 0xFDBB84, 0xE34A33,
4821 0xFEF0D9, 0xFDCC8A, 0xFC8D59, 0xD7301F,
4822 0xFEF0D9, 0xFDCC8A, 0xFC8D59, 0xE34A33, 0xB30000,
4823 0xFEF0D9, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xE34A33, 0xB30000,
4824 0xFEF0D9, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0x990000,
4825 0xFFF7EC, 0xFEE8C8, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0x990000,
4826 0xFFF7EC, 0xFEE8C8, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0xB30000, 0x7F0000> csCBOrRd;
4827 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4828 /** @class csCBPuBu
4829 @ingroup cs
4830 @extends csCB_tpl
4831 ColorBrewer2 "PuBu" 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 0xECE7F2, 0xA6BDDB, 0x2B8CBE,
4834 0xF1EEF6, 0xBDC9E1, 0x74A9CF, 0x0570B0,
4835 0xF1EEF6, 0xBDC9E1, 0x74A9CF, 0x2B8CBE, 0x045A8D,
4836 0xF1EEF6, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x2B8CBE, 0x045A8D,
4837 0xF1EEF6, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x034E7B,
4838 0xFFF7FB, 0xECE7F2, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x034E7B,
4839 0xFFF7FB, 0xECE7F2, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x045A8D, 0x023858> csCBPuBu;
4840 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4841 /** @class csCBBuPu
4842 @ingroup cs
4843 @extends csCB_tpl
4844 ColorBrewer2 "CbBuPu" 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 0xE0ECF4, 0x9EBCDA, 0x8856A7,
4847 0xEDF8FB, 0xB3CDE3, 0x8C96C6, 0x88419D,
4848 0xEDF8FB, 0xB3CDE3, 0x8C96C6, 0x8856A7, 0x810F7C,
4849 0xEDF8FB, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8856A7, 0x810F7C,
4850 0xEDF8FB, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x6E016B,
4851 0xF7FCFD, 0xE0ECF4, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x6E016B,
4852 0xF7FCFD, 0xE0ECF4, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x810F7C, 0x4D004B> csCBBuPu;
4853 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4854 /** @class csCBOranges
4855 @ingroup cs
4856 @extends csCB_tpl
4857 ColorBrewer2 "Oranges" 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 0xFEE6CE, 0xFDAE6B, 0xE6550D,
4860 0xFEEDDE, 0xFDBE85, 0xFD8D3C, 0xD94701,
4861 0xFEEDDE, 0xFDBE85, 0xFD8D3C, 0xE6550D, 0xA63603,
4862 0xFEEDDE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xE6550D, 0xA63603,
4863 0xFEEDDE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0x8C2D04,
4864 0xFFF5EB, 0xFEE6CE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0x8C2D04,
4865 0xFFF5EB, 0xFEE6CE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0xA63603, 0x7F2704> csCBOranges;
4866 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4867 /** @class csCBBuGn
4868 @ingroup cs
4869 @extends csCB_tpl
4870 ColorBrewer2 "BuGn" 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 0xE5F5F9, 0x99D8C9, 0x2CA25F,
4873 0xEDF8FB, 0xB2E2E2, 0x66C2A4, 0x238B45,
4874 0xEDF8FB, 0xB2E2E2, 0x66C2A4, 0x2CA25F, 0x006D2C,
4875 0xEDF8FB, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x2CA25F, 0x006D2C,
4876 0xEDF8FB, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x005824,
4877 0xF7FCFD, 0xE5F5F9, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x005824,
4878 0xF7FCFD, 0xE5F5F9, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x006D2C, 0x00441B> csCBBuGn;
4879 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4880 /** @class csCBYlOrBr
4881 @ingroup cs
4882 @extends csCB_tpl
4883 ColorBrewer2 "YlOrBr" 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 0xFFF7BC, 0xFEC44F, 0xD95F0E,
4886 0xFFFFD4, 0xFED98E, 0xFE9929, 0xCC4C02,
4887 0xFFFFD4, 0xFED98E, 0xFE9929, 0xD95F0E, 0x993404,
4888 0xFFFFD4, 0xFEE391, 0xFEC44F, 0xFE9929, 0xD95F0E, 0x993404,
4889 0xFFFFD4, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x8C2D04,
4890 0xFFFFE5, 0xFFF7BC, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x8C2D04,
4891 0xFFFFE5, 0xFFF7BC, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x993404, 0x662506> csCBYlOrBr;
4892 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4893 /** @class csCBYlGn
4894 @ingroup cs
4895 @extends csCB_tpl
4896 ColorBrewer2 "csCBYlGn" 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 0xF7FCB9, 0xADDD8E, 0x31A354,
4899 0xFFFFCC, 0xC2E699, 0x78C679, 0x238443,
4900 0xFFFFCC, 0xC2E699, 0x78C679, 0x31A354, 0x006837,
4901 0xFFFFCC, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x31A354, 0x006837,
4902 0xFFFFCC, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x005A32,
4903 0xFFFFE5, 0xF7FCB9, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x005A32,
4904 0xFFFFE5, 0xF7FCB9, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x006837, 0x004529> csCBYlGn;
4905 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4906 /** @class csCBReds
4907 @ingroup cs
4908 @extends csCB_tpl
4909 ColorBrewer2 "Reds" 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 0xFEE0D2, 0xFC9272, 0xDE2D26,
4912 0xFEE5D9, 0xFCAE91, 0xFB6A4A, 0xCB181D,
4913 0xFEE5D9, 0xFCAE91, 0xFB6A4A, 0xDE2D26, 0xA50F15,
4914 0xFEE5D9, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xDE2D26, 0xA50F15,
4915 0xFEE5D9, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0x99000D,
4916 0xFFF5F0, 0xFEE0D2, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0x99000D,
4917 0xFFF5F0, 0xFEE0D2, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0xA50F15, 0x67000D> csCBReds;
4918 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4919 /** @class csCBRdPu
4920 @ingroup cs
4921 @extends csCB_tpl
4922 ColorBrewer2 "RdPu" 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 0xFDE0DD, 0xFA9FB5, 0xC51B8A,
4925 0xFEEBE2, 0xFBB4B9, 0xF768A1, 0xAE017E,
4926 0xFEEBE2, 0xFBB4B9, 0xF768A1, 0xC51B8A, 0x7A0177,
4927 0xFEEBE2, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xC51B8A, 0x7A0177,
4928 0xFEEBE2, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177,
4929 0xFFF7F3, 0xFDE0DD, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177,
4930 0xFFF7F3, 0xFDE0DD, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177, 0x49006A> csCBRdPu;
4931 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4932 /** @class csCBGreens
4933 @ingroup cs
4934 @extends csCB_tpl
4935 ColorBrewer2 "Greens" 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 0xE5F5E0, 0xA1D99B, 0x31A354,
4938 0xEDF8E9, 0xBAE4B3, 0x74C476, 0x238B45,
4939 0xEDF8E9, 0xBAE4B3, 0x74C476, 0x31A354, 0x006D2C,
4940 0xEDF8E9, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x31A354, 0x006D2C,
4941 0xEDF8E9, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x005A32,
4942 0xF7FCF5, 0xE5F5E0, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x005A32,
4943 0xF7FCF5, 0xE5F5E0, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x006D2C, 0x00441B> csCBGreens;
4944 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4945 /** @class csCBYlGnBu
4946 @ingroup cs
4947 @extends csCB_tpl
4948 ColorBrewer2 "YlGnBu" 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 0xEDF8B1, 0x7FCDBB, 0x2C7FB8,
4951 0xFFFFCC, 0xA1DAB4, 0x41B6C4, 0x225EA8,
4952 0xFFFFCC, 0xA1DAB4, 0x41B6C4, 0x2C7FB8, 0x253494,
4953 0xFFFFCC, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x2C7FB8, 0x253494,
4954 0xFFFFCC, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x0C2C84,
4955 0xFFFFD9, 0xEDF8B1, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x0C2C84,
4956 0xFFFFD9, 0xEDF8B1, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x253494, 0x081D58> csCBYlGnBu;
4957 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4958 /** @class csCBPurples
4959 @ingroup cs
4960 @extends csCB_tpl
4961 ColorBrewer2 "Purples" 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 0xEFEDF5, 0xBCBDDC, 0x756BB1,
4964 0xF2F0F7, 0xCBC9E2, 0x9E9AC8, 0x6A51A3,
4965 0xF2F0F7, 0xCBC9E2, 0x9E9AC8, 0x756BB1, 0x54278F,
4966 0xF2F0F7, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x756BB1, 0x54278F,
4967 0xF2F0F7, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x4A1486,
4968 0xFCFBFD, 0xEFEDF5, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x4A1486,
4969 0xFCFBFD, 0xEFEDF5, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x54278F, 0x3F007D> csCBPurples;
4970 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4971 /** @class csCBGnBu
4972 @ingroup cs
4973 @extends csCB_tpl
4974 ColorBrewer2 "GnBu" 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 0xE0F3DB, 0xA8DDB5, 0x43A2CA,
4977 0xF0F9E8, 0xBAE4BC, 0x7BCCC4, 0x2B8CBE,
4978 0xF0F9E8, 0xBAE4BC, 0x7BCCC4, 0x43A2CA, 0x0868AC,
4979 0xF0F9E8, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x43A2CA, 0x0868AC,
4980 0xF0F9E8, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x08589E,
4981 0xF7FCF0, 0xE0F3DB, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x08589E,
4982 0xF7FCF0, 0xE0F3DB, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x0868AC, 0x084081> csCBGnBu;
4983 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4984 /** @class csCBGreys
4985 @ingroup cs
4986 @extends csCB_tpl
4987 ColorBrewer2 "Greys" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4988 typedef csCB_tpl<9,
4989 0xF0F0F0, 0xBDBDBD, 0x636363,
4990 0xF7F7F7, 0xCCCCCC, 0x969696, 0x525252,
4991 0xF7F7F7, 0xCCCCCC, 0x969696, 0x636363, 0x252525,
4992 0xF7F7F7, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x636363, 0x252525,
4993 0xF7F7F7, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525,
4994 0xFFFFFF, 0xF0F0F0, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525,
4995 0xFFFFFF, 0xF0F0F0, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525, 0x000000> csCBGreys;
4996 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4997 /** @class csCBYlOrRd
4998 @ingroup cs
4999 @extends csCB_tpl
5000 ColorBrewer2 "YlOrRd" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
5001 typedef csCB_tpl<8,
5002 0xFFEDA0, 0xFEB24C, 0xF03B20,
5003 0xFFFFB2, 0xFECC5C, 0xFD8D3C, 0xE31A1C,
5004 0xFFFFB2, 0xFECC5C, 0xFD8D3C, 0xF03B20, 0xBD0026,
5005 0xFFFFB2, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xF03B20, 0xBD0026,
5006 0xFFFFB2, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xFC4E2A, 0xE31A1C, 0xB10026,
5007 0xFFFFCC, 0xFFEDA0, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xFC4E2A, 0xE31A1C, 0xB10026> csCBYlOrRd;
5008 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5009 /** @class csCBPuRd
5010 @ingroup cs
5011 @extends csCB_tpl
5012 ColorBrewer2 "PuRd" 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 0xE7E1EF, 0xC994C7, 0xDD1C77,
5015 0xF1EEF6, 0xD7B5D8, 0xDF65B0, 0xCE1256,
5016 0xF1EEF6, 0xD7B5D8, 0xDF65B0, 0xDD1C77, 0x980043,
5017 0xF1EEF6, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xDD1C77, 0x980043,
5018 0xF1EEF6, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x91003F,
5019 0xF7F4F9, 0xE7E1EF, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x91003F,
5020 0xF7F4F9, 0xE7E1EF, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x980043, 0x67001F> csCBPuRd;
5021 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5022 /** @class csCBBlues
5023 @ingroup cs
5024 @extends csCB_tpl
5025 ColorBrewer2 "Blues" 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 0xDEEBF7, 0x9ECAE1, 0x3182BD,
5028 0xEFF3FF, 0xBDD7E7, 0x6BAED6, 0x2171B5,
5029 0xEFF3FF, 0xBDD7E7, 0x6BAED6, 0x3182BD, 0x08519C,
5030 0xEFF3FF, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x3182BD, 0x08519C,
5031 0xEFF3FF, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x084594,
5032 0xF7FBFF, 0xDEEBF7, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x084594,
5033 0xF7FBFF, 0xDEEBF7, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x08519C, 0x08306B> csCBBlues;
5034 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5035 /** @class csCBPuBuGn
5036 @ingroup cs
5037 @extends csCB_tpl
5038 ColorBrewer2 "PuBuGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
5039 typedef csCB_tpl<9,
5040 0xECE2F0, 0xA6BDDB, 0x1C9099,
5041 0xF6EFF7, 0xBDC9E1, 0x67A9CF, 0x02818A,
5042 0xF6EFF7, 0xBDC9E1, 0x67A9CF, 0x1C9099, 0x016C59,
5043 0xF6EFF7, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x1C9099, 0x016C59,
5044 0xF6EFF7, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016450,
5045 0xFFF7FB, 0xECE2F0, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016450,
5046 0xFFF7FB, 0xECE2F0, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016C59, 0x014636> csCBPuBuGn;
5047 //@}
5048
5049 /** @endcond */
5050
5051 //========================================================================================================================================================
5052 /** @name 2D Color Schemes */
5053 //@{
5054#if !(MISSING_P1907R1)
5055 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5056 /** Compute a color from Richardson's 2D complex number coloring scheme.
5057 See: Richardson (1991); Visualizing quantum scattering on the CM-2 supercomputer; Computer Physics Communications 63; pp 84-94"
5058 This is a continuous, 2D color scheme!
5059 @tparam cutDepth See: tfrmComplexCut()
5060 @tparam argCuts See: tfrmComplexCut()
5061 @tparam absCuts See: tfrmComplexCut()
5062 @tparam logAbs See: tfrmComplexCut() */
5063 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5065 public:
5066 /** Set given colorTpl instance to the selected color in the color scheme.
5067 @param aColor color object to set.
5068 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5069 @param csY A value that, along with csX, identifies the color in the scheme.
5070 @return Returns a reference to \a aColor. */
5071 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5072 csFltType c_abs2 = csX*csX+csY*csY;
5073 csFltType c_abs = std::sqrt(c_abs2);
5074 csFltType c_abs2p1 = 1 + c_abs2;
5075 csFltType x_scl = csX / std::sqrt(30.0/5.0);
5076 csFltType y_scl = csY / std::sqrt(2.0);
5077 csFltType ofs = (c_abs<1 ? -1.0 : 1.0) * (0.5 - c_abs/c_abs2p1);
5078 aColor.setChansRGB_dbl(std::clamp(ofs + (0.5 + (std::sqrt(2.0/3.0) * csX) / c_abs2p1), 0.0, 1.0),
5079 std::clamp(ofs + (0.5 - (x_scl - y_scl) / c_abs2p1), 0.0, 1.0),
5080 std::clamp(ofs + (0.5 - (x_scl + y_scl) / c_abs2p1), 0.0, 1.0));
5081 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5082 }
5083 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5084 @param csX A value that, along with csY, identifies the color in the scheme.
5085 @param csY A value that, along with csX, identifies the color in the scheme.
5086 @return Returns a colorTpl value */
5087 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5088 /** Set given colorTpl instance to the selected color in the color scheme.
5089 @param aColor color object to set.
5090 @param csZ A value that identifies the color in the scheme.
5091 @return Returns a reference to \a aColor. */
5092 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5093 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5094 @param csZ A value that identifies the color in the scheme.
5095 @return Returns a colorTpl value */
5096 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5097 };
5098 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5099 /** Compute a color for a point in @f$\mathbb{R}^2@f$ using a discrete color scheme for the phase angle.
5100 This is a continuous, 2D color scheme!
5101 @tparam colorScheme Integer indexed color scheme to use for the argument. csCColdeRainbow is a traditional choice.
5102 @tparam argWrap Number of times to wrap around the color ramp for arg
5103 @tparam cutDepth See: tfrmComplexCut()
5104 @tparam argCuts See: tfrmComplexCut()
5105 @tparam absCuts See: tfrmComplexCut()
5106 @tparam logAbs See: tfrmComplexCut() */
5107 template<typename colorScheme, int argWrap, double cutDepth, double argCuts, double absCuts, bool logAbs>
5109 public:
5110 /** Set given colorTpl instance to the selected color in the color scheme.
5111 @param aColor color object to set.
5112 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5113 @param csY A value that, along with csX, identifies the color in the scheme.
5114 @return Returns a reference to \a aColor. */
5115 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5116 csIntType numC = colorScheme::numC;
5117 double tau = std::numbers::pi * 2; // 2*Pi
5118 double zArg = std::atan2(csY, csX); // Arg
5119 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
5120 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)));
5121 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5122 }
5123 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5124 @param csX A value that, along with csY, identifies the color in the scheme.
5125 @param csY A value that, along with csX, identifies the color in the scheme.
5126 @return Returns a colorTpl value */
5127 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5128 /** Set given colorTpl instance to the selected color in the color scheme.
5129 @param aColor color object to set.
5130 @param csZ A value that identifies the color in the scheme.
5131 @return Returns a reference to \a aColor. */
5132 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5133 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5134 @param csZ A value that identifies the color in the scheme.
5135 @return Returns a colorTpl value */
5136 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5137 };
5138 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5139 /** Compute a color for a point in @f$\mathbb{R}^2@f$ using a continuous color scheme for the phase angle.
5140 This is a continuous, 2D color scheme!
5141 @tparam colorScheme Integer indexed color scheme to use for the argument. csCColdeRainbow is a traditional choice.
5142 @tparam argWrap Number of times to wrap around the color ramp for arg
5143 @tparam cutDepth See: tfrmComplexCut()
5144 @tparam argCuts See: tfrmComplexCut()
5145 @tparam absCuts See: tfrmComplexCut()
5146 @tparam logAbs See: tfrmComplexCut() */
5147 template<typename colorScheme, int argWrap, double cutDepth, double argCuts, double absCuts, bool logAbs>
5149 public:
5150 /** Set given colorTpl instance to the selected color in the color scheme.
5151 @param aColor color object to set.
5152 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5153 @param csY A value that, along with csX, identifies the color in the scheme.
5154 @return Returns a reference to \a aColor. */
5155 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5156 double tau = std::numbers::pi * 2; // 2*Pi
5157 double zArg = std::atan2(csY, csX); // Arg
5158 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
5159 aColor.csSet<colorScheme>(static_cast<csFltType>(mjr::math::ivl::wrapCC(mjr::math::ivl::unit_clamp(pzArg)*argWrap, 1.0)));
5160 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5161 }
5162 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5163 @param csX A value that, along with csY, identifies the color in the scheme.
5164 @param csY A value that, along with csX, identifies the color in the scheme.
5165 @return Returns a colorTpl value */
5166 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5167 /** Set given colorTpl instance to the selected color in the color scheme.
5168 @param aColor color object to set.
5169 @param csZ A value that identifies the color in the scheme.
5170 @return Returns a reference to \a aColor. */
5171 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5172 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5173 @param csZ A value that identifies the color in the scheme.
5174 @return Returns a colorTpl value */
5175 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5176 };
5177 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5178 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSL.
5179 See: Bernd Thaller (2000); Visual Quantum Mechanics; pp 2-8
5180 This is a continuous, 2D color scheme!
5181 @tparam cutDepth See: tfrmComplexCut()
5182 @tparam argCuts See: tfrmComplexCut()
5183 @tparam absCuts See: tfrmComplexCut()
5184 @tparam logAbs See: tfrmComplexCut() */
5185 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5186 using cs2dThallerHSL = cs2dThaller_tpl<1, 0, cutDepth, argCuts, absCuts, logAbs> ;
5187 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5188 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSV and maximum value.
5189 See: Bernd Thaller (2000); Visual Quantum Mechanics; pp 2-8
5190 This is a continuous, 2D color scheme!
5191 @tparam cutDepth See: tfrmComplexCut()
5192 @tparam argCuts See: tfrmComplexCut()
5193 @tparam absCuts See: tfrmComplexCut()
5194 @tparam logAbs See: tfrmComplexCut() */
5195 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5196 using cs2dThallerHSVm = cs2dThaller_tpl<0, 1, cutDepth, argCuts, absCuts, logAbs> ;
5197 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5198 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSV and dynamic value.
5199 See: Bernd Thaller (2000); Visual Quantum Mechanics; pp 2-8
5200 This is a continuous, 2D color scheme!
5201 @tparam cutDepth See: tfrmComplexCut()
5202 @tparam argCuts See: tfrmComplexCut()
5203 @tparam absCuts See: tfrmComplexCut()
5204 @tparam logAbs See: tfrmComplexCut() */
5205 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5206 using cs2dThallerHSV = cs2dThaller_tpl<0, 0, cutDepth, argCuts, absCuts, logAbs> ;
5207#endif
5208 //@}
5209
5210 template <class csT, class csAT> colorTpl& csSet(csAT csArg) { return csT::c(*this, csArg); }
5211 template <class csT, class csAT> colorTpl& csSet(csAT csArg1, csAT csArg2) { return csT::c(*this, csArg1, csArg2); }
5212
5213 };
5214
5215////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5216 /** i/O stream output operator for colorTpl types. */
5217 template <class clrChanT, int numChan, int redChanIdx = -1, int blueChanIdx = -1, int greenChanIdx = -1, int alphaChanIdx = -1>
5218 requires ((numChan>0) && // Must have at least 1 chan
5219 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
5220 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
5221 (redChanIdx < numChan) &&
5222 (blueChanIdx < numChan) &&
5223 (greenChanIdx < numChan) &&
5224 (alphaChanIdx < numChan) &&
5225 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
5226 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
5227 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
5228 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
5229 (redChanIdx != blueChanIdx) &&
5230 (redChanIdx != alphaChanIdx) &&
5231 (greenChanIdx != blueChanIdx) &&
5232 (greenChanIdx != alphaChanIdx) &&
5233 (blueChanIdx != alphaChanIdx)))) // Chans can't be the same if non-negative
5234 inline std::ostream&
5235 operator<< (std::ostream &out, colorTpl<clrChanT, numChan> const& color) {
5236 // 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..
5237 out << "<";
5238 if (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) > sizeof(uint64_t))) {
5239 for(int i=0; i<(numChan-1); i++)
5240 out << color.getChan(i) << ", ";
5241 out << color.getChan(numChan-1) << ">";
5242 } else {
5243 for(int i=0; i<(numChan-1); i++)
5244 out << static_cast<uint64_t>(color.getChan(i)) << ", ";
5245 out << static_cast<uint64_t>(color.getChan(numChan-1)) << ">";
5246 }
5247 return out;
5248 }
5249
5250////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5251 /** Inequality operator for colorTpl types. */
5252 template <class clrChanT, int numChan, int redChanIdx = -1, int blueChanIdx = -1, int greenChanIdx = -1, int alphaChanIdx = -1>
5253 requires ((numChan>0) && // Must have at least 1 chan
5254 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
5255 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
5256 (redChanIdx < numChan) &&
5257 (blueChanIdx < numChan) &&
5258 (greenChanIdx < numChan) &&
5259 (alphaChanIdx < numChan) &&
5260 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
5261 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
5262 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
5263 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
5264 (redChanIdx != blueChanIdx) &&
5265 (redChanIdx != alphaChanIdx) &&
5266 (greenChanIdx != blueChanIdx) &&
5267 (greenChanIdx != alphaChanIdx) &&
5268 (blueChanIdx != alphaChanIdx)))) // Chans can't be the same if non-negative
5269 inline bool
5270 operator!= (colorTpl<clrChanT, numChan> const& color1, colorTpl<clrChanT, numChan> const& color2) {
5271 return color1.isNotEqual(color2);
5272 }
5273
5274} // end namespace mjr
5275
5276#define MJR_INCLUDE_MRcolorTpl
5277#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 constexpr csIntType numC
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 constexpr csIntType maxNumC
static constexpr uint32_t d[]
static constexpr csIntType minNumC
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 constexpr csIntType numC
static constexpr cornerColorEnum cols[]
static constexpr int numA
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 constexpr csIntType numC
static colorTpl & c(colorRefType aColor, saT csG)
Set given colorTpl instance to the selected color in the color scheme.
static constexpr uint32_t d[]
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.
static constexpr csIntType numC
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.
static constexpr int psize
static constexpr double pcoff[]
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 constexpr csIntType numC
static colorTpl & c(colorRefType aColor, saT csG)
Template for web safe 216 pallets.
static constexpr uint32_t d[]
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 constexpr csIntType numC
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)
static constexpr int noRGBchanIdx
colorTpl & setChans_byte(colConALLbyte byteColor)
cs2dThaller_tpl< 0, 0, cutDepth, argCuts, absCuts, logAbs > cs2dThallerHSV
uint8_t getChan_byte(int chan) const
colorTpl & setChansRGBA_dbl(colConRGBAdbl dblColor)
double getC0_dbl() const
static constexpr bool chanIsByte
static constexpr int redChan
colorTpl & tfrmGreyScaleRGB(void)
Transform the current color by rendering it into a true grey via the same method used by the luminanc...
static constexpr int blueChan
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 ...
static constexpr bool goodArithSDP
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 & setRGBfromColorSpace(colorSpaceEnum space, double inCh1, double inCh2, double inCh3)
static constexpr bool goodArithSP
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
static constexpr bool chanIsDouble
colConRGBAdbl getColConRGBA_dbl()
static constexpr double RGBluminanceWeightR
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.
static constexpr csIntType chanStepMax
colorTpl(std::string colorString)
Uses the setColorFromString() method to set the initialize the object.
colChanI8 thePartsA[numChan]
std::tuple< colChanI8, colChanI8, colChanI8, colChanI8 > clrChanTup4
colorTpl & linearInterpolateRGB(double aDouble, colorArgType col1, colorArgType col2)
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)
std::vector< colChanI8 > clrChanVec
std::tuple< colChanI8, colChanI8, colChanI8, colChanI8 > clrChanTup6
colorTpl & tfrmDiv(colorArgType aCol)
Computes the arithmetic division of the current color by the given color.
static constexpr int channelCount
colConRGBdbl getColConRGB_dbl()
static constexpr bool chanIsInt
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< uint8_t, numChan > colConALLbyte
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.
static constexpr int maxWavelength
clrChanT getBlue() const
colorTpl< double, 3 > colConRGBdbl
colConRGBAbyte getColConRGBA_byte()
colorTpl & setChansRGBA_byte(colConRGBAbyte byteColor)
colorType const & colorCRefType
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)
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.
static constexpr double RGBluminanceWeightB
colorTpl< uint8_t, 3 > colConRGBbyte
std::function< colorTpl(colorTpl &)> cr2coType
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 ...
static constexpr colChanI8 minChanVal
colorTpl & setToMagenta()
double distDeltaE1976(colorArgType aColor) const
LAB Delta E* distance between current color and given one.
std::tuple< colChanI8, colChanI8 > clrChanTup2
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...
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< double, 3 > colConDbl3
colorTpl & setToHalf()
colChanI8 clampTop(iT arithValue)
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)
union mjr::colorTpl::@232376034174210205274057162046216343220267377054 theColor
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.
static constexpr colChanI8 meanChanVal
std::function< void(colorTpl &)> cr2voidType
colorTpl & setChanNC(int chan, colChanI8 cVal)
colorTpl & tfrmShiftL(colorArgType aCol)
The Shift Left Transform modifies the current color.
colorTpl & setRGBfromLogPackIntBGRA(packed4Cint anInt)
std::function< colorTpl(colorTpl)> co2coType
colorTpl & setToGreen()
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...
static constexpr bool ptrIsSmaller
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
static constexpr int minWavelength
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)
std::tuple< colChanI8, colChanI8, colChanI8, colChanI8 > clrChanTup5
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()
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)
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...
static constexpr maskType maskAllZero
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...
colorTpl< double, numChan > colConALLdbl
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)
colChanI8 getChanNC(int chan) const
static constexpr bool chanIsUnsigned
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.
colorTpl & setC0_byte(uint8_t cVal)
cs2dThaller_tpl< 0, 1, cutDepth, argCuts, absCuts, logAbs > cs2dThallerHSVm
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...
static constexpr int bitsPerChan
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.
colorTpl< uint8_t, 4 > colConRGBAbyte
void setChansToMin()
Set all channels to minChanVal.
channelArithFltType luminanceRGB(void) const
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.
static constexpr colChanI8 maxChanVal
colorTpl & setAlpha_byte(uint8_t cVal)
uint8_t getGreen_byte() const
colorTpl & linearInterpolate(double aDouble, colorArgType col1, colorArgType col2)
colorTpl(cornerColorEnum cornerColor)
Uses the setToCorner() method to set the initialize the object.
colorTpl & tfrmChanIncr(int chan=0, clrChanT v=1)
Adds the value to the give channel.
colorTpl & tfrmMinI(colorArgType aCol)
Makes the current color the minimum of the current color or the given color.
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 & setC3_dbl(double cVal)
colorTpl & setC1_byte(uint8_t cVal)
colorTpl & setToRed()
colorTpl & setRed_dbl(double cVal)
std::tuple< colChanI8, colChanI8, colChanI8 > clrChanTup3
static constexpr bool goodMask
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)
static constexpr int sizeOfColor
colorSpaceEnum
Color spaces.
@ HSV
HSV color space. H in [0, 360]. S in [0, 1]. V in [0, 1].
@ HSL
HSL color space. H in [0, 360]. S in [0, 1]. L in [0, 1].
@ RGB
RGB color space. R in [0, 1]. G in [0, 1]. B in [0, 1].
@ LCH
CIE-L*ch color space. L in [0, 100]. C in [0, 100]. H in [0, 360].
@ LAB
CIE-L*ab color space. L in [0, 100]. A in REALS. B in REALS.
@ NONE
Used when the color channels don't have an assocaited color space.
@ XYZ
XYZ color space. X in [0, 1]. Y in [0, 1]. Z in [0, 1].
static constexpr bool perfectMask
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.
static constexpr int alphaChan
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.
colChanI8 clampBot(iT arithValue)
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...
static constexpr maskType maskAllOne
colorTpl & setChansRGB(colChanI8 r, colChanI8 g, colChanI8 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.
@ BUMP
exponential bump map interpolation
colorTpl & setChans(colChanI8 cVal)
colorTpl & setChans(clrChanVec &chanValues)
This function sets color channels from the data in a std::vector.
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.
std::tuple< colChanI8 > clrChanTup1
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.
static constexpr bool goodArithFlt
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< double, 4 > colConRGBAdbl
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,...
cs2dThaller_tpl< 1, 0, cutDepth, argCuts, absCuts, logAbs > cs2dThallerHSL
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.
@ BLACK
Color cube corner color with RGB=000.
@ BLUE
Color cube corner color with RGB=001.
@ CYAN
Color cube corner color with RGB=011.
@ YELLOW
Color cube corner color with RGB=110.
@ GREEN
Color cube corner color with RGB=010.
@ RED
Color cube corner color with RGB=100.
@ WHITE
Color cube corner color with RGB=111.
@ MAGENTA
Color cube corner color with RGB=101.
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)
static constexpr int bitsPerPixel
colorTpl(clrChanT cVal)
Uses setChans() to set all channels to the given value.
static constexpr bool goodArithLog
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.
static constexpr double RGBluminanceWeightG
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.
std::conditional< ptrIsSmaller, colorCRefType, colorType >::type colorArgType
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)
std::function< colorTpl &(colorTpl &)> cr2crType
colorTpl & setChansRGBA(colChanI8 r, colChanI8 g, colChanI8 b, colChanI8 a)
colorTpl & setRGBcmpGreyTGA16bit(uint32_t tga16val)
Computes a 24-bit truecolor value intended for use in producing 16-bit greyscale TGA.
static constexpr bool chanIsFloat
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.
static constexpr bool goodArithD
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 ...
static constexpr int greenChan