MRaster lib 21.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 "MRMathCPP.hpp"
35
36////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
37#include <algorithm> /* STL algorithm C++11 */
38#include <array> /* array template C++11 */
39#include <bit> /* STL bit manipulation C++20 */
40#include <climits> /* std:: C limits.h C++11 */
41#include <cmath> /* std:: C math.h C++11 */
42#include <complex> /* Complex Numbers C++11 */
43#include <concepts> /* Concepts library C++20 */
44#include <cstring> /* std:: C string.h C++11 */
45#include <iomanip> /* C++ stream formatting C++11 */
46#include <iostream> /* C++ iostream C++11 */
47#include <limits> /* C++ Numeric limits C++11 */
48#include <span> /* STL spans C++20 */
49#include <sstream> /* C++ string stream C++ */
50#include <string> /* C++ strings C++11 */
51#include <tuple> /* STL tuples C++11 */
52#include <type_traits> /* C++ metaprogramming C++11 */
53#include <utility> /* STL Misc Utilities C++11 */
54#include <vector> /* STL vector C++11 */
55
56////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
57/** Set to 1 to look for 128-bit integer types, and 0 to not look for them.
58 Right now this only works on GCC & Clang! */
59#ifndef MJR_LOOK_FOR_128_BIT_TYPES
60#define MJR_LOOK_FOR_128_BIT_TYPES MRASTER_OPT_128_INT
61#endif
62
63////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
64#if MJR_LOOK_FOR_128_BIT_TYPES
65#ifdef __GNUC__
66#ifdef __SIZEOF_INT128__
67#if __SIZEOF_INT128__ == 16
68typedef unsigned __int128 mjr_uint128_t;
69typedef __int128 mjr_int128_t;
70#define MJR_HAVE_128_BIT_TYPES
71#endif
72#endif
73#endif
74#endif
75
76////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
77#ifdef MJR_HAVE_128_BIT_TYPES
78typedef mjr_uint128_t mjr_uintBiggest_t; //!< The largest unsigned integer supported on the platform
79typedef mjr_int128_t mjr_intBiggest_t; //!< The largest signed integer supported on the platform
80#else
81typedef uint64_t mjr_uintBiggest_t; //!< The largest unsigned integer supported on the platform
82typedef int64_t mjr_intBiggest_t; //!< The largest signed integer supported on the platform
83#endif
84
85////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
86// Put everything in the mjr namespace
87namespace mjr {
88
89////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
90
91/** @brief Template Class used to house colors for ramCanvas objects.@EOL
92
93 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
94 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
95 "fundamental" type for tools requiring a space efficient and high performance set of concrete objects representing colors. The canonical example is
96 representing an image as a very large, rectangular array of colors.
97
98 @par Size efficiency
99
100 While this class supports large channel counts and very deep channels, it is best optimized for colors that take less than 64-bits of RAM. This is
101 because the library uses an integer to cover color channel array in RAM to make memory operations faster. With a compiler supporting ISO C++, this object
102 should take no more than the maximum of sizeof(clrChanT)*numChan or the mask used to cover the data. See the next paragraph for details on the "mask".
103
104 The most common use cases are 24-bit RGB/RGBA and greyscale up to 64-bits deep. All of these types are smaller than a 64-bit pointer, so it is
105 almost always better to pass these values around by reference. That said, some types are quite large -- an RGBA image with 64-bit floating point channels
106 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
107 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
108 the end user can employ to use this same strategy: colorArgType.
109
110 @par Memory Layout and Performance
111
112 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
113 integer type exists that can cover the entire channel array without wasting too much space, we can achieve serious performance gains. The trick is
114 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"
115 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:
116
117 - An 8-bit RGBA color is covered by a uint32_t, and so is an 8-bit RGB color -- we waste 1 byte per pixel, or 1/4 of the space.
118 - An 8-bit, 5 channel color is NOT covered by an integer, but a 6 channel one would be covered by a uint64_t.
119
120 When we can't cover the channel array, the mask type will be set to an uint8_t to avoid any alignment issues with the union.
121
122 Some common diagrams of common cases might help:
123
124 2222222222222222 Cover: 16-bits
125 11111111 1x8 Waste 1/2 => No Cover
126 1111111122222222 2x8 Waste 0/2 => Cover with 16-bits
127
128 44444444444444444444444444444444 Cover: 32-bits
129 111111112222222233333333 3x8 Waste 1/4 => Cover with 32-bits
130 11111111222222223333333344444444 4x8 Waste 0/4 => Cover with 32-bits
131
132 8888888888888888888888888888888888888888888888888888888888888888
133 1111111122222222333333334444444455555555 5x8 Waste 3/8 => No cover
134 111111112222222233333333444444445555555566666666 6x8 Waste 2/8 => Cover with 64-bits
135 111111111111111122222222222222223333333333333333 3x16 Waste 2/8 => Cover with 64-bits
136
137 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
138 1111111122222222333333334444444455555555666666667777777788888888999999990000000011111111 11x8 Waste 5/16 => No Cover
139 111111112222222233333333444444445555555566666666777777778888888899999999000000001111111122222222 12x8 Waste 4/16 => Cover with uint128_t
140 11111111111111112222222222222222333333333333333344444444444444445555555555555555 5x16 Waste 6/16 == No Cover
141 111111111111111122222222222222223333333333333333444444444444444455555555555555556666666666666666 6x16 Waste 4/16 => Cover with uint128_t
142 111111111111111111111111111111112222222222222222222222222222222233333333333333333333333333333333 3x32 Waste 4/16 => Cover with uint128_t
143
144 @par Usage
145
146 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
147 state return a reference to the object after the change. This provides, at a performance impact, the ability to use the value returned by such a function
148 in the expression in 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
149 drawing function. As another example, this provides the ability to do "method chaining" like so: aColor.setToRed().setToBlack() -- which will lead to
150 aColor being black. That said, it means we must use compiler optimization features to throw away this refrence if it is not used!!
151
152 Several methods are provided that transform the color object as a whole. For example, methods are provided to compute component-wise linear histogram
153 transformations. Note that transformation methods are not provided to transform just one component of an object or a range of components. The philosophy
154 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
155 function to add the second half of two integers together -- integers are one "thingy" and so are colors. :)
156
157 @par Construction
158
159 Several constructors are provided. All in all, the goal is to make it easy to construct color objects with a specified color.
160
161 |--------------------------------+---------------------+----------------------------------------|
162 | Type | Member Helper | Cast Application |
163 |--------------------------------+---------------------+----------------------------------------|
164 | colorT | copy | |
165 | four clrChanT | setChans | |
166 | three clrChanT | setChans | |
167 | two clrChanT | setChans | |
168 | one clrChanT | setChans | drawPoint(x, y, 128); |
169 | Named Corner Colors via string | setColorFromString | drawPoint(x, y, "Red"); |
170 | Web hex string | setColorFromString | drawPoint(x, y, "#FF0000"); |
171 | Extended web hex string | setColorFromString | drawPoint(x, y, "##FFFF00000000"); |
172 | Single character string | setColorFromString | drawPoint(x, y, "R"); |
173 | Named Corner Colors via ENUM | setToCorner | drawPoint(x, y, cornerColorEnum::RED); |
174 |--------------------------------+---------------------+----------------------------------------|
175
176 @tparam clrChanT Type to contain the channel information. This type should be a unsigned integral type, a float, or double.
177 @tparam numChan The number of channels this color will have. Common choices are 1 for greyscale, 3 for RGB, and 4 for RGBA.
178 @tparam redChanIdx Index for the Red channel. -1 indicates no Red chan.
179 @tparam blueChanIdx Index for the Blue channel. -1 indicates no Red channel.
180 @tparam greenChanIdx Index for the Green channel. -1 indicates no Red channel.
181 @tparam alphaChanIdx Index for the Alpha channel. -1 indicates no Red channel.
182 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
183 are all negative and numChan == 3, then alphaChanIdx won't be assigned, but red, blue, and green will be. */
184 template <class clrChanT, int numChan, int redChanIdx = -1, int greenChanIdx = -1, int blueChanIdx = -1, int alphaChanIdx = -1>
185 requires ((numChan>0) && // Must have at least 1 chan
186 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
187 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
188 (redChanIdx < numChan) &&
189 (blueChanIdx < numChan) &&
190 (greenChanIdx < numChan) &&
191 (alphaChanIdx < numChan) &&
192 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
193 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
194 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
195 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
196 (redChanIdx != blueChanIdx) &&
197 (redChanIdx != alphaChanIdx) &&
198 (greenChanIdx != blueChanIdx) &&
199 (greenChanIdx != alphaChanIdx) &&
200 (blueChanIdx != alphaChanIdx)))) // Chans can't be teh same if non-negative
201 class colorTpl {
202
203 public:
204
205 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
206 /** @name Public type related types -- meta-types? ;) */
207 //@{
208 /** This object type */
210 /** Pointer to colorTpl */
212 /** Reference to colorTpl) */
214 /** Reference to const colorTpl */
215 typedef colorType const& colorCRefType;
216 /** Type for the channels (clrChanT) */
217 typedef clrChanT channelType;
218 //@}
219
220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
221 /** @name Public types for std::tuple & std::vector containing clrChanT values */
222 //@{
223 typedef std::tuple<clrChanT, clrChanT, clrChanT, clrChanT> clrChanTup6;
224 typedef std::tuple<clrChanT, clrChanT, clrChanT, clrChanT> clrChanTup5;
225 typedef std::tuple<clrChanT, clrChanT, clrChanT, clrChanT> clrChanTup4;
226 typedef std::tuple<clrChanT, clrChanT, clrChanT> clrChanTup3;
227 typedef std::tuple<clrChanT, clrChanT> clrChanTup2;
228 typedef std::tuple<clrChanT> clrChanTup1;
229
230 typedef std::vector<clrChanT> clrChanVec;
231 //@}
232
233 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
234 /** @name Public types for for packed integers. */
235 //@{
236 typedef uint32_t packed4Cint; //!< Used for passing & returning integers with packed 8-bit channels
237 //@}
238
239 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
240 /** @name Public color types related to colorT.
241 These types are used for things like color space computations and sources for setting channels, etc...*/
242 //@{
243 typedef colorTpl<double, 3> colConDbl3; //!< Used for color space computations. Type identical to colConRGBdbl, but might not be RGB.
244 typedef colorTpl<double, 3> colConRGBdbl; //!< RGB with double channels.
245 typedef colorTpl<double, 4> colConRGBAdbl; //!< RGBA with double channels.
246 typedef colorTpl<uint8_t, 3> colConRGBbyte; //!< RGB with uint8_t channels.
247 typedef colorTpl<uint8_t, 4> colConRGBAbyte; //!< RGBA with uint8_t channels.
248 typedef colorTpl<double, numChan> colConALLdbl; //!< Color with the same number of challens as colorT, but with double channels
249 typedef colorTpl<uint8_t, numChan> colConALLbyte; //!< Color with the same number of challens as colorT, but with uint8_t channels
250 //@}
251
252 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
253 /** @cond pat */
254 /** @name Public arithmetic types */
255 //@{
256 /** @typedef maskType
257 Unsigned integer mask to cover the channel array without wasting too much space.
258 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
259 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
260 64 bits. When a cover can't be found, this type is set to uint8_t -- to avoid any alignment issues in RAM.
261
262 The constant goodMask can be used to tell if maskType is large enough to cover.
263 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
264 typedef typename std::conditional<std::cmp_greater_equal(sizeof(uint8_t), sizeof(clrChanT)*numChan), uint8_t,
265 typename std::conditional<std::cmp_greater_equal(sizeof(uint16_t), sizeof(clrChanT)*numChan), uint16_t,
266 typename std::conditional<std::cmp_greater_equal(sizeof(uint32_t), sizeof(clrChanT)*numChan), uint32_t,
267 typename std::conditional<std::cmp_greater_equal(sizeof(uint64_t), sizeof(clrChanT)*numChan),
268 typename std::conditional<std::cmp_less_equal(3*sizeof(uint64_t), sizeof(clrChanT)*numChan*4), uint64_t,
269 uint8_t
270 >::type,
271 typename std::conditional<std::cmp_greater_equal(sizeof(mjr_uintBiggest_t), sizeof(clrChanT)*numChan),
272 typename std::conditional<std::cmp_less_equal(3*sizeof(mjr_uintBiggest_t), sizeof(clrChanT)*numChan*4), mjr_uintBiggest_t,
273 uint8_t
274 >::type,
275 uint8_t
276 >::type>::type>::type>::type>::type maskType;
277
278 /** @typedef channelArithDType
279 Arithmetic type for differences of clrChanT values.
280 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.
281
282 The constant goodArithD can be used to tell if channelArithDType is large enough.
283 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
284 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
285 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)*2), int8_t,
286 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)*2), int16_t,
287 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)*2), int32_t,
288 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)*2), int64_t,
290 >::type>::type>::type>::type>::type channelArithDType;
291
292 /** @typedef channelArithSPType
293 Arithmetic type for sums and products of clrChanT values.
294 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.
295
296 The constant goodArithSP can be used to tell if channelArithSPType is large enough.
297 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
298 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
299 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)*2), uint8_t,
300 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)*2), uint16_t,
301 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)*2), uint32_t,
302 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)*2), uint64_t,
304 >::type>::type>::type>::type>::type channelArithSPType;
305
306 /** @typedef channelArithSDPType
307 Arithmetic type for sums, differences, and products of clrChanT values.
308 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.
309
310 The constant goodArithSDP can be used to tell if channelArithSDPType is large enough.
311 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
312 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
313 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)*4), int8_t,
314 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)*4), int16_t,
315 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)*4), int32_t,
316 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)*4), int64_t,
318 >::type>::type>::type>::type>::type channelArithSDPType;
319
320 /** @typedef channelArithFltType
321 Floating point type suitable for arithmetic of clrChanT values.
322 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.
323
324 The constant goodArithFlt can be used to tell if channelArithFltType is large enough.
325 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
326 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, clrChanT,
327 typename std::conditional<std::cmp_greater_equal(sizeof(int8_t), sizeof(clrChanT)), float,
328 typename std::conditional<std::cmp_greater_equal(sizeof(int16_t), sizeof(clrChanT)), float,
329 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)), double,
330 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)), long double,
331 long double
332 >::type>::type>::type>::type>::type channelArithFltType;
333
334 /** @typedef channelArithLogType
335 Arithmetic type suitable for for logical operations of clrChanT values.
336
337 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
338 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
339 general the size of quad floats can vary a bit across hardware platforms, so I suggest not using them for channel types.
340
341 The constant goodArithLog can be used to tell if channelArithLogType the same size as clrChanT.
342 Note we use cmp_greater_equal and cmp_less_equal because the operators confuse Doxygen. */
343 typedef typename std::conditional<std::is_integral<clrChanT>::value, clrChanT,
344 typename std::conditional<std::cmp_greater_equal(sizeof(int32_t), sizeof(clrChanT)), uint32_t,
345 typename std::conditional<std::cmp_greater_equal(sizeof(int64_t), sizeof(clrChanT)), uint64_t,
346 typename std::conditional<std::cmp_greater_equal(sizeof(mjr_uintBiggest_t), sizeof(clrChanT)), mjr_uintBiggest_t,
347 uint64_t
348 >::type>::type>::type>::type channelArithLogType;
349 //@}
350 /** @endcond */
351
352 private:
353
354 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
355 /** @name Private Object Data */
356 //@{
357 /** Holds the color channel data.
358 The union is used to overlay a mask integer leading to dramatic performance improvements for common color types.
359
360 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
361 "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
362 "correct" way with modern C++; however, I'll need to do quite a bit of performance testing first... */
363 union {
364 maskType theInt;
365 clrChanT thePartsA[numChan];
366 } theColor;
367 //@}
368
369 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
370 /** @name Private utility functions */
371 //@{
372 //--------------------------------------------------------------------------------------------------------------------------------------------------------
373 /** This is a helper function for setRGBfromColorSpace. */
374 inline double hslHelperVal(double n1, double n2, double hue) {
375 hue = mjr::math::ivl::wrapCO(hue, 360.0);
376 if(hue<60)
377 return n1+(n2-n1)*hue/60.0;
378 else if(hue<180)
379 return n2;
380 else if (hue < 240)
381 return n1+(n2-n1)*(240-hue)/60.0;
382 else
383 return n1;
384 }
385 //--------------------------------------------------------------------------------------------------------------------------------------------------------
386 /** Set all channels to meanChanVal. */
387 inline void setChansToMean() { std::fill_n(theColor.thePartsA, numChan, meanChanVal); }
388 //--------------------------------------------------------------------------------------------------------------------------------------------------------
389 /** Set all channels to minChanVal. */
390 inline void setChansToMin() {
391 if(goodMask)
392 setMaskNC(maskAllZero);
393 else
394 std::fill_n(theColor.thePartsA, numChan, minChanVal);
395 }
396 //--------------------------------------------------------------------------------------------------------------------------------------------------------
397 /** Set all channels to maxChanVal. */
398 inline void setChansToMax() {
399 if(chanIsInt && goodMask)
400 setMaskNC(~static_cast<maskType>(0));
401 else
402 std::fill_n(theColor.thePartsA, numChan, maxChanVal);
403 }
404 //--------------------------------------------------------------------------------------------------------------------------------------------------------
405 /** Sets the current color based upon the contents of the given std::string.
406 This is the guts of the magic constructor taking a string. If colorString starts with a "#", then setChans() will be used.
407 Otherwise setToCorner() will be used */
408 inline colorTpl& setColorFromString(std::string colorString) {
409 if ( !(colorString.empty())) {
410 if(colorString[0] == '#') {
411 setChans(colorString, true);
412 } else {
413 if(((colorString[0] == 'b') || (colorString[0] == 'B')) && (colorString.size() > 1)) {
414 if( (colorString[2]=='u') || (colorString[2]=='U') )
415 setToBlue();
416 else
417 setToBlack();
418 } else {
419 setToCorner(colorString[0]);
420 }
421 }
422 }
423 return *this;
424 }
425 //--------------------------------------------------------------------------------------------------------------------------------------------------------
426 /** Convert a uint8_t to a clrChanT (for integral clrChanT) */
427 inline clrChanT convertByteToChan(uint8_t cVal) const requires (std::integral<clrChanT>) {
428 if(chanIsByte)
429 return cVal;
430 else
431 return static_cast<clrChanT>(static_cast<channelArithSPType>(cVal) * static_cast<channelArithSPType>(maxChanVal) / static_cast<channelArithSPType>(255));
432 }
433 //--------------------------------------------------------------------------------------------------------------------------------------------------------
434 /** Convert a uint8_t to a clrChanT (for floating point clrChanT)*/
435 inline clrChanT convertByteToChan(uint8_t cVal) const requires (std::floating_point<clrChanT>) {
436 return (static_cast<clrChanT>(cVal) / static_cast<clrChanT>(255));
437 }
438 //--------------------------------------------------------------------------------------------------------------------------------------------------------
439 /** Convert hex CString to clrChanT (for integral clrChanT) */
440 inline clrChanT convertHexStringToChan(std::string hexString) const requires (std::integral<clrChanT>) {
441 if (sizeof(unsigned long) >= sizeof(clrChanT))
442 return static_cast<clrChanT>( std::stoul(hexString, nullptr, 16));
443 else
444 return static_cast<clrChanT>(std::stoull(hexString, nullptr, 16));
445 }
446 //--------------------------------------------------------------------------------------------------------------------------------------------------------
447 /** Convert hex CString to clrChanT (for floating point clrChanT)*/
448 inline clrChanT convertHexStringToChan(std::string hexString) const requires (std::floating_point<clrChanT>) {
449 if (sizeof(unsigned long) >= sizeof(clrChanT))
450 return static_cast<clrChanT>( std::stoul(hexString, nullptr, 16)) / static_cast<clrChanT>((chanIsInt ? 1 : std::pow(2, bitsPerChan)));
451 else
452 return static_cast<clrChanT>(std::stoull(hexString, nullptr, 16)) / static_cast<clrChanT>((chanIsInt ? 1 : std::pow(2, bitsPerChan)));
453 }
454 //--------------------------------------------------------------------------------------------------------------------------------------------------------
455 /** Convert a clrChanT to a uint8_t (for floating point clrChanT) */
456 inline uint8_t convertChanToByte(clrChanT cVal) const requires (std::floating_point<clrChanT>) {
457 return static_cast<uint8_t>(cVal * static_cast<clrChanT>(255) / maxChanVal);
458 }
459 //--------------------------------------------------------------------------------------------------------------------------------------------------------
460 /** Convert a clrChanT to a uint8_t (for integral clrChanT) */
461 inline uint8_t convertChanToByte(clrChanT cVal) const requires (std::integral<clrChanT>) {
462 /* 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
463 below. */
464 if(chanIsByte)
465 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.
466 else
467 return static_cast<uint8_t>(static_cast<channelArithSPType>(cVal) * static_cast<channelArithSPType>(255) / static_cast<channelArithSPType>(maxChanVal));
468 }
469 //--------------------------------------------------------------------------------------------------------------------------------------------------------
470 /** Convert a double to a clrChanT */
471 inline clrChanT convertDoubleToChan(double cVal) const {
472 /* Performance: Not all compilers recognize multiplication by 1.0 as a NOOP. Hence the if-then below. */
473 if(chanIsInt)
474 return static_cast<clrChanT>(cVal * maxChanVal);
475 else
476 return static_cast<clrChanT>(cVal);
477 }
478 //--------------------------------------------------------------------------------------------------------------------------------------------------------
479 /** Convert a clrChanT to a double */
480 inline double convertChanToDouble(clrChanT cVal) const {
481 if(chanIsInt)
482 return static_cast<double>(cVal) / static_cast<double>(maxChanVal);
483 else
484 return static_cast<double>(cVal);
485 }
486 //--------------------------------------------------------------------------------------------------------------------------------------------------------
487 /** Return the mask value */
488 inline maskType getMaskNC() const {
489#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
490#pragma GCC diagnostic push
491#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
492#endif
493 return theColor.theInt;
494#if __GNUC__
495#pragma GCC diagnostic pop
496#endif
497 }
498 //--------------------------------------------------------------------------------------------------------------------------------------------------------
499 /** Set the mask value */
500 inline void setMaskNC(maskType aMask) { theColor.theInt = aMask; }
501 //@}
502
503 public:
504
505 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
506 /** @name Public Constants Related to RGBA channels */
507 //@{
508 constexpr static int noRGBchanIdx = (redChanIdx < 0) && (greenChanIdx < 0) && (blueChanIdx < 0) && (alphaChanIdx < 0);
509 constexpr static int redChan = (noRGBchanIdx && numChan > 0 ? 0 : redChanIdx);
510 constexpr static int greenChan = (noRGBchanIdx && numChan > 1 ? 1 : greenChanIdx);
511 constexpr static int blueChan = (noRGBchanIdx && numChan > 2 ? 2 : blueChanIdx);
512 constexpr static int alphaChan = (noRGBchanIdx && numChan > 3 ? 3 : alphaChanIdx);
513 //@}
514
515 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
516 /** @name Public Constants Related to template paramaters */
517 //@{
518 constexpr static int bitsPerChan = (int)(sizeof(clrChanT)*CHAR_BIT); //!< Number of bits in clrChanT
519 constexpr static int bitsPerPixel = numChan*bitsPerChan; //!< Number of color data bits
520 constexpr static bool chanIsInt = std::is_integral<clrChanT>::value; //!< clrChanT is an integral type
521 constexpr static bool chanIsFloat = std::is_floating_point<clrChanT>::value; //!< clrChanT is a floating pint type
522 constexpr static bool chanIsUnsigned = std::is_unsigned<clrChanT>::value; //!< clrChanT is an unsigned integral type
523 constexpr static bool chanIsByte = std::is_same<clrChanT, uint8_t>::value; //!< is clrChanT an 8-bit unsigned int?
524 constexpr static bool chanIsDouble = std::is_same<clrChanT, double>::value; //!< is clrChanT a double?
525 constexpr static bool goodMask = (sizeof(maskType) >= sizeof(clrChanT)*numChan); //!< maskType is big enough
526 constexpr static bool perfectMask = (sizeof(maskType) == sizeof(clrChanT)*numChan); //!< maskType is perfectly sized
527 constexpr static bool goodArithD = (chanIsFloat || (sizeof(channelArithDType) >= sizeof(clrChanT)*2)); //!< channelArithDType is big enough
528 constexpr static bool goodArithSP = (chanIsFloat || (sizeof(channelArithSPType) >= sizeof(clrChanT)*2)); //!< channelArithSPType is big enough
529 constexpr static bool goodArithSDP = (chanIsFloat || (sizeof(channelArithSDPType) >= sizeof(clrChanT)*4)); //!< channelArithSDPType is big enough
530 constexpr static bool goodArithFlt = (chanIsFloat || (sizeof(channelArithFltType) > sizeof(clrChanT))); //!< channelArithFltType is big enough
531 constexpr static bool goodArithLog = (sizeof(channelArithLogType) == sizeof(clrChanT)); //!< channelArithLogType is the right size
532 constexpr static int sizeOfColor = (int)(goodMask ? sizeof(maskType) : sizeof(clrChanT)*numChan); //!< Size of this object
533 constexpr static bool ptrIsSmaller = sizeOfColor > (int)sizeof(colorPtrType); //!< This object smaller than a pointer
534 constexpr static clrChanT maxChanVal = (chanIsInt ? std::numeric_limits<clrChanT>::max() : 1); //!< maximum value for a channel
535 constexpr static clrChanT minChanVal = (chanIsInt ? std::numeric_limits<clrChanT>::min() : 0); //!< maximum value for a channel
536 constexpr static clrChanT meanChanVal = (maxChanVal-minChanVal)/2; //!< middle value for a channel
537 constexpr static maskType maskAllOne = ~(static_cast<maskType>(0)); //!< mask value all ones
538 constexpr static maskType maskAllZero = static_cast<maskType>(0); //!< mask value all zeros
539 constexpr static int channelCount = numChan; //!< Number of channels
540 //@}
541
542 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
543 /** @name Public type for argument passing */
544 //@{
545 /** A type for passing colorTpl objects to functions.
546
547 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
548 colorType const& -- resulting in pass by refrence. */
549 typedef typename std::conditional<ptrIsSmaller, colorCRefType, colorType>::type colorArgType;
550 //@}
551
552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
553 /** @cond cst */
554 /** @name Color Scheme Related Types */
555 //@{
556 /** A type used for discreet color scheme indexes.
557 This will be uint64_t for floating point clrChanT, and the larger of uint32_t and colorChanArithSPType for integral clrChanT.
558 We use cmp_less because < confuses Doxygen.*/
559 typedef typename std::conditional<std::cmp_less(sizeof(channelArithSPType), sizeof(uint32_t)), uint32_t,
560 typename std::conditional<std::is_floating_point<clrChanT>::value, uint64_t,
561 channelArithSPType
562 >::type>::type csIntType;
563
564 /** A type used for continous color scheme indexes. */
565 typedef double csFltType;
566 /** A type used for 2D continous color scheme indexes. */
567 typedef std::complex<csFltType> csCplxType;
568 /** A clrChanT-similar type color scheme indexes. */
569 typedef typename std::conditional<std::is_floating_point<clrChanT>::value, csFltType, csIntType>::type csNatType;
570 //@}
571 /** @endcond */
572
573 /** @name Color Scheme Constants */
574 //@{
575 /* 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. */
576 constexpr static csIntType chanStepMax = (chanIsInt ? static_cast<csIntType>(maxChanVal) : std::numeric_limits<uint32_t>::max()); //!< Finite "steps" for a color scheme: [0, chanStepMax]
577 constexpr static int minWavelength = 360; //!< Minimum wavelength for wavelength conversion
578 constexpr static int maxWavelength = 830; //!< Maximum wavelength for wavelength conversion
579 //@}
580
581 /** @name Default RGB Luminescence Weights */
582 //@{
583 constexpr static double RGBluminanceWeightR = 0.2126;
584 constexpr static double RGBluminanceWeightG = 0.7152;
585 constexpr static double RGBluminanceWeightB = 0.0722;
586 //@}
587
588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
589 /** @name Public Enums Constants */
590 //@{
591 /** Colors at the corners of the RGB color cube. */
592 enum class cornerColorEnum { BLACK, //!< Color cube corner color with RGB=000
593 RED, //!< Color cube corner color with RGB=100
594 GREEN, //!< Color cube corner color with RGB=010
595 BLUE, //!< Color cube corner color with RGB=001
596 YELLOW, //!< Color cube corner color with RGB=110
597 CYAN, //!< Color cube corner color with RGB=011
598 MAGENTA, //!< Color cube corner color with RGB=101
599 WHITE //!< Color cube corner color with RGB=111
600 };
601 /** Color spaces.
602 This ENUM is used by setRGBfromColorSpace(), interplColorSpace(), and rgb2colorSpace(). In this context these color spaces use double values for each
603 channel. Angles (the H of HSV, HSL, & LCH) are in degrees, and will always be normalized to [0, 360). */
604 enum class colorSpaceEnum { RGB, //!< RGB color space. R in [0, 1]. G in [0, 1]. B in [0, 1].
605 HSL, //!< HSL color space. H in [0, 360]. S in [0, 1]. L in [0, 1].
606 HSV, //!< HSV color space. H in [0, 360]. S in [0, 1]. V in [0, 1].
607 LAB, //!< CIE-L*ab color space. L in [0, 100]. A in REALS. B in REALS.
608 XYZ, //!< XYZ color space. X in [0, 1]. Y in [0, 1]. Z in [0, 1].
609 LCH, //!< CIE-L*ch color space. L in [0, 100]. C in [0, 100]. H in [0, 360]
610 NONE //!< Used when the color channels don't have an assocaited color space
611 };
612 /** Interpolation methods for emperical color matching functions. */
613 enum class cmfInterpolationEnum { FLOOR, //!< closest lower
614 CEILING, //!< closest upper
615 NEAREST, //!< closest
616 LINEAR, //!< linear interpolation
617 BUMP //!< exponential bump map interpolation
618 // MJR TODO NOTE cmfInterpolationEnum: Add Chebychev and cubic spline options.
619 };
620 //@}
621
622 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
623 /** @name Constructors: C++ Utility */
624 //@{
625 //--------------------------------------------------------------------------------------------------------------------------------------------------------
626 /** The no arg constructor is a noop so we don't needlessly initialize millions of pixels -- compiler warnings are expected. */
628 //--------------------------------------------------------------------------------------------------------------------------------------------------------
629 /** Copy constructor (heavily used for assignment in the ramCanvas library). */
630 colorTpl(const colorType& aColor) {
631 /* 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.
632 Sometimes we might even want to copy an unitilzied color -- sometimes it makes the code easier to write.*/
633 if(goodMask)
634 setMaskNC(aColor.getMaskNC());
635 else
636 std::copy_n(aColor.theColor.thePartsA, numChan, theColor.thePartsA);
637 }
638 //--------------------------------------------------------------------------------------------------------------------------------------------------------
639 /** Initializer list. Unspecified channels are set ot minChanVal, and extra channel values are ignored. */
640 colorTpl(std::initializer_list<clrChanT> cVals) {
641 int numChanGiven = static_cast<int>(cVals.size());
642 auto p = cVals.begin();
643 for(int i=0; i<std::min(numChanGiven, numChan); i++) {
644 setChanNC(i, *p);
645 ++p;
646 }
647 if (numChanGiven < numChan)
648 for(int i=numChanGiven; i<numChan; i++)
649 setChanToMin(i);
650 }
651 //@}
652
653 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
654 /** @name Constructors: RGB
655 These all use setChansRGB or setChansRGBA internally; however, these constructors will set any unspecified channels to min. */
656 //@{
657 colorTpl(clrChanT r, clrChanT g, clrChanT b, clrChanT a) {
658 if (numChan > 4)
659 setChansToMin();
660 setChansRGBA(r, g, b, a);
661 }
662 colorTpl(clrChanT r, clrChanT g, clrChanT b) {
663 if (numChan > 3)
664 setChansToMin();
665 setChansRGB(r, g, b);
666 }
667 //@}
668
669 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
670 /** @name Constructors: Conversions
671 These are all guarnteed to set all channels of the object. */
672 //@{
673 //--------------------------------------------------------------------------------------------------------------------------------------------------------
674 /** Uses setChans() to set all channels to the given value
675 @param cVal The value to set the channels to */
676 colorTpl(clrChanT cVal) { setChans(cVal); }
677 //--------------------------------------------------------------------------------------------------------------------------------------------------------
678 /** Uses the setToCorner() method to set the initialize the object.
679 Note that no constructor exists taking a character to provide to setToCorner(). Why? Because character literals are integers in C++, and they might
680 be the same as clrChanT -- rendering ambiguous overload cases.*/
681 colorTpl(cornerColorEnum cornerColor) { setToCorner(cornerColor); }
682 //--------------------------------------------------------------------------------------------------------------------------------------------------------
683 /** Uses the setColorFromString() method to set the initialize the object. */
684 colorTpl(std::string colorString) { setColorFromString(colorString); }
685 //--------------------------------------------------------------------------------------------------------------------------------------------------------
686 /** Uses the setColorFromString() method to set the initialize the object. */
687 colorTpl(const char* colorCString) { setColorFromString(std::string(colorCString)); }
688 //@}
689
690 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
691 /** @name Destructor */
692 //@{
693 /** The destructor for this class is a no-op. */
695 //@}
696
697 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
698 /** @name Utility Methods */
699 //@{
700 /** Copy the contents of the given color object into the current object.
701 When sizeof(colorTpl)<=sizeof(maskType), this function consists of a single assignment statement. Otherwise it is O(numChan).
702 @return Returns a reference to the current color object.*/
703 inline colorTpl& copy(colorArgType aCol) {
704 if(goodMask)
705 setMaskNC(aCol.getMaskNC());
706 else
707 for(int i=0; i<numChan; i++)
708 setChanNC(i, aCol.getChanNC(i));
709 return *this;
710 }
711 //@}
712
713 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
714 /** @name Named Channel Access
715 Provides access to the specified color channel value with compile time index check.
716 - _dbl versions work with double values scaled to [0, 1].
717 - _byte versions work with uint8_t values scaled to [0, 255]
718 - Numbered channel names are 0 indexed. */
719 //@{
720 inline clrChanT getRed() const requires ((redChan>=0) && (numChan>redChan)) { return getChanNC(redChan); }
721 inline clrChanT getBlue() const requires ((blueChan>=0) && (numChan>blueChan)) { return getChanNC(blueChan); }
722 inline clrChanT getGreen() const requires ((greenChan>=0) && (numChan>greenChan)) { return getChanNC(greenChan); }
723 inline clrChanT getAlpha() const requires ((alphaChan>=0) && (numChan>alphaChan)) { return getChanNC(alphaChan); }
724
725 inline double getRed_dbl() const { return convertChanToDouble(getRed()); }
726 inline double getGreen_dbl() const { return convertChanToDouble(getGreen()); }
727 inline double getBlue_dbl() const { return convertChanToDouble(getBlue()); }
728 inline double getAlpha_dbl() const { return convertChanToDouble(getAlpha()); }
729
730 inline uint8_t getRed_byte() const { return convertChanToByte(getRed()); }
731 inline uint8_t getGreen_byte() const { return convertChanToByte(getGreen()); }
732 inline uint8_t getBlue_byte() const { return convertChanToByte(getBlue()); }
733 inline uint8_t getAlpha_byte() const { return convertChanToByte(getAlpha()); }
734
735 inline clrChanT getC0() const { return getChanNC(0); }
736 inline clrChanT getC1() const requires (numChan>1) { return getChanNC(1); }
737 inline clrChanT getC2() const requires (numChan>2) { return getChanNC(2); }
738 inline clrChanT getC3() const requires (numChan>3) { return getChanNC(3); }
739
740 inline double getC0_dbl() const { return convertChanToDouble(getC0()); }
741 inline double getC1_dbl() const { return convertChanToDouble(getC1()); }
742 inline double getC2_dbl() const { return convertChanToDouble(getC2()); }
743 inline double getC3_dbl() const { return convertChanToDouble(getC3()); }
744
745 inline uint8_t getC0_byte() const { return convertChanToByte(getC0()); }
746 inline uint8_t getC1_byte() const { return convertChanToByte(getC1()); }
747 inline uint8_t getC2_byte() const { return convertChanToByte(getC2()); }
748 inline uint8_t getC3_byte() const { return convertChanToByte(getC3()); }
749 //@}
750
751 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
752 /** @name Indexed Channel Access
753 Provides access to an indexed color channel value with run time index check.
754 The channels are 0 indexed.
755 - _dbl versions work with double values scaled to [0, 1].
756 - _byte versions work with uint8_t values scaled to [0, 255] */
757 //--------------------------------------------------------------------------------------------------------------------------------------------------------
758 inline clrChanT getChan(int chan) const {
759 if((chan >= 0) && (chan < numChan)) [[likely]]
760 return getChanNC(chan);
761 else
762 return minChanVal;
763 }
764 //--------------------------------------------------------------------------------------------------------------------------------------------------------
765 inline double getChan_dbl(int chan) const {
766 if((chan >= 0) && (chan < numChan)) [[likely]]
767 return convertChanToDouble(getChanNC(chan));
768 else
769 return 0.0;
770 }
771 //--------------------------------------------------------------------------------------------------------------------------------------------------------
772 inline uint8_t getChan_byte(int chan) const {
773 if((chan >= 0) && (chan < numChan)) [[likely]]
774 return convertChanToByte(getChanNC(chan));
775 else
776 return 0;
777 }
778 //@}
779
780 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
781 /** @name Set Named Channel Value
782 Provides access to the specified color channel value with compile time index check.
783 - _dbl versions work with double values scaled to [0, 1].
784 - _byte versions work with uint8_t values scaled to [0, 255]
785 - Numbered channel names are 0 indexed. */
786 //@{
787 /* Performance: numChan is known at compile time, so the optimizer will produce an assignment or no code at all -- i.e. the test for numChan is done at
788 compile time only, and imposes zero overhead at runtime. */
789 /* 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
790 for example. */
791 /* Useablity: We could do this with a template, but that means we need ".template set" syntax in some cases. That's just too uguly. */
792
793 inline colorTpl& setC0(clrChanT cVal) { return setChanNC(0, cVal); }
794 inline colorTpl& setC1(clrChanT cVal) requires (numChan>1) { return setChanNC(1, cVal); }
795 inline colorTpl& setC2(clrChanT cVal) requires (numChan>2) { return setChanNC(2, cVal); }
796 inline colorTpl& setC3(clrChanT cVal) requires (numChan>3) { return setChanNC(3, cVal); }
797
798 inline colorTpl& setC0_dbl(double cVal) { return setC0(convertDoubleToChan(cVal)); }
799 inline colorTpl& setC1_dbl(double cVal) { return setC1(convertDoubleToChan(cVal)); }
800 inline colorTpl& setC2_dbl(double cVal) { return setC2(convertDoubleToChan(cVal)); }
801 inline colorTpl& setC3_dbl(double cVal) { return setC3(convertDoubleToChan(cVal)); }
802
803 inline colorTpl& setC0_byte(uint8_t cVal) { return setC0(convertByteToChan(cVal)); }
804 inline colorTpl& setC1_byte(uint8_t cVal) { return setC1(convertByteToChan(cVal)); }
805 inline colorTpl& setC2_byte(uint8_t cVal) { return setC2(convertByteToChan(cVal)); }
806 inline colorTpl& setC3_byte(uint8_t cVal) { return setC3(convertByteToChan(cVal)); }
807
808 inline colorTpl& setRed(clrChanT cVal) requires ((redChan>=0) && (numChan>redChan)) { return setChanNC(redChan, cVal); }
809 inline colorTpl& setBlue(clrChanT cVal) requires ((blueChan>=0) && (numChan>blueChan)) { return setChanNC(blueChan, cVal); }
810 inline colorTpl& setGreen(clrChanT cVal) requires ((greenChan>=0) && (numChan>greenChan)) { return setChanNC(greenChan, cVal); }
811 inline colorTpl& setAlpha(clrChanT cVal) requires ((alphaChan>=0) && (numChan>alphaChan)) { return setChanNC(alphaChan, cVal); }
812
813 inline colorTpl& setRed_dbl(double cVal) { return setRed(convertDoubleToChan(cVal)); }
814 inline colorTpl& setGreen_dbl(double cVal) { return setGreen(convertDoubleToChan(cVal)); }
815 inline colorTpl& setBlue_dbl(double cVal) { return setBlue(convertDoubleToChan(cVal)); }
816 inline colorTpl& setAlpha_dbl(double cVal) { return setAlpha(convertDoubleToChan(cVal)); }
817
818 inline colorTpl& setRed_byte(uint8_t cVal) { return setRed(convertByteToChan(cVal)); }
819 inline colorTpl& setGreen_byte(uint8_t cVal) { return setGreen(convertByteToChan(cVal)); }
820 inline colorTpl& setBlue_byte(uint8_t cVal) { return setBlue(convertByteToChan(cVal)); }
821 inline colorTpl& setAlpha_byte(uint8_t cVal) { return setAlpha(convertByteToChan(cVal)); }
822
823 inline colorTpl& setChansRGBA(clrChanT r, clrChanT g, clrChanT b, clrChanT a) { setRed(r); setGreen(g); setBlue(b); setAlpha(a); return *this; }
824 inline colorTpl& setChansRGB(clrChanT r, clrChanT g, clrChanT b) { setRed(r); setGreen(g); setBlue(b); return *this; }
825
826 inline colorTpl& setChansRGBA_dbl(double r, double g, double b, double a) { return setChansRGBA(convertDoubleToChan(r), convertDoubleToChan(g), convertDoubleToChan(b), convertDoubleToChan(a)); }
827 inline colorTpl& setChansRGB_dbl(double r, double g, double b) { return setChansRGB(convertDoubleToChan(r), convertDoubleToChan(g), convertDoubleToChan(b)); }
828
829 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)); }
830 inline colorTpl& setChansRGB_byte(uint8_t r, uint8_t g, uint8_t b) { return setChansRGB(convertByteToChan(r), convertByteToChan(g), convertByteToChan(b)); }
831
832 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; }
833 inline colorTpl& setChansRGB(clrChanTup3 chanValues) { setRed(std::get<0>(chanValues)); setGreen(std::get<1>(chanValues)); setBlue(std::get<2>(chanValues)); return *this; }
834 //@}
835
836 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
837 /** @name Canonical Color Types.
838 Provide conversions to/from canonical color types. */
839 //@{
840 inline colorTpl& setChans_dbl(colConALLdbl dblColor) { for(int i=0; i<numChan; i++) setChanNC(i, convertDoubleToChan(dblColor.getChanNC(i))); return *this; }
841 inline colorTpl& setChans_byte(colConALLbyte byteColor) { for(int i=0; i<numChan; i++) setChanNC(i, convertByteToChan(byteColor.getChanNC(i))); return *this; }
842 inline colorTpl& setChansRGBA_dbl(colConRGBAdbl dblColor) { return setChansRGBA(convertDoubleToChan(dblColor.getRed()), convertDoubleToChan(dblColor.getGreen()), convertDoubleToChan(dblColor.getBlue()), convertDoubleToChan(dblColor.getAlpha())); }
843 inline colorTpl& setChansRGB_dbl(colConRGBdbl dblColor) { return setChansRGB( convertDoubleToChan(dblColor.getRed()), convertDoubleToChan(dblColor.getGreen()), convertDoubleToChan(dblColor.getBlue())); }
844 inline colorTpl& setChansRGBA_byte(colConRGBAbyte byteColor) { return setChansRGBA(convertByteToChan(byteColor.getRed()), convertByteToChan(byteColor.getGreen()), convertByteToChan(byteColor.getBlue()), convertByteToChan(byteColor.getAlpha())); }
845 inline colorTpl& setChansRGB_byte(colConRGBbyte byteColor) { return setChansRGB( convertByteToChan(byteColor.getRed()), convertByteToChan(byteColor.getGreen()), convertByteToChan(byteColor.getBlue())); }
846
847 inline colConALLdbl getColCon_dbl() { colConALLdbl rCol; for(int i=0; i<numChan; i++) rCol.setChanNC(i, convertChanToDouble(getChanNC(i))); return rCol; }
848 inline colConALLbyte getColCon_byte() { colConALLbyte rCol; for(int i=0; i<numChan; i++) rCol.setChanNC(i, convertChanToByte( getChanNC(i))); return rCol; }
849 inline colConRGBAdbl getColConRGBA_dbl() { return colConRGBAdbl( getChan_dbl(bestRedChan()), getChan_dbl(bestGreenChan()), getChan_dbl(bestBlueChan()), getChan_dbl(bestAlphaChan())); }
850 inline colConRGBdbl getColConRGB_dbl() { return colConRGBdbl( getChan_dbl(bestRedChan()), getChan_dbl(bestGreenChan()), getChan_dbl(bestBlueChan())); }
851 inline colConRGBAbyte getColConRGBA_byte() { return colConRGBAbyte(getChan_byte(bestRedChan()), getChan_byte(bestGreenChan()), getChan_byte(bestBlueChan()), getChan_byte(bestAlphaChan())); }
852 inline colConRGBbyte getColConRGB_byte() { return colConRGBbyte( getChan_byte(bestRedChan()), getChan_byte(bestGreenChan()), getChan_byte(bestBlueChan())); }
853 //@}
854
855 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
856 /** @name Best guess for named channel index.
857 These are used when we wish to get the named channel index, but the current color might not have specified an approprate value. */
858 //--------------------------------------------------------------------------------------------------------------------------------------------------------
859 /* Returns redChan if non-negative and 0 otherwise */
860 inline int bestRedChan() {
861 if (redChan >= 0)
862 return redChan; // If we have an identical red, then return it.
863 else
864 return 0; // Otherwise return 0 -- we are guarnteed at least one channel.
865 }
866 //--------------------------------------------------------------------------------------------------------------------------------------------------------
867 /* 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. */
868 inline int bestGreenChan() {
869 if (greenChan >= 0)
870 return greenChan; // If we have an identified green, then return it.
871 else if (numChan == 1)
872 return 0; // for greyscale, return chan 0
873 else
874 return 1; // If we have more than 1 channel, then return 1
875 }
876 //--------------------------------------------------------------------------------------------------------------------------------------------------------
877 /* 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. */
878 inline int bestBlueChan() {
879 if (blueChan >= 0)
880 return blueChan; // If we have an identified blue, then return it.
881 else if (numChan == 1)
882 return 0; // for greyscale, return chan 0
883 else if (numChan == 2)
884 return -1; // No sensible value for blue channel with 2 channel images
885 else
886 return 2; // If we have at least three channels, then return chan 2
887 }
888 //--------------------------------------------------------------------------------------------------------------------------------------------------------
889 /* Returns alphaChan if it is non-negative. If we only have four or more channels, then returns 3. Otherwise returns -1. */
890 inline int bestAlphaChan() {
891 if (alphaChan >= 0)
892 return alphaChan; // If we have an identified alpha, then return it.
893 else if (numChan >= 4)
894 return 3; // If we have at least four channels, then return chan 3
895 else
896 return -1; // No sensible value for alpha channel
897 }
898 //@}
899
900 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
901 /** @name Setting a single Channel by Index
902 Provides access to an indexed color channel value with run time index check.
903 The channels are 0 indexed.
904 - _dbl versions work with double values scaled to [0, 1].
905 - _byte versions work with uint8_t values scaled to [0, 255] */
906 //--------------------------------------------------------------------------------------------------------------------------------------------------------
907 inline colorTpl& setChanToMax(int chan) {
908 if((chan >= 0) && (chan < numChan)) [[likely]]
909 setChanNC(chan, maxChanVal);
910 return *this;
911 }
912 //--------------------------------------------------------------------------------------------------------------------------------------------------------
913 inline colorTpl& setChanToMin(int chan) {
914 if((chan >= 0) && (chan < numChan)) [[likely]]
915 setChanNC(chan, minChanVal);
916 return *this;
917 }
918 //--------------------------------------------------------------------------------------------------------------------------------------------------------
919 inline colorTpl& setChan(int chan, clrChanT cVal) {
920 if((chan >= 0) && (chan < numChan)) [[likely]]
921 setChanNC(chan, cVal);
922 return *this;
923 }
924 //--------------------------------------------------------------------------------------------------------------------------------------------------------
925 inline colorTpl& setChan_dbl(int chan, double cVal) {
926 /* Performance: We expect chan to be in range most of the time. If it is not, we waste time here computing the channel value.. */
927 return setChan(chan, convertDoubleToChan(cVal));
928 }
929 //--------------------------------------------------------------------------------------------------------------------------------------------------------
930 inline colorTpl& setChan_byte(int chan, uint8_t cVal) {
931 /* Performance: We expect chan to be in range most of the time. If it is not, we waste time here computing the channel value.. */
932 /* Performance: When chanIsByte, convertByteToChan is a NOOP. As it's inline, this leads to zero overhead for the chanIsByte case. */
933 return setChan(chan, convertByteToChan(cVal));
934 }
935 //@}
936
937 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
938 /** @name Set/Get Single Channel values with no index checks.
939 @warning These functions are fast, but have no error checking. Use them wrong, and get a segfault! */
940 //@{
941 //--------------------------------------------------------------------------------------------------------------------------------------------------------
942 /** Sets the specified color channel value with no index check. */
943 inline colorTpl& setChanNC(int chan, clrChanT cVal) { theColor.thePartsA[chan] = cVal; return *this; }
944 //--------------------------------------------------------------------------------------------------------------------------------------------------------
945 /** Provides access to an specified color channel value with no index check. */
946 inline clrChanT getChanNC(int chan) const {
947#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
948#pragma GCC diagnostic push
949#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
950#endif
951 return theColor.thePartsA[chan];
952#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
953#pragma GCC diagnostic pop
954#endif
955 }
956 //@}
957
958 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
959 /** @name Set All Channel Values To One Value
960 Sets all components of the current object from to \a cVal.
961 - _dbl versions work with double values scaled to [0, 1].
962 - _byte versions work with uint8_t values scaled to [0, 255] */
963 //@{
964 //--------------------------------------------------------------------------------------------------------------------------------------------------------
965 inline colorTpl& setChans(clrChanT cVal) {
966 for(int i=0; i<numChan; i++)
967 setChanNC(i, cVal);
968 return *this;
969 }
970 //--------------------------------------------------------------------------------------------------------------------------------------------------------
971 inline colorTpl& setChans_dbl(double cVal) { return setChans(convertDoubleToChan(cVal)); }
972 inline colorTpl& setChans_byte(uint8_t cVal) { return setChans(convertByteToChan(cVal)); }
973 //@}
974
975 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
976 /** @name Set Channel Value(s) with clrChanT values */
977 //@{
978 //--------------------------------------------------------------------------------------------------------------------------------------------------------
979 /** Sets the first four channels current object.
980 @param chanValues The values for the components
981 @return Returns a reference to the current color object.*/
982 inline colorTpl& setChans(clrChanTup4 chanValues) { /* Requires: Inherits numChan>3 from getC3. */
983 setC0(std::get<0>(chanValues));
984 setC1(std::get<1>(chanValues));
985 setC2(std::get<2>(chanValues));
986 return setC3(std::get<3>(chanValues));
987 }
988 //--------------------------------------------------------------------------------------------------------------------------------------------------------
989 /** Sets the first three channels current object.
990 @param chanValues The values for the components
991 @return Returns a reference to the current color object.*/
992 inline colorTpl& setChans(clrChanTup3 chanValues) { /* Requires: Inherits numChan>2 from getC2. */
993 setC0(std::get<0>(chanValues));
994 setC1(std::get<1>(chanValues));
995 return setC2(std::get<2>(chanValues));
996 }
997 //--------------------------------------------------------------------------------------------------------------------------------------------------------
998 /** This function sets color channels from the data in a std::vector.
999 @warning input vector must have at least #channelCount elements! This is *not* checked!
1000
1001 @param chanValues A std::vector containing the color channels.
1002 @return Returns a reference to the current color object.*/
1003 inline colorTpl& setChans(clrChanVec& chanValues) {
1004 for(int i=0; i<numChan; i++)
1005 setChanNC(i, chanValues[i]);
1006 return *this;
1007 }
1008 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1009 /** Sets the current color based upon the contents of the given color hex string.
1010 A color hex string is similar to the hash hex strings used in HTML, but extended to larger depths and higher channel counts.
1011
1012 #FF0000 -- Red for an RGB color with 8-bit per channels
1013 #FFFF00000000 -- Red for an RGB color with 16-bit per channels
1014 #FF0000EE -- Red for an RGBA color with 8-bit per channels (with alpha set to EE)
1015 #FFFFFFFFFF -- White for a 5 channel color with 8-bit per channels
1016 Fewer channel specifiers may be provided than channels in the current color, then the value of clearUndefinedChannels defines the behavior: NOOP or
1017 set them to #minChanVal. If the colorHexString is somehow invalid, then all channels are considered undefined, and the action is defined by the
1018 value of clearUndefinedChannels.
1019 @param colorHexString Hex string specifying a color.
1020 @param clearUndefinedChannels Specify error action and what to do with unspecified channels.
1021 @return Returns a reference to the current color object.*/
1022 inline colorTpl& setChans(std::string colorHexString, bool clearUndefinedChannels = false) {
1023 std::string::size_type sizeOfString = colorHexString.size();
1024 std::string::size_type digitsPerChan = bitsPerChan / 4;
1025 if (sizeOfString > 0) { // Not empty
1026 if (colorHexString[0] == '#') { // Starts with hash
1027 if (0 == ((sizeOfString-1) % digitsPerChan)) { // Has correct number of digits
1028 if (std::string::npos == colorHexString.find_first_not_of("0123456789abcdefABCDEF", 1)) { // All hex digits after the pound
1029 std::string::size_type numChanGiven = (sizeOfString-1) / digitsPerChan;
1030 if (numChan < numChanGiven)
1031 numChanGiven = numChan;
1032 std::string curHexStr(digitsPerChan, 1);
1033 for(std::string::size_type i=0; i<numChanGiven; i++) {
1034 for(std::string::size_type j=0; j<digitsPerChan; j++)
1035 curHexStr[j] = colorHexString[1+j+digitsPerChan*i];
1036 setChan(static_cast<int>(i), convertHexStringToChan(curHexStr));
1037 }
1038 if (clearUndefinedChannels && (numChanGiven < numChan))
1039 for(std::string::size_type i=numChanGiven; i<numChan; i++)
1040 setChanToMin(static_cast<int>(i));
1041 return *this;
1042 }
1043 }
1044 }
1045 }
1046 if (clearUndefinedChannels)
1047 return setToBlack();
1048 else
1049 return *this;
1050 }
1051 //@}
1052
1053 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1054 /** @name Set To Special Colors (RGB Corners)
1055 While the assumed color model is RGB, these functions are generalized beyond RGB in that non-RGB channels are uniformly, and usefully, manipulated.
1056 For example, setToBlack and setToWhite functions set all channels to minimum and maximum respectively -- both reasonable definitions for "black" and
1057 "white" in many situations. The "primary" colors (red, blue, and green) set all non-RGB channels to minimum, and the "secondary" colors (cyan,
1058 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
1059 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
1060 integer channels and good masks. 2) It makes each secondary an inverse (a logical NOT for integer colors) color from a primary across all
1061 channels. Note that the other functions in this group end with a call to one of the setTo*() functions. */
1062 //@{
1063 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1064 inline colorTpl& setToBlack() { setChansToMin(); return *this; }
1065 inline colorTpl& setToWhite() { setChansToMax(); return *this; }
1066 inline colorTpl& setToRed() { setChansToMin(); setChanToMax(0); return *this; }
1067 inline colorTpl& setToBlue() { setChansToMin(); setChanToMax(2); return *this; }
1068 inline colorTpl& setToGreen() { setChansToMin(); setChanToMax(1); return *this; }
1069 inline colorTpl& setToCyan() { setChansToMax(); setChanToMin(0); return *this; }
1070 inline colorTpl& setToYellow() { setChansToMax(); setChanToMin(2); return *this; }
1071 inline colorTpl& setToMagenta() { setChansToMax(); setChanToMin(1); return *this; }
1072 inline colorTpl& setToHalf() { setChansToMean(); return *this; }
1073 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1074 /** Set the current color based upon the single character given -- 0==black, R, G, B, M, C, Y, W/1==white).
1075 The color is acutally set using one of the setTo*() functions. If \a cornerColor is invalid, then setToBlack().
1076 @param cornerColor Character specifying the color
1077 @return Returns a reference to the current color object.*/
1078 inline colorTpl& setToCorner(char cornerColor) {
1079 /* This case is ordered by the frequency in which colors are generally encountered. This will vary for different applications. */
1080 switch(cornerColor) {
1081 case '0': return setToBlack(); break;
1082 case '1': [[fallthrough]];
1083 case 'w': [[fallthrough]];
1084 case 'W': return setToWhite(); break;
1085 case 'r': [[fallthrough]];
1086 case 'R': return setToRed(); break;
1087 case 'g': [[fallthrough]];
1088 case 'G': return setToGreen(); break;
1089 case 'b': [[fallthrough]];
1090 case 'B': return setToBlue(); break;
1091 case 'y': [[fallthrough]];
1092 case 'Y': return setToYellow(); break;
1093 case 'c': [[fallthrough]];
1094 case 'C': return setToCyan(); break;
1095 case 'm': [[fallthrough]];
1096 case 'M': return setToMagenta(); break;
1097 default: return setToBlack(); break;
1098 }
1099 }
1100 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1101 /** Set the color to the given corner color.
1102 The color is acutally set using one of the setTo*() functions. If \a cornerColor is invalid, then setToBlack().
1103 @param cornerColor Enum value specifying the color
1104 @return Returns a reference to the current color object.*/
1105 inline colorTpl& setToCorner(cornerColorEnum cornerColor) {
1106 /* This case is ordered by the frequency in which colors are generally encountered. This will vary for different applications. */
1107 switch(cornerColor) {
1108 case cornerColorEnum::BLACK: return setToBlack(); break;
1109 case cornerColorEnum::WHITE: return setToWhite(); break;
1110 case cornerColorEnum::RED: return setToRed(); break;
1111 case cornerColorEnum::GREEN: return setToGreen(); break;
1112 case cornerColorEnum::BLUE: return setToBlue(); break;
1113 case cornerColorEnum::YELLOW: return setToYellow(); break;
1114 case cornerColorEnum::CYAN: return setToCyan(); break;
1115 case cornerColorEnum::MAGENTA: return setToMagenta(); break;
1116 default: return setToBlack(); break; // Some compilers don't realize all cases are covered above...
1117 }
1118 return *this;
1119 }
1120 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1121 /** Set the color to the named corner color.
1122 If cornerColor is one character long, then the call is equivalent to setToCorner(cornerColor[0]). Otherwise a valid corner color name string is
1123 expected: red, blue, green, cyan, yellow, magenta, black, or white. If \a cornerColor is invalid, then setToBlack(). The color is actually set
1124 using one of the setTo*() functions.
1125 @param cornerColor String value specifying the color
1126 @return Returns a reference to the current color object.*/
1127 inline colorTpl& setToCorner(std::string cornerColor) {
1128 std::string::size_type sizeOfString = cornerColor.size();
1129 if (sizeOfString > 0) {
1130 if(((cornerColor[0] == 'b') || (cornerColor[0] == 'B')) && (sizeOfString > 0)) {
1131 if( (cornerColor[2]=='u') || (cornerColor[2]=='U') )
1132 return setToBlue();
1133 else
1134 return setToBlack();
1135 } else {
1136 return setToCorner(cornerColor[0]);
1137 }
1138 }
1139 return setToBlack();
1140 }
1141 //@}
1142
1143 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1144 /** @name Color Setting Methods via Logically Packed Integers.
1145 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.
1146 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
1147 derived from integer literals in C++ code. setRGBfromLogPackIntARGB() is heavily used for color schemes. */
1148 //@{
1149 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1150 /** Set the color based upon the bytes of the given integer ordered from LSB to MSB.
1151 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
1152 are interpreted as by setChans_byte. Any channels beyond four are left untouched.
1153 @param anInt The integer from which to extract bytes to set color
1154 @param rIdx Location of red byte in \a anInt
1155 @param gIdx Location of green byte in \a anInt
1156 @param bIdx Location of blue byte in \a anInt
1157 @param aIdx Location of alpha byte in \a anInt
1158 @return Returns a reference to the current color object.*/
1159 inline colorTpl& setRGBAfromLogPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx, uint8_t aIdx) {
1160 /* Requires: Inherits numChan>3 from setAlpha. */
1161 uint8_t bytes[4];
1162 bytes[0] = (0xFF & anInt); anInt = anInt >> 8;
1163 bytes[1] = (0xFF & anInt); anInt = anInt >> 8;
1164 bytes[2] = (0xFF & anInt); anInt = anInt >> 8;
1165 bytes[3] = (0xFF & anInt);
1166 setRed_byte( bytes[rIdx]);
1167 setGreen_byte(bytes[gIdx]);
1168 setBlue_byte( bytes[bIdx]);
1169 setAlpha_byte(bytes[aIdx]);
1170 return *this;
1171 }
1172 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1173 /** Just like setRGBAfromLogPackIntGen, but no A */
1174 inline colorTpl& setRGBfromLogPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx) {
1175 uint8_t bytes[4];
1176 /* Requires: Inherits numChan>2 from setBlue. */
1177 bytes[0] = (0xFF & anInt); anInt = anInt >> 8;
1178 bytes[1] = (0xFF & anInt); anInt = anInt >> 8;
1179 bytes[2] = (0xFF & anInt); anInt = anInt >> 8;
1180 bytes[3] = (0xFF & anInt);
1181 setRed_byte( bytes[rIdx]);
1182 setGreen_byte(bytes[gIdx]);
1183 setBlue_byte( bytes[bIdx]);
1184 return *this;
1185 }
1186 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1187 /* These four pixel formats (ARGB, RGBA, ABGR, & BGRA) are commonly used (SDL, OpenGL, ImageJ, etc...). Note we have two methods per pixel format --
1188 one for RGB & one for RGBA */
1189 inline colorTpl& setRGBAfromLogPackIntARGB(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 2, 1, 0, 3); } /* Requires: Inherits numChan>3 from setAlpha. */
1190 inline colorTpl& setRGBfromLogPackIntARGB( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 2, 1, 0); } /* Requires: Inherits numChan>2 from setBlue. */
1191 inline colorTpl& setRGBAfromLogPackIntRGBA(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 3, 2, 1, 0); } /* Requires: Inherits numChan>3 from setAlpha. */
1192 inline colorTpl& setRGBfromLogPackIntRGBA( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 3, 2, 1); } /* Requires: Inherits numChan>2 from setBlue. */
1193 inline colorTpl& setRGBAfromLogPackIntABGR(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 0, 1, 2, 3); } /* Requires: Inherits numChan>3 from setAlpha. */
1194 inline colorTpl& setRGBfromLogPackIntABGR( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 0, 1, 2); } /* Requires: Inherits numChan>2 from setBlue. */
1195 inline colorTpl& setRGBAfromLogPackIntBGRA(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 1, 2, 3, 0); } /* Requires: Inherits numChan>3 from setAlpha. */
1196 inline colorTpl& setRGBfromLogPackIntBGRA( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 1, 2, 3); } /* Requires: Inherits numChan>2 from setBlue. */
1197 /* This pixel format (ABRG) is used by POV-Ray for height fields */
1198 inline colorTpl& setRGBAfromLogPackIntABRG(packed4Cint anInt) { return setRGBAfromLogPackIntGen(anInt, 1, 0, 2, 3); } /* Requires: Inherits numChan>3 from setAlpha. */
1199 inline colorTpl& setRGBfromLogPackIntABRG( packed4Cint anInt) { return setRGBfromLogPackIntGen( anInt, 1, 0, 2); } /* Requires: Inherits numChan>2 from setBlue. */
1200 //@}
1201
1202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1203 /** @name TGA Height Maps for POVray */
1204 //@{
1205 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1206 /** Computes a 24-bit truecolor value intended for use in producing 16-bit greyscale TGA.
1207 This is the color scheme that should be used for POVray 16-bit height files
1208 @param tga16val An integer
1209 @return Returns a reference to the current color object. */
1210 inline colorTpl& setRGBcmpGreyTGA16bit(uint32_t tga16val) requires(chanIsByte) {
1211 /* Requires: Inherits numChan>1 from setGreen. */
1212 tga16val = mjr::math::ivl::wrapCC(tga16val, 0x0000FFFFu);
1213 return setRGBfromLogPackIntABRG(tga16val);
1214 // setChansToMin();
1215 // setGreen_byte(static_cast<clrChanT>( tga16val & 0xff)); // 0
1216 // setRed_byte( static_cast<clrChanT>((tga16val >> 8) & 0xff)); // 1
1217 // return *this;
1218 }
1219 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1220 /** Computes a 24-bit truecolor value intended for use in producing 24-bit greyscale TGA.
1221 @param tga24val An integer
1222 @return Returns a reference to the current color object. */
1223 inline colorTpl& setRGBcmpGreyTGA24bit(uint32_t tga24val) requires(chanIsByte) {
1224 /* Requires: Inherits numChan>2 from setBlue. */
1225 tga24val = mjr::math::ivl::wrapCC(tga24val, 0x00FFFFFFu);
1226 return setRGBfromLogPackIntABRG(tga24val);
1227 // setGreen_byte( tga24val & 0xff); // 0
1228 // setRed_byte( (tga24val >> 8) & 0xff); // 1
1229 // setBlue_byte( (tga24val >> 16) & 0xff); // 2
1230 // return *this;
1231 } //BRG
1232 //@}
1233
1234 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1235 /** @name Color Setting Methods via Physically Packed Integers.
1236 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. */
1237 //@{
1238 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1239 /** Set the color based upon the bytes of the given integer ordered as in RAM.
1240 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
1241 as by setChans_byte. Any channels beyond four are left untouched.
1242 @param anInt The integer from which to extract bytes to set color
1243 @param rIdx Location of red byte in \a anInt
1244 @param gIdx Location of green byte in \a anInt
1245 @param bIdx Location of blue byte in \a anInt
1246 @param aIdx Location of alpha byte in \a anInt
1247 @return Returns a reference to the current color object.*/
1248 inline colorTpl& setRGBAfromPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx, uint8_t aIdx) {
1249 /* Requires: Inherits numChan>3 from setAlpha. */
1250 uint8_t *curByte = (uint8_t *)(&anInt);
1251 setRed_byte( curByte[rIdx]);
1252 setGreen_byte(curByte[gIdx]);
1253 setBlue_byte( curByte[bIdx]);
1254 setAlpha_byte(curByte[aIdx]);
1255 return *this;
1256 }
1257 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1258 /** Just like setRGBAfromPackIntGen, but no A */
1259 inline colorTpl& setRGBfromPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx) {
1260 /* Requires: Inherits numChan>2 from setBlue. */
1261 uint8_t *curByte = (uint8_t *)(&anInt);
1262 setRed_byte( curByte[rIdx]);
1263 setGreen_byte(curByte[gIdx]);
1264 setBlue_byte( curByte[bIdx]);
1265 return *this;
1266 }
1267 //@}
1268
1269 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1270 /** @name Setting Colors Based Upon Other Color Spaces
1271 Other Colorspaces.
1272 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
1273 alternate colorspaces computations all take place with double floating point values. Various other tools are also available for manipulating colors
1274 in other colorspaces (see: interplColorSpace() and rgb2colorSpace() for example).. See the #colorSpaceEnum for details regarding supported colorspaces. */
1275 //@{
1276 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1277 /** Set the color indicated by the given HSV values.
1278 The 'unit' in the name indicates that the values for h, s, and v are the unit interval, [0,1].
1279 @param H The Hue.
1280 @param S The Saturation.
1281 @param V The Value
1282 @return Returns a reference to the current color object. */
1283 inline colorTpl& setRGBfromUnitHSV(double H, double S, double V) { return setRGBfromColorSpace(colorSpaceEnum::HSV, H*360.0, S, V); }
1284 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1285 /** Set the color indicated by the given HSL values.
1286 The 'unit' in the name indicates that The ranges for h, s, and v are the the unit interval -- i.e. [0,1].
1287 @param H The Hue.
1288 @param S The Saturation.
1289 @param L The Lightness or Luminescence
1290 @return Returns a reference to the current color object. */
1291 inline colorTpl& setRGBfromUnitHSL(double H, double S, double L) { return setRGBfromColorSpace(colorSpaceEnum::HSL, H*360.0, S, L); }
1292 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1293 /** Set the color indicated by the color space and values.
1294 @param space The colorspace
1295 @param inCh1 Channel one value for given colorspace
1296 @param inCh2 Channel two value for given colorspace
1297 @param inCh3 Channel three value for given colorspace
1298 @return Returns a reference to the current color object. */
1299 inline colorTpl& setRGBfromColorSpace(colorSpaceEnum space, double inCh1, double inCh2, double inCh3) {
1300 // Note: If space==RGB => C0==R, C1=G, C2=B regardless of redChan, blueChan, & greenChan.
1301 double outR = 0.0, outG = 0.0, outB = 0.0;
1302 if (space == colorSpaceEnum::HSL) {
1303 if( (inCh3 >= 0.0) && (inCh3 <= 1.0) && (inCh2 >= 0.0) && (inCh2 <= 1.0) ) {
1304 double H = mjr::math::ivl::wrapCO(inCh1, 360.0);
1305 const double epsilon = 0.000001;
1306 double m1, m2;
1307 if(inCh3 <= 0.5)
1308 m2 = inCh3 * (1.0 + inCh2);
1309 else
1310 m2 = inCh3 + inCh2 - inCh3 * inCh2;
1311 m1 = 2.0 * inCh3 - m2;
1312 if(inCh2 < epsilon) {
1313 outR = inCh3;
1314 outG = inCh3;
1315 outB = inCh3;
1316 } else {
1317 outR = mjr::math::ivl::unit_clamp(hslHelperVal(m1, m2, H+120));
1318 outG = mjr::math::ivl::unit_clamp(hslHelperVal(m1, m2, H));
1319 outB = mjr::math::ivl::unit_clamp(hslHelperVal(m1, m2, H-120));
1320 }
1321 }
1322 } else if ((space == colorSpaceEnum::LAB) || (space == colorSpaceEnum::XYZ) || (space == colorSpaceEnum::LCH)) {
1323 double X, Y, Z;
1324 if (space == colorSpaceEnum::XYZ) {
1325 X = inCh1 / 100.0;
1326 Y = inCh2 / 100.0;
1327 Z = inCh3 / 100.0;
1328 } else {
1329 Y = ( inCh1 + 16.0 ) / 116.0;
1330 if (space == colorSpaceEnum::LCH) {
1331 X = std::cos(inCh3 * std::numbers::pi / 180.0) * inCh2 / 500.0 + Y;
1332 Z = Y - std::sin(inCh3 * std::numbers::pi / 180.0) * inCh2 / 200.0;
1333 } else {
1334 X = inCh2 / 500.0 + Y;
1335 Z = Y - inCh3 / 200.0;
1336 }
1337 X = (X > 0.206893034423 ? std::pow(X, 3) : ( X - 16.0 / 116.0 ) / 7.787) * 95.047 / 100.0;
1338 Y = (Y > 0.206893034423 ? std::pow(Y, 3) : ( Y - 16.0 / 116.0 ) / 7.787) * 100.000 / 100.0;
1339 Z = (Z > 0.206893034423 ? std::pow(Z, 3) : ( Z - 16.0 / 116.0 ) / 7.787) * 108.883 / 100.0;
1340 }
1341 outR = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
1342 outG = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
1343 outB = X * 0.0557 + Y * -0.2040 + Z * 1.0570;
1344 outR = mjr::math::ivl::unit_clamp((outR > 0.0031308 ? 1.055 * std::pow(outR, 1.0 / 2.4) - 0.055 : 12.92 * outR));
1345 outG = mjr::math::ivl::unit_clamp((outG > 0.0031308 ? 1.055 * std::pow(outG, 1.0 / 2.4) - 0.055 : 12.92 * outG));
1346 outB = mjr::math::ivl::unit_clamp((outB > 0.0031308 ? 1.055 * std::pow(outB, 1.0 / 2.4) - 0.055 : 12.92 * outB));
1347 } else if (space == colorSpaceEnum::RGB) {
1348 outR = mjr::math::ivl::unit_clamp(inCh1);
1349 outG = mjr::math::ivl::unit_clamp(inCh2);
1350 outB = mjr::math::ivl::unit_clamp(inCh3);
1351 } else if (space == colorSpaceEnum::HSV) {
1352 double t;
1353 double f = static_cast<double>(std::modf(inCh1 * 6.0 / 360.0, &t));
1354 int i = static_cast<int>(t) % 6;
1355 double p = inCh3 * (1 - inCh2);
1356 double q = inCh3 * (1 - inCh2 * f);
1357 double u = inCh3 * (1 - (inCh2 * (1 - f)));
1358 double w = inCh3;
1359 switch (i) {
1360 case 0: outR = mjr::math::ivl::unit_clamp(w); outG = mjr::math::ivl::unit_clamp(u); outB = mjr::math::ivl::unit_clamp(p); break;
1361 case 1: outR = mjr::math::ivl::unit_clamp(q); outG = mjr::math::ivl::unit_clamp(w); outB = mjr::math::ivl::unit_clamp(p); break;
1362 case 2: outR = mjr::math::ivl::unit_clamp(p); outG = mjr::math::ivl::unit_clamp(w); outB = mjr::math::ivl::unit_clamp(u); break;
1363 case 3: outR = mjr::math::ivl::unit_clamp(p); outG = mjr::math::ivl::unit_clamp(q); outB = mjr::math::ivl::unit_clamp(w); break;
1364 case 4: outR = mjr::math::ivl::unit_clamp(u); outG = mjr::math::ivl::unit_clamp(p); outB = mjr::math::ivl::unit_clamp(w); break;
1365 case 5: outR = mjr::math::ivl::unit_clamp(w); outG = mjr::math::ivl::unit_clamp(p); outB = mjr::math::ivl::unit_clamp(q); break;
1366 default: outR = 0.0 ; outG = 0.0 ; outB = 0.0 ; break;
1367 }
1368 } else {
1369 std::cerr << "ERROR: Unsupported color space used in setRGBfromColorSpace!" << std::endl;
1370 }
1371 setChansRGB(static_cast<clrChanT>(maxChanVal * outR),
1372 static_cast<clrChanT>(maxChanVal * outG),
1373 static_cast<clrChanT>(maxChanVal * outB));
1374 return *this;
1375 }
1376 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1377 /** @overload */
1379 /* Requires: Inherits numChan>2 from getC2. */
1380 /* This use of getC0/getC1/getC2 for RGB is OK -- that is how colConDbl3 objects work */
1381 return setRGBfromColorSpace(space, inColor.getC0(), inColor.getC1(), inColor.getC2());
1382 }
1383 //@}
1384
1385 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1386 /** @name Setting Colors Based Upon Spectral Color */
1387 //@{
1388 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1389 /** Set the color indicated by the given wavelength.
1390 This function uses an algorithm based upon the color matching functions as tabulated in table 3 from Stockman and Sharpe (2000) -- I believe they
1391 are taken from Stiles and Burch 10-degree (1959). Four of the algorithms are based upon simple linear interpolation, while one is based upon
1392 exponential bump functions closely matching the color matching functions. The method of interpolation may be specified via the final argument.
1393
1394 @warning If you are looking for a wavelength color scheme, then see the csRainbowCM class: http://richmit.github.io/mraster/ColorSchemes.html
1395
1396 @param wavelength The wavelength to convert into RGB
1397 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
1398 @return Returns a reference to the current color object. */
1399 inline colorTpl& setRGBfromWavelengthCM(double wavelength, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
1400 // Color matching function table & metadata.
1401 // Tabulated in table 3 from Stockman and Sharpe (2000). I beleive they are taken from Stiles and Burch 10-degree (1959)
1402 const double minWL = 390.0; // Min wavelength in table
1403 const double maxWL = 830.0; // Max wavelength in table
1404 const int numPT = 89; // Number fo points in the table
1405 const double rScl = 3.1673; // Scale factors for color function
1406 const double gScl = 1.0517;
1407 const double bScl = 1.0019;
1408 const static int cmfW[] = { 390, 395, 400, 405, 410, 415, 420, 425, 430,
1409 435, 440, 445, 450, 455, 460, 465, 470, 475,
1410 480, 485, 490, 495, 500, 505, 510, 515, 520,
1411 525, 530, 535, 540, 545, 550, 555, 560, 565,
1412 570, 575, 580, 585, 590, 595, 600, 605, 610,
1413 615, 620, 625, 630, 635, 640, 645, 650, 655,
1414 660, 665, 670, 675, 680, 685, 690, 695, 700,
1415 705, 710, 715, 720, 725, 730, 735, 740, 745,
1416 750, 755, 760, 765, 770, 775, 780, 785, 790,
1417 795, 800, 805, 810, 815, 820, 825, 830 };
1418 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,
1419 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,
1420 -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,
1421 -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,
1422 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,
1423 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,
1424 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,
1425 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,
1426 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,
1427 3.7700E-05, 2.7600E-05, 2.0300E-05, 1.4900E-05, 1.1000E-05, 8.1800E-06, 6.0900E-06, 4.5500E-06 };
1428 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,
1429 -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,
1430 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,
1431 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,
1432 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,
1433 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,
1434 -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,
1435 -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,
1436 -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,
1437 -1.3700E-07, -8.8000E-08, -5.5300E-08, -3.3600E-08, -1.9600E-08, -1.0900E-08, -5.7000E-09, -2.7700E-09 };
1438 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,
1439 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,
1440 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,
1441 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,
1442 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,
1443 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,
1444 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,
1445 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,
1446 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,
1447 1.5000E-09, 9.8600E-10, 6.3900E-10, 4.0700E-10, 2.5300E-10, 1.5200E-10, -8.6400E-11, 4.4200E-11 };
1448
1449 // Clip the wavelength to be in range
1450 wavelength = std::clamp(wavelength, minWL, maxWL);
1451
1452 // Figure out where we are in our color function table
1453 double fIdx = (wavelength-minWL)/(maxWL-minWL)*(numPT-1.0);
1454 int iIdx1 = static_cast<int>(fIdx);
1455 int iIdx2 = iIdx1+1;
1456
1457 // If we fell off the edge, then we set our indexes to the appropriate edge
1458 if(iIdx2>(numPT-1)) { iIdx1 = numPT-2; iIdx2 = numPT-1; fIdx = static_cast<double>(iIdx1); }
1459 if(iIdx1<0) { iIdx1 = 0; iIdx2 = 1; fIdx = static_cast<double>(iIdx1); }
1460
1461 // Interpolate using our tabulated color matching function
1462 double rf, gf, bf;
1463 switch(interpMethod) {
1464 case cmfInterpolationEnum::FLOOR : // Closest with wavelength lower than given value
1465 rf=cmfR[iIdx1];
1466 gf=cmfG[iIdx1];
1467 bf=cmfB[iIdx1];
1468 break;
1469 case cmfInterpolationEnum::CEILING : // Closest with wavelength greater than given value
1470 rf=cmfR[iIdx2];
1471 gf=cmfG[iIdx2];
1472 bf=cmfB[iIdx2];
1473 break;
1474 case cmfInterpolationEnum::NEAREST : // Closest with wavelength to given value
1475 if( std::abs(wavelength-cmfW[iIdx2]) < std::abs(wavelength-cmfW[iIdx1])) {
1476 rf=cmfR[iIdx2];
1477 gf=cmfG[iIdx2];
1478 bf=cmfB[iIdx2];
1479 } else {
1480 rf=cmfR[iIdx1];
1481 gf=cmfG[iIdx1];
1482 bf=cmfB[iIdx1];
1483 }
1484 break;
1485 case cmfInterpolationEnum::LINEAR : // Linear interpolation between data points
1486 rf = (fIdx-static_cast<double>(iIdx1)) * (cmfR[iIdx2] - cmfR[iIdx1]) + cmfR[iIdx1];
1487 gf = (fIdx-static_cast<double>(iIdx1)) * (cmfG[iIdx2] - cmfG[iIdx1]) + cmfG[iIdx1];
1488 bf = (fIdx-static_cast<double>(iIdx1)) * (cmfB[iIdx2] - cmfB[iIdx1]) + cmfB[iIdx1];
1489 break;
1490 case cmfInterpolationEnum::BUMP : // Use exponential hump functions -- MJR developed algorithm 2007
1491 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));
1492 gf = 1.05 / std::exp(0.0004 * (wavelength-540.0)*(wavelength-540.0));
1493 bf = 1.00 / std::exp(0.0010 * (wavelength-450.0)*(wavelength-450.0));
1494 break;
1495 default:
1496 rf = gf = bf = 0.0;
1497 break;
1498 }
1499
1500 // Make them positive and scale to a [0,1] range
1501 rf=(rf>0.0 ? rf : 0.0)/rScl;
1502 gf=(gf>0.0 ? gf : 0.0)/gScl;
1503 bf=(bf>0.0 ? bf : 0.0)/bScl;
1504
1505 // We are done. Set the color and exit.
1506 setChansRGB_dbl(rf, gf, bf);
1507 return *this;
1508 }
1509 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1510 /** Set the color indicated by the given wavelength.
1511 This function uses an algorithm based upon linear approximations to the color match functions. I believe the original algorithm is due to Dan
1512 Bruton, and his FORTRAN version is available (at least as of 1997) at http://www.physics.sfasu.edu/astro/color.html
1513
1514 @warning If you are looking for a wavelength color scheme, then see the csRainbowLA class: http://richmit.github.io/mraster/ColorSchemes.html
1515
1516 @param wavelength to convert
1517 @return Returns a reference to the current color object. */
1518 inline colorTpl& setRGBfromWavelengthLA(double wavelength) {
1519 double rf, gf, bf;
1520
1521 const double minWL = 380.0; // Min wavelength in table
1522 const double maxWL = 780.0; // Max wavelength in table
1523
1524 // Clip the wavelength to be in range
1525 if(wavelength < minWL)
1526 wavelength = minWL;
1527 if(wavelength > maxWL)
1528 wavelength = maxWL;
1529
1530 // Compute color match functions.
1531 rf = gf = bf = 0;
1532 if ( (wavelength >= 380) && (wavelength < 440)) {
1533 rf = (440-wavelength)/(440-380);
1534 gf = 0.0;
1535 bf = 1.0;
1536 } else if( (wavelength >= 440) && (wavelength < 490)) {
1537 rf = 0.0;
1538 gf = (wavelength-440)/(490-440);
1539 bf = 1.0;
1540 } else if( (wavelength >= 490) && (wavelength < 510)) {
1541 rf = 0.0;
1542 gf = 1.0;
1543 bf = (510-wavelength)/(510-490);
1544 } else if( (wavelength >= 510) && (wavelength < 580)) {
1545 rf = (wavelength-510)/(580-510);
1546 gf = 1.0;
1547 bf = 0.0;
1548 } else if( (wavelength >= 580) && (wavelength < 645)) {
1549 rf = 1.0;
1550 gf = (645-wavelength)/(645-580);
1551 bf = 0.0;
1552 } else if( (wavelength >= 645) && (wavelength <= 780)) {
1553 rf = 1.0;
1554 gf = 0.0;
1555 bf = 0.0;
1556 }
1557
1558 /* Lower the intensity near edges of vision. */
1559 double edgeIntensityAdj;
1560 if(wavelength > 700.0) {
1561 edgeIntensityAdj=0.3 + 0.7 * (780-wavelength)/(780-700);
1562 } else if(wavelength < 420.0) {
1563 edgeIntensityAdj=0.3 + 0.7 * (wavelength - 380)/(420-380);
1564 } else {
1565 edgeIntensityAdj=1.0;
1566 }
1567
1568 return setChansRGB_dbl(edgeIntensityAdj*rf, edgeIntensityAdj*gf, edgeIntensityAdj*bf);
1569 }
1570 //@}
1571
1572 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1573 /** @name Color Ramps, Gradients, Interpolation, Binary Thresholds.
1574 Members in this section form the computational foundation for many of the named color schemes found in this class. */
1575 //@{
1576 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1577 /** 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.
1578 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
1579 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
1580 poor performance -- both due to the use of floating point arithmetic. Note this function operates correctly with any channel type and with an
1581 arbitrary number of channels -- it is NOT limited to RGB colors or RGB color corners for anchors.
1582
1583 @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
1584 directly. In fact, the first step might be to see if a suitable gradient color scheme is already are predefined:
1585 http://richmit.github.io/mraster/ColorSchemes.html
1586
1587 @param csX The value to convert
1588 @param anchors Doubles for which color equals the corresponding corner.
1589 @param colors A vector of colors to use
1590 @return A reference to this object */
1591 inline colorTpl& cmpGradiant(csFltType csX, std::vector<csFltType > const& anchors, std::vector<colorType> const& colors) {
1592 typename std::vector<colorType>::size_type numColors = colors.size();
1593 if((numColors >= 2) && (anchors.size() == numColors)) {
1594 for(typename std::vector<colorType>::size_type i=0; i<(numColors-1); i++) {
1595 csFltType lowAnchor = anchors[i];
1596 csFltType highAnchor = anchors[i+1];
1597 if( (csX >= lowAnchor) && (csX <= highAnchor) ) {
1598 return linearInterpolate(std::abs((csX-lowAnchor)/(highAnchor-lowAnchor)), colors[i], colors[i+1]);
1599 }
1600 }
1601 }
1602 return *this;
1603 }
1604 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1605 /** Identical to the other cmpGradiant() function except that equidistant anchors are automatically generated on [0, 1] for the given colors array. */
1606 inline colorTpl& cmpGradiant(csFltType csX, std::vector<colorType> const& colors) {
1607 typename std::vector<colorType>::size_type numColors = colors.size();
1608 if(numColors >= 2) {
1609 for(typename std::vector<colorType>::size_type i=0; i<(numColors-1); i++) {
1610 csFltType lowAnchor = static_cast<csFltType>(i) / static_cast<csFltType>(numColors-1);
1611 csFltType highAnchor = static_cast<csFltType>(i+1)/ static_cast<csFltType>(numColors-1);
1612 if( (csX >= lowAnchor) && (csX <= highAnchor) ) {
1613 return linearInterpolate(std::abs((csX-lowAnchor)/(highAnchor-lowAnchor)), colors[i], colors[i+1]);
1614 }
1615 }
1616 }
1617 return *this;
1618 }
1619 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1620 /** Identical to the other equidistant cmpGradiant() function except that this one works on just the RGB channels and takes an array of packed integers. */
1621 inline colorTpl& cmpGradiant(csFltType csX, csIntType numColors, const packed4Cint* colors) {
1622 if(numColors >= 2) {
1623 for(csIntType i=0; i<(numColors-1); i++) {
1624 csFltType lowAnchor = static_cast<csFltType>(i) / static_cast<csFltType>(numColors-1);
1625 csFltType highAnchor = static_cast<csFltType>(i+1)/ static_cast<csFltType>(numColors-1);
1626 if( (csX >= lowAnchor) && (csX <= highAnchor) ) {
1627 colorTpl c1;
1628 colorTpl c2;
1629 c1.setRGBfromLogPackIntARGB(colors[i]);
1630 c2.setRGBfromLogPackIntARGB(colors[i+1]);
1631 return linearInterpolateRGB(std::abs((csX-lowAnchor)/(highAnchor-lowAnchor)), c1, c2);
1632 }
1633 }
1634 }
1635 return *this;
1636 }
1637 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1638 /** This is simply a version of cmpRGBcornerCGradiant() that computes the length of the final argument as a C-string.
1639 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
1640 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1641
1642 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1643
1644 @param csX The value to convert
1645 @param cornerColors Characters specifying color (as used by setColor)
1646 @return A reference to this object */
1647 inline colorTpl& cmpRGBcornerCGradiant(csFltType csX, const char *cornerColors) {
1648 return cmpRGBcornerCGradiant(csX, static_cast<csIntType>(std::strlen(cornerColors)), cornerColors);
1649 }
1650 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1651 /** This is simply a version of cmpRGBcornerDGradiant() that computes the length of the final argument as a C-string.
1652 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
1653 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1654
1655 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1656
1657 @param csIdx The value to convert
1658 @param cornerColors Characters specifying color (as used by setColor)
1659 @return A reference to this object */
1660 inline colorTpl& cmpRGBcornerDGradiant(csIntType csIdx, const char *cornerColors) {
1661 return cmpRGBcornerDGradiant(csIdx, static_cast<csIntType>(std::strlen(cornerColors)), cornerColors);
1662 }
1663 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1664 /** Color value based upon a color ramp passing through the given sequence of corner colors at equal intervals along [0, (mjr::colorTpl::chanStepMax *
1665 (numColors - 1) + 1)]. At 0, the color will be the first specified color. At (mjr::colorTpl::chanStepMax * ( numColors - 1) + 1) it will be the
1666 last color specified color. This function uses precise integer arithmetic. cornerColors need not be a real C-string -- i.e. no need for an
1667 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1668
1669 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1670
1671 @param csIdx The value to convert
1672 @param numColors The number of colors
1673 @param cornerColors An array of things that can be passed to setToCorner() -- usually char or cornerColorEnum
1674 @return A reference to this object */
1675 template <typename ccT>
1676 inline colorTpl& cmpRGBcornerDGradiant(csIntType csIdx, csIntType numColors, const ccT* cornerColors) {
1677 csIdx = mjr::math::ivl::wrapCC(csIdx, static_cast<csIntType>(chanStepMax * numColors - chanStepMax)); // First wrap to the total color count
1678 csIntType edgeNum = csIdx / chanStepMax;
1679 if (edgeNum == (numColors-1)) {
1680 edgeNum = edgeNum - 1;
1681 csIdx = chanStepMax;
1682 } else {
1683 csIdx = csIdx % chanStepMax;
1684 }
1685 colorTpl c1;
1686 colorTpl c2;
1687 c1.setToCorner(cornerColors[edgeNum]);
1688 c2.setToCorner(cornerColors[edgeNum+1]);
1689 for (int j : {redChan, greenChan, blueChan}) {
1690 csIntType cVal;
1691 if(c1.getChan(j) > c2.getChan(j)) {
1692 cVal = chanStepMax - csIdx;
1693 } else if(c1.getChan(j) < c2.getChan(j)) {
1694 cVal = csIdx;
1695 } else {
1696 cVal = ( c1.getChan(j) > 0 ? chanStepMax : 0);
1697 }
1698 if (chanIsFloat)
1699 setChan(j, static_cast<clrChanT>(cVal) / static_cast<clrChanT>(chanStepMax));
1700 else
1701 setChan(j, static_cast<clrChanT>(cVal));
1702 }
1703 return *this;
1704 }
1705 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1706 /** 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
1707 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
1708 terminating NULL. Note this function uses RGB corner colors as anchors, and is thus designed to work with RGB colors.
1709
1710 @warning Many gradient color schemes are predefined: http://richmit.github.io/mraster/ColorSchemes.html
1711
1712 @param csX The value to convert
1713 @param numColors The number of colors
1714 @param cornerColors An array of things that can be passed to setToCorner() -- usually char or cornerColorEnum
1715 @return A reference to this object */
1716 template <typename ccT>
1717 inline colorTpl& cmpRGBcornerCGradiant(csFltType csX, csIntType numColors, const ccT* cornerColors) {
1718 /* 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
1719 the optimizer will figure it out someday... The optimizer works in strange ways. */
1720 if(numColors >= 2) {
1721 csX = mjr::math::ivl::wrapCC(csX, static_cast<csFltType>(1));
1722 csFltType mF = csX * static_cast<csFltType>(numColors - 1);
1723 csIntType mI = static_cast<csIntType>(mF);
1724 if (mI >= (numColors-2)) mI=numColors-2;
1725 colorTpl c1;
1726 colorTpl c2;
1727 c1.setToCorner(cornerColors[mI]);
1728 c2.setToCorner(cornerColors[mI+1]);
1729 return linearInterpolate(mF-static_cast<csFltType>(mI), c1, c2);
1730 } else {
1731 return *this;
1732 }
1733 }
1734 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1735 /** Set the current color to a value linearly interpolated between the two given colors.
1736 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
1737 converted to HSL, the interpolation is done, and the result is converted back to RGB and the current color is set. Unlike linearInterpolate, this
1738 function will NOT interpolate every channel. Rather, as this function deals specifically with RGB and HSL space, only the RGB channels will be
1739 interpolated.
1740 @param space The color space to use
1741 @param aDouble The distance from col1
1742 @param col1 The starting color
1743 @param col2 The ending color
1744 @return Returns a reference to the current color object.*/
1745 inline colorTpl& interplColorSpace(colorSpaceEnum space, double aDouble, colorArgType col1, colorArgType col2) {
1746 /* Requires: Inherits numChan>2 from getC2. */
1747 /* This use of getC0/getC1/getC2 for RGB is OK -- that is how colConDbl3 objects work */
1748 if( (aDouble >= 0.0) && (aDouble <= 1.0) ) {
1749 // Convert our given colors into HSL
1750 colConDbl3 acol1 = col1.rgb2colorSpace(space);
1751 colConDbl3 acol2 = col2.rgb2colorSpace(space);
1752
1753 // Interpolate values
1754 double out1, out2, out3;
1755 if ((space == colorSpaceEnum::HSL) || (space == colorSpaceEnum::HSV))
1756 out1 = mjr::math::linm::interpolate_degrees(acol1.getC0(), acol2.getC0(), aDouble);
1757 else
1758 out1 = mjr::math::linm::interpolate(acol1.getC0(), acol2.getC0(), aDouble);
1759 out2 = mjr::math::linm::interpolate(acol1.getC1(), acol2.getC1(), aDouble);
1760 if (space == colorSpaceEnum::LCH)
1761 out3 = mjr::math::linm::interpolate_degrees(acol1.getC2(), acol2.getC2(), aDouble);
1762 else
1763 out3 = mjr::math::linm::interpolate(acol1.getC2(), acol2.getC2(), aDouble);
1764
1765 // Set color
1766 setRGBfromColorSpace(space, out1, out2, out3);
1767 }
1768 // Return
1769 return *this;
1770 }
1771 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1772 /** Compute the weighted mean of the given colors.
1773
1774 @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.
1775
1776 @param w1 The first weight
1777 @param w2 The second weight
1778 @param w3 The third weight
1779 @param w4 The fourth weight
1780 @param col1 The first color
1781 @param col2 The second color
1782 @param col3 The third color
1783 @param col4 The fourth color
1784 @return Returns a reference to the current color object. */
1785 inline colorTpl& wMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3, channelArithFltType w4,
1786 colorArgType col1, colorArgType col2, colorArgType col3, colorArgType col4) {
1787 for(int i=0; i<numChan; i++)
1788 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithFltType>(col1.getChanNC(i)) * w1) +
1789 (static_cast<channelArithFltType>(col2.getChanNC(i)) * w2) +
1790 (static_cast<channelArithFltType>(col3.getChanNC(i)) * w3) +
1791 (static_cast<channelArithFltType>(col4.getChanNC(i)) * w4)));
1792
1793 return *this;
1794 }
1795 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1796 /** @overload */
1797 inline colorTpl& wMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3,
1798 colorArgType col1, colorArgType col2, colorArgType col3) {
1799 for(int i=0; i<numChan; i++)
1800 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithFltType>(col1.getChanNC(i)) * w1) +
1801 (static_cast<channelArithFltType>(col2.getChanNC(i)) * w2) +
1802 (static_cast<channelArithFltType>(col3.getChanNC(i)) * w3)));
1803 return *this;
1804 }
1805 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1806 /** @overload */
1807 inline colorTpl& wMean(channelArithFltType w1, channelArithFltType w2, colorArgType col1, colorArgType col2) {
1808 for(int i=0; i<numChan; i++)
1809 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithFltType>(col1.getChanNC(i)) * w1) +
1810 (static_cast<channelArithFltType>(col2.getChanNC(i)) * w2)));
1811 return *this;
1812 }
1813 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1814 /** Compute the unit weighted mean of the given colors -- like wMean(), but last weight is computed such that weights sum to 1.0.
1815 @param w1 The first weight in the range [0, 1) -- the range not checked!
1816 @param w2 The second weight in the range [0, 1) -- the range not checked!
1817 @param w3 The third weight in the range [0, 1) -- the range not checked!
1818 @param col1 The first color
1819 @param col2 The second color
1820 @param col3 The third color
1821 @param col4 The fourth color
1822 @return Returns a reference to the current color object. */
1823 inline colorTpl& uMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3,
1824 colorArgType col1, colorArgType col2, colorArgType col3, colorArgType col4) {
1825 return wMean(w1, w2, w3, 1-w1-w2-w3, col1, col2, col3, col4);
1826 }
1827 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1828 /** @overload */
1829 inline colorTpl& uMean(channelArithFltType w1, channelArithFltType w2, colorArgType col1, colorArgType col2, colorArgType col3) {
1830 return wMean(w1, w2, 1-w1-w2, col1, col2, col3);
1831 }
1832 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1833 /** @overload */
1834 inline colorTpl& uMean(channelArithFltType w1, colorArgType col1, colorArgType col2) {
1835 return wMean(w1, 1-w1, col1, col2);
1836 }
1837 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1838 /** Set the current color to a value linearly interpolated between the two given colors.
1839 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
1840 conversions and as few type conversions as possible.
1841 @param aDouble The distance from col1
1842 @param col1 The starting color
1843 @param col2 The ending color
1844 @return Returns a reference to the current color object.*/
1845 inline colorTpl& linearInterpolate(double aDouble, colorArgType col1, colorArgType col2) {
1846 if( (aDouble >= 0.0) && (aDouble <= 1.0) )
1847 for(int i=0; i<numChan; i++)
1848 setChanNC(i, static_cast<clrChanT>(mjr::math::linm::interpolate(static_cast<double>(col1.getChanNC(i)), static_cast<double>(col2.getChanNC(i)), aDouble)));
1849 return *this;
1850 }
1851 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1852 /** Set the RGB channels of the current color to a value linearly interpolated between the two given colors.
1853 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
1854 conversions and as few type conversions as possible.
1855 @param aDouble The distance from col1
1856 @param col1 The starting color
1857 @param col2 The ending color
1858 @return Returns a reference to the current color object.*/
1859 inline colorTpl& linearInterpolateRGB(double aDouble, colorArgType col1, colorArgType col2) {
1860 if( (aDouble >= 0.0) && (aDouble <= 1.0) )
1861 for (int i : {redChan, blueChan, greenChan})
1862 setChanNC(i, static_cast<clrChanT>(mjr::math::linm::interpolate(static_cast<double>(col1.getChanNC(i)), static_cast<double>(col2.getChanNC(i)), aDouble)));
1863 return *this;
1864 }
1865 //@}
1866
1867 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1868 /** @name Logical Operators */
1869 //@{
1870 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1871 /** Performs a logical OR with the current object and the given object and places the value in the current object.
1872 @param aCol The color to use in the computation.
1873 @return Returns a reference to the current color object.*/
1874 inline colorTpl& tfrmOr(colorArgType aCol) requires (std::integral<clrChanT>) {
1875 if(goodMask)
1876 setMaskNC(getMaskNC() | aCol.getMaskNC());
1877 else
1878 for(int i=0; i<numChan; i++)
1879 setChanNC(i, getChanNC(i) | aCol.getChanNC(i));
1880 return *this;
1881 }
1882#if !(MISSING_P0476R2)
1883 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1884 /** Template specialization member function differing from the above function only in supported template conditions. */
1885 inline colorTpl& tfrmOr(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1886 /* Performance: Yep. Sometimes floating point colors get a goodMask. */
1887 if(goodMask)
1888 setMaskNC(getMaskNC() | aCol.getMaskNC());
1889 else
1890 for(int i=0; i<numChan; i++)
1891 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) | std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
1892 return *this;
1893 }
1894#endif
1895 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1896 /** Performs a logical NOR with the current object and the given object and places the value in the current object.
1897 @param aCol The color to use in the computation.
1898 @return Returns a reference to the current color object.*/
1899 inline colorTpl& tfrmNor(colorArgType aCol) requires (std::integral<clrChanT>) {
1900 if(goodMask)
1901 setMaskNC(~(getMaskNC() | aCol.getMaskNC()));
1902 else
1903 for(int i=0; i<numChan; i++)
1904 setChanNC(i, ~(getChanNC(i) | aCol.getChanNC(i)));
1905 return *this;
1906 }
1907#if !(MISSING_P0476R2)
1908 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1909 /** Template specialization member function differing from the above function only in supported template conditions. */
1910 inline colorTpl& tfrmNor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1911 if(goodMask)
1912 setMaskNC(~(getMaskNC() | aCol.getMaskNC()));
1913 else
1914 for(int i=0; i<numChan; i++)
1915 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) | std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
1916 return *this;
1917 }
1918#endif
1919 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1920 /** Performs a logical AND with the current object and the given object and places the value in the current object.
1921 @param aCol The color to use in the computation.
1922 @return Returns a reference to the current color object.*/
1923 inline colorTpl& tfrmAnd(colorArgType aCol) requires (std::integral<clrChanT>) {
1924 if(goodMask)
1925 setMaskNC(getMaskNC() & aCol.getMaskNC());
1926 else
1927 for(int i=0; i<numChan; i++)
1928 setChanNC(i, getChanNC(i) & aCol.getChanNC(i));
1929 return *this;
1930 }
1931#if !(MISSING_P0476R2)
1932 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1933 /** Template specialization member function differing from the above function only in supported template conditions. */
1934 inline colorTpl& tfrmAnd(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1935 if(goodMask)
1936 setMaskNC(getMaskNC() & aCol.getMaskNC());
1937 else
1938 for(int i=0; i<numChan; i++)
1939 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) & std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
1940 return *this;
1941 }
1942#endif
1943 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1944 /** Performs a logical NAND with the current object and the given object and places the value in the current object.
1945 @param aCol The color to use in the computation.
1946 @return Returns a reference to the current color object.*/
1947 inline colorTpl& tfrmNand(colorArgType aCol) requires (std::integral<clrChanT>) {
1948 if(goodMask)
1949 setMaskNC(~(getMaskNC() & aCol.getMaskNC()));
1950 else
1951 for(int i=0; i<numChan; i++)
1952 setChanNC(i, ~(getChanNC(i) & aCol.getChanNC(i)));
1953 return *this;
1954 }
1955#if !(MISSING_P0476R2)
1956 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1957 /** Template specialization member function differing from the above function only in supported template conditions. */
1958 inline colorTpl& tfrmNand(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1959 if(goodMask)
1960 setMaskNC(~(getMaskNC() & aCol.getMaskNC()));
1961 else
1962 for(int i=0; i<numChan; i++)
1963 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) & std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
1964 return *this;
1965 }
1966#endif
1967 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1968 /** Performs a logical EXCLUSIVE OR (XOR) with the current object and the given object and places the value in the current object.
1969 @param aCol The color to use in the computation.
1970 @return Returns a reference to the current color object.*/
1971 inline colorTpl& tfrmXor(colorArgType aCol) requires (std::integral<clrChanT>) {
1972 if(goodMask)
1973 setMaskNC(getMaskNC() ^ aCol.getMaskNC());
1974 else
1975 for(int i=0; i<numChan; i++)
1976 setChanNC(i, getChanNC(i) ^ aCol.getChanNC(i));
1977 return *this;
1978 }
1979#if !(MISSING_P0476R2)
1980 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1981 /** Template specialization member function differing from the above function only in supported template conditions. */
1982 inline colorTpl& tfrmXor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
1983 if(goodMask)
1984 setMaskNC(getMaskNC() ^ aCol.getMaskNC());
1985 else
1986 for(int i=0; i<numChan; i++)
1987 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) ^ std::bit_cast<channelArithLogType>(aCol.getChanNC(i))));
1988 return *this;
1989 }
1990#endif
1991 //--------------------------------------------------------------------------------------------------------------------------------------------------------
1992 /** Performs a logical NOT EXCLUSIVE OR (NXOR) with the current object and the given object and places the value in the current object.
1993 @param aCol The color to use in the computation.
1994 @return Returns a reference to the current color object.*/
1995 inline colorTpl& tfrmNxor(colorArgType aCol) requires (std::integral<clrChanT>) {
1996 if(goodMask)
1997 setMaskNC(~(getMaskNC() ^ aCol.getMaskNC()));
1998 else
1999 for(int i=0; i<numChan; i++)
2000 setChanNC(i, ~(getChanNC(i) ^ aCol.getChanNC(i)));
2001 return *this;
2002 }
2003#if !(MISSING_P0476R2)
2004 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2005 /** Template specialization member function differing from the above function only in supported template conditions. */
2006 inline colorTpl& tfrmNxor(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2007 if(goodMask)
2008 setMaskNC(~(getMaskNC() ^ aCol.getMaskNC()));
2009 else
2010 for(int i=0; i<numChan; i++)
2011 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)) ^ std::bit_cast<channelArithLogType>(aCol.getChanNC(i)))));
2012 return *this;
2013 }
2014#endif
2015 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2016 /** Performs logical (bit-wise) negation of current object.
2017 @return Returns a reference to the current color object.*/
2018 inline colorTpl& tfrmNot(void) requires (std::integral<clrChanT>) {
2019 if(goodMask)
2020 setMaskNC(~(getMaskNC()));
2021 else
2022 for(int i=0; i<numChan; i++)
2023 setChanNC(i, ~(getChanNC(i)));
2024 return *this;
2025 }
2026#if !(MISSING_P0476R2)
2027 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2028 /** Template specialization member function differing from the above function only in supported template conditions. */
2029 inline colorTpl& tfrmNot(void) requires (std::floating_point<clrChanT>) {
2030 if(goodMask)
2031 setMaskNC(~(getMaskNC()));
2032 else
2033 for(int i=0; i<numChan; i++)
2034 setChanNC(i, std::bit_cast<clrChanT>(~(std::bit_cast<channelArithLogType>(getChanNC(i)))));
2035 return *this;
2036 }
2037#endif
2038 //@}
2039
2040 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2041 /** @name Arithmetic Operators */
2042 //@{
2043 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2044 /** Computes the square of the difference for each channel between the given color and the current color object.
2045 @param aCol The color to use in the computation.
2046 @return Returns a reference to the current color object.*/
2048 for(int i=0; i<numChan; i++)
2049 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithSDPType>(getChanNC(i)) - static_cast<channelArithSDPType>(aCol.getChanNC(i))) *
2050 (static_cast<channelArithSDPType>(getChanNC(i)) - static_cast<channelArithSDPType>(aCol.getChanNC(i)))));
2051 return *this;
2052 }
2053 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2054 /** Computes the absolute value of the difference for each channel between the given color and the current color object.
2055 @param aCol The color to use in the computation.
2056 @return Returns the absolute value of the difference for each channel.*/
2058 for(int i=0; i<numChan; i++)
2059 setChanNC(i, static_cast<clrChanT>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i)))));
2060 return *this;
2061 }
2062 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2063 /** Computes the arithmetic sum of the given color and the current one.
2064 @param aCol The color to use in the computation.
2065 @return Returns a reference to the current color object.*/
2067 for(int i=0; i<numChan; i++)
2068 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))));
2069 return *this;
2070 }
2071 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2072 /** Computes the arithmetic division of the current color by the given color.
2073 If a channel of aCol is zero, then the corresponding channel of the current color object will be left untouched.
2074 @param aCol The color to use in the computation.
2075 @return Returns a reference to the current color object.*/
2077 for(int i=0; i<numChan; i++)
2078 if (aCol.getChanNC(i) != 0)
2079 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) / static_cast<channelArithSPType>(aCol.getChanNC(i))));
2080 return *this;
2081 }
2082 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2083 /** Computes the arithmetic product of the given color and the current one.
2084 @param aCol The color to use in the computation.
2085 @return Returns a reference to the current color object.*/
2087 for(int i=0; i<numChan; i++)
2088 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(aCol.getChanNC(i))));
2089 return *this;
2090 }
2091 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2092 /** Computes the product of the given color and the current one.
2093 If the result of a multiplication is too large, it will be set to the maximum component value.
2094 @param aCol The color to use in the computation.
2095 @return Returns a reference to the current color object.*/
2097 for(int i=0; i<numChan; i++)
2098 setChanNC(i, clampTop(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(aCol.getChanNC(i))));
2099 return *this;
2100 }
2101 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2102 /** Computes the component wise scaled sign of the difference between the current color and the given one.
2103 As an example of the computation, the red component of the current color is computed like this:
2104 - R=#minChanVal iff(R<color.R)
2105 - R=#meanChanVal iff(R==color.R)
2106 - R=#maxChanVal iff(R>color.R)
2107 @param aCol The color to use in the computation.
2108 @return Returns a reference to the current color object.*/
2110 for(int i=0; i<numChan; i++) {
2111 if(getChanNC(i) < aCol.getChanNC(i)) {
2112 setChanNC(i, minChanVal);
2113 } else if(getChanNC(i) > aCol.getChanNC(i)) {
2114 setChanNC(i, maxChanVal);
2115 } else {
2116 setChanNC(i, meanChanVal);
2117 }
2118 }
2119 return *this;
2120 }
2121 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2122 /** Computes the arithmetic difference of the given color from the current one.
2123 If the result a differences is negative, then that component will be set to zero.
2124 @param aCol The color to use in the computation.
2125 @return Returns a reference to the current color object.*/
2127 for(int i=0; i<numChan; i++)
2128 setChanNC(i, clampBot(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i))));
2129 return *this;
2130 }
2131 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2132 /** Computes the negative of the arithmetic difference of the given color from the current one.
2133 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
2134 component will be set to zero.
2135 @param aCol The color to use in the computation.
2136 @return Returns a reference to the current color object.*/
2138 for(int i=0; i<numChan; i++)
2139 setChanNC(i, clampBot(static_cast<channelArithDType>(aCol.getChanNC(i)) - static_cast<channelArithDType>(getChanNC(i))));
2140 return *this;
2141 }
2142 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2143 /** Computes the arithmetic sum of the given color from the current one.
2144 If the result of a sum is greater than the maximum value, then that component will be set to the maximum value.
2145 @param aCol The color to use in the computation.
2146 @return Returns a reference to the current color object.*/
2148 for(int i=0; i<numChan; i++)
2149 setChanNC(i, clampTop(static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))));
2150 return *this;
2151 }
2152 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2153 /** Computes the arithmetic sum of the current color and aCol, then divids by dCol.
2154 If the result is greater than the maximum value, then that component will be set to the maximum value.
2155 If a channel of dCol is zero, then the corresponding channel of the current color object will be left untouched.
2156 @param aCol The color to use for initial add.
2157 @param dCol The color to use for final division.
2158 @return Returns a reference to the current color object.*/
2160 for(int i=0; i<numChan; i++)
2161 if (dCol.getChanNC(i) != 0)
2162 setChanNC(i, clampTop((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) /
2163 static_cast<channelArithSPType>(dCol.getChanNC(i))));
2164 return *this;
2165 }
2166 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2167 /** Computes the arithmetic difference of the given color from the current one.
2168 @param aCol The color to use in the computation.
2169 @return Returns a reference to the current color object.*/
2171 for(int i=0; i<numChan; i++)
2172 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aCol.getChanNC(i))));
2173 return *this;
2174 }
2175 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2176 /** Computes the arithmetic modulus of the current by the given one.
2177 If a channel of aCol is zero, then the corresponding channel of the current object is left untouched.
2178 @param aCol The color to use in the computation.
2179 @return Returns a reference to the current color object.*/
2180 inline colorTpl& tfrmMod(colorArgType aCol) requires (std::integral<clrChanT>) {
2181 for(int i=0; i<numChan; i++)
2182 if (aCol.getChanNC(i) != 0) // MJR TODO NOTE tfrmMod: What about floats?
2183 setChanNC(i, getChanNC(i) % aCol.getChanNC(i));
2184 return *this;
2185 }
2186 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2187 /** Template specialization member function differing from the above function only in supported template conditions. */
2188 inline colorTpl& tfrmMod(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2189 for(int i=0; i<numChan; i++)
2190 setChanNC(i, static_cast<clrChanT>(std::fmod(static_cast<double>(getChanNC(i)), static_cast<double>(aCol.getChanNC(i)))));
2191 return *this;
2192 }
2193 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2194 /** Transforms the color: r=#maxChanVal-r, g=#maxChanVal-r, and b=#maxChanVal-b
2195 @return Returns a reference to the current color object.*/
2197 // MJR TODO NOTE tfrmInvert: This is just as fast as array refs...
2198 // MJR TODO NOTE tfrmInvert: We should use this universally across the library -- to isolate the code from the array specifics...
2199 for(int i=0; i<numChan; i++)
2200 setChanNC(i, maxChanVal - getChanNC(i));
2201 return *this;
2202 }
2203 //@}
2204
2205 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2206 /** @name Named Operators */
2207 //@{
2208
2209 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2210 /** Power: c=maxChanVal*(c/maxChanVal)^p.
2211 Floating point Numbers are used for intermediate values and the result cast to a colorChanType at the end.
2212 @return Returns a reference to the current color object.*/
2213 inline colorTpl& tfrmPow(double p) {
2214 for(int i=0; i<numChan; i++)
2215 setChanNC(i, static_cast<clrChanT>(static_cast<double>(maxChanVal) * std::pow(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal), p)));
2216 return *this;
2217 }
2218 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2219 /** Adds 1.0 and takes the natural logarithm of each channel.
2220 Floating point Numbers are used for intermediate values and the result cast to a colorChanType at the end.
2221 @return Returns a reference to the current color object.*/
2222 inline colorTpl& tfrmLn1() {
2223 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2224 for(int i=0; i<numChan; i++)
2225 setChanNC(i, static_cast<clrChanT>(std::log(1.0 + static_cast<double>(getChanNC(i)))));
2226 return *this;
2227 }
2228 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2229 /** Computes ln(c)*scale for each channel value c. If c==0, then the value is left undisturbed.
2230 For floating point images, large negative values will result for channel values <1. For this reason, tfrmLn1() is normally more appropriate for
2231 images with floating point channels. Floating point Numbers are used for intermediate values and the result cast to a colorChanType at the end.
2232 @param scale The scale value to multiply by the final result.
2233 @return Returns a reference to the current color object.*/
2234 inline colorTpl& tfrmLn(double scale) {
2235 /* Performance: Even if the compiler fails to unroll this loop, the runtime is dominated by the double computations. */
2236 for(int i=0; i<numChan; i++) {
2237 clrChanT cVal = getChanNC(i);
2238 if(cVal != 0)
2239 setChanNC(i, static_cast<clrChanT>(std::log(static_cast<double>(cVal)) * scale));
2240 }
2241 return *this;
2242 }
2243 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2244 /** Linearly interpolate between the current color and the given color (at a point scaled the unit interval).
2245 If \a aDouble is 0, then the current color will not change. If \a aDouble is 1, then the current color will be tooCol.
2246 @param aDouble Distance from the current color (on a unit interval)
2247 @param tooCol The color we are interpolating with.
2248 @return Returns a reference to the current color object.*/
2249 inline colorTpl& tfrmMix(double aDouble, colorArgType tooCol) {
2250 if( (aDouble >= 0.0) && (aDouble <= 1.0) )
2251 for(int i=0; i<numChan; i++)
2252 setChanNC(i, static_cast<clrChanT>(mjr::math::linm::interpolate(static_cast<double>(getChanNC(i)), static_cast<double>(tooCol.getChanNC(i)), aDouble)));
2253 return *this;
2254 }
2255 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2256 /** Copies the given argument into the current color object.
2257 Scan as copy() -- just with a name more suited to transformation code.
2258 @return Returns a reference to the current color object.*/
2259 inline colorTpl& tfrmCopy(colorArgType aCol) { return copy(aCol); }
2260 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2261 /** Makes the current color the maximum of the current color or the given color.
2262 Colors are ordered by intensity (thus the 'I' in the name)
2263 @param aCol The color to use in the computation.
2264 @return Returns a reference to the current color object.*/
2266 channelArithSPType thisSum = 0;
2267 channelArithSPType thatSum = 0;
2268 for(int i=0; i<numChan; i++) {
2269 thisSum += static_cast<channelArithSPType>(getChanNC(i));
2270 thatSum += static_cast<channelArithSPType>(aCol.getChanNC(i));
2271 }
2272 if(thisSum < thatSum)
2273 tfrmCopy(aCol);
2274 return *this;
2275 }
2276 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2277 /** Makes the current color the minimum of the current color or the given color.
2278 Colors are ordered by intensity (thus the 'I' in the name)
2279 @param aCol The color to use in the computation.
2280 @return Returns a reference to the current color object.*/
2282 /* Performance: Finding the max of two arrays in parallel with one loop is faster than calling max twice, once for each array. */
2283 channelArithSPType thisSum = 0;
2284 channelArithSPType thatSum = 0;
2285 for(int i=0; i<numChan; i++) {
2286 thisSum += static_cast<channelArithSPType>(getChanNC(i));
2287 thatSum += static_cast<channelArithSPType>(aCol.getChanNC(i));
2288 }
2289 if(thisSum > thatSum)
2290 tfrmCopy(aCol);
2291 return *this;
2292 }
2293 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2294 /** Makes each component of the current color the maximum of that component and the corresponding component of the given color.
2295 @param aCol The color to use in the computation.
2296 @return Returns a reference to the current color object.*/
2298 for(int i=0; i<numChan; i++)
2299 if(getChanNC(i) < aCol.getChanNC(i))
2300 setChanNC(i, aCol.getChanNC(i));
2301 return *this;
2302 }
2303 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2304 /** Makes each component of the current color the minimum of that component and the corresponding component of the given color.
2305 @param aCol The color to use in the computation.
2306 @return Returns a reference to the current color object.*/
2308 for(int i=0; i<numChan; i++)
2309 if(getChanNC(i) > aCol.getChanNC(i))
2310 setChanNC(i, aCol.getChanNC(i));
2311 return *this;
2312 }
2313 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2314 /** The Shift Left Transform modifies the current color.
2315 @param aCol Number of bits to shift left
2316 @return Returns a reference to the current color object.*/
2317 inline colorTpl& tfrmShiftL(colorArgType aCol) requires (std::integral<clrChanT>) {
2318 for(int i=0; i<numChan; i++)
2319 setChanNC(i, getChanNC(i) << aCol.getChanNC(i));
2320 return *this;
2321 }
2322#if !(MISSING_P0476R2)
2323 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2324 /** Template specialization member function differing from the above function only in supported template conditions. */
2325 inline colorTpl& tfrmShiftL(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2326 for(int i=0; i<numChan; i++)
2327 /* 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. */
2328 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) << static_cast<uint64_t>(aCol.getChanNC(i))));
2329 return *this;
2330 }
2331#endif
2332 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2333 /** The Shift Right Transform modifies the current color.
2334 @param aCol How many bits to shift.
2335 @return Returns a reference to the current color object.*/
2336 inline colorTpl& tfrmShiftR(colorArgType aCol) requires (std::integral<clrChanT>) {
2337 for(int i=0; i<numChan; i++)
2338 setChanNC(i, getChanNC(i) >> aCol.getChanNC(i));
2339 return *this;
2340 }
2341#if !(MISSING_P0476R2)
2342 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2343 /** Template specialization member function differing from the above function only in supported template conditions. */
2344 inline colorTpl& tfrmShiftR(colorArgType aCol) requires (std::floating_point<clrChanT>) {
2345 for(int i=0; i<numChan; i++)
2346 setChanNC(i, std::bit_cast<clrChanT>(std::bit_cast<channelArithLogType>(getChanNC(i)) >> static_cast<uint64_t>(aCol.getChanNC(i))));
2347 return *this;
2348 }
2349#endif
2350 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2351 /** The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, C_i, 0)
2352 @param lowCol lower cutoff value
2353 @param highCol upper cutoff value
2354 @return Returns a reference to the current color object.*/
2355 inline colorTpl& tfrmSaw(colorArgType lowCol, colorArgType highCol) {
2356 for(int i=0; i<numChan; i++)
2357 setChanNC(i, ((lowCol.getChanNC(i) <= getChanNC(i)) && (highCol.getChanNC(i) >= getChanNC(i)) ? getChanNC(i) : 0));
2358 return *this;
2359 }
2360 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2361 /** The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, maxChanVal, 0)
2362 @param lowCol lower cutoff value
2363 @param highCol upper cutoff value
2364 @return Returns a reference to the current color object.*/
2365 inline colorTpl& tfrmStep(colorArgType lowCol, colorArgType highCol) {
2366 for(int i=0; i<numChan; i++)
2367 setChanNC(i, ((lowCol.getChanNC(i) <= getChanNC(i)) && (highCol.getChanNC(i) >= getChanNC(i)) ? maxChanVal : 0));
2368 return *this;
2369 }
2370 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2371 /** The DiracTot (total) Transform modifies the current color: Set current color to white if it equals aCol, and black otherwise.
2372 @param aCol Dirac trigger value
2373 @return Returns a reference to the current color object.*/
2375 for(int i=0; i<numChan; i++)
2376 if(aCol.getChanNC(i) != getChanNC(i))
2377 return setToBlack();
2378 return setToWhite();
2379 }
2380 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2381 /** The Dirac Transform modifies the current color: C_i = ifelse(C_i==aCol.C_i, maxChanVal, 0)
2382 @param aCol Dirac trigger value
2383 @return Returns a reference to the current color object.*/
2385 for(int i=0; i<numChan; i++)
2386 setChanNC(i, ((aCol.getChanNC(i) == getChanNC(i)) ? maxChanVal : 0));
2387 return *this;
2388 }
2389 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2390 /** The Fuzzy Dirac Transform modifies the current color: C_i=ifelse(|R-ctrCol.R|<=radCol.R), maxChanVal, 0)
2391 @param ctrCol Center Color
2392 @param radCol Radius Color
2393 @return Returns a reference to the current color object.*/
2395 for(int i=0; i<numChan; i++)
2396 setChanNC(i, ((std::abs(ctrCol.getChanNC(i) - getChanNC(i)) <= radCol.getChanNC(i)) ? maxChanVal : 0));
2397 return *this;
2398 }
2399 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2400 /** Computes the arithmetic mean of the given color and the current one.
2401 @param aCol The color to use in the computation.
2402 @return Returns a reference to the current color object.*/
2404 for(int i=0; i<numChan; i++)
2405 setChanNC(i, static_cast<clrChanT>((static_cast<channelArithSPType>(getChanNC(i)) + static_cast<channelArithSPType>(aCol.getChanNC(i))) / 2));
2406 return *this;
2407 }
2408 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2409 /** Computes the geometric mean of the given color and the current one.
2410 Floating point Numbers re used for intermediate values and the result cast to a colorChanType at the end.
2411 @param aCol The color to use in the computation.
2412 @return Returns a reference to the current color object.*/
2414 for(int i=0; i<numChan; i++)
2415 setChanNC(i, static_cast<clrChanT>(std::sqrt(static_cast<channelArithFltType>(getChanNC(i)) * static_cast<channelArithFltType>(aCol.getChanNC(i)))));
2416 return *this;
2417 }
2418 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2419 /** Transform the current color by rendering it into a true grey via the same method used by the luminanceRGB() function.
2420 This function only sets the red, blue, and green channels -- all other channels are left untouched.
2421 @return Returns a reference to the current color object.*/
2423 /* Requires: Inherits numChan>2 from getC2. */
2424 double lumU = static_cast<double>(luminanceRGB());
2425 setRed_dbl( lumU);
2426 setGreen_dbl(lumU);
2427 setBlue_dbl( lumU);
2428 return *this;
2429 }
2430 //@}
2431
2432 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2433 /** @name Color Reduction Transformations */
2434 //@{
2435 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2436 /** The 216 Palate Web Safe Transform modifies the current color into the closest web safe color from the 216 color web safe pallet.
2437 This function only sets the red, blue, and green channels -- all other channels are left untouched.
2438 @return Returns a reference to the current color object.*/
2439 inline colorTpl& tfrmWebSafeRGB() requires (redChan>=0) {
2440 for (int c : {redChan, blueChan, greenChan}) {
2441 int charCompVal = convertChanToByte(getChanNC(c));
2442 int minDist = 256;
2443 int minCol;
2444 for(int pv : { 0x0, 0x33, 0x66, 0x99, 0xCC, 0xFF }) {
2445 int curDist = std::abs(charCompVal - pv);
2446 if( curDist < minDist ) {
2447 minDist = curDist;
2448 minCol = pv;
2449 }
2450 }
2451 setChanNC(c, convertByteToChan(static_cast<uint8_t>(minCol)));
2452 }
2453 return *this;
2454 }
2455 //@}
2456
2457 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2458 /** @name Alternate Color Space Stuff */
2459 //@{
2460 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2461 /** Compute channels for given color space coordinates for the current color.
2462 Note RGB returns float RGB normalized to 1.0.
2463 @param space The color space to convert to
2464 @return An RGB color with double channels. */
2466 /* Requires: Inherits numChan>2 from getBlue. */
2467
2468 double redF = getRed_dbl();
2469 double greenF = getGreen_dbl();
2470 double blueF = getBlue_dbl();
2471
2472 if (space == colorSpaceEnum::RGB)
2473 return colConDbl3(redF, greenF, blueF);
2474
2475 if ((space == colorSpaceEnum::HSL) || (space == colorSpaceEnum::HSV)) {
2476 clrChanT rgbMaxI = getMaxRGB();
2477 clrChanT rgbMinI = getMinRGB();
2478
2479 channelArithSDPType rangeI = rgbMaxI - rgbMinI;
2480
2481 double rgbMaxF = static_cast<double>(rgbMaxI) / static_cast<double>(maxChanVal);
2482 double rgbMinF = static_cast<double>(rgbMinI) / static_cast<double>(maxChanVal);
2483
2484 double rangeF = rgbMaxF - rgbMinF;
2485 double sumF = rgbMaxF + rgbMinF;
2486
2487 // Compute L
2488 double L = sumF / 2.0;
2489 double V = rgbMaxF;
2490
2491 // Compute H & S
2492 double S, H;
2493 if((rgbMaxI == 0) || (rangeI == 0)) {
2494 S = 0.0;
2495 H = 0.0;
2496 } else {
2497
2498 if (space == colorSpaceEnum::HSL) {
2499 if(L <= 0.5)
2500 S = rangeF / sumF;
2501 else
2502 S = rangeF / ( 2.0 - sumF);
2503 } else {
2504 S = rangeF / rgbMaxF;
2505 }
2506
2507 H = 0.0;
2508 if(getRed() == rgbMaxI)
2509 H = 0.0 + (greenF - blueF) / rangeF;
2510 else if(getGreen() == rgbMaxI)
2511 H = 2.0 + (blueF - redF) / rangeF;
2512 else if(getBlue() == rgbMaxI)
2513 H = 4.0 + (redF - greenF) / rangeF;
2514 H = mjr::math::ivl::wrapCO(H * 60.0, 360.0);
2515 }
2516 if (space == colorSpaceEnum::HSL)
2517 return colConDbl3(H, S, L);
2518 else
2519 return colConDbl3(H, S, V);
2520 } else {
2521 redF = 100.0 * ((redF > 0.04045) ? std::pow((redF + 0.055) / 1.055, 2.4) : redF / 12.92);
2522 greenF = 100.0 * ((greenF > 0.04045) ? std::pow((greenF + 0.055) / 1.055, 2.4) : greenF / 12.92);
2523 blueF = 100.0 * ((blueF > 0.04045) ? std::pow((blueF + 0.055) / 1.055, 2.4) : blueF / 12.92);
2524
2525 double X = (0.4124 * redF + 0.3576 * greenF + 0.1805 * blueF);
2526 double Y = (0.2126 * redF + 0.7152 * greenF + 0.0722 * blueF); // luminance with weights RGBluminanceWeightR, RGBluminanceWeightG, RGBluminanceWeightB
2527 double Z = (0.0193 * redF + 0.1192 * greenF + 0.9505 * blueF);
2528
2529 if (space == colorSpaceEnum::XYZ)
2530 return colConDbl3(X, Y, Z);
2531
2532 X /= 95.0429;
2533 Y /= 100.0;
2534 Z /= 108.89;
2535
2536 X = (X > 0.008856 ? std::pow(X, 1.0 / 3.0) : (7.787 * X) + (16.0 / 116.0));
2537 Y = (Y > 0.008856 ? std::pow(Y, 1.0 / 3.0) : (7.787 * Y) + (16.0 / 116.0));
2538 Z = (Z > 0.008856 ? std::pow(Z, 1.0 / 3.0) : (7.787 * Z) + (16.0 / 116.0));
2539
2540 double L = (116.0 * Y) - 16.0;
2541 double A = 500.0 * (X - Y);
2542 double B = 200.0 * (Y - Z);
2543
2544 if (space == colorSpaceEnum::LAB)
2545 return colConDbl3(L, A, B);
2546
2547 double C = std::hypot(A, B);
2548
2549 double H = 0.0;
2550 if ( std::abs(A) > 1.0e-5) // Not Grey
2551 H = mjr::math::ivl::wrapCO(atan2(B,A) * 180.0 / std::numbers::pi, 360.0);
2552
2553 if (space == colorSpaceEnum::LCH)
2554 return colConDbl3(L, C, H);
2555 }
2556
2557 return colConDbl3(0.0, 0.0, 0.0);
2558 }
2559 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2560 /** Compute channels for given color space coordinates for the current color.
2561 Note RGB returns float RGB normalized to 1.0.
2562 @param space The color space to stringify
2563 @return A string representing the color space. */
2564 inline std::string colorSpaceToString(colorSpaceEnum space) {
2565 switch (space) {
2566 case colorSpaceEnum::RGB : return std::string("rgb");
2567 case colorSpaceEnum::HSL : return std::string("HSL");
2568 case colorSpaceEnum::HSV : return std::string("HSV");
2569 case colorSpaceEnum::LAB : return std::string("Lab");
2570 case colorSpaceEnum::XYZ : return std::string("XYZ");
2571 case colorSpaceEnum::LCH : return std::string("Lch");
2572 default: return std::string("ERROR");
2573 }
2574 }
2575 //@}
2576
2577 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2578 /** @name Color Transformation Functions */
2579 //@{
2580 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2581 /** The Linear Grey Level Scale transform modifies the current color such that: C_n=c*C_n+b.
2582 This function transforms all channels --- not just RGBA.
2583 @param c The "contrast" value
2584 @param b The "brightness" value
2585 @return Returns a reference to the current color object.*/
2586 inline colorTpl& tfrmLinearGreyLevelScale(double c, double b) {
2587 for(int i=0; i<numChan; i++)
2588 setChanNC(i, static_cast<clrChanT>(c * static_cast<double>(getChanNC(i)) + b));
2589 return *this;
2590 }
2591 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2592 /** The Linear Grey Level Scale transform modifies the current color such that: R=rc*R+rb, G=gc*G+gb, B=bc*B+bb.
2593 This function ONLY transforms the red, green, and blue channels.
2594 @param rc The "contrast" value for red
2595 @param rb The "brightness" value for red
2596 @param gc The "contrast" value for green
2597 @param gb The "brightness" value for green
2598 @param bc The "contrast" value for blue
2599 @param bb The "brightness" value for blue
2600 @return Returns a reference to the current color object.*/
2601 inline colorTpl& tfrmLinearGreyLevelScaleRGB(double rc, double rb, double gc, double gb, double bc, double bb) {
2602 /* Requires: Inherits numChan>3 from setAlpha & getC3. */
2603 setRed( static_cast<clrChanT>(rc * static_cast<double>(getRed()) + rb));
2604 setGreen(static_cast<clrChanT>(gc * static_cast<double>(getGreen()) + gb));
2605 setBlue( static_cast<clrChanT>(bc * static_cast<double>(getBlue()) + bb));
2606 return *this;
2607 }
2608 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2609 /** Perform a tfrmLinearGreyLevelScale based on a complex number.
2610 @param z The complex number
2611 @param cutDepth Range: @f$[1, ~30]@f$ Smaller means more contrast on cuts.
2612 @param argCuts Number of grey cuts for arg
2613 @param absCuts Number of grey cuts for abs
2614 @param logAbs If true, then take the logorithm of abs for cuts. */
2615 inline colorTpl& tfrmComplexCut(std::complex<double> z, double cutDepth, double argCuts, double absCuts, bool logAbs = true) {
2616 double tau = std::numbers::pi * 2; // 2*Pi
2617 double zArg = std::arg(z); // Arg
2618 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
2619 if (argCuts > 0)
2620 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(pzArg*argCuts) - pzArg*argCuts)/cutDepth, 0);
2621 if (absCuts > 0) {
2622 double zAbs = std::abs(z); // Abs
2623 if (logAbs) {
2624 double lzAbs = std::log(zAbs);
2625 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(lzAbs*absCuts) - lzAbs*absCuts)/cutDepth, 0);
2626 } else {
2627 tfrmLinearGreyLevelScale(1.0 - std::fabs(int(zAbs*absCuts) - zAbs*absCuts)/cutDepth, 0);
2628 }
2629 }
2630 return *this;
2631 }
2632 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2633 /** The Standard Power Transform modifies the current color such that: C_i = maxChanVal*(C_i / maxChanVal)**p.
2634 @return Returns a reference to the current color object.*/
2635 inline colorTpl& tfrmStdPow(double p) {
2636 for(int i=0; i<numChan; i++)
2637 setChanNC(i, static_cast<clrChanT>(std::pow(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal), p) * static_cast<double>(maxChanVal)));
2638 return *this;
2639 }
2640 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2641 /** The Standard Power Transform modifies the current color such that:
2642 R=#maxChanVal*(R/#maxChanVal)**rp, B=#maxChanVal*(B/#maxChanVal)**gp, B=#maxChanVal*(B/#maxChanVal)**bp
2643 @return Returns a reference to the current color object.*/
2644 inline colorTpl& tfrmStdPowRGB(double rp, double gp, double bp) {
2645 /* Requires: Inherits numChan>2 from setBlue & getC2. */
2646 setRed( static_cast<clrChanT>(std::pow(static_cast<double>(getRed()) / static_cast<double>(maxChanVal), rp) * static_cast<double>(maxChanVal)));
2647 setGreen(static_cast<clrChanT>(std::pow(static_cast<double>(getGreen()) / static_cast<double>(maxChanVal), gp) * static_cast<double>(maxChanVal)));
2648 setBlue( static_cast<clrChanT>(std::pow(static_cast<double>(getBlue()) / static_cast<double>(maxChanVal), bp) * static_cast<double>(maxChanVal)));
2649 return *this;
2650 }
2651 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2652 /** The Standard Power Transform with p=2. The new color will be: C_i = C_i * C_i / maxChanVal == (C_i/maxChanVal)^2*maxChanVal
2653 This computation is done with integer math if clrChanT is integral.
2654 @return Returns a reference to the current color object.*/
2655 inline colorTpl& tfrmStdPowSqr(void) {
2656 for(int i=0; i<numChan; i++)
2657 setChanNC(i, static_cast<clrChanT>(static_cast<channelArithSPType>(getChanNC(i)) * static_cast<channelArithSPType>(getChanNC(i)) /
2658 static_cast<channelArithSPType>(maxChanVal)));
2659 return *this;
2660 }
2661 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2662 /** The Standard Power Transform with p=1/2. The new color will be: C_i = sqrt(C_i / maxChanVal) * maxChanVal
2663 @return Returns a reference to the current color object.*/
2664 inline colorTpl& tfrmStdPowSqrt(void) {
2665 for(int i=0; i<numChan; i++)
2666 setChanNC(i, static_cast<clrChanT>(std::sqrt(static_cast<double>(getChanNC(i)) / static_cast<double>(maxChanVal)) * static_cast<double>(maxChanVal)));
2667 return *this;
2668 }
2669 //@}
2670
2671 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2672 /** @name Mathematical Operations On Color(s)
2673 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
2674 result. */
2675 //@{
2676 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2677 /** Use the R, G, & B channels to compute a floating point value representing a grey scale.
2678 What is returned is the dot product of the given color and the three scalars: R*redWt+G*greenWt+B*blueWt.
2679 @param redWt The red weight
2680 @param greenWt The green weight
2681 @param blueWt The blue weight
2682 @return The integer representing grey value for the given color. */
2683 inline channelArithFltType rgb2GreyDotProd(channelArithFltType redWt = RGBluminanceWeightR,
2684 channelArithFltType greenWt = RGBluminanceWeightG,
2685 channelArithFltType blueWt = RGBluminanceWeightB) const {
2686 /* Requires: Inherits numChan>2 from getC2. */
2687 return (static_cast<channelArithFltType>(getRed()) * static_cast<channelArithFltType>(redWt) +
2688 static_cast<channelArithFltType>(getGreen()) * static_cast<channelArithFltType>(greenWt) +
2689 static_cast<channelArithFltType>(getBlue()) * static_cast<channelArithFltType>(blueWt));
2690 }
2691 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2692 /** Compute the luminance of the current color via the definition given in the ITU-R Recommendation BT.709.
2693 The output value will be between 0 and 1, and is given by: (RGBluminanceWeightR*R+RGBluminanceWeightG*G+RGBluminanceWeightB*B)/#maxChanVal.
2694 @return The luminance for the current object. */
2695 inline channelArithFltType luminanceRGB(void) const {
2696 /* Requires: Inherits numChan>2 from getC2. */
2697 return ((static_cast<channelArithFltType>(getRed()) * static_cast<channelArithFltType>(RGBluminanceWeightR) +
2698 static_cast<channelArithFltType>(getGreen()) * static_cast<channelArithFltType>(RGBluminanceWeightG) +
2699 static_cast<channelArithFltType>(getBlue()) * static_cast<channelArithFltType>(RGBluminanceWeightB)) / static_cast<channelArithFltType>(maxChanVal));
2700 }
2701 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2702 /** Compute the unscaled intensity (sum of the R, G, & B components) of the current color
2703 @return The unscaled intensity for the current object. */
2704 inline channelArithSPType intensityRGB(void) const {
2705 /* Requires: Inherits numChan>2 from getC2. */
2706 return static_cast<channelArithSPType>(static_cast<channelArithSPType>(getRed()) +
2707 static_cast<channelArithSPType>(getGreen()) +
2708 static_cast<channelArithSPType>(getC2()));
2709 }
2710 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2711 /** Compute the sum of the components.
2712 @return Sum of components. */
2713 inline channelArithSPType intensity() const {
2714 channelArithSPType sum = 0;
2715 for(int i=0; i<numChan; i++)
2716 sum += getChan(i);
2717 return (sum);
2718 }
2719 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2720 /** Compute the scaled intensity (sum of the first three components divided by the maximum intensity possible) of the current color
2721 @return The scaled intensity for the current object. */
2722 inline channelArithFltType intensityScaledRGB() const {
2723 return (static_cast<channelArithFltType>(intensityRGB()) / static_cast<channelArithFltType>(3) / static_cast<channelArithFltType>(maxChanVal));
2724 }
2725 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2726 /** Compute the scaled intensity (sum of the components divided by the maximum intensity possible) of the current color
2727 @return Sum of components. */
2728 inline channelArithFltType intensityScaled() const {
2729 return (static_cast<channelArithFltType>(intensity()) / static_cast<channelArithFltType>(numChan) / static_cast<channelArithFltType>(maxChanVal));
2730 }
2731 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2732 /** Returns the value of the largest component.
2733 @return The value of the largest color component currently stored.*/
2734 inline clrChanT getMaxC() const {
2735 /* 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.
2736 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
2737 code. */
2738 if(numChan == 1) { // 1 channel
2739 return getChanNC(0);
2740 } else if(numChan == 2) { // 2 channels
2741 return std::max(getChanNC(0), getChanNC(1));
2742 } else if(numChan == 3) { // 3 channels
2743 return mjr::math::odr::max3(getChanNC(0), getChanNC(1), getChanNC(2));
2744 } else if(numChan == 4) { // 4 channels
2745 return mjr::math::odr::max4(getChanNC(0), getChanNC(1), getChanNC(2), getChanNC(3));
2746 } else { // More than 3 channels
2747 clrChanT theMax = minChanVal;
2748 for(int i=0; i<numChan; i++)
2749 if(theMax < getChanNC(i))
2750 theMax = getChanNC(i);
2751 return theMax;
2752 }
2753 }
2754 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2755 /** Returns the value of the smallest component.
2756 @return The value of the smallest color component currently stored.*/
2757 inline clrChanT getMinC() const {
2758 if(numChan == 1) { // 1 channel
2759 return getChanNC(0);
2760 } else if(numChan == 2) { // 2 channels
2761 return std::min(getChanNC(0), getChanNC(1));
2762 } else if(numChan == 3) { // 3 channels
2763 return mjr::math::odr::min3(getChanNC(0), getChanNC(1), getChanNC(2));
2764 } else if(numChan == 4) { // 4 channels
2765 return mjr::math::odr::min4(getChanNC(0), getChanNC(1), getChanNC(2), getChanNC(3));
2766 } else {
2767 clrChanT theMin = maxChanVal;
2768 for(int i=0; i<numChan; i++)
2769 if(theMin > getChanNC(i))
2770 theMin = getChanNC(i);
2771 return theMin;
2772 }
2773 }
2774 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2775 /** Returns the value of the largest component from R, G, and B. This function is highly optimized.
2776 @return The value of the largest color component.*/
2777 inline clrChanT getMaxRGB() const { return mjr::math::odr::max3(getRed(), getGreen(), getBlue()); } /* Requires: Inherits numChan>2 from getC2. */
2778 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2779 /** Returns the value of the smallest component from R, G, and B. This function is highly optimized.
2780 @return The value of the smallest color component.*/
2781 inline clrChanT getMinRGB() const { return mjr::math::odr::min3(getRed(), getGreen(), getBlue()); } /* Requires: Inherits numChan>2 from getC2. */
2782 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2783 /** Compute the dot product between the current color and the given color. i.e. c1.r*c2.r+c1.g*c2.g+...
2784 @param aColor the given color
2785 @return Returns dot product.*/
2786 inline channelArithFltType dotProd(colorArgType aColor) const {
2787 channelArithFltType daProd = 0;
2788 for(int i=0; i<numChan; i++)
2789 daProd += static_cast<channelArithFltType>(static_cast<channelArithFltType>(getChanNC(i)) * static_cast<channelArithFltType>(aColor.getChanNC(i)));
2790 return daProd;
2791 }
2792 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2793 /** Distance between current color and given one (sum squares of channel differences -- Euclidean distance squared).
2794 @param aColor The given color
2795 @return Returns Distance */
2796 inline channelArithFltType distHypot(colorArgType aColor) const {
2797 channelArithFltType daDist = 0;
2798 for(int i=0; i<numChan; i++)
2799 daDist += (static_cast<channelArithFltType>((static_cast<channelArithFltType>(getChanNC(i)) - static_cast<channelArithFltType>(aColor.getChanNC(i))) *
2800 (static_cast<channelArithFltType>(getChanNC(i)) - static_cast<channelArithFltType>(aColor.getChanNC(i)))));
2801 return static_cast<channelArithFltType>(std::sqrt(daDist));
2802 }
2803 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2804 /** Distance between current color and given one (sum of absolute channel differences).
2805 @param aColor the given color
2806 @return Returns Distance */
2807 inline channelArithSPType distSumAbs(colorArgType aColor) const {
2808 channelArithSPType daDist = 0;
2809 for(int i=0; i<numChan; i++)
2810 daDist += static_cast<channelArithSPType>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))));
2811 return daDist;
2812 }
2813 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2814 /** Distance between current color and given one (maximum of absolute value of channel differences).
2815 @param aColor the given color
2816 @return Returns Distance */
2817 inline channelArithSPType distMaxAbs(colorArgType aColor) const {
2818 channelArithSPType daDist = 0;
2819 for(int i=0; i<numChan; i++) {
2820 channelArithSPType tmp = static_cast<channelArithSPType>(std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))));
2821 if (daDist < tmp)
2822 daDist = tmp;
2823 }
2824 return daDist;
2825 }
2826 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2827 /** LAB Delta E* distance between current color and given one.
2828 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.
2829 @param aColor the given color
2830 @return Returns Distance -- note return is a double not a channelArithFltType. */
2831 inline double distDeltaE1976(colorArgType aColor) const {
2832 colConDbl3 acol1 = rgb2colorSpace(colorSpaceEnum::LAB);
2833 colConDbl3 acol2 = aColor.rgb2colorSpace(colorSpaceEnum::LAB);
2834 double daDist = 0;
2835 for (int c=0; c<3; c++)
2836 daDist += std::pow(acol1.getChanNC(c) - acol2.getChanNC(c), 2);
2837 daDist = std::sqrt(daDist);
2838 return daDist;
2839 }
2840 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2841 /** LAB Delta E* 1994 (graphic arts) distance between current color and given one.
2842 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.
2843 Note: The Delta E* 1994 distance measurement is NOT symetric -- the 1976 one is!
2844 @param aColor the given color
2845 @return Returns Distance -- note return is a double not a channelArithFltType. */
2846 inline double distDeltaE1994(colorArgType aColor) const {
2847 colConDbl3 acol1 = rgb2colorSpace(colorSpaceEnum::LAB);
2848 colConDbl3 acol2 = aColor.rgb2colorSpace(colorSpaceEnum::LAB);
2849 double k1 = 0.045;
2850 double k2 = 0.015;
2851 double kL = 1.000;
2852 double kC = 1.000;
2853 double kH = 1.000;
2854 double sL = 1.000;
2855 double dL = acol1.getC0() - acol2.getC0();
2856 double da = acol1.getC1() - acol2.getC1();
2857 double db = acol1.getC2() - acol2.getC2();
2858 double c1 = std::sqrt(std::pow(acol1.getC1(), 2) + std::pow(acol1.getC2(), 2));
2859 double c2 = std::sqrt(std::pow(acol2.getC1(), 2) + std::pow(acol2.getC2(), 2));
2860 double sH = 1.000 + k2 * c1;
2861 double sC = 1.000 + k1 * c1;
2862 double dC = c2 - c2;
2863 double dH2 = std::pow(da, 2) + std::pow(db, 2) - std::pow(dC, 2);
2864 if (dH2 < 0.0)
2865 dH2 = 0.000;
2866 double dE = std::sqrt(std::pow(dL/kL/sL, 2) + std::pow(dC/kC/sC, 2) + dH2/std::pow(kH*sH, 2));
2867 return dE;
2868 }
2869 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2870 /** 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).
2871 Note the implications for floating point clrChanT.
2872 @return non-zero if the given color is logically the same as the current color*/
2873 inline bool isClose(colorArgType aColor, clrChanT epsilon) const {
2874 for(int i=0; i<numChan; i++)
2875 if (std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))) > epsilon)
2876 return false;
2877 return true;
2878 }
2879 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2880 /** Like isClose(), but only checks the R, G, & B channels.
2881 @return non-zero if the given RGB color is the same as the current color*/
2882 inline bool isCloseRGB(colorArgType aColor, clrChanT epsilon) const requires(blueChan >= 0) {
2883 for (int i : {redChan, blueChan, greenChan})
2884 if (std::abs(static_cast<channelArithDType>(getChanNC(i)) - static_cast<channelArithDType>(aColor.getChanNC(i))) > epsilon)
2885 return false;
2886 return true;
2887 }
2888 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2889 /** Returns non-zero if the current color is precicely equal to aColor.
2890 Note the implications for floating point clrChanT.
2891 @return non-zero if the given color is logically the same as the current color*/
2892 inline bool isEqual(colorArgType aColor) const {
2893 if(perfectMask)
2894 return (getMaskNC() == aColor.getMaskNC());
2895 else
2896 for(int i=0; i<numChan; i++)
2897 if(getChanNC(i) != aColor.getChanNC(i))
2898 return false;
2899 return true;
2900 }
2901 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2902 /** Like isEqual(), but only checks the R, G, & B channels.
2903 @return non-zero if the given RGB color is the same as the current color*/
2904 inline bool isEqualRGB(colorArgType aColor) const {
2905 /* Requires: Inherits RGB channel requirements from getRed/getGreen/getBlue. */
2906 return ((getRed() == aColor.getRed() ) &&
2907 (getGreen() == aColor.getGreen()) &&
2908 (getBlue() == aColor.getBlue()));
2909 }
2910 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2911 /** Returns non-zero if the given color is logically NOT the same as the current color.
2912 Note the implications for floating point clrChanT.
2913 @return non-zero if the given color is logically the same as the current color*/
2914 inline bool isNotEqual(colorArgType aColor) const { return !(isEqual(aColor)); }
2915 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2916 /** Returns non-zero if the given color is black (all componnets are zero)
2917 @return non-zero if the given color is black (all componnets are zero) */
2918 inline bool isBlack() {
2919 if(perfectMask)
2920 return (getMaskNC() == maskAllZero);
2921 else
2922 for(int i=0; i<numChan; i++)
2923 if(getChanNC(i) != 0)
2924 return false;
2925 return true;
2926 }
2927 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2928 /** LIke isBlack(), but only checks the R, G, & B channels
2929 @return non-zero if the given color is black (R, G, & B are are zero) */
2930 inline bool isBlackRGB() const { return ((getRed() == 0) && (getGreen() == 0) && (getBlue() == 0)); } /* Requires: Inherits RGB channel requirements from getRed/getGreen/getBlue. */
2931 //@}
2932
2933 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2934 /** @name Channel Clipping Functions */
2935 //@{
2936 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2937 /** Clamp a value to (infinity, maxChanVal].
2938 Input values larger than maxChanVal are mapped to maxChanVal. Values less than minChanVal are not changed.
2939 @param arithValue The value to clamp */
2940 template <typename iT>
2941 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>)
2942 inline clrChanT clampTop(iT arithValue) {
2943 if(arithValue > static_cast<iT>(maxChanVal))
2944 return static_cast<clrChanT>(maxChanVal);
2945 else
2946 return static_cast<clrChanT>(arithValue);
2947 }
2948 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2949 /** Clamp a value to [minChanVal, infinity).
2950 @param arithValue The value to clamp */
2951 template <typename iT>
2952 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>)
2953 inline clrChanT clampBot(iT arithValue) {
2954 if(arithValue < static_cast<iT>(minChanVal))
2955 return static_cast<clrChanT>(minChanVal);
2956 else
2957 return static_cast<clrChanT>(arithValue);
2958 }
2959 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2960 /** Clamp a value to [minChanVal, maxChanVal].
2961 @param arithValue The value to clamp */
2962 template <typename iT>
2963 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>)
2964 inline clrChanT clampAll(iT arithValue) {
2965 if (arithValue > static_cast<iT>(maxChanVal))
2966 return static_cast<clrChanT>(maxChanVal);
2967 else if(arithValue < static_cast<iT>(minChanVal))
2968 return static_cast<clrChanT>(minChanVal);
2969 else
2970 return static_cast<clrChanT>(arithValue);
2971 }
2972 //@}
2973
2974 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2975 /** @name Meta Color Schemes */
2976 //@{
2977 //--------------------------------------------------------------------------------------------------------------------------------------------------------
2978#if !(MISSING_P1907R1)
2979 /** Compute a color from a polynomial space curve in the RGB color space. This is a continuous color scheme!
2980 @tparam coefs Polynomial coefficients*/
2981 template<double...coefs>
2983 public:
2984 /** Set given colorTpl instance to the selected color in the color scheme.
2985 @param aColor color object to set.
2986 @param csX A value in [0, 1] that identifies the color in the scheme.
2987 @return Returns a reference to \a aColor. */
2988 static inline colorTpl& c(colorRefType aColor, csFltType csX) {
2989 double pR = pcoff[0 * psize];
2990 double pG = pcoff[1 * psize];
2991 double pB = pcoff[2 * psize];
2992 for (unsigned int i=1; i<psize; i++) {
2993 pR = pR * csX + pcoff[i + 0 * psize];
2994 pG = pG * csX + pcoff[i + 1 * psize];
2995 pB = pB * csX + pcoff[i + 2 * psize];
2996 }
2997 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));
2998 }
2999 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3000 @param csX A value in [0, 1] that identifies the color in the scheme.
3001 @return Returns a colorTpl value */
3002 static inline colorTpl c(csFltType csX) { colorTpl tmp; return c(tmp, csX); }
3003 private:
3004 constexpr static int psize = (sizeof...(coefs)) / 3;
3005 constexpr static double pcoff[] = { coefs... };
3006 };
3007#endif
3008#if !(MISSING_P1907R1)
3009 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3010 /** 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.
3011 This is a continous color scheme!
3012 @tparam start colour (1=red, 2=green, 3=blue; ex: 0.5=purple;
3013 @tparam rots Rotations in colour in [-1.5, 1.5]. ex: -1.0 is one blue->green->red cycle;
3014 @tparam hue Hue intensity scaling in [0, 1] (0 == greyscale).
3015 @tparam gamma Gamma correction for intensity. */
3016 template<double start, double rots, double hue, double gamma>
3018 public:
3019 /** Set given colorTpl instance to the selected color in the color scheme.
3020 @param aColor color object to set.
3021 @param csX A value in [0, 1] that identifies the color in the scheme.
3022 @return Returns a reference to \a aColor. */
3023 static inline colorTpl& c(colorRefType aColor, csFltType csX) {
3024 //csX=mjr::math::ivl::wrapCC(csX, 0.0, 1.0);
3025 double angle=2*std::numbers::pi*(start/3.0+1.0+rots*csX);
3026 csX=std::pow(csX, gamma);
3027 double ampl=hue*csX*(1-csX)/2.0;
3028 return aColor.setChansRGB_dbl(std::clamp(csX+ampl*(-0.14861*std::cos(angle)+1.78277*std::sin(angle)), 0.0, 1.0),
3029 std::clamp(csX+ampl*(-0.29227*std::cos(angle)-0.90649*std::sin(angle)), 0.0, 1.0),
3030 std::clamp(csX+ampl*(+1.97294*std::cos(angle)), 0.0, 1.0));
3031 }
3032 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3033 @param csX A value in [0, 1] that identifies the color in the scheme.
3034 @return Returns a colorTpl value */
3035 static inline colorTpl c(csFltType csX) { colorTpl tmp; return c(tmp, csX); }
3036 };
3037#endif
3038 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3039 /** Template for HSL color schemes.
3040 If clrChanT is integral, this is a discrete color scheme, otherwise it is continuous.. */
3041 template<cornerColorEnum corner>
3043 public:
3044 constexpr static csIntType numC = (chanIsInt ? meanChanVal : 0);
3045 /** Set given colorTpl instance to the selected color in the color scheme.
3046 @param aColor color object to set.
3047 @param csVal Index of color in pallet. Wrapped to [0, meanChanVal].
3048 @return Returns a reference to \a aColor. */
3049 static inline colorTpl& c(colorRefType aColor, csNatType csVal) {
3050 clrChanT cVal = static_cast<clrChanT>(mjr::math::ivl::wrapCC(csVal, meanChanVal));
3051 colorTpl cc(corner);
3052 return aColor.setChansRGB(static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getRed() ? cVal : -cVal)),
3053 static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getGreen() ? cVal : -cVal)),
3054 static_cast<clrChanT>(meanChanVal + (meanChanVal < cc.getBlue() ? cVal : -cVal)));
3055 }
3056 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3057 @param csVal Index of color in pallet. Wrapped to [0, meanChanVal].
3058 @return Returns a colorTpl value */
3059 static inline colorTpl c(csNatType csVal) { colorTpl tmp; return c(tmp, csVal); }
3060 };
3061 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3062 /** Template providing RGB color cube gradiant color schemes */
3063 template<cornerColorEnum...corners>
3064 class csCC_tpl {
3065 public:
3066 constexpr static csIntType numC = ((sizeof...(corners)) - 1) * chanStepMax + 1;
3067 /** Set given colorTpl instance to the selected color in the color scheme.
3068 @param aColor color object to set.
3069 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3070 @return Returns a reference to \a aColor. */
3071 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) {
3072 csFltType csX = static_cast<csFltType>(csG);
3073 return aColor.cmpRGBcornerCGradiant(csX, numA, cols);
3074 }
3075 /** Set given colorTpl instance to the selected color in the color scheme.
3076 @param aColor color object to set.
3077 @param csG Integer used to select a color from the discrete gradiaant.
3078 @return Returns a reference to \a aColor. */
3079 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) {
3080 csIntType csIdx = static_cast<csIntType>(csG);
3081 return aColor.cmpRGBcornerDGradiant(csIdx % numC, numA, cols);
3082 }
3083 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3084 @param csG color scheme selector
3085 @return Returns a colorTpl value */
3086 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) {
3087 colorTpl tmp;
3088 return c(tmp, csG);
3089 }
3090 private:
3091 constexpr static int numA = (sizeof...(corners));
3092 constexpr static cornerColorEnum cols[] = { corners... };
3093 };
3094 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3095 /** Binary color scheme. First color for even inputs and second color for odd. */
3096 template<cornerColorEnum a, cornerColorEnum b>
3098 public:
3099 constexpr static csIntType numC = 2;
3100 /** Set given colorTpl instance to the selected color in the color scheme.
3101 @param aColor color object to set.
3102 @param csIdx Index of color in pallet. Not wrapped or clipped. Even values get color \a a, while odd values get color \a b.
3103 @return Returns a reference to \a aColor. */
3104 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) { if (csIdx % 2) return aColor.setToCorner(b); else return aColor.setToCorner(a); }
3105 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3106 @param csIdx Index of color in pallet. Not wrapped or clipped. Even values get color \a a, while odd values get color \a b.
3107 @return Returns a colorTpl value */
3108 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3109 };
3110 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3111 /** Template for fixed size pallets. */
3112 template<uint32_t...colors>
3113 class csFP_tpl {
3114 public:
3115 constexpr static csIntType numC = (sizeof...(colors));
3116 /** Set given colorTpl instance to the selected color in the color scheme.
3117 @param aColor color object to set.
3118 @param csG Integer used to select a color from the discrete gradiaant.
3119 @return Returns a reference to \a aColor. */
3120 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) {
3121 csFltType csX = static_cast<csFltType>(csG);
3122 return aColor.cmpGradiant(mjr::math::ivl::wrapCC(csX, 1.0), numC, d);
3123 }
3124 /** Set given colorTpl instance to the selected color in the color scheme.
3125 @param aColor color object to set.
3126 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3127 @return Returns a reference to \a aColor. */
3128 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) {
3129 csIntType csIdx = static_cast<csIntType>(csG);
3130 return aColor.setRGBfromLogPackIntARGB(d[csIdx % numC]);
3131 }
3132 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3133 @param csG color scheme color selector
3134 @return Returns a colorTpl value */
3135 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) {
3136 colorTpl tmp;
3137 return c(tmp, csG);
3138 }
3139 private:
3140 constexpr static uint32_t d[] = { colors... };
3141 };
3142 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3143 /** Template for Color Brewer 2 variable sized pallets. */
3144 template<csIntType mx, uint32_t...colors>
3145 class csCB_tpl {
3146 public:
3147 constexpr static csIntType minNumC = 3;
3148 constexpr static csIntType maxNumC = mx;
3149 /** Set given colorTpl instance to the selected color in the color scheme.
3150 @param aColor color object to set.
3151 @param csG Integer used to select a color from the discrete gradiaant.
3152 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3153 @return Returns a reference to \a aColor. */
3154 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG, csIntType numC=maxNumC) requires (std::floating_point<saT>) {
3155 csFltType csX = static_cast<csFltType>(csG);
3156 csIntType b = std::clamp(numC, minNumC, maxNumC);
3157 return aColor.cmpGradiant(mjr::math::ivl::wrapCC(csX, 1.0), b, &d[b*(b-1)/2-3+0]);
3158 }
3159 /** Set given colorTpl instance to the selected color in the color scheme.
3160 @param aColor color object to set.
3161 @param csG Floating point value in [0, 1] used to select a color from the continuous color gradiant.
3162 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3163 @return Returns a reference to \a aColor. */
3164 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG, csIntType numC=maxNumC) requires (std::integral<saT>) {
3165 csIntType csIdx = static_cast<csIntType>(csG);
3166 csIntType b = std::clamp(numC, minNumC, maxNumC);
3167 csIntType i = csIdx % b;
3168 return aColor.setRGBfromLogPackIntARGB(d[b*(b-1)/2-3+i]);
3169 }
3170 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3171 @param csG color scheme color selector
3172 @param numC Number of colors for the given scheme. Will be clamped to [minNumC, maxNumC].
3173 @return Returns a colorTpl value */
3174 template<typename saT> static inline colorTpl c(saT csG, csIntType numC=maxNumC) requires (std::integral<saT> || std::floating_point<saT>) {
3175 colorTpl tmp;
3176 return c(tmp, csG, numC);
3177 }
3178 private:
3179 constexpr static uint32_t d[] = { colors... };
3180 };
3181 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3182 /** Wrapper for Color Brewer 2 variable sized pallet template to produce a simple fixed color scheme with a numC member.
3183 @tparam varColorScheme A color brewer variable sized color scheme
3184 @tparam numClr The number of colors wanted in the fixed sized scheme.*/
3185 template<class varColorScheme, csIntType numClr>
3186 requires((varColorScheme::minNumC <= numClr) && (varColorScheme::maxNumC >= numClr))
3188 public:
3189 constexpr static csIntType numC = numClr;
3190 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::floating_point<saT>) { return varColorScheme::c(aColor, csG, numClr); }
3191 template<typename saT> static inline colorTpl& c(colorRefType aColor, saT csG) requires (std::integral<saT>) { return varColorScheme::c(aColor, csG, numClr); }
3192 template<typename saT> static inline colorTpl c(saT csG) requires (std::integral<saT> || std::floating_point<saT>) { return varColorScheme::c(csG, numC); }
3193 };
3194 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3195 /** Template for web safe 216 pallets. */
3196 template<uint32_t...colors>
3197 class csWS_tpl {
3198 public:
3199 constexpr static csIntType numC = (sizeof...(colors));
3200 /** Set given colorTpl instance to the selected color in the color scheme.
3201 @param aColor color object to set.
3202 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3203 @return Returns a reference to \a aColor. */
3204 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) { return aColor.setRGBfromLogPackIntARGB(d[csIdx % numC]); }
3205 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3206 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3207 @return Returns a reference a colorTpl value. */
3208 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3209 /** Set given colorTpl instance to the selected color in the color scheme.
3210 @param aColor color object to set.
3211 @param csCol input color to convert to a web safe color.
3212 @return Returns a reference to \a aColor. */
3213 static colorTpl& c(colorRefType aColor, colorRefType csCol) {
3214 aColor.copy(csCol);
3215 aColor.tfrmWebSafeRGB();
3216 int colIdx = 36 * (aColor.getRed_byte() / 0x33) + 6 * (aColor.getGreen_byte() / 0x33) + 1 * (aColor.getBlue_byte() / 0x33) + 1;
3217 return aColor.setRGBfromLogPackIntARGB(d[colIdx]);
3218 }
3219 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3220 @param csCol input color to convert to a web safe color.
3221 @return Returns a reference a colorTpl value. */
3222 static colorTpl c(colorRefType csCol) { colorTpl tmp; return c(tmp, csCol); }
3223 private:
3224 constexpr static uint32_t d[] = { colors... };
3225 };
3226 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3227 /** Template for Thaller 2D color schemes. */
3228 template<bool useHSL, bool maxV, double cutDepth, double argCuts, double absCuts, bool logAbs>
3229 requires( !(useHSL && maxV))
3231 public:
3232 /** Set given colorTpl instance to the selected color in the color scheme.
3233 @param aColor color object to set.
3234 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
3235 @param csY A value that, along with csX, identifies the color in the scheme.
3236 @return Returns a reference to \a aColor. */
3237 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
3238 double tau = std::numbers::pi * 2; // 2*Pi
3239 double zAbs = std::sqrt(csX*csX+csY*csY); // Abs
3240 double zArg = std::atan2(csY, csX); // Arg
3241 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
3242 double val = (maxV ? 1 : 4.0*std::atan(zAbs)/tau); // V for HSV
3243 if (useHSL)
3244 aColor.setRGBfromUnitHSL(pzArg, 1.0, val);
3245 else
3246 aColor.setRGBfromUnitHSV(pzArg, 1.0, val);
3247 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
3248 }
3249 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3250 @param csX A value that, along with csY, identifies the color in the scheme.
3251 @param csY A value that, along with csX, identifies the color in the scheme.
3252 @return Returns a colorTpl value */
3253 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
3254 /** Set given colorTpl instance to the selected color in the color scheme.
3255 @param aColor color object to set.
3256 @param csZ A value that identifies the color in the scheme.
3257 @return Returns a reference to \a aColor. */
3258 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
3259 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3260 @param csZ A value that identifies the color in the scheme.
3261 @return Returns a colorTpl value */
3262 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
3263 };
3264 //@}
3265
3266 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3267 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3268 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3269
3270 /** @cond color-schemes */
3271 /* Doxygen is pretty bad at formatting these bits... */
3272
3273 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3274 /** @defgroup cs Color Schemes */
3275
3276#if !(MISSING_P1907R1)
3277 //========================================================================================================================================================
3278 /** @name Color Schemes: Polynomial */
3279 //@{
3280 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3281 /*- @class csPLYgrey
3282 @ingroup cs
3283 @extends csPLY_tpl
3284 Greyscale */
3285 typedef csPLY_tpl<1.0, 0.0,
3286 1.0, 0.0,
3287 1.0, 0.0> csPLYgrey;
3288 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3289 /** @class csPLYquad
3290 @ingroup cs
3291 @extends csPLY_tpl
3292 Quadratic */
3293 typedef csPLY_tpl<1.0, 0.0, 0.0,
3294 1.0, 0.0, 0.0,
3295 1.0, 0.0, 0.0> csPLYquad;
3296 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3297 /** @class csPLYturbo
3298 @ingroup cs
3299 @extends csPLY_tpl
3300 Similar to the Google turbo colormap.
3301 Note this colormap is not identical to turbo, and lacks some of it's more sophisticated characteristics; however, it looks nice.
3302 See: https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html */
3303 typedef csPLY_tpl< 40703.92740, -218720.2701, 492368.2177, -590441.1804, 384271.9078, -101352.6555, -30425.81099,
3304 32619.05953, -10529.162296, 1625.5688083, -124.13217495, 4.867108400, 0.15787894011,
3305 20766.64723, -122258.4886, 315808.0723, -470687.9792, 447662.9929, -283594.9850, 121141.42864,
3306 -34482.96363, 6288.268231, -682.8118257, 37.74849512, 2.025549368, 0.06643490255,
3307 -94331.85477, 587011.8043, -1597312.2220, 2495306.9899, -2470958.0510, 1616523.3372, -706621.97816,
3308 204052.57726, -37536.525321, 4109.7062335, -257.68681737, 13.750387410, 0.16179522842> csPLYturbo;
3309 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3310 /** @class csPLYparula
3311 @ingroup cs
3312 @extends csPLY_tpl
3313 Similar to the Matlab parula colormap.
3314 Note this colormap is not identical to parula, and lacks some of it's more sophisticated characteristics; however, it looks nice.
3315 See: https://www.mathworks.com/help/matlab/ref/parula.html */
3316 typedef csPLY_tpl< 62043.87545, -399037.6523, 1122946.9120, -1812238.5254, 1846100.4184, -1230398.5816, 537273.93047,
3317 -149254.730651, 24535.019552, -2015.3894764, 44.825447931, 0.6772663755, 0.2018889435,
3318 -17121.77553, 108751.1007, -300422.7570, 473217.4661, -468061.6834, 301522.8593, -126770.41694,
3319 33776.781210, -5288.933402, 404.6316583, -7.800267203, 1.3431462881, 0.1677335602,
3320 -17004.66127, 100139.7442, -255248.5285, 366029.9549, -319570.5392, 169195.6211, -48015.67328,
3321 2478.369459, 2717.762128, -795.8032035, 72.119793045, 1.1497391882, 0.5347179324> csPLYparula;
3322 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3323 /** @class csPLYmagma
3324 @ingroup cs
3325 @extends csPLY_tpl
3326 Similar, but not identical, to the matplotlib magma colormap.
3327 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3328 typedef csPLY_tpl<746.7387907, -3433.588054, 6464.361262, -6369.328232, 3470.981211, -1010.528460, 141.7946515,
3329 -15.78575778, 6.066078845, 0.2765580349, 0.000406276347,
3330 885.3555317, -5488.721941, 14347.739660, -20613.711506, 17758.797775, -9380.063372, 2976.8215781,
3331 -529.56166374, 45.254936301, -0.9276250448, 0.006923020887,
3332 -3360.6362774, 17553.826465, -38851.355442, 47349.901018, -34548.072322, 15336.155184, -3997.3017542,
3333 548.12480687, -32.540585926, 2.6406562133, 0.006263758764> csPLYmagma;
3334 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3335 /** @class csPLYinferno
3336 @ingroup cs
3337 @extends csPLY_tpl
3338 Similar, but not identical, to the matplotlib inferno colormap.
3339 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3340 typedef csPLY_tpl<-19.63292067, 452.2107953, -1685.008066, 2775.510486, -2442.279827, 1181.312494, -280.5809421,
3341 10.74924866, 8.60430465, 0.1030211659, 0.002048171596,
3342 1970.76446015, -10379.8617699, 23277.924908, -28925.873437, 21688.815122, -10002.539645, 2763.0755166,
3343 -419.99828889, 28.92908793, -0.2365793129, 0.001175881895,
3344 2525.53763382, -12168.1567723, 24862.266312, -28273.600973, 19817.598983, -8983.810158, 2683.7805375,
3345 -515.72960422, 52.67809976, 0.0641022894, 0.024051180021> csPLYinferno;
3346 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3347 /** @class csPLYplasma
3348 @ingroup cs
3349 @extends csPLY_tpl
3350 Similar, but not identical, to the matplotlib plasma colormap.
3351 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3352 typedef csPLY_tpl<-43.8322257, 285.8375115, -806.7514473, 1301.765273, -1325.274751, 878.0715655, -374.7228293,
3353 98.20716947, -15.31425214, 2.899584724, 0.05309687850,
3354 1014.1378090, -5599.3136737, 13256.9879694, -17529.001879, 14102.556299, -7032.4501033, 2110.7323912,
3355 -350.31653834, 28.69509557, -1.086029536, 0.03452846048,
3356 -829.5844973, 4029.2020771, -8461.6295286, 10078.322085, -7471.246818, 3531.4365043, -1036.2596994,
3357 175.24253651, -17.51426724, 1.646647586, 0.52562476199> csPLYplasma;
3358 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3359 /** @class csPLYviridis
3360 @ingroup cs
3361 @extends csPLY_tpl
3362 Similar, but not identical, to the matplotlib viridis colormap.
3363 See: https://bids.github.io/colormap/ and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3364 typedef csPLY_tpl<-5.432077171, 4.751786889, 6.203735901, -4.599931518, -0.32724109679, 0.1077083262, 0.274455424454,
3365 4.641571316, -13.749439404, 14.153964947, -5.758238189, 0.21481356454, 1.3964696839, 0.005767962397,
3366 26.272107604, -65.320967828, 56.656299565, -19.291808950, 0.09197688076, 1.3867705979, 0.332663881113> csPLYviridis;
3367 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3368 /** @class csPLYcividis
3369 @ingroup cs
3370 @extends csPLY_tpl
3371 Similar, but not identical, to the cividis colormap.
3372 Note this map dosen't have the flat red and sharp increase in blue at the start of the map.
3373 See: https://github.com/marcosci/cividis and https://matplotlib.org/stable/tutorials/colors/colormaps.html */
3374 typedef csPLY_tpl<-10.6296994279, 27.5479183452, -25.1086313881, 9.3401209056, -0.1385953043, -0.0177903167,
3375 -0.2641767638, 0.6924831686, -0.5155427716, 0.2071305342, 0.6695454456, 0.1273928107,
3376 9.7085048454, -25.9409393982, 24.1852720215, -9.7350011883, 1.7347333905, 0.3185822998> csPLYcividis;
3377 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3378 /** @class csPLYhsvRB
3379 @ingroup cs
3380 @extends csPLY_tpl
3381 Similar to csCColdeRainbow, but a little softer. */
3382 typedef csPLY_tpl<8.746561257e-11, 4.285714286, -4.285714286, 1.166666667e+00,
3383 1.200000000e+01, -21.000000000, 9.023809524, -2.161907281e-13,
3384 -1.200000000e+01, 15.000000000, -3.023809524, 2.380952381e-02> csPLYhsvRB;
3385 //@}
3386#endif
3387
3388#if !(MISSING_P1907R1)
3389 //========================================================================================================================================================
3390 /** @name Color Schemes: CubeHelix */
3391 //@{
3392 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3393 /** @class csCHstd
3394 @ingroup cs
3395 @extends csCubeHelix_tpl
3396 The "standard" cubehelix color scheme with start=0.5, rots=-1.5, hue=1, and gamma=1. */
3397 typedef csCubeHelix_tpl<0.5, -1.5, 1.0, 1.0> csCHstd;
3398 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3399 /** @class csCHblu
3400 @ingroup cs
3401 @extends csCubeHelix_tpl
3402 The "blues" cubehelix color scheme with start=0.5, rots=-0.5, hue=1, and gamma=1. */
3403 typedef csCubeHelix_tpl<0.5, -0.5, 1.0, 1.0> csCHblu;
3404 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3405 /** @class csCHvio
3406 @ingroup cs
3407 @extends csCubeHelix_tpl
3408 The "violets" cubehelix color scheme with start=0.5, rots=0.0, hue=1, and gamma=1. */
3409 typedef csCubeHelix_tpl<0.5, 0.0, 1.0, 1.0> csCHvio;
3410 //@}
3411#endif
3412
3413 //========================================================================================================================================================
3414 /** @name Color Schemes: White In Center Circular Gradients */
3415 //@{
3416 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3417 /** @class csCCwicR
3418 @ingroup cs
3419 @extends csCC_tpl
3420 Color cycle starting and ending with red with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3421 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::WHITE, cornerColorEnum::RED> csCCwicR;
3422 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3423 /** @class csCCwicG
3424 @ingroup cs
3425 @extends csCC_tpl
3426 Color cycle starting and ending with green with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3427 typedef csCC_tpl<cornerColorEnum::GREEN, cornerColorEnum::WHITE, cornerColorEnum::GREEN> csCCwicG;
3428 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3429 /** @class csCCwicB
3430 @ingroup cs
3431 @extends csCC_tpl
3432 Color cycle starting and ending with blue with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3433 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::WHITE, cornerColorEnum::BLUE> csCCwicB;
3434 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3435 /** @class csCCwicM
3436 @ingroup cs
3437 @extends csCC_tpl
3438 Color cycle starting and ending with magenta with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3439 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::WHITE, cornerColorEnum::MAGENTA> csCCwicM;
3440 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3441 /** @class csCCwicY
3442 @ingroup cs
3443 @extends csCC_tpl
3444 Color cycle starting and ending with yellow with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3445 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::WHITE, cornerColorEnum::YELLOW> csCCwicY;
3446 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3447 /** @class csCCwicC
3448 @ingroup cs
3449 @extends csCC_tpl
3450 Color cycle starting and ending with cyan with white in the center. Provides (mjr::colorTpl::chanStepMax*2+1) colors with duplicates. */
3451 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::WHITE, cornerColorEnum::CYAN> csCCwicC;
3452 //@}
3453
3454 //========================================================================================================================================================
3455 /** @name Color Schemes: RGB Constant Brightness Ramps */
3456 //@{
3457 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3458 /** @class csCCconsTwo
3459 @ingroup cs
3460 @extends csCC_tpl
3461 Color cycle around the cube with constant brightness of two. Provides (mjr::colorTpl::chanStepMax*3+1) unique colors. */
3462 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csCCconsTwo;
3463 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3464 /** @class csCCconsOne
3465 @ingroup cs
3466 @extends csCC_tpl
3467 Color cycle around the cube with constant brightness of one. Provides (mjr::colorTpl::chanStepMax*3+1) unique colors. */
3468 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::RED, cornerColorEnum::GREEN, cornerColorEnum::BLUE> csCCconsOne;
3469 //@}
3470
3471 //========================================================================================================================================================
3472 /** @name Color Schemes: Start and end with a primary with the secondary mixed from the primaries in the middle. */
3473 //@{
3474 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3475 /** @class csCCmixRYG
3476 @ingroup cs
3477 @extends csCC_tpl
3478 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3479 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::GREEN> csCCmixRYG;
3480 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3481 /** @class csCCmixRMB
3482 @ingroup cs
3483 @extends csCC_tpl
3484 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3485 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::MAGENTA, cornerColorEnum::BLUE> csCCmixRMB;
3486 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3487 /** @class csCCmixGCB
3488 @ingroup cs
3489 @extends csCC_tpl
3490 Provides (mjr::colorTpl::chanStepMax*2+1) unique colors. */
3491 typedef csCC_tpl<cornerColorEnum::GREEN, cornerColorEnum::CYAN, cornerColorEnum::BLUE> csCCmixGCB;
3492 //@}
3493
3494 //========================================================================================================================================================
3495 /** @name Color Schemes: RGB Divergent Ramps */
3496 //@{
3497 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3498 /** @class csCCdivBWR
3499 @ingroup cs
3500 @extends csCC_tpl
3501 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. */
3502 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::WHITE, cornerColorEnum::RED> csCCdivBWR;
3503 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3504 /** @class csCCdivCWM
3505 @ingroup cs
3506 @extends csCC_tpl
3507 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. */
3508 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::WHITE, cornerColorEnum::MAGENTA> csCCdivCWM;
3509 //@}
3510
3511 //========================================================================================================================================================
3512 /** @name Color Schemes: RGB Cube Diagional Ramps */
3513 //@{
3514 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3515 /** @class csCCdiag01
3516 @ingroup cs
3517 @extends csCC_tpl
3518 Gradient across the diagonal of the RGB color cube from black to white. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3519 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csCCdiag01;
3520 /** @class csCCdiag10
3521 @ingroup cs
3522 @extends csCC_tpl
3523 Gradient across the diagonal of the RGB color cube from white to black. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3524 typedef csCC_tpl<cornerColorEnum::WHITE, cornerColorEnum::BLACK> csCCdiag10;
3525 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3526 /** @class csCCdiagCR
3527 @ingroup cs
3528 @extends csCC_tpl
3529 Gradient across the diagonal of the RGB color cube from cyan to red. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3530 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::RED> csCCdiagCR;
3531 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3532 /** @class csCCdiagMG
3533 @ingroup cs
3534 @extends csCC_tpl
3535 Gradient across the diagonal of the RGB color cube from magenta to green. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3536 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::GREEN> csCCdiagMG;
3537 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3538 /** @class csCCdiagYB
3539 @ingroup cs
3540 @extends csCC_tpl
3541 Gradient across the diagonal of the RGB color cube from yellow to blue. Provides about (mjr::colorTpl::chanStepMax + 1) unique colors. */
3542 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::BLUE> csCCdiagYB;
3543 //@}
3544
3545 //========================================================================================================================================================
3546 /** @name Color Schemes: Classic RGB Ramps */
3547 //@{
3548 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3549 /** @class csCColdeFireRamp
3550 @ingroup cs
3551 @extends csCC_tpl
3552 Classic color cube "Fire Ramp". */
3553 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCColdeFireRamp;
3554 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3555 /** @class csCColdeColdToHot
3556 @ingroup cs
3557 @extends csCC_tpl
3558 Classical cold to hot color cube ramp. Provides (mjr::colorTpl::chanStepMax*4+1) unique colors. */
3559 typedef csCC_tpl<cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::GREEN,
3560 cornerColorEnum::YELLOW, cornerColorEnum::RED> csCColdeColdToHot;
3561 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3562 /** @class csCColdeIceToWaterToHot
3563 @ingroup cs
3564 @extends csCC_tpl
3565 Modified version of the classical cold to hot color cube ramp.ramp. It starts at white (ice), moves up to blue (cold),
3566 then yellow through red (hot). Provides (mjr::colorTpl::chanStepMax*4+1) unique colors. */
3567 typedef csCC_tpl<cornerColorEnum::WHITE, cornerColorEnum::CYAN, cornerColorEnum::BLUE,
3568 cornerColorEnum::YELLOW, cornerColorEnum::RED> csCColdeIceToWaterToHot;
3569 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3570 /** @class csCColdeRainbow
3571 @ingroup cs
3572 @extends csCC_tpl
3573 The classic HSV rainbow color scheme based upon an edge traversal of the RGB color cube. Provides (6 * mjr::colorTpl::chanStepMax + 1) colors. */
3574 typedef csCC_tpl<cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::GREEN, cornerColorEnum::CYAN,
3575 cornerColorEnum::BLUE, cornerColorEnum::MAGENTA, cornerColorEnum::RED> csCColdeRainbow;
3576 //@}
3577
3578 //========================================================================================================================================================
3579 /** @name Color Schemes: Classic Fractal RGB Gradients.
3580 Gradients frequently used to color fractal images. */
3581 //@{
3582 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3583 /** @class csCCfractal0RYBCW
3584 @ingroup cs
3585 @extends csCC_tpl
3586 Provides (5 * mjr::colorTpl::chanStepMax + 1) colors. */
3587 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW,
3588 cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCfractal0RYBCW;
3589 /** @class csCCfractalYR
3590 @ingroup cs
3591 @extends csCC_tpl
3592 Provides (mjr::colorTpl::chanStepMax + 1) colors. */
3593 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::RED> csCCfractalYR;
3594 /** @class csCCfractalYB
3595 @ingroup cs
3596 @extends csCC_tpl
3597 Provides (mjr::colorTpl::chanStepMax + 1) colors. */
3598 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::BLUE> csCCfractalYB;
3599 //@}
3600
3601 //========================================================================================================================================================
3602 /** @name Color Schemes: RGB Sum Ramps */
3603 //@{
3604 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3605 /** @class csCCsumRGB
3606 @ingroup cs
3607 @extends csCC_tpl
3608 RGB cube sum-ramp: RGB == Black -> Red -> Yellow -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3609 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCCsumRGB;
3610 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3611 /** @class csCCsumBGR
3612 @ingroup cs
3613 @extends csCC_tpl
3614 RGB cube sum-ramp: BGR == Black -> Blue -> cyan -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3615 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCsumBGR;
3616 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3617 /** @class csCCsumGRB
3618 @ingroup cs
3619 @extends csCC_tpl
3620 RGB cube sum-ramp: GRB == Black -> Green -> yellow -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3621 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN, cornerColorEnum::YELLOW, cornerColorEnum::WHITE> csCCsumGRB;
3622 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3623 /** @class csCCsumGBR
3624 @ingroup cs
3625 @extends csCC_tpl
3626 RGB cube sum-ramp: GBR == Black -> Green -> cyan -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3627 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN, cornerColorEnum::CYAN, cornerColorEnum::WHITE> csCCsumGBR;
3628 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3629 /** @class csCCsumBRG
3630 @ingroup cs
3631 @extends csCC_tpl
3632 RGB cube sum-ramp: BRG == Black -> Blue -> magenta -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3633 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE, cornerColorEnum::MAGENTA, cornerColorEnum::WHITE> csCCsumBRG;
3634 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3635 /** @class csCCsumRBG
3636 @ingroup cs
3637 @extends csCC_tpl
3638 RGB cube sum-ramp: RBG Black -> Red -> Magenta -> White. Provides (3 * mjr::colorTpl::chanStepMax + 1) different colors. */
3639 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED, cornerColorEnum::MAGENTA, cornerColorEnum::WHITE> csCCsumRBG;
3640 //@}
3641
3642 //========================================================================================================================================================
3643 /** @name Color Schemes: RGB Up-Down Ramps */
3644 //@{
3645 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3646 /** @class csCCudRg
3647 @ingroup cs
3648 @extends csCC_tpl
3649 RGB Up-Down Ramp: Rg == Red Up and Green Down == cyan -> magenta. Provides chanStepMax different colors.*/
3650 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::MAGENTA> csCCudRg;
3651 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3652 /** @class csCCudRb
3653 @ingroup cs
3654 @extends csCC_tpl
3655 RGB Up-Down Ramp: Rb == Red Up and Blue Down == cyan -> yellow. Provides chanStepMax different colors.*/
3656 typedef csCC_tpl<cornerColorEnum::CYAN, cornerColorEnum::YELLOW> csCCudRb;
3657 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3658 /** @class csCCudGr
3659 @ingroup cs
3660 @extends csCC_tpl
3661 RGB Up-Down Ramp: Gr == Green Up and Red Down == magenta -> cyan. Provides chanStepMax different colors. */
3662 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::CYAN> csCCudGr;
3663 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3664 /** @class csCCudGb
3665 @ingroup cs
3666 @extends csCC_tpl
3667 RGB Up-Down Ramp: Gb == Green Up and Blue Down == magenta -> yellow. Provides chanStepMax different colors. */
3668 typedef csCC_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW> csCCudGb;
3669 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3670 /** @class csCCudBr
3671 @ingroup cs
3672 @extends csCC_tpl
3673 RGB Up-Down Ramp: Br == Blue Up and Red Down == yellow -> cyan. Provides chanStepMax different colors. */
3674 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csCCudBr;
3675 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3676 /** @class csCCudBg
3677 @ingroup cs
3678 @extends csCC_tpl
3679 RGB Up-Down Ramp: Bg == Blue Up and Green Down == yellow -> magenta. Provides chanStepMax different colors. */
3680 typedef csCC_tpl<cornerColorEnum::YELLOW, cornerColorEnum::MAGENTA> csCCudBg;
3681 //@}
3682
3683 //========================================================================================================================================================
3684 /** @name Color Schemes: Ramp from black to corner */
3685 //@{
3686 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csCCu0W; //!< Ramp from black to white
3687 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::RED> csCCu0R; //!< Ramp from black to red
3688 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::BLUE> csCCu0B; //!< Ramp from black to blue
3689 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::GREEN> csCCu0G; //!< Ramp from black to green
3690 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::CYAN> csCCu0C; //!< Ramp from black to cyan
3691 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::MAGENTA> csCCu0M; //!< Ramp from black to magenta
3692 typedef csCC_tpl<cornerColorEnum::BLACK, cornerColorEnum::YELLOW> csCCu0Y; //!< Ramp from black to yellow
3693 //@}
3694
3695 //========================================================================================================================================================
3696 /** @name Color Schemes: Binary */
3697 //@{
3698 typedef csBin_tpl<cornerColorEnum::BLACK, cornerColorEnum::WHITE> csBin01; //!< Binary Black-White color scheme. First color for even inputs and second color for odd.
3699 typedef csBin_tpl<cornerColorEnum::GREEN, cornerColorEnum::BLUE> csBinGB; //!< Binary Green-Blue color scheme. First color for even inputs and second color for odd.
3700 typedef csBin_tpl<cornerColorEnum::RED, cornerColorEnum::BLUE> csBinRB; //!< Binary Red-Blue color scheme. First color for even inputs and second color for odd.
3701 typedef csBin_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::CYAN> csBinMC; //!< Binary Magenta-Cyan color scheme. First color for even inputs and second color for odd.
3702 typedef csBin_tpl<cornerColorEnum::YELLOW, cornerColorEnum::CYAN> csBinYC; //!< Binary Yellow-Cyan color scheme. First color for even inputs and second color for odd.
3703 typedef csBin_tpl<cornerColorEnum::RED, cornerColorEnum::GREEN> csBinRG; //!< Binary Red-Green color scheme. First color for even inputs and second color for odd.
3704 typedef csBin_tpl<cornerColorEnum::MAGENTA, cornerColorEnum::YELLOW> csBinMY; //!< Binary Magenta-Yellow color scheme. First color for even inputs and second color for odd.
3705 //@}
3706
3707 //========================================================================================================================================================
3708 /** @name Color Schemes: Pseudo-Grey
3709 These color schemes start with black and move toward white trying to increase perceptional brightness, they don't stay precisely on the diagonal. */
3710 //@{
3711 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3712 /** @class csPGrey3x
3713 @ingroup cs
3714 A Pseudo-Grey color scheme with 3 * mjr::colorTpl::chanStepMax colors. */
3715 class csPGrey3x {
3716 public:
3717 constexpr static csIntType numC = 3*chanStepMax;
3718 /** Set given colorTpl instance to the selected color in the color scheme.
3719 @param aColor color object to set.
3720 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3721 @return Returns a reference to \a aColor. */
3722 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) {
3723 csIdx = csIdx % numC;
3724 return aColor.setChansRGB(static_cast<clrChanT>(csIdx / 3 + (csIdx%3==0?1:0)),
3725 static_cast<clrChanT>(csIdx / 3 + (csIdx%3==1?1:0)),
3726 static_cast<clrChanT>(csIdx / 3 + (csIdx%3==2?1:0)));
3727 }
3728 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3729 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3730 @return Returns a colorTpl value */
3731 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3732 };
3733 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3734 /** @class csPGrey4x
3735 @ingroup cs
3736 A Pseudo-Grey color scheme with 4 * mjr::colorTpl::chanStepMax colors. */
3737 class csPGrey4x {
3738 public:
3739 constexpr static csIntType numC = 4*chanStepMax;
3740 /** Set given colorTpl instance to the selected color in the color scheme.
3741 @param aColor color object to set.
3742 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3743 @return Returns a reference to \a aColor. */
3744 static inline colorTpl& c(colorRefType aColor, csIntType csIdx) {
3745 csIdx = csIdx % numC;
3746 return aColor.setChansRGB(static_cast<clrChanT>(csIdx / 4 + ((csIdx+1)%4==0?1:0)),
3747 static_cast<clrChanT>(csIdx / 4 + ((csIdx+2)%4==0?1:0)),
3748 static_cast<clrChanT>(csIdx / 4 + ((csIdx+3)%4==0?1:0)));
3749 }
3750 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3751 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3752 @return Returns a colorTpl value */
3753 static inline colorTpl c(csIntType csIdx) { colorTpl tmp; return c(tmp, csIdx); }
3754 };
3755 //@}
3756
3757 //========================================================================================================================================================
3758 /** @name Color Schemes: HSL Saturation Ramps */
3759 //@{
3760 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3761 /** @class csHSLhR
3762 @ingroup cs
3763 @extends csHSLh_tpl
3764 HSL color scheme extending from the center of the HSL color space to the red vertex.
3765 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3766 typedef csHSLh_tpl<cornerColorEnum::RED> csHSLhR;
3767 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3768 /** @class csHSLhG
3769 @ingroup cs
3770 @extends csHSLh_tpl
3771 HSL color scheme extending from the center of the HSL color space to the green vertex.
3772 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3773 typedef csHSLh_tpl<cornerColorEnum::GREEN> csHSLhG;
3774 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3775 /** @class csHSLhB
3776 @ingroup cs
3777 @extends csHSLh_tpl
3778 HSL color scheme extending from the center of the HSL color space to the blue vertex.
3779 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3780 typedef csHSLh_tpl<cornerColorEnum::BLUE> csHSLhB;
3781 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3782 /** @class csHSLhC
3783 @ingroup cs
3784 @extends csHSLh_tpl
3785 HSL color scheme extending from the center of the HSL color space to the cyan vertex.
3786 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3787 typedef csHSLh_tpl<cornerColorEnum::CYAN> csHSLhC;
3788 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3789 /** @class csHSLhM
3790 @ingroup cs
3791 @extends csHSLh_tpl
3792 HSL color scheme extending from the center of the HSL color space to the magenta vertex.
3793 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3794 typedef csHSLh_tpl<cornerColorEnum::MAGENTA> csHSLhM;
3795 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3796 /** @class csHSLhY
3797 @ingroup cs
3798 @extends csHSLh_tpl
3799 HSL color scheme extending from the center of the HSL color space to the yellow vertex.
3800 Provides mjr::colorTpl::meanChanVal unique colors for integral clrChanT. For floating point clrChanT, csIdx may be any value in [0, mjr::colorTpl::meanChanVal]. */
3801 typedef csHSLh_tpl<cornerColorEnum::YELLOW> csHSLhY;
3802 //@}
3803
3804 //========================================================================================================================================================
3805 /** @name Color Schemes: Rainbows */
3806 //@{
3807 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3808 /** @class csRainbowLA
3809 @ingroup cs
3810 Computes a color value based upon a linear approximation of the color match functions used to approximate wavelength to RGB conversion.
3811 The linear color function approximation is not very accurate, but it is quite attractive. */
3812 class csRainbowLA {
3813 public:
3814 /** Set given colorTpl instance to the selected color in the color scheme.
3815 @param aColor color object to set.
3816 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3817 @param numC Number of colors to provide
3818 @return Returns a reference to \a aColor. */
3819 static inline colorTpl& c(colorRefType aColor, csIntType csIdx, csIntType numC) {
3820 csIdx = mjr::math::ivl::wrapCC(csIdx, numC);
3821 return aColor.setRGBfromWavelengthLA(mjr::math::linm::gen_map(static_cast<double>(csIdx),
3822 static_cast<double>(0),
3823 static_cast<double>(numC),
3824 static_cast<double>(minWavelength),
3825 static_cast<double>(maxWavelength)));
3826 }
3827 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3828 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3829 @param numC Number of colors to provide
3830 @return Returns a reference a colorTpl value. */
3831 static inline colorTpl c(csIntType csIdx, csIntType numC) {
3832 colorTpl tmp;
3833 return c(tmp, numC, csIdx);
3834 }
3835 };
3836 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3837 /** @class csRainbowCM
3838 @ingroup cs
3839 Computes a color value based upon an algorithm to convert wavelength to RGB that uses the Color Matching functions.
3840 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum) */
3841 class csRainbowCM {
3842 public:
3843 /** Set given colorTpl instance to the selected color in the color scheme.
3844 @param aColor color object to set.
3845 @param numC Number of colors to provide.
3846 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3847 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
3848 @return Returns a reference to \a aColor. */
3849 static inline colorTpl& c(colorRefType aColor, csIntType csIdx, csIntType numC, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
3850 csIdx = mjr::math::ivl::wrapCC(csIdx, numC);
3851 return aColor.setRGBfromWavelengthCM(mjr::math::linm::gen_map(static_cast<double>(csIdx),
3852 static_cast<double>(0),
3853 static_cast<double>(numC),
3854 static_cast<double>(minWavelength),
3855 static_cast<double>(maxWavelength)),
3856 interpMethod);
3857 }
3858 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
3859 @param csIdx Index of color in pallet. Wrapped to [0, numC-1].
3860 @param numC Number of colors to provide.
3861 @param interpMethod Specify the interpolation method (see: cmfInterpolationEnum)
3862 @return Returns a reference a colorTpl value. */
3863 static inline colorTpl c(csIntType csIdx, csIntType numC, cmfInterpolationEnum interpMethod = cmfInterpolationEnum::LINEAR) {
3864 colorTpl tmp;
3865 return c(tmp, numC, csIdx, interpMethod);
3866 }
3867 };
3868 //@}
3869
3870 //========================================================================================================================================================
3871 /** @name "Web Safe" Color Schemes */
3872 //@{
3873 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3874 /** @class csWSnormalVision
3875 @ingroup cs
3876 @extends csWS_tpl
3877 The "web safe" color pallet of 216 colors as seen by someone with normal color vision.
3878 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)
3879 pallet for color reduction. The colors are ordered in lexicographical ordering based upon the hexadecimal web-based color name scheme "#RRGGBB" --
3880 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(). */
3881 typedef csWS_tpl<0x000000, 0x000033, 0x000066, 0x000099, 0x0000CC, 0x0000FF, 0x003300, 0x003333, 0x003366, 0x003399, 0x0033CC,
3882 0x0033FF, 0x006600, 0x006633, 0x006666, 0x006699, 0x0066CC, 0x0066FF, 0x009900, 0x009933, 0x009966, 0x009999,
3883 0x0099CC, 0x0099FF, 0x00CC00, 0x00CC33, 0x00CC66, 0x00CC99, 0x00CCCC, 0x00CCFF, 0x00FF00, 0x00FF33, 0x00FF66,
3884 0x00FF99, 0x00FFCC, 0x00FFFF, 0x330000, 0x330033, 0x330066, 0x330099, 0x3300CC, 0x3300FF, 0x333300, 0x333333,
3885 0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336600, 0x336633, 0x336666, 0x336699, 0x3366CC, 0x3366FF, 0x339900,
3886 0x339933, 0x339966, 0x339999, 0x3399CC, 0x3399FF, 0x33CC00, 0x33CC33, 0x33CC66, 0x33CC99, 0x33CCCC, 0x33CCFF,
3887 0x33FF00, 0x33FF33, 0x33FF66, 0x33FF99, 0x33FFCC, 0x33FFFF, 0x660000, 0x660033, 0x660066, 0x660099, 0x6600CC,
3888 0x6600FF, 0x663300, 0x663333, 0x663366, 0x663399, 0x6633CC, 0x6633FF, 0x666600, 0x666633, 0x666666, 0x666699,
3889 0x6666CC, 0x6666FF, 0x669900, 0x669933, 0x669966, 0x669999, 0x6699CC, 0x6699FF, 0x66CC00, 0x66CC33, 0x66CC66,
3890 0x66CC99, 0x66CCCC, 0x66CCFF, 0x66FF00, 0x66FF33, 0x66FF66, 0x66FF99, 0x66FFCC, 0x66FFFF, 0x990000, 0x990033,
3891 0x990066, 0x990099, 0x9900CC, 0x9900FF, 0x993300, 0x993333, 0x993366, 0x993399, 0x9933CC, 0x9933FF, 0x996600,
3892 0x996633, 0x996666, 0x996699, 0x9966CC, 0x9966FF, 0x999900, 0x999933, 0x999966, 0x999999, 0x9999CC, 0x9999FF,
3893 0x99CC00, 0x99CC33, 0x99CC66, 0x99CC99, 0x99CCCC, 0x99CCFF, 0x99FF00, 0x99FF33, 0x99FF66, 0x99FF99, 0x99FFCC,
3894 0x99FFFF, 0xCC0000, 0xCC0033, 0xCC0066, 0xCC0099, 0xCC00CC, 0xCC00FF, 0xCC3300, 0xCC3333, 0xCC3366, 0xCC3399,
3895 0xCC33CC, 0xCC33FF, 0xCC6600, 0xCC6633, 0xCC6666, 0xCC6699, 0xCC66CC, 0xCC66FF, 0xCC9900, 0xCC9933, 0xCC9966,
3896 0xCC9999, 0xCC99CC, 0xCC99FF, 0xCCCC00, 0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCCC, 0xCCCCFF, 0xCCFF00, 0xCCFF33,
3897 0xCCFF66, 0xCCFF99, 0xCCFFCC, 0xCCFFFF, 0xFF0000, 0xFF0033, 0xFF0066, 0xFF0099, 0xFF00CC, 0xFF00FF, 0xFF3300,
3898 0xFF3333, 0xFF3366, 0xFF3399, 0xFF33CC, 0xFF33FF, 0xFF6600, 0xFF6633, 0xFF6666, 0xFF6699, 0xFF66CC, 0xFF66FF,
3899 0xFF9900, 0xFF9933, 0xFF9966, 0xFF9999, 0xFF99CC, 0xFF99FF, 0xFFCC00, 0xFFCC33, 0xFFCC66, 0xFFCC99, 0xFFCCCC,
3900 0xFFCCFF, 0xFFFF00, 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFFFFFF> csWSnormalVision;
3901 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3902 /** @class csWSprotanopia
3903 @ingroup cs
3904 @extends csWS_tpl
3905 The "web safe" color pallet of 216 colors as seen by someone with Protanopia.
3906 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSprotanopiaAlt. */
3907 typedef csWS_tpl<0x000000, 0x002346, 0x004487, 0x0060C1, 0x0078F0, 0x719CFF, 0x312C00, 0x2E2E30, 0x0D3366, 0x0053A6,
3908 0x006FDE, 0x5B91FF, 0x635800, 0x61592E, 0x5C5B5F, 0x4E5F93, 0x1A66CC, 0x007EFE, 0x948500, 0x93852D, 0x90865E,
3909 0x8A898F, 0x7E8DC2, 0x6792F8, 0xC5B000, 0xC5B12B, 0xC3B25D, 0xBFB38D, 0xB8B6BF, 0xADBAF2, 0xF6DC00, 0xF6DD29,
3910 0xF5DD5C, 0xF2DF8C, 0xEDE1BD, 0xE6E4EE, 0x1E1B08, 0x002448, 0x00468B, 0x0062C4, 0x0079F2, 0x739DFF, 0x373200,
3911 0x343333, 0x19376A, 0x0054AA, 0x0070E1, 0x6094FF, 0x655B00, 0x645B2F, 0x5E5D61, 0x506195, 0x2067CD, 0x2581FF,
3912 0x958600, 0x95862E, 0x92875E, 0x8C8A90, 0x7F8EC3, 0x6993FA, 0xC6B100, 0xC6B22C, 0xC4B25D, 0xC0B48E, 0xB9B7BF,
3913 0xAEBBF2, 0xF7DD00, 0xF7DD29, 0xF5DE5C, 0xF3DF8C, 0xEEE2BD, 0xE7E5EF, 0x3C360F, 0x323748, 0x00478E, 0x0065CA,
3914 0x007CF8, 0x7AA1FF, 0x4A420B, 0x46433A, 0x324676, 0x0059B4, 0x0074EA, 0x6E9AFF, 0x6F6300, 0x6D6432, 0x686666,
3915 0x59699C, 0x326ED5, 0x518DFF, 0x9B8B00, 0x9B8B2F, 0x988C61, 0x918F93, 0x8593C7, 0x6E98FE, 0xCAB500, 0xCAB52D,
3916 0xC8B65E, 0xC4B88F, 0xBDBBC1, 0xB2BEF5, 0xFAE000, 0xFAE02A, 0xF8E15D, 0xF6E28D, 0xF1E4BF, 0xEAE7F0, 0x5A5117,
3917 0x55514A, 0x39538F, 0x0067D0, 0x2782FF, 0x83A6FF, 0x635913, 0x5F5941, 0x505B80, 0x005EBF, 0x007AF6, 0x7DA2FF,
3918 0x7F720D, 0x7E7237, 0x78746D, 0x6A77A5, 0x497BDF, 0x709BFF, 0xA69500, 0xA59532, 0xA29665, 0x9B9899, 0x8F9CCE,
3919 0x83A4FF, 0xD2BC00, 0xD1BC2F, 0xCFBD61, 0xCBBF93, 0xC4C1C6, 0xB9C5FA, 0xFFE41C, 0xFFE532, 0xFEE65E, 0xFBE790,
3920 0xF7E9C1, 0xEFECF4, 0x786C1E, 0x746C4C, 0x646D90, 0x356FD5, 0x5D91FF, 0x8CABFF, 0x7E711B, 0x7B7146, 0x707387,
3921 0x5275C8, 0x4387FF, 0x8AAAFF, 0x948415, 0x92853C, 0x8C8675, 0x7F88AF, 0x648CEB, 0x87A7FF, 0xB5A20E, 0xB5A336,
3922 0xB1A46A, 0xAAA5A0, 0x9EA8D7, 0x98B1FF, 0xDDC600, 0xDDC631, 0xDBC764, 0xD7C997, 0xCFCBCB, 0xC4CEFF, 0xFFE655,
3923 0xFFE75C, 0xFFE873, 0xFFEB97, 0xFFF1C5, 0xF8F4F8, 0x968726, 0x93874E, 0x888892, 0x6E89D7, 0x7BA0FF, 0x96B1FF,
3924 0x9A8B23, 0x988B4A, 0x8F8C8B, 0x7A8ECE, 0x779DFF, 0x96B1FF, 0xAC9A1E, 0xAA9A42, 0xA59B7C, 0x999DB9, 0x82A0F6,
3925 0x98B2FF, 0xC8B317, 0xC7B43A, 0xC4B470, 0xBDB6A8, 0xB1B8E0, 0xAABDFF, 0xECD30F, 0xECD435, 0xE9D469, 0xE5D69D,
3926 0xDED8D2, 0xCFD7FF, 0xFFE871, 0xFFE975, 0xFFEA86, 0xFFEDA2, 0xFFF2C8, 0xFFFAFA> csWSprotanopia;
3927 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3928 /** @class csWSdeutanopia
3929 @ingroup cs
3930 @extends csWS_tpl
3931 The "web safe" color pallet of 216 colors as seen by someone with Deutanopia.
3932 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSdeutanopiaAlt. */
3933 typedef csWS_tpl<0x000000, 0x002135, 0x004168, 0x005E97, 0x0076BE, 0x008BDF, 0x362A0C, 0x2F2D34, 0x003E68, 0x005E9A, 0x0078C2,
3934 0x008CE2, 0x6D5418, 0x6A5538, 0x5E5A69, 0x3D629A, 0x0078C9, 0x0090EC, 0xA37E25, 0xA27E3D, 0x9B816C, 0x8D869D,
3935 0x728ECF, 0x3398FF, 0xDAA831, 0xD9A844, 0xD4AA6F, 0xCBAEA0, 0xBBB3D1, 0xA5BBFF, 0xFFCD72, 0xFFCD77, 0xFFCF87,
3936 0xFFD3A6, 0xFBDAD4, 0xE6DCFF, 0x221A00, 0x131E30, 0x003F67, 0x005D96, 0x0076BF, 0x008BDF, 0x3D2F09, 0x373133,
3937 0x003B65, 0x005D99, 0x0078C2, 0x008CE2, 0x705617, 0x6D5737, 0x615B68, 0x43639A, 0x0078C9, 0x0090EC, 0xA58600,
3938 0xA4803C, 0x9D826B, 0x8F879D, 0x758FCE, 0x3999FF, 0xDBA830, 0xDAA943, 0xD6AB6F, 0xCCAEA0, 0xBDB4D1, 0xA7BBFF,
3939 0xFFCD74, 0xFFCD78, 0xFFCF88, 0xFFD4A6, 0xFCDBD4, 0xE7DDFF, 0x453500, 0x3F352F, 0x253D60, 0x005A94, 0x0076BF,
3940 0x008BE1, 0x534000, 0x4F4031, 0x3D4763, 0x005995, 0x0076C2, 0x008CE4, 0x7B5E11, 0x795F35, 0x6F6367, 0x586A98,
3941 0x0076C9, 0x0090EE, 0xAC8421, 0xAA853B, 0xA4876A, 0x978C9C, 0x8093CD, 0x519CFE, 0xE0AC2E, 0xDFAC42, 0xDAAE6E,
3942 0xD2B29F, 0xC3B7D1, 0xADBEFF, 0xFFCE79, 0xFFCF7C, 0xFFD08B, 0xFFD5A7, 0xFFDDD3, 0xEBDFFF, 0x674F00, 0x634E2C,
3943 0x57535F, 0x385B90, 0x0073C0, 0x008CE5, 0x705600, 0x6C552D, 0x625961, 0x496192, 0x0073C2, 0x008DE8, 0x8E6C00,
3944 0x8C6D31, 0x847064, 0x737696, 0x507FC7, 0x0090F3, 0xA69500, 0xB78E37, 0xB29068, 0xA6949A, 0x929BCC, 0x6FA4FD,
3945 0xE9B22A, 0xE8B33F, 0xE4B56C, 0xDBB89D, 0xCEBDCF, 0xB9C4FF, 0xFFD080, 0xFFD184, 0xFFD291, 0xFFD6A9, 0xFFDDD0,
3946 0xF4E4FF, 0x886900, 0x856726, 0x7E6A5E, 0x6E7190, 0x4B7AC0, 0x008CEC, 0x8F6D00, 0x8C6C27, 0x856F5F, 0x767591,
3947 0x577EC2, 0x008DEF, 0xA67F00, 0xA47E2B, 0x9E8161, 0x918694, 0x7B8DC5, 0x4C97F6, 0xCA9A00, 0xC99B32, 0xC49D65,
3948 0xBAA198, 0xAAA7C9, 0x8FAEFB, 0xF6C600, 0xF5BC3B, 0xF1BE6A, 0xEAC19B, 0xDEC6CD, 0xCBCCFF, 0xFFD389, 0xFFD38C,
3949 0xFFD497, 0xFFD8AB, 0xFFDECC, 0xFFEAFD, 0xA98200, 0xA8801A, 0xA2835B, 0x97888E, 0x838FC0, 0x5E98F1, 0xAE8600,
3950 0xAD841C, 0xA7875C, 0x9D8B8F, 0x8A92C1, 0x679BF2, 0xC09300, 0xBF9322, 0xBB955E, 0xB19992, 0xA09FC3, 0x85A7F5,
3951 0xDFAA00, 0xDEAB2A, 0xDAAC62, 0xD2B095, 0xC5B5C7, 0xB0BCF9, 0xFFC750, 0xFFC857, 0xFFCA6F, 0xFCCD99, 0xF1D2CB,
3952 0xE1D8FD, 0xFFD592, 0xFFD594, 0xFFD79D, 0xFFDAAD, 0xFFDFC8, 0xFFE8EF> csWSdeutanopia;
3953 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3954 /** @class csWStritanoptia
3955 @ingroup cs
3956 @extends csWS_tpl
3957 The "web safe" color pallet of 216 colors as seen by someone with Tritanoptia.
3958 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWStritanoptiaAlt. */
3959 typedef csWS_tpl<0x000000, 0x001C1D, 0x003739, 0x005155, 0x006A6E, 0x007F85, 0x173033, 0x0A3236, 0x004347, 0x00595E, 0x006F74,
3960 0x008389, 0x2D5F66, 0x2A6068, 0x15656D, 0x00727A, 0x00828A, 0x00929A, 0x448F9A, 0x42909A, 0x39929D, 0x1F97A3,
3961 0x00A1AC, 0x00ACB7, 0x5ABFCD, 0x59BFCD, 0x54C1CF, 0x47C4D3, 0x29CAD9, 0x00D0DF, 0x73EDFF, 0x73EDFF, 0x73EEFF,
3962 0x72EEFF, 0x70EFFF, 0x6EEFFF, 0x330600, 0x301517, 0x212A2D, 0x00474B, 0x006469, 0x007C82, 0x363033, 0x333236,
3963 0x263C41, 0x005056, 0x006A70, 0x008187, 0x415F66, 0x3F6068, 0x35656D, 0x146D76, 0x007F87, 0x009099, 0x518F9A,
3964 0x4F909A, 0x49929D, 0x3997A3, 0x00A0AC, 0x00ABB7, 0x64BFD7, 0x63BFCD, 0x5EC1CF, 0x54C4D3, 0x3ECAD9, 0x00D1E0,
3965 0x7AEDFF, 0x7AEDFF, 0x79EEFF, 0x78EEFF, 0x76EFFF, 0x74EFFF, 0x660B00, 0x651615, 0x602B2D, 0x563F44, 0x42545B,
3966 0x006B73, 0x673033, 0x663336, 0x623D41, 0x584C51, 0x445D64, 0x007179, 0x6C5F66, 0x6B6067, 0x67656C, 0x5E6D75,
3967 0x4D7982, 0x228791, 0x758F9A, 0x74909A, 0x71929D, 0x6997A3, 0x5A9FAB, 0x3EA9B6, 0x82BECD, 0x81BFCD, 0x7EC1CF,
3968 0x77C4D3, 0x6BCAD9, 0x57D1E1, 0x92EDFF, 0x92EDFF, 0x90EEFF, 0x8EEEFF, 0x8BEFFF, 0x88EFFF, 0x991100, 0x981612,
3969 0x962B2C, 0x904044, 0x87555B, 0x796A71, 0x9A3032, 0x993335, 0x963D40, 0x914C51, 0x885D64, 0x7A7078, 0x9D5F66,
3970 0x9C6067, 0x9A656C, 0x946D75, 0x8C7982, 0x7E8791, 0xA28F99, 0xA2909A, 0x9F929D, 0x9A97A3, 0x929FAB, 0x86A9B6,
3971 0xABBECD, 0xAABFCD, 0xA8C1CF, 0xA3C4D3, 0x9CCAD9, 0x91D1E1, 0xB6EDFF, 0xB5EDFF, 0xB4EEFF, 0xB0EEFF, 0xACEFFF,
3972 0xA6EFFF, 0xCC1600, 0xCB170B, 0xCA2B2B, 0xC64043, 0xC0555A, 0xB76A71, 0xCC3030, 0xCC3334, 0xCA3D3F, 0xC64C50,
3973 0xC15E64, 0xB87178, 0xCF5F65, 0xCE6067, 0xCC656C, 0xC96E75, 0xC37982, 0xBB8791, 0xD38F99, 0xD2909A, 0xD0929D,
3974 0xCD98A2, 0xC79FAB, 0xBFA9B6, 0xD9BECC, 0xD8BFCD, 0xD7C1CF, 0xD3C4D3, 0xCECAD9, 0xC6D1E1, 0xE0EEFF, 0xE0EEFF,
3975 0xDDEEFF, 0xD9EEFF, 0xD3EFFF, 0xCBEFFF, 0xFE1C00, 0xFE1A00, 0xFD2B28, 0xFA4042, 0xF6555A, 0xF06A71, 0xFF3331,
3976 0xFF3332, 0xFE3D3E, 0xFB4C4F, 0xF75E63, 0xF07178, 0xFF6569, 0xFF656A, 0xFF666C, 0xFD6E74, 0xF87981, 0xF28791,
3977 0xFF949C, 0xFF949D, 0xFF959E, 0xFF99A2, 0xFC9FAA, 0xF6A9B5, 0xFFBECA, 0xFFBFCA, 0xFFC0CD, 0xFFC4D1, 0xFFCAD8,
3978 0xFBD1E1, 0xFFE4F2, 0xFFE5F3, 0xFFE6F5, 0xFFEAF9, 0xFDEFFF, 0xF4F0FF> csWStritanoptia;
3979 //--------------------------------------------------------------------------------------------------------------------------------------------------------
3980 /** @class csWSprotanopiaAlt
3981 @ingroup cs
3982 @extends csWS_tpl
3983 The "web safe" color pallet of 216 colors as seen by someone with Protanopia.
3984 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSprotanopia. */
3985 typedef csWS_tpl<0x000000, 0x000E33, 0x001D66, 0x002B99, 0x003ACC, 0x0048FF, 0x422F00, 0x303133, 0x003566, 0x003D99, 0x0047CC,
3986 0x0053FF, 0x845D00, 0x7E5E33, 0x606266, 0x266699, 0x006BCC, 0x0072FF, 0xC68C00, 0xC38D33, 0xB38F66, 0x909399,
3987 0x6896CC, 0x009BFF, 0xFFBB00, 0xFFBB32, 0xFCBD66, 0xE6C099, 0xC0C4CC, 0x9DC7FF, 0xFFE900, 0xFFEA31, 0xFFEB65,
3988 0xFFED99, 0xFFF1CC, 0xF0F5FF, 0x1A1202, 0x001633, 0x002166, 0x002E99, 0x003BCC, 0x0049FF, 0x453100, 0x333333,
3989 0x003766, 0x003F99, 0x0048CC, 0x0053FF, 0x855E00, 0x7F5F33, 0x616366, 0x2A6699, 0x006CCC, 0x0072FF, 0xC78C00,
3990 0xC38D33, 0xB48F66, 0x919499, 0x6997CC, 0x009BFF, 0xFFBB00, 0xFFBB32, 0xFCBD66, 0xE6C099, 0xC0C5CC, 0x9DC8FF,
3991 0xFFEA00, 0xFFEA31, 0xFFEB65, 0xFFED99, 0xFFF1CC, 0xF0F6FF, 0x332405, 0x1D2733, 0x002D66, 0x003699, 0x0042CC,
3992 0x004EFF, 0x4F3804, 0x413A33, 0x003E66, 0x004499, 0x004DCC, 0x0057FF, 0x8A6100, 0x846233, 0x666666, 0x376999,
3993 0x006ECC, 0x0075FF, 0xC98E00, 0xC68F33, 0xB79166, 0x939599, 0x6E99CC, 0x009DFF, 0xFFBC00, 0xFFBD32, 0xFEBE66,
3994 0xE8C199, 0xC2C6CC, 0xA0C9FF, 0xFFEA00, 0xFFEB32, 0xFFEC65, 0xFFEE99, 0xFFF2CC, 0xF2F6FF, 0x4D3607, 0x3E3833,
3995 0x003C66, 0x004399, 0x004CCC, 0x0057FF, 0x604407, 0x564533, 0x2E4966, 0x004E99, 0x0056CC, 0x005FFF, 0x926703,
3996 0x8D6833, 0x726C66, 0x496F99, 0x0074CC, 0x007AFF, 0xCE9200, 0xCB9233, 0xBD9566, 0x999999, 0x769CCC, 0x00A0FF,
3997 0xFFBF00, 0xFFBF32, 0xFFC166, 0xEDC499, 0xC6C8CC, 0xA5CBFF, 0xFFEC00, 0xFFED32, 0xFFEE66, 0xFFF099, 0xFFF4CC,
3998 0xF4F8FF, 0x66490A, 0x5E4A33, 0x3A4E66, 0x005299, 0x0059CC, 0x0062FF, 0x745209, 0x6D5333, 0x4D5766, 0x005B99,
3999 0x0061CC, 0x0069FF, 0x9E7008, 0x9A7133, 0x837466, 0x5E7899, 0x007CCC, 0x0081FF, 0xD69700, 0xD39833, 0xC59A66,
4000 0xA59E99, 0x82A1CC, 0x16A5FF, 0xFFC300, 0xFFC333, 0xFFC466, 0xF3C799, 0xCCCCCC, 0xACCFFF, 0xFFEF00, 0xFFEF32,
4001 0xFFF166, 0xFFF399, 0xFFF6CC, 0xF9FBFF, 0x805B0C, 0x7A5C34, 0x5C6066, 0x006399, 0x0069CC, 0x0070FF, 0x8A620C,
4002 0x856334, 0x676766, 0x396A99, 0x006FCC, 0x0076FF, 0xAE7B0B, 0xAA7C34, 0x967E66, 0x738299, 0x2786CC, 0x008BFF,
4003 0xE19F08, 0xDE9F33, 0xD1A166, 0xB3A599, 0x90A9CC, 0x4FACFF, 0xFFC800, 0xFFC833, 0xFFCA66, 0xFCCC99, 0xD7D1CC,
4004 0xB7D4FF, 0xFFF300, 0xFFF332, 0xFFF466, 0xFFF799, 0xFFFACC, 0xFFFFFF> csWSprotanopiaAlt;
4005 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4006 /** @class csWSdeutanopiaAlt
4007 @ingroup cs
4008 @extends csWS_tpl
4009 The "web safe" color pallet of 216 colors as seen by someone with Deutanopia.
4010 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWSdeutanopia. */
4011 typedef csWS_tpl<0x000000, 0x001433, 0x002866, 0x003C99, 0x0050CB, 0x0064FE, 0x3A2A0B, 0x2C2F33, 0x003866, 0x004699, 0x0057CB,
4012 0x0069FE, 0x755316, 0x6F5635, 0x585D67, 0x226599, 0x0070CC, 0x007EFF, 0xAF7D20, 0xAC7E39, 0x9E8468, 0x848C9A,
4013 0x5F93CC, 0x009DFF, 0xEAA72B, 0xE8A83F, 0xDFAB6B, 0xCBB29B, 0xAFBBCD, 0x8FC2FF, 0xFFD036, 0xFFD146, 0xFFD46E,
4014 0xFFD99D, 0xF7E1CE, 0xDBE9FF, 0x231800, 0x001F33, 0x002D66, 0x003F99, 0x0052CB, 0x0065FE, 0x412E09, 0x333333,
4015 0x003C66, 0x004999, 0x0059CB, 0x006BFE, 0x775515, 0x725735, 0x5B5F66, 0x2C6799, 0x0072CC, 0x007FFE, 0xB17E20,
4016 0xAE7F39, 0xA08568, 0x858D9A, 0x6294CC, 0x009EFF, 0xEBA72B, 0xE9A83F, 0xE0AC6B, 0xCCB39B, 0xB0BBCD, 0x91C2FF,
4017 0xFFD136, 0xFFD246, 0xFFD46E, 0xFFDA9D, 0xF8E2CE, 0xDCEAFF, 0x453000, 0x393532, 0x003E65, 0x004B98, 0x005ACB,
4018 0x006CFE, 0x563C00, 0x4D4032, 0x2C4865, 0x005398, 0x0061CB, 0x0071FE, 0x825C11, 0x7D5E34, 0x666666, 0x446D99,
4019 0x0077CC, 0x0084FE, 0xB7821E, 0xB48338, 0xA78968, 0x8C9199, 0x6C98CC, 0x00A1FF, 0xEFAA2A, 0xEDAB3E, 0xE4AF6A,
4020 0xD2B69B, 0xB5BECD, 0x97C5FF, 0xFFD335, 0xFFD445, 0xFFD66E, 0xFFDC9D, 0xFCE4CE, 0xE0ECFF, 0x684900, 0x624B2F,
4021 0x485364, 0x005C98, 0x0069CB, 0x0077FE, 0x725000, 0x6D5230, 0x545A64, 0x106398, 0x006ECB, 0x007CFE, 0x946800,
4022 0x906A32, 0x7E7165, 0x617898, 0x0081CB, 0x008DFE, 0xC38A1A, 0xC08B37, 0xB49067, 0x999999, 0x7E9FCC, 0x38A8FF,
4023 0xF7B027, 0xF5B13D, 0xEDB46A, 0xDBBB9B, 0xBEC4CD, 0xA3CAFF, 0xFFD733, 0xFFD844, 0xFFDA6D, 0xFFE09D, 0xFFE7CE,
4024 0xE7F0FF, 0x8B6100, 0x87632C, 0x736A63, 0x537297, 0x007BCA, 0x0087FE, 0x926600, 0x8E682C, 0x7B6F63, 0x5E7697,
4025 0x007FCA, 0x008BFE, 0xAC7900, 0xA97A2F, 0x9A8064, 0x7F8897, 0x5790CB, 0x009AFE, 0xD4960E, 0xD19734, 0xC79B66,
4026 0xB0A398, 0x94ABCB, 0x68B2FE, 0xFFB822, 0xFFB93A, 0xFABC68, 0xEAC39A, 0xCCCCCC, 0xB3D2FF, 0xFFDE30, 0xFFDE42,
4027 0xFFE16C, 0xFFE69C, 0xFFEDCD, 0xF1F6FF, 0xAE7900, 0xAB7A26, 0x9D8061, 0x818996, 0x5B90CA, 0x009AFD, 0xB37D00,
4028 0xB07E27, 0xA38461, 0x878C96, 0x6494CA, 0x009DFD, 0xC78C00, 0xC58D2A, 0xB99162, 0x9F9A96, 0x83A1CA, 0x47AAFD,
4029 0xE9A400, 0xE7A52F, 0xDEA964, 0xCAB097, 0xAEB9CA, 0x8DC0FE, 0xFFC319, 0xFFC436, 0xFFC767, 0xFDCD99, 0xE2D6CB,
4030 0xC8DDFE, 0xFFE62B, 0xFFE73F, 0xFFE96B, 0xFFEE9B, 0xFFF5CD, 0xFFFFFF> csWSdeutanopiaAlt;
4031 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4032 /** @class csWStritanoptiaAlt
4033 @ingroup cs
4034 @extends csWS_tpl
4035 The "web safe" color pallet of 216 colors as seen by someone with Tritanoptia.
4036 For more about web safe colors, see mjr::colorTpl::csWSnormalVision. Also seemjr::colorTpl::csWStritanoptia. */
4037 typedef csWS_tpl<0x000000, 0x00191E, 0x00323D, 0x004B5B, 0x00647A, 0x007C98, 0x202E31, 0x113237, 0x00404A, 0x005463, 0x006A7F,
4038 0x00819C, 0x415C61, 0x3C5D63, 0x21646D, 0x00707E, 0x008093, 0x0093AC, 0x618A92, 0x5F8B93, 0x548F99, 0x3296A4,
4039 0x00A1B4, 0x00AFC7, 0x82B8C2, 0x80B8C3, 0x79BBC7, 0x69C0CF, 0x42C8DA, 0x00D3EA, 0xA2E6F3, 0xA1E6F3, 0x9CE8F6,
4040 0x91ECFC, 0x7DF2FF, 0x53FAFF, 0x340010, 0x2C1A1C, 0x00333A, 0x004B5A, 0x006479, 0x007D98, 0x392E2F, 0x333333,
4041 0x004147, 0x005462, 0x006A7E, 0x00819C, 0x4D5C5F, 0x4A5E62, 0x39646C, 0x00707D, 0x008093, 0x0093AB, 0x698A91,
4042 0x678B92, 0x5D8F98, 0x4296A3, 0x00A1B3, 0x00AFC6, 0x87B8C1, 0x85B8C2, 0x7FBBC6, 0x70C0CE, 0x4FC8DA, 0x00D3E9,
4043 0xA6E6F2, 0xA5E6F3, 0xA0E8F6, 0x95ECFC, 0x82F2FF, 0x5CFAFF, 0x670021, 0x651527, 0x583338, 0x364E52, 0x006674,
4044 0x007E94, 0x692C35, 0x673139, 0x5B4244, 0x3C565B, 0x006C7A, 0x008298, 0x725C5E, 0x705E60, 0x666666, 0x507278,
4045 0x00818F, 0x0094A8, 0x838B8D, 0x818C8E, 0x7B9094, 0x6B97A0, 0x46A2B0, 0x00B0C4, 0x9AB8BF, 0x99B9C0, 0x94BCC4,
4046 0x88C1CC, 0x71C9D8, 0x3CD4E7, 0xB5E6F0, 0xB4E7F1, 0xB0E9F4, 0xA7ECFA, 0x97F3FF, 0x7AFBFF, 0x9B0031, 0x990035,
4047 0x933041, 0x854D54, 0x686969, 0x1C808C, 0x9C293F, 0x9A2E42, 0x943F4C, 0x86565B, 0x6B6E6F, 0x288591, 0xA15B63,
4048 0xA05D65, 0x9A656A, 0x8D7275, 0x758387, 0x4496A2, 0xAC8B8E, 0xAA8C8F, 0xA59092, 0x999999, 0x86A4AA, 0x63B2BF,
4049 0xBABABA, 0xB9BABB, 0xB5BDBF, 0xADC2C7, 0x9DCAD3, 0x83D5E3, 0xD0E7EC, 0xCFE8ED, 0xCBEAF0, 0xC4EDF6, 0xB7F3FF,
4050 0xA3FCFF, 0xCE0042, 0xCD0044, 0xC92A4E, 0xC04A5D, 0xB1676F, 0x978284, 0xCF214C, 0xCE284E, 0xCA3C56, 0xC15463,
4051 0xB26D75, 0x988788, 0xD3596B, 0xD25B6C, 0xCE6371, 0xC5717B, 0xB68388, 0x9E9899, 0xDA8A92, 0xD98B93, 0xD58F97,
4052 0xCD989D, 0xBFA5A7, 0xAAB4B6, 0xE5B9BD, 0xE4BABE, 0xE0BDC0, 0xD9C3C5, 0xCCCCCC, 0xBBD6DD, 0xF3E8E9, 0xF2E9E9,
4053 0xEFEBEB, 0xE9EFF0, 0xDFF5FA, 0xD0FDFF, 0xFF0052, 0xFF0054, 0xFE205B, 0xF84668, 0xED6478, 0xDD818B, 0xFF095A,
4054 0xFF1B5C, 0xFF3662, 0xF8506E, 0xEE6B7D, 0xDE858F, 0xFF5674, 0xFF5875, 0xFF607A, 0xFB6F83, 0xF1818F, 0xE1979E,
4055 0xFF8898, 0xFF8999, 0xFF8E9C, 0xFF96A3, 0xF7A3AC, 0xE8B3B8, 0xFFB8C1, 0xFFB9C2, 0xFFBCC4, 0xFFC2C9, 0xFFCBD0,
4056 0xF2D7D9, 0xFFE7EC, 0xFFE8ED, 0xFFEAEE, 0xFFEFF2, 0xFFF6F7, 0xFFFFFF> csWStritanoptiaAlt;
4057 //@}
4058 //========================================================================================================================================================
4059 /** @name Interesting Pallets */
4060 //@{
4061 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4062 /** @class csFPcircular12
4063 @ingroup cs
4064 @extends csFP_tpl */
4065 typedef csFP_tpl<0xFF0000, 0xFF7D00, 0xFFFF00, 0x7DFF00, 0x66CC00, 0x66FFB2, 0x00FFFF,
4066 0x007DFF, 0x0000FF, 0x7D00FF, 0xFF00FF, 0xFF007D> csFPcircular12;
4067 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4068 /** @class csFPcircular24
4069 @ingroup cs
4070 @extends csFP_tpl */
4071 typedef csFP_tpl<0xFF0000, 0xFF3F00, 0xFF7D00, 0xFFBE00, 0xFFE100, 0xFFFF00, 0x7DFF00, 0x7DCC00, 0x009600, 0x00BE00, 0x00FF5A,
4072 0x00FFBE, 0x00FFFF, 0x00BEFF, 0x007DFF, 0x003FFF, 0x0000FF, 0x3F00FF, 0x7D00FF, 0xBE00FF, 0xFF00FF, 0xFF00BE,
4073 0xFF007D, 0xFF003F> csFPcircular24;
4074 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4075 /** @class csFPblAqGrYeOrReVi200
4076 @ingroup cs
4077 @extends csFP_tpl */
4078 typedef csFP_tpl<0x0000FF, 0x0008FF, 0x000FFF, 0x0017FF, 0x001FFF, 0x0027FF, 0x002EFF, 0x0036FF, 0x003EFF, 0x0046FF, 0x004DFF,
4079 0x0055FF, 0x005DFF, 0x0064FF, 0x006CFF, 0x0074FF, 0x007CFF, 0x0083FF, 0x008BFF, 0x0093FF, 0x009BFF, 0x00A2FF,
4080 0x00AAFF, 0x00B2FF, 0x00B9FF, 0x00C1FF, 0x00C9FF, 0x00D1FF, 0x00D8FF, 0x00E0FF, 0x00E8FF, 0x00F0FF, 0x00F7FF,
4081 0x00FFFF, 0x00FDF8, 0x00FAF0, 0x01F8E9, 0x01F6E2, 0x01F3DB, 0x01F1D3, 0x02EFCC, 0x02EDC5, 0x02EABE, 0x02E8B6,
4082 0x03E6AF, 0x03E3A8, 0x03E1A0, 0x03DF99, 0x04DC92, 0x04DA8B, 0x04D883, 0x04D67C, 0x05D375, 0x05D16E, 0x05CF66,
4083 0x05CC5F, 0x06CA58, 0x06C850, 0x06C549, 0x06C342, 0x07C13B, 0x07BF33, 0x07BC2C, 0x07BA25, 0x08B81E, 0x08B516,
4084 0x08B30F, 0x0FB50F, 0x17B70E, 0x1EBA0E, 0x25BC0D, 0x2CBE0D, 0x34C00C, 0x3BC30C, 0x42C50B, 0x49C70B, 0x51C90B,
4085 0x58CC0A, 0x5FCE0A, 0x66D009, 0x6ED209, 0x75D508, 0x7CD708, 0x84D908, 0x8BDB07, 0x92DD07, 0x99E006, 0xA1E206,
4086 0xA8E405, 0xAFE605, 0xB6E904, 0xBEEB04, 0xC5ED04, 0xCCEF03, 0xD3F203, 0xDBF402, 0xE2F602, 0xE9F801, 0xF0FB01,
4087 0xF8FD00, 0xFFFF00, 0xFFFC00, 0xFFFA00, 0xFFF700, 0xFFF400, 0xFFF100, 0xFFEF00, 0xFFEC00, 0xFFE900, 0xFFE600,
4088 0xFFE400, 0xFFE100, 0xFFDE00, 0xFFDC00, 0xFFD900, 0xFFD600, 0xFFD300, 0xFFD100, 0xFFCE00, 0xFFCB00, 0xFFC800,
4089 0xFFC600, 0xFFC300, 0xFFC000, 0xFFBE00, 0xFFBB00, 0xFFB800, 0xFFB500, 0xFFB300, 0xFFB000, 0xFFAD00, 0xFFAA00,
4090 0xFFA800, 0xFFA500, 0xFFA000, 0xFF9B00, 0xFF9600, 0xFF9100, 0xFF8C00, 0xFF8700, 0xFF8200, 0xFF7D00, 0xFF7800,
4091 0xFF7300, 0xFF6E00, 0xFF6900, 0xFF6400, 0xFF5F00, 0xFF5A00, 0xFF5500, 0xFF5000, 0xFF4B00, 0xFF4600, 0xFF4100,
4092 0xFF3C00, 0xFF3700, 0xFF3200, 0xFF2D00, 0xFF2800, 0xFF2300, 0xFF1E00, 0xFF1900, 0xFF1400, 0xFF0F00, 0xFF0A00,
4093 0xFF0500, 0xFF0000, 0xFA0004, 0xF50008, 0xF0000C, 0xEB0010, 0xE60015, 0xE00019, 0xDB001D, 0xD60021, 0xD10025,
4094 0xCC0029, 0xC7002D, 0xC20031, 0xBD0036, 0xB8003A, 0xB3003E, 0xAE0042, 0xA80046, 0xA3004A, 0x9E004E, 0x990052,
4095 0x940057, 0x8F005B, 0x8A005F, 0x850063, 0x800067, 0x7B006B, 0x76006F, 0x700073, 0x6B0078, 0x66007C, 0x610080,
4096 0x5C0084, 0x570088> csFPblAqGrYeOrReVi200;
4097 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4098 /** @class csFPcmoceanAlgae
4099 @ingroup cs
4100 @extends csFP_tpl */
4101 typedef csFP_tpl<0xD7F9D0, 0xD6F8CE, 0xD4F7CD, 0xD3F6CB, 0xD2F5CA, 0xD1F4C8, 0xCFF4C7, 0xCEF3C5, 0xCDF2C4, 0xCCF1C3, 0xCAF0C1,
4102 0xC9EFC0, 0xC8EEBE, 0xC7EDBD, 0xC5ECBB, 0xC4EBBA, 0xC3EBB9, 0xC2EAB7, 0xC0E9B6, 0xBFE8B4, 0xBEE7B3, 0xBDE6B1,
4103 0xBBE5B0, 0xBAE4AF, 0xB9E4AD, 0xB8E3AC, 0xB6E2AB, 0xB5E1A9, 0xB4E0A8, 0xB2DFA6, 0xB1DEA5, 0xB0DEA4, 0xAFDDA2,
4104 0xADDCA1, 0xACDBA0, 0xABDA9E, 0xAADA9D, 0xA8D99C, 0xA7D89A, 0xA6D799, 0xA4D698, 0xA3D596, 0xA2D595, 0xA0D494,
4105 0x9FD392, 0x9ED291, 0x9DD190, 0x9BD18F, 0x9AD08D, 0x99CF8C, 0x97CE8B, 0x96CD8A, 0x95CD88, 0x93CC87, 0x92CB86,
4106 0x91CA85, 0x8FCA83, 0x8EC982, 0x8CC881, 0x8BC780, 0x8AC77E, 0x88C67D, 0x87C57C, 0x85C47B, 0x84C47A, 0x83C379,
4107 0x81C277, 0x80C176, 0x7EC175, 0x7DC074, 0x7BBF73, 0x7ABE72, 0x78BE71, 0x77BD6F, 0x75BC6E, 0x74BB6D, 0x72BB6C,
4108 0x71BA6B, 0x6FB96A, 0x6EB969, 0x6CB868, 0x6BB767, 0x69B666, 0x67B665, 0x66B564, 0x64B463, 0x62B462, 0x61B361,
4109 0x5FB260, 0x5DB25F, 0x5BB15E, 0x5AB05D, 0x58AF5D, 0x56AF5C, 0x54AE5B, 0x52AD5A, 0x50AD59, 0x4EAC59, 0x4CAB58,
4110 0x4AAB57, 0x48AA57, 0x46A956, 0x44A855, 0x42A855, 0x3FA754, 0x3DA654, 0x3BA654, 0x39A553, 0x37A453, 0x34A353,
4111 0x32A352, 0x30A252, 0x2EA152, 0x2CA052, 0x2AA052, 0x289F51, 0x269E51, 0x249D51, 0x229C51, 0x209C51, 0x1E9B51,
4112 0x1C9A51, 0x1B9951, 0x199851, 0x189750, 0x169650, 0x159650, 0x139550, 0x129450, 0x109350, 0x0F9250, 0x0E9150,
4113 0x0D904F, 0x0C8F4F, 0x0B8F4F, 0x0A8E4F, 0x098D4F, 0x098C4F, 0x088B4E, 0x088A4E, 0x07894E, 0x07884E, 0x07874D,
4114 0x07864D, 0x07864D, 0x07854D, 0x07844D, 0x07834C, 0x07824C, 0x08814C, 0x08804B, 0x087F4B, 0x097E4B, 0x097D4B,
4115 0x0A7C4A, 0x0A7C4A, 0x0B7B4A, 0x0B7A49, 0x0C7949, 0x0C7849, 0x0D7748, 0x0D7648, 0x0E7548, 0x0E7447, 0x0F7347,
4116 0x0F7347, 0x107246, 0x107146, 0x117045, 0x116F45, 0x126E45, 0x126D44, 0x126C44, 0x136B43, 0x136A43, 0x146A43,
4117 0x146942, 0x146842, 0x156741, 0x156641, 0x156540, 0x166440, 0x166340, 0x16623F, 0x17623F, 0x17613E, 0x17603E,
4118 0x175F3D, 0x185E3D, 0x185D3C, 0x185C3C, 0x185B3B, 0x185B3B, 0x195A3A, 0x19593A, 0x195839, 0x195739, 0x195638,
4119 0x195538, 0x195437, 0x195437, 0x1A5336, 0x1A5235, 0x1A5135, 0x1A5034, 0x1A4F34, 0x1A4E33, 0x1A4D33, 0x1A4D32,
4120 0x1A4C32, 0x1A4B31, 0x1A4A30, 0x1A4930, 0x1A482F, 0x1A472F, 0x1A472E, 0x1A462E, 0x1A452D, 0x1A442C, 0x1A432C,
4121 0x19422B, 0x19412B, 0x19402A, 0x194029, 0x193F29, 0x193E28, 0x193D27, 0x193C27, 0x183B26, 0x183B26, 0x183A25,
4122 0x183924, 0x183824, 0x183723, 0x173622, 0x173522, 0x173521, 0x173420, 0x173320, 0x16321F, 0x16311E, 0x16301E,
4123 0x162F1D, 0x152F1C, 0x152E1C, 0x152D1B, 0x142C1A, 0x142B1A, 0x142A19, 0x142918, 0x132918, 0x132817, 0x132716,
4124 0x122616, 0x122515, 0x122414> csFPcmoceanAlgae;
4125 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4126 /** @class csFPcmoceanAmp
4127 @ingroup cs
4128 @extends csFP_tpl */
4129 typedef csFP_tpl<0xF1EDEC, 0xF1ECEB, 0xF0EBE9, 0xEFE9E8, 0xEFE8E7, 0xEEE7E5, 0xEEE6E4, 0xEDE5E3, 0xEDE3E1, 0xECE2E0, 0xECE1DE,
4130 0xEBE0DD, 0xEBDFDC, 0xEADDDA, 0xEADCD9, 0xE9DBD7, 0xE9DAD6, 0xE9D9D4, 0xE8D8D3, 0xE8D6D2, 0xE7D5D0, 0xE7D4CF,
4131 0xE6D3CD, 0xE6D2CC, 0xE6D1CA, 0xE5CFC9, 0xE5CEC8, 0xE4CDC6, 0xE4CCC5, 0xE4CBC3, 0xE3C9C2, 0xE3C8C0, 0xE2C7BF,
4132 0xE2C6BD, 0xE2C5BC, 0xE1C4BB, 0xE1C3B9, 0xE1C1B8, 0xE0C0B6, 0xE0BFB5, 0xDFBEB3, 0xDFBDB2, 0xDFBCB0, 0xDEBAAF,
4133 0xDEB9AE, 0xDEB8AC, 0xDDB7AB, 0xDDB6A9, 0xDDB5A8, 0xDCB4A6, 0xDCB2A5, 0xDCB1A3, 0xDBB0A2, 0xDBAFA1, 0xDBAE9F,
4134 0xDAAD9E, 0xDAAC9C, 0xD9AA9B, 0xD9A999, 0xD9A898, 0xD8A796, 0xD8A695, 0xD8A594, 0xD7A492, 0xD7A291, 0xD7A18F,
4135 0xD6A08E, 0xD69F8C, 0xD69E8B, 0xD59D89, 0xD59C88, 0xD59A87, 0xD49985, 0xD49884, 0xD49782, 0xD39681, 0xD3957F,
4136 0xD3947E, 0xD2927D, 0xD2917B, 0xD2907A, 0xD18F78, 0xD18E77, 0xD18D76, 0xD08C74, 0xD08B73, 0xD08971, 0xCF8870,
4137 0xCF876F, 0xCF866D, 0xCE856C, 0xCE846A, 0xCD8369, 0xCD8168, 0xCD8066, 0xCC7F65, 0xCC7E64, 0xCC7D62, 0xCB7C61,
4138 0xCB7A60, 0xCB795E, 0xCA785D, 0xCA775B, 0xC9765A, 0xC97559, 0xC97457, 0xC87256, 0xC87155, 0xC87054, 0xC76F52,
4139 0xC76E51, 0xC66D50, 0xC66B4E, 0xC66A4D, 0xC5694C, 0xC5684A, 0xC56749, 0xC46548, 0xC46447, 0xC36346, 0xC36244,
4140 0xC36143, 0xC25F42, 0xC25E41, 0xC15D3F, 0xC15C3E, 0xC05B3D, 0xC0593C, 0xC0583B, 0xBF573A, 0xBF5639, 0xBE5438,
4141 0xBE5336, 0xBD5235, 0xBD5134, 0xBD4F33, 0xBC4E32, 0xBC4D31, 0xBB4C30, 0xBB4A30, 0xBA492F, 0xBA482E, 0xB9462D,
4142 0xB9452C, 0xB8442B, 0xB8422B, 0xB7412A, 0xB74029, 0xB63F29, 0xB53D28, 0xB53C27, 0xB43B27, 0xB43926, 0xB33826,
4143 0xB23726, 0xB23525, 0xB13425, 0xB03325, 0xB03125, 0xAF3024, 0xAE2F24, 0xAE2D24, 0xAD2C24, 0xAC2B24, 0xAB2A24,
4144 0xAA2824, 0xAA2724, 0xA92624, 0xA82524, 0xA72424, 0xA62225, 0xA52125, 0xA42025, 0xA31F25, 0xA21E25, 0xA11D25,
4145 0xA01C26, 0x9F1B26, 0x9E1A26, 0x9D1926, 0x9C1827, 0x9B1727, 0x9A1627, 0x991527, 0x981527, 0x971428, 0x951328,
4146 0x941328, 0x931228, 0x921128, 0x911129, 0x901029, 0x8E1029, 0x8D1029, 0x8C0F29, 0x8B0F29, 0x890F29, 0x880F29,
4147 0x870E29, 0x850E29, 0x840E29, 0x830E29, 0x810E29, 0x800E29, 0x7F0E29, 0x7D0E29, 0x7C0E29, 0x7B0E29, 0x790E29,
4148 0x780E28, 0x770E28, 0x750E28, 0x740E28, 0x730E27, 0x710E27, 0x700E27, 0x6F0E26, 0x6D0E26, 0x6C0F26, 0x6B0F25,
4149 0x690F25, 0x680F25, 0x670F24, 0x650F24, 0x640E23, 0x630E23, 0x610E22, 0x600E22, 0x5F0E21, 0x5D0E21, 0x5C0E21,
4150 0x5B0E20, 0x5A0E1F, 0x580E1F, 0x570E1E, 0x560E1E, 0x540D1D, 0x530D1D, 0x520D1C, 0x510D1C, 0x4F0D1B, 0x4E0D1A,
4151 0x4D0C1A, 0x4B0C19, 0x4A0C19, 0x490C18, 0x480B17, 0x460B17, 0x450B16, 0x440B16, 0x430A15, 0x410A14, 0x400A14,
4152 0x3F0A13, 0x3D0912, 0x3C0912> csFPcmoceanAmp;
4153 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4154 /** @class csFPcmoceanBalance
4155 @ingroup cs
4156 @extends csFP_tpl */
4157 typedef csFP_tpl<0x181C43, 0x191E46, 0x1A1F49, 0x1B214C, 0x1C224F, 0x1D2352, 0x1E2555, 0x1F2658, 0x20275B, 0x21295F, 0x212A62,
4158 0x222B65, 0x232D69, 0x242E6C, 0x252F6F, 0x253073, 0x263276, 0x27337A, 0x27347D, 0x283681, 0x283784, 0x293888,
4159 0x293A8C, 0x293B8F, 0x293C93, 0x293E97, 0x293F9A, 0x29409E, 0x2942A2, 0x2843A5, 0x2745A9, 0x2647AC, 0x2548B0,
4160 0x234AB3, 0x214CB6, 0x1F4EB8, 0x1C50BA, 0x1952BC, 0x1655BD, 0x1357BE, 0x1059BE, 0x0D5BBE, 0x0C5EBE, 0x0A60BE,
4161 0x0A62BE, 0x0A64BE, 0x0B66BD, 0x0D68BD, 0x0F6ABD, 0x116CBC, 0x136EBC, 0x1670BC, 0x1972BB, 0x1B74BB, 0x1E76BB,
4162 0x2178BB, 0x237ABA, 0x267BBA, 0x297DBA, 0x2B7FBA, 0x2E81BA, 0x3083BA, 0x3384BA, 0x3686BA, 0x3888BA, 0x3B89BA,
4163 0x3E8BBA, 0x408DBA, 0x438FBA, 0x4690BA, 0x4892BA, 0x4B94BA, 0x4E95BA, 0x5197BA, 0x5399BA, 0x569ABB, 0x599CBB,
4164 0x5C9DBB, 0x5F9FBB, 0x62A0BB, 0x65A2BC, 0x68A4BC, 0x6BA5BC, 0x6EA7BD, 0x71A8BD, 0x75AABE, 0x78ABBE, 0x7BACBF,
4165 0x7EAEBF, 0x81AFC0, 0x85B1C0, 0x88B2C1, 0x8BB4C2, 0x8EB5C3, 0x91B7C3, 0x94B8C4, 0x98BAC5, 0x9BBBC6, 0x9EBCC7,
4166 0xA1BEC8, 0xA4BFC9, 0xA7C1CA, 0xAAC2CB, 0xADC4CC, 0xB0C5CD, 0xB3C7CE, 0xB6C9CF, 0xB9CAD0, 0xBCCCD2, 0xBFCDD3,
4167 0xC1CFD4, 0xC4D0D5, 0xC7D2D7, 0xCAD4D8, 0xCDD5D9, 0xD0D7DA, 0xD3D9DC, 0xD5DADD, 0xD8DCDE, 0xDBDEE0, 0xDEE0E1,
4168 0xE1E1E3, 0xE3E3E4, 0xE6E5E6, 0xE9E7E7, 0xEBE9E9, 0xEEEAEA, 0xF1ECEC, 0xF1ECEB, 0xF0EAE9, 0xEFE8E6, 0xEEE5E3,
4169 0xEDE3E0, 0xECE0DE, 0xEBDEDB, 0xEADCD8, 0xE9D9D5, 0xE8D7D2, 0xE7D5CF, 0xE6D2CD, 0xE5D0CA, 0xE5CEC7, 0xE4CBC4,
4170 0xE3C9C1, 0xE2C7BE, 0xE1C4BB, 0xE1C2B8, 0xE0C0B5, 0xDFBDB2, 0xDFBBB0, 0xDEB9AD, 0xDDB6AA, 0xDCB4A7, 0xDCB2A4,
4171 0xDBAFA1, 0xDAAD9E, 0xDAAB9B, 0xD9A998, 0xD8A696, 0xD8A493, 0xD7A290, 0xD69F8D, 0xD69D8A, 0xD59B87, 0xD49984,
4172 0xD39681, 0xD3947F, 0xD2927C, 0xD18F79, 0xD18D76, 0xD08B73, 0xCF8970, 0xCF866E, 0xCE846B, 0xCD8268, 0xCD7F65,
4173 0xCC7D63, 0xCB7B60, 0xCA795D, 0xCA765B, 0xC97458, 0xC87255, 0xC76F53, 0xC76D50, 0xC66B4D, 0xC5684B, 0xC46648,
4174 0xC36346, 0xC36143, 0xC25F41, 0xC15C3F, 0xC05A3C, 0xBF573A, 0xBE5538, 0xBE5236, 0xBD5034, 0xBC4D32, 0xBB4B30,
4175 0xBA482E, 0xB9452C, 0xB8432B, 0xB74029, 0xB63D28, 0xB43B27, 0xB33826, 0xB23525, 0xB13325, 0xAF3024, 0xAE2E24,
4176 0xAC2B24, 0xAB2924, 0xA92624, 0xA72424, 0xA52125, 0xA31F25, 0xA11D25, 0x9F1B26, 0x9D1926, 0x9B1727, 0x991627,
4177 0x971428, 0x941328, 0x921228, 0x901029, 0x8D1029, 0x8B0F29, 0x880F29, 0x860E29, 0x830E29, 0x800E29, 0x7E0E29,
4178 0x7B0E29, 0x780E28, 0x760E28, 0x730E27, 0x700E27, 0x6D0E26, 0x6B0F25, 0x680F25, 0x650F24, 0x630E23, 0x600E22,
4179 0x5E0E21, 0x5B0E20, 0x580E1F, 0x560E1E, 0x530D1D, 0x510D1C, 0x4E0D1B, 0x4B0C19, 0x490C18, 0x460B17, 0x440B16,
4180 0x410A14, 0x3F0A13, 0x3C0912> csFPcmoceanBalance;
4181 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4182 /** @class csFPcmoceanCurl
4183 @ingroup cs
4184 @extends csFP_tpl */
4185 typedef csFP_tpl<0x151D44, 0x151F45, 0x162146, 0x162347, 0x172548, 0x172749, 0x18294A, 0x182B4B, 0x182D4C, 0x192F4D, 0x19314F,
4186 0x1A3350, 0x1A3551, 0x1A3652, 0x1B3853, 0x1B3A54, 0x1B3C56, 0x1B3E57, 0x1C4058, 0x1C4259, 0x1C435A, 0x1C455B,
4187 0x1C475D, 0x1C495E, 0x1C4B5F, 0x1C4C60, 0x1C4E61, 0x1C5062, 0x1C5263, 0x1C5465, 0x1B5666, 0x1B5867, 0x1B5968,
4188 0x1A5B69, 0x1A5D6A, 0x1A5F6B, 0x19616C, 0x19636D, 0x18656E, 0x17666F, 0x176870, 0x166A71, 0x156C72, 0x146E73,
4189 0x147074, 0x137275, 0x127476, 0x127676, 0x117777, 0x117978, 0x117B79, 0x117D79, 0x117F7A, 0x12817B, 0x13837B,
4190 0x14847C, 0x16867C, 0x17887D, 0x1A8A7D, 0x1C8C7E, 0x1F8D7E, 0x228F7E, 0x25917F, 0x29937F, 0x2C947F, 0x309680,
4191 0x349880, 0x389981, 0x3B9B81, 0x3F9C81, 0x439E82, 0x479F82, 0x4BA183, 0x50A284, 0x54A484, 0x57A585, 0x5BA686,
4192 0x5FA887, 0x63A988, 0x67AB89, 0x6BAC8A, 0x6FAD8B, 0x72AF8C, 0x76B08D, 0x7AB18E, 0x7DB390, 0x81B491, 0x85B593,
4193 0x88B794, 0x8BB896, 0x8FBA97, 0x92BB99, 0x96BC9B, 0x99BE9D, 0x9CBF9F, 0xA0C0A0, 0xA3C2A2, 0xA6C3A4, 0xA9C5A6,
4194 0xACC6A9, 0xB0C8AB, 0xB3C9AD, 0xB6CBAF, 0xB9CCB2, 0xBCCEB4, 0xBFCFB6, 0xC2D1B9, 0xC5D2BB, 0xC8D4BE, 0xCBD5C0,
4195 0xCED7C3, 0xD1D8C5, 0xD3DAC8, 0xD6DCCB, 0xD9DDCD, 0xDCDFD0, 0xDFE1D3, 0xE2E2D6, 0xE4E4D8, 0xE7E6DB, 0xEAE8DE,
4196 0xEDEAE1, 0xF0EBE4, 0xF2EDE7, 0xF5EFEA, 0xF8F1ED, 0xFBF3F0, 0xFDF5F3, 0xFEF6F5, 0xFCF4F1, 0xFBF1EE, 0xFAEFEB,
4197 0xF9ECE7, 0xF8EAE4, 0xF6E7E1, 0xF5E5DD, 0xF4E2DA, 0xF3E0D6, 0xF2DDD3, 0xF2DBD0, 0xF1D8CC, 0xF0D6C9, 0xEFD3C6,
4198 0xEED1C3, 0xEDCFBF, 0xECCCBC, 0xECCAB9, 0xEBC7B6, 0xEAC5B3, 0xE9C2AF, 0xE9C0AC, 0xE8BDA9, 0xE7BBA6, 0xE7B8A3,
4199 0xE6B6A0, 0xE5B39D, 0xE5B19A, 0xE4AE98, 0xE3AC95, 0xE3A992, 0xE2A78F, 0xE1A48D, 0xE1A28A, 0xE09F88, 0xE09D85,
4200 0xDF9A83, 0xDE9880, 0xDE957E, 0xDD937C, 0xDC907A, 0xDB8E78, 0xDB8B76, 0xDA8974, 0xD98672, 0xD88471, 0xD7816F,
4201 0xD67F6E, 0xD67C6C, 0xD57A6B, 0xD4776A, 0xD37569, 0xD27268, 0xD07067, 0xCF6E66, 0xCE6B65, 0xCD6964, 0xCC6764,
4202 0xCA6463, 0xC96263, 0xC86062, 0xC65D62, 0xC55B61, 0xC35961, 0xC25761, 0xC05561, 0xBF5360, 0xBD5160, 0xBB4E60,
4203 0xBA4C60, 0xB84A60, 0xB64860, 0xB44660, 0xB34460, 0xB14260, 0xAF4160, 0xAD3F60, 0xAB3D60, 0xA93B60, 0xA73960,
4204 0xA53760, 0xA33660, 0xA13460, 0x9F3260, 0x9D3060, 0x9B2F60, 0x992D61, 0x972B61, 0x952A61, 0x922861, 0x902760,
4205 0x8E2560, 0x8C2460, 0x892260, 0x872160, 0x852060, 0x821F60, 0x801D5F, 0x7D1C5F, 0x7B1B5E, 0x781A5E, 0x76195D,
4206 0x73195D, 0x71185C, 0x6E175B, 0x6C175A, 0x691659, 0x661658, 0x641557, 0x611556, 0x5E1455, 0x5C1453, 0x591452,
4207 0x571350, 0x54134E, 0x51134D, 0x4F124B, 0x4C1249, 0x491247, 0x471145, 0x441143, 0x421041, 0x3F103F, 0x3D0F3D,
4208 0x3A0F3B, 0x380E39, 0x350D36> csFPcmoceanCurl;
4209 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4210 /** @class csFPcmoceanDeep
4211 @ingroup cs
4212 @extends csFP_tpl */
4213 typedef csFP_tpl<0xFDFECC, 0xFBFDCB, 0xF9FCCA, 0xF7FBC8, 0xF5FAC7, 0xF3FAC6, 0xF1F9C5, 0xEFF8C4, 0xEDF7C3, 0xEBF7C1, 0xE9F6C0,
4214 0xE7F5BF, 0xE5F4BE, 0xE3F4BD, 0xE1F3BC, 0xDFF2BB, 0xDDF2BA, 0xDBF1B9, 0xD9F0B8, 0xD7EFB7, 0xD4EFB6, 0xD2EEB5,
4215 0xD0EDB4, 0xCEECB3, 0xCCECB3, 0xCAEBB2, 0xC8EAB1, 0xC6EAB0, 0xC4E9AF, 0xC1E8AF, 0xBFE7AE, 0xBDE7AD, 0xBBE6AC,
4216 0xB9E5AC, 0xB7E5AB, 0xB5E4AA, 0xB2E3AA, 0xB0E2A9, 0xAEE2A9, 0xACE1A8, 0xAAE0A8, 0xA7E0A7, 0xA5DFA7, 0xA3DEA6,
4217 0xA1DDA6, 0x9FDDA5, 0x9CDCA5, 0x9ADBA5, 0x98DAA4, 0x96DAA4, 0x94D9A4, 0x92D8A4, 0x90D7A4, 0x8DD7A3, 0x8BD6A3,
4218 0x89D5A3, 0x87D4A3, 0x85D3A3, 0x83D3A3, 0x81D2A3, 0x7FD1A3, 0x7DD0A3, 0x7CCFA3, 0x7ACEA3, 0x78CEA3, 0x76CDA3,
4219 0x75CCA3, 0x73CBA3, 0x71CAA3, 0x70C9A3, 0x6EC8A3, 0x6DC7A3, 0x6BC6A3, 0x6AC5A4, 0x69C4A4, 0x67C3A4, 0x66C2A4,
4220 0x65C2A4, 0x64C1A4, 0x63C0A4, 0x62BFA4, 0x61BEA4, 0x60BDA4, 0x5FBCA4, 0x5EBBA4, 0x5DBAA4, 0x5CB9A4, 0x5BB8A4,
4221 0x5AB7A4, 0x5AB6A4, 0x59B4A4, 0x58B3A4, 0x58B2A4, 0x57B1A4, 0x56B0A4, 0x56AFA4, 0x55AEA3, 0x55ADA3, 0x54ACA3,
4222 0x53ABA3, 0x53AAA3, 0x52A9A3, 0x52A8A3, 0x51A7A3, 0x51A6A2, 0x51A5A2, 0x50A4A2, 0x50A3A2, 0x4FA2A2, 0x4FA1A2,
4223 0x4FA0A2, 0x4E9FA1, 0x4E9EA1, 0x4D9DA1, 0x4D9CA1, 0x4D9BA1, 0x4C9AA0, 0x4C99A0, 0x4B98A0, 0x4B97A0, 0x4B96A0,
4224 0x4A959F, 0x4A949F, 0x4A939F, 0x49929F, 0x49919E, 0x49909E, 0x488F9E, 0x488E9E, 0x488D9D, 0x478C9D, 0x478B9D,
4225 0x478A9D, 0x46899D, 0x46889C, 0x46879C, 0x45869C, 0x45859C, 0x45849B, 0x44839B, 0x44829B, 0x44819B, 0x44809B,
4226 0x437F9A, 0x437E9A, 0x437D9A, 0x427C9A, 0x427B99, 0x427A99, 0x427999, 0x417899, 0x417799, 0x417698, 0x407598,
4227 0x407498, 0x407398, 0x407298, 0x407197, 0x3F7097, 0x3F6F97, 0x3F6E97, 0x3F6D97, 0x3F6C96, 0x3E6B96, 0x3E6A96,
4228 0x3E6996, 0x3E6896, 0x3E6795, 0x3E6695, 0x3E6595, 0x3E6495, 0x3E6394, 0x3E6294, 0x3E6194, 0x3E6094, 0x3E5F93,
4229 0x3E5E93, 0x3E5C93, 0x3E5B93, 0x3E5A92, 0x3E5992, 0x3E5892, 0x3E5791, 0x3E5691, 0x3F5590, 0x3F5490, 0x3F538F,
4230 0x3F528F, 0x3F508E, 0x404F8D, 0x404E8D, 0x404D8C, 0x404C8B, 0x414B8A, 0x414A89, 0x414988, 0x414887, 0x414785,
4231 0x414684, 0x414583, 0x414481, 0x424380, 0x41427E, 0x41417D, 0x41407B, 0x41407A, 0x413F78, 0x413E76, 0x413D75,
4232 0x403C73, 0x403C71, 0x403B70, 0x403A6E, 0x3F396C, 0x3F386B, 0x3F3869, 0x3E3767, 0x3E3666, 0x3D3564, 0x3D3562,
4233 0x3D3461, 0x3C335F, 0x3C325D, 0x3B325C, 0x3B315A, 0x3A3058, 0x3A3057, 0x392F55, 0x392E54, 0x382D52, 0x382D51,
4234 0x372C4F, 0x362B4D, 0x362A4C, 0x352A4A, 0x352949, 0x342847, 0x342846, 0x332744, 0x322643, 0x322541, 0x312540,
4235 0x30243E, 0x30233D, 0x2F223B, 0x2F223A, 0x2E2139, 0x2D2037, 0x2D1F36, 0x2C1F34, 0x2B1E33, 0x2B1D32, 0x2A1C30,
4236 0x291C2F, 0x281B2D, 0x281A2C> csFPcmoceanDeep;
4237 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4238 /** @class csFPcmoceanDense
4239 @ingroup cs
4240 @extends csFP_tpl */
4241 typedef csFP_tpl<0xE6F1F1, 0xE4F0F0, 0xE3EFEF, 0xE1EEEF, 0xDFEDEE, 0xDDEDED, 0xDCECED, 0xDAEBEC, 0xD8EAEC, 0xD7E9EB, 0xD5E9EB,
4242 0xD3E8EA, 0xD1E7EA, 0xD0E6E9, 0xCEE5E9, 0xCCE4E8, 0xCBE4E8, 0xC9E3E8, 0xC7E2E7, 0xC6E1E7, 0xC4E0E6, 0xC2DFE6,
4243 0xC1DFE6, 0xBFDEE6, 0xBEDDE5, 0xBCDCE5, 0xBADBE5, 0xB9DAE4, 0xB7DAE4, 0xB6D9E4, 0xB4D8E4, 0xB2D7E4, 0xB1D6E3,
4244 0xAFD5E3, 0xAED4E3, 0xACD4E3, 0xABD3E3, 0xA9D2E3, 0xA8D1E3, 0xA6D0E3, 0xA5CFE2, 0xA3CEE2, 0xA2CEE2, 0xA0CDE2,
4245 0x9FCCE2, 0x9ECBE2, 0x9CCAE2, 0x9BC9E2, 0x9AC8E2, 0x98C7E2, 0x97C6E2, 0x96C5E2, 0x94C5E2, 0x93C4E2, 0x92C3E2,
4246 0x90C2E2, 0x8FC1E2, 0x8EC0E2, 0x8DBFE2, 0x8CBEE2, 0x8ABDE3, 0x89BCE3, 0x88BBE3, 0x87BAE3, 0x86B9E3, 0x85B8E3,
4247 0x84B7E3, 0x83B6E3, 0x82B5E3, 0x81B4E3, 0x80B3E3, 0x7FB2E3, 0x7FB1E4, 0x7EB0E4, 0x7DAFE4, 0x7CAEE4, 0x7BADE4,
4248 0x7BACE4, 0x7AABE4, 0x79AAE4, 0x79A9E4, 0x78A8E4, 0x78A7E4, 0x77A6E4, 0x77A5E4, 0x76A4E5, 0x76A3E5, 0x75A1E5,
4249 0x75A0E5, 0x759FE5, 0x759EE5, 0x749DE5, 0x749CE4, 0x749BE4, 0x749AE4, 0x7498E4, 0x7397E4, 0x7396E4, 0x7395E4,
4250 0x7394E4, 0x7393E3, 0x7391E3, 0x7390E3, 0x738FE3, 0x738EE2, 0x748DE2, 0x748BE2, 0x748AE2, 0x7489E1, 0x7488E1,
4251 0x7487E0, 0x7485E0, 0x7584DF, 0x7583DF, 0x7582DE, 0x7581DE, 0x757FDD, 0x757EDD, 0x767DDC, 0x767CDC, 0x767BDB,
4252 0x7679DA, 0x7678DA, 0x7777D9, 0x7776D8, 0x7775D7, 0x7773D7, 0x7772D6, 0x7871D5, 0x7870D4, 0x786FD3, 0x786ED2,
4253 0x786CD2, 0x786BD1, 0x786AD0, 0x7969CF, 0x7968CE, 0x7966CD, 0x7965CC, 0x7964CB, 0x7963CA, 0x7962C9, 0x7961C8,
4254 0x7960C7, 0x795EC5, 0x795DC4, 0x795CC3, 0x795BC2, 0x795AC1, 0x7959C0, 0x7958BF, 0x7957BD, 0x7956BC, 0x7954BB,
4255 0x7953BA, 0x7952B8, 0x7951B7, 0x7950B6, 0x794FB5, 0x784EB3, 0x784DB2, 0x784CB1, 0x784BAF, 0x784AAE, 0x7849AD,
4256 0x7748AB, 0x7747AA, 0x7746A9, 0x7745A7, 0x7743A6, 0x7642A5, 0x7641A3, 0x7640A2, 0x763FA0, 0x753E9F, 0x753D9D,
4257 0x753C9C, 0x743B9B, 0x743B99, 0x743A98, 0x733996, 0x733895, 0x733793, 0x723692, 0x723590, 0x72348F, 0x71338D,
4258 0x71328C, 0x70318A, 0x703088, 0x6F2F87, 0x6F2E85, 0x6E2D84, 0x6E2D82, 0x6D2C81, 0x6D2B7F, 0x6C2A7E, 0x6C297C,
4259 0x6B287A, 0x6B2879, 0x6A2777, 0x6A2675, 0x692574, 0x682472, 0x682471, 0x67236F, 0x67226D, 0x66216C, 0x65216A,
4260 0x652068, 0x641F67, 0x631F65, 0x621E63, 0x621D62, 0x611D60, 0x601C5E, 0x5F1B5D, 0x5F1B5B, 0x5E1A59, 0x5D1A58,
4261 0x5C1956, 0x5B1954, 0x5A1853, 0x5A1851, 0x591750, 0x58174E, 0x57164C, 0x56164B, 0x551649, 0x541548, 0x531546,
4262 0x521544, 0x511443, 0x501441, 0x4F1440, 0x4E133E, 0x4D133D, 0x4B133B, 0x4A133A, 0x491238, 0x481237, 0x471236,
4263 0x461234, 0x451133, 0x441132, 0x421130, 0x41112F, 0x40102E, 0x3F102D, 0x3E102B, 0x3C102A, 0x3B0F29, 0x3A0F28,
4264 0x390F27, 0x380F25, 0x360E24> csFPcmoceanDense;
4265 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4266 /** @class csFPcmoceanHaline
4267 @ingroup cs
4268 @extends csFP_tpl */
4269 typedef csFP_tpl<0x2A186C, 0x2A196E, 0x2A1971, 0x2B1973, 0x2B1975, 0x2C1A78, 0x2C1A7A, 0x2D1A7D, 0x2D1A7F, 0x2D1B82, 0x2E1B84,
4270 0x2E1B87, 0x2E1C89, 0x2E1C8C, 0x2E1C8E, 0x2E1D91, 0x2E1D93, 0x2E1E95, 0x2E1E98, 0x2E1F9A, 0x2D209C, 0x2D219D,
4271 0x2C229F, 0x2B24A0, 0x2A25A1, 0x2927A2, 0x2829A3, 0x262BA3, 0x252DA3, 0x242EA3, 0x2230A3, 0x2132A2, 0x2034A2,
4272 0x1E35A1, 0x1D37A1, 0x1C39A0, 0x1B3AA0, 0x193C9F, 0x183D9E, 0x173F9E, 0x16409D, 0x15419C, 0x14439C, 0x13449B,
4273 0x12459B, 0x11479A, 0x104899, 0x0F4999, 0x0F4A98, 0x0E4C97, 0x0D4D97, 0x0D4E96, 0x0D4F96, 0x0C5095, 0x0C5195,
4274 0x0C5294, 0x0C5394, 0x0C5493, 0x0D5593, 0x0D5692, 0x0D5792, 0x0E5891, 0x0E5991, 0x0F5A91, 0x0F5B90, 0x105C90,
4275 0x115D8F, 0x115E8F, 0x125F8F, 0x13608E, 0x14618E, 0x14628E, 0x15638E, 0x16638D, 0x17648D, 0x18658D, 0x18668C,
4276 0x19678C, 0x1A688C, 0x1B698C, 0x1C6A8C, 0x1D6B8B, 0x1D6B8B, 0x1E6C8B, 0x1F6D8B, 0x206E8B, 0x216F8B, 0x22708A,
4277 0x22718A, 0x23718A, 0x24728A, 0x25738A, 0x26748A, 0x26758A, 0x27768A, 0x287689, 0x297789, 0x297889, 0x2A7989,
4278 0x2B7A89, 0x2B7B89, 0x2C7C89, 0x2D7C89, 0x2D7D89, 0x2E7E89, 0x2F7F89, 0x2F8089, 0x308189, 0x318289, 0x318288,
4279 0x328388, 0x338488, 0x338588, 0x348688, 0x348788, 0x358888, 0x358988, 0x368988, 0x378A88, 0x378B88, 0x388C88,
4280 0x388D88, 0x398E88, 0x398F88, 0x3A9087, 0x3A9087, 0x3B9187, 0x3B9287, 0x3C9387, 0x3C9487, 0x3D9587, 0x3D9687,
4281 0x3E9787, 0x3E9886, 0x3F9986, 0x3F9986, 0x409A86, 0x419B86, 0x419C85, 0x429D85, 0x429E85, 0x439F85, 0x43A084,
4282 0x44A184, 0x44A284, 0x45A384, 0x46A483, 0x46A483, 0x47A583, 0x48A682, 0x48A782, 0x49A882, 0x4AA981, 0x4AAA81,
4283 0x4BAB81, 0x4CAC80, 0x4CAD80, 0x4DAE7F, 0x4EAE7F, 0x4FAF7E, 0x50B07E, 0x51B17D, 0x51B27D, 0x52B37C, 0x53B47C,
4284 0x54B57B, 0x55B67B, 0x56B77A, 0x57B879, 0x58B879, 0x5AB978, 0x5BBA77, 0x5CBB77, 0x5DBC76, 0x5EBD75, 0x5FBE75,
4285 0x61BF74, 0x62BF73, 0x63C072, 0x65C172, 0x66C271, 0x68C370, 0x69C46F, 0x6BC46E, 0x6CC56E, 0x6EC66D, 0x70C76C,
4286 0x71C86B, 0x73C86A, 0x75C969, 0x77CA68, 0x78CB68, 0x7ACB67, 0x7CCC66, 0x7ECD65, 0x80CE64, 0x82CE63, 0x84CF62,
4287 0x86D062, 0x89D061, 0x8BD160, 0x8DD25F, 0x8FD25F, 0x92D35E, 0x94D35D, 0x97D45D, 0x99D45D, 0x9BD55C, 0x9ED65C,
4288 0xA0D65C, 0xA3D75C, 0xA5D75C, 0xA8D85C, 0xAAD85C, 0xADD85C, 0xAFD95D, 0xB1D95D, 0xB4DA5E, 0xB6DA5F, 0xB8DB60,
4289 0xBBDB61, 0xBDDC62, 0xBFDC63, 0xC1DD64, 0xC4DD65, 0xC6DE66, 0xC8DE67, 0xCADF69, 0xCCDF6A, 0xCEE06C, 0xD0E06D,
4290 0xD2E16F, 0xD4E170, 0xD6E272, 0xD8E273, 0xDAE375, 0xDCE377, 0xDEE479, 0xE0E57A, 0xE1E57C, 0xE3E67E, 0xE5E680,
4291 0xE7E781, 0xE9E783, 0xEBE885, 0xECE987, 0xEEE989, 0xF0EA8A, 0xF2EA8C, 0xF3EB8E, 0xF5EC90, 0xF7EC92, 0xF8ED94,
4292 0xFAEE96, 0xFCEE98, 0xFDEF9A> csFPcmoceanHaline;
4293 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4294 /** @class csFPcmoceanIce
4295 @ingroup cs
4296 @extends csFP_tpl */
4297 typedef csFP_tpl<0x040613, 0x050614, 0x050715, 0x060817, 0x070918, 0x080A1A, 0x090B1B, 0x0A0C1D, 0x0B0D1E, 0x0C0D1F, 0x0D0E21,
4298 0x0E0F22, 0x0F1024, 0x101125, 0x111227, 0x121328, 0x13132A, 0x14142B, 0x15152C, 0x16162E, 0x17172F, 0x171831,
4299 0x181832, 0x191934, 0x1A1A35, 0x1B1B37, 0x1C1C38, 0x1D1C3A, 0x1E1D3B, 0x1F1E3D, 0x1F1F3E, 0x201F40, 0x212041,
4300 0x222143, 0x232244, 0x242246, 0x252347, 0x252449, 0x26254A, 0x27254C, 0x28264E, 0x29274F, 0x292851, 0x2A2852,
4301 0x2B2954, 0x2C2A55, 0x2C2B57, 0x2D2B59, 0x2E2C5A, 0x2F2D5C, 0x2F2E5E, 0x302F5F, 0x312F61, 0x313062, 0x323164,
4302 0x333266, 0x333267, 0x343369, 0x35346B, 0x35356C, 0x36356E, 0x363670, 0x373771, 0x383873, 0x383975, 0x393976,
4303 0x393A78, 0x3A3B7A, 0x3A3C7B, 0x3A3D7D, 0x3B3E7F, 0x3B3E80, 0x3C3F82, 0x3C4084, 0x3C4185, 0x3D4287, 0x3D4389,
4304 0x3D448A, 0x3E458C, 0x3E468D, 0x3E478F, 0x3E4890, 0x3E4992, 0x3E4993, 0x3F4A95, 0x3F4B96, 0x3F4C97, 0x3F4E99,
4305 0x3F4F9A, 0x3F509B, 0x3F519D, 0x3F529E, 0x3F539F, 0x3F54A0, 0x3F55A1, 0x3F56A2, 0x3F57A3, 0x3F58A4, 0x3F59A5,
4306 0x3E5AA6, 0x3E5CA7, 0x3E5DA8, 0x3E5EA9, 0x3E5FAA, 0x3E60AB, 0x3E61AB, 0x3E62AC, 0x3E63AD, 0x3E65AD, 0x3E66AE,
4307 0x3E67AF, 0x3E68AF, 0x3E69B0, 0x3E6AB0, 0x3F6BB1, 0x3F6CB2, 0x3F6EB2, 0x3F6FB3, 0x3F70B3, 0x3F71B4, 0x4072B4,
4308 0x4073B4, 0x4074B5, 0x4075B5, 0x4176B6, 0x4178B6, 0x4279B7, 0x427AB7, 0x427BB7, 0x437CB8, 0x437DB8, 0x447EB9,
4309 0x447FB9, 0x4580B9, 0x4581BA, 0x4682BA, 0x4684BB, 0x4785BB, 0x4786BB, 0x4887BC, 0x4988BC, 0x4989BC, 0x4A8ABD,
4310 0x4B8BBD, 0x4B8CBD, 0x4C8DBE, 0x4D8EBE, 0x4E8FBF, 0x4E90BF, 0x4F91BF, 0x5092C0, 0x5194C0, 0x5195C0, 0x5296C1,
4311 0x5397C1, 0x5498C2, 0x5599C2, 0x559AC2, 0x569BC3, 0x579CC3, 0x589DC3, 0x599EC4, 0x5A9FC4, 0x5BA0C5, 0x5CA1C5,
4312 0x5DA2C5, 0x5EA3C6, 0x5FA4C6, 0x5FA6C7, 0x60A7C7, 0x61A8C7, 0x62A9C8, 0x63AAC8, 0x64ABC9, 0x65ACC9, 0x67ADC9,
4313 0x68AECA, 0x69AFCA, 0x6AB0CB, 0x6BB1CB, 0x6CB2CB, 0x6DB3CC, 0x6EB4CC, 0x6FB5CD, 0x71B6CD, 0x72B8CE, 0x73B9CE,
4314 0x74BACE, 0x75BBCF, 0x77BCCF, 0x78BDD0, 0x79BED0, 0x7BBFD0, 0x7CC0D1, 0x7DC1D1, 0x7FC2D2, 0x80C3D2, 0x82C4D3,
4315 0x83C5D3, 0x85C6D3, 0x86C7D4, 0x88C8D4, 0x89C9D5, 0x8BCAD5, 0x8CCBD6, 0x8ECCD6, 0x90CDD7, 0x92CED7, 0x93CFD8,
4316 0x95D0D8, 0x97D1D9, 0x99D2D9, 0x9AD3DA, 0x9CD4DA, 0x9ED5DB, 0xA0D6DC, 0xA2D6DC, 0xA4D7DD, 0xA6D8DE, 0xA8D9DE,
4317 0xA9DADF, 0xABDBE0, 0xADDCE0, 0xAFDDE1, 0xB1DEE2, 0xB3DFE3, 0xB5E0E3, 0xB7E1E4, 0xB9E2E5, 0xBAE3E6, 0xBCE4E7,
4318 0xBEE5E7, 0xC0E6E8, 0xC2E6E9, 0xC4E7EA, 0xC6E8EB, 0xC8E9EC, 0xC9EAED, 0xCBEBEE, 0xCDECEF, 0xCFEDEF, 0xD1EEF0,
4319 0xD3EFF1, 0xD5F0F2, 0xD6F1F3, 0xD8F2F4, 0xDAF3F5, 0xDCF4F6, 0xDEF5F7, 0xE0F6F8, 0xE1F7F9, 0xE3F9FA, 0xE5FAFB,
4320 0xE7FBFB, 0xE8FCFC, 0xEAFDFD> csFPcmoceanIce;
4321 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4322 /** @class csFPcmoceanTempo
4323 @ingroup cs
4324 @extends csFP_tpl */
4325 typedef csFP_tpl<0xFFF6F4, 0xFDF5F3, 0xFCF4F1, 0xFBF3F0, 0xF9F2EE, 0xF8F1ED, 0xF7F0EB, 0xF5EFEA, 0xF4EEE8, 0xF2EDE7, 0xF1ECE5,
4326 0xF0EBE4, 0xEEEAE2, 0xEDEAE1, 0xEBE9DF, 0xEAE8DE, 0xE9E7DD, 0xE7E6DB, 0xE6E5DA, 0xE4E4D8, 0xE3E3D7, 0xE2E2D6,
4327 0xE0E2D4, 0xDFE1D3, 0xDDE0D1, 0xDCDFD0, 0xDBDECF, 0xD9DDCD, 0xD8DDCC, 0xD6DCCB, 0xD5DBC9, 0xD3DAC8, 0xD2D9C7,
4328 0xD1D8C5, 0xCFD8C4, 0xCED7C3, 0xCCD6C1, 0xCBD5C0, 0xC9D4BF, 0xC8D4BE, 0xC6D3BC, 0xC5D2BB, 0xC3D1BA, 0xC2D1B9,
4329 0xC0D0B7, 0xBFCFB6, 0xBDCEB5, 0xBCCEB4, 0xBACDB3, 0xB9CCB2, 0xB7CBB0, 0xB6CBAF, 0xB4CAAE, 0xB3C9AD, 0xB1C8AC,
4330 0xB0C8AB, 0xAEC7AA, 0xACC6A9, 0xABC5A8, 0xA9C5A6, 0xA8C4A5, 0xA6C3A4, 0xA4C3A3, 0xA3C2A2, 0xA1C1A1, 0xA0C0A0,
4331 0x9EC09F, 0x9CBF9F, 0x9BBE9E, 0x99BE9D, 0x97BD9C, 0x96BC9B, 0x94BC9A, 0x92BB99, 0x91BA98, 0x8FBA97, 0x8DB997,
4332 0x8BB896, 0x8AB795, 0x88B794, 0x86B693, 0x85B593, 0x83B592, 0x81B491, 0x7FB390, 0x7DB390, 0x7CB28F, 0x7AB18E,
4333 0x78B18E, 0x76B08D, 0x74AF8D, 0x72AF8C, 0x71AE8B, 0x6FAD8B, 0x6DAD8A, 0x6BAC8A, 0x69AB89, 0x67AB89, 0x65AA88,
4334 0x63A988, 0x61A987, 0x5FA887, 0x5DA786, 0x5BA686, 0x59A685, 0x57A585, 0x56A485, 0x54A484, 0x52A384, 0x50A284,
4335 0x4EA183, 0x4BA183, 0x49A083, 0x479F82, 0x459F82, 0x439E82, 0x419D82, 0x3F9C81, 0x3D9C81, 0x3B9B81, 0x3A9A81,
4336 0x389981, 0x369880, 0x349880, 0x329780, 0x309680, 0x2E9580, 0x2C947F, 0x2A937F, 0x29937F, 0x27927F, 0x25917F,
4337 0x24907F, 0x228F7E, 0x218E7E, 0x1F8D7E, 0x1E8D7E, 0x1C8C7E, 0x1B8B7D, 0x1A8A7D, 0x19897D, 0x17887D, 0x16877C,
4338 0x16867C, 0x15857C, 0x14847C, 0x13847B, 0x13837B, 0x12827B, 0x12817B, 0x11807A, 0x117F7A, 0x117E7A, 0x117D79,
4339 0x117C79, 0x117B79, 0x117A78, 0x117978, 0x117878, 0x117777, 0x117677, 0x127676, 0x127576, 0x127476, 0x137375,
4340 0x137275, 0x137174, 0x147074, 0x146F73, 0x146E73, 0x156D73, 0x156C72, 0x166B72, 0x166A71, 0x166971, 0x176870,
4341 0x176770, 0x17666F, 0x18656F, 0x18656E, 0x18646E, 0x19636D, 0x19626D, 0x19616C, 0x19606C, 0x1A5F6B, 0x1A5E6B,
4342 0x1A5D6A, 0x1A5C6A, 0x1A5B69, 0x1B5A68, 0x1B5968, 0x1B5867, 0x1B5867, 0x1B5766, 0x1B5666, 0x1C5565, 0x1C5465,
4343 0x1C5364, 0x1C5263, 0x1C5163, 0x1C5062, 0x1C4F62, 0x1C4E61, 0x1C4D61, 0x1C4C60, 0x1C4C5F, 0x1C4B5F, 0x1C4A5E,
4344 0x1C495E, 0x1C485D, 0x1C475D, 0x1C465C, 0x1C455B, 0x1C445B, 0x1C435A, 0x1C425A, 0x1C4259, 0x1C4158, 0x1C4058,
4345 0x1B3F57, 0x1B3E57, 0x1B3D56, 0x1B3C56, 0x1B3B55, 0x1B3A54, 0x1B3954, 0x1B3853, 0x1A3753, 0x1A3652, 0x1A3651,
4346 0x1A3551, 0x1A3450, 0x1A3350, 0x19324F, 0x19314F, 0x19304E, 0x192F4D, 0x192E4D, 0x182D4C, 0x182C4C, 0x182B4B,
4347 0x182A4B, 0x18294A, 0x17284A, 0x172749, 0x172648, 0x172548, 0x172447, 0x162347, 0x162246, 0x162146, 0x162045,
4348 0x151F45, 0x151E44, 0x151D44> csFPcmoceanTempo;
4349 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4350 /** @class csFPmplBrBG
4351 @ingroup cs
4352 @extends csFP_tpl */
4353 typedef csFP_tpl<0x563105, 0x5A3305, 0x5E3605, 0x633906, 0x673B06, 0x6C3E07, 0x704007, 0x744307, 0x794608, 0x7B4708, 0x824B09,
4354 0x844C09, 0x8A5009, 0x8C510A, 0x93570E, 0x955910, 0x9A5F14, 0x9E6217, 0xA16418, 0xA76A1C, 0xAA6E1F, 0xAF7122,
4355 0xB17323, 0xB67927, 0xBA7D2A, 0xBF802D, 0xC08330, 0xC48B39, 0xC6903F, 0xC99546, 0xCA9749, 0xCE9F52, 0xD0A458,
4356 0xD3A95F, 0xD5AE65, 0xD8B36B, 0xDAB972, 0xDBBB75, 0xDFC27E, 0xE1C583, 0xE3C889, 0xE4CB8E, 0xE6CE94, 0xE8D199,
4357 0xEAD49F, 0xEBD6A2, 0xEDDAAA, 0xEFDDAF, 0xF1E0B5, 0xF3E3BA, 0xF5E6C0, 0xF5E8C4, 0xF5E9C8, 0xF5EACA, 0xF5EBD0,
4358 0xF5ECD4, 0xF5EDD8, 0xF5EEDC, 0xF5EFE0, 0xF5F0E4, 0xF5F1E8, 0xF5F2EA, 0xF5F3F0, 0xF5F4F4, 0xF2F4F4, 0xEEF3F2,
4359 0xEBF2F1, 0xE7F1F0, 0xE3F0EF, 0xE0F0ED, 0xDCEFEC, 0xD9EEEB, 0xD5EDEA, 0xD1ECE8, 0xCEEBE7, 0xCCEBE6, 0xC6E9E4,
4360 0xC1E7E2, 0xBBE5DF, 0xB6E3DC, 0xB0E0D9, 0xABDED6, 0xA5DCD4, 0xA0DAD1, 0x9AD7CE, 0x94D5CB, 0x8FD3C8, 0x89D0C5,
4361 0x84CEC3, 0x7ECBC0, 0x78C7BC, 0x75C5BA, 0x6CBFB4, 0x67BAB0, 0x61B6AC, 0x5BB2A8, 0x55AEA4, 0x4FAAA0, 0x49A59C,
4362 0x43A198, 0x3D9D94, 0x379990, 0x32958D, 0x2E9189, 0x2A8D85, 0x268981, 0x22857D, 0x20837B, 0x1A7E76, 0x167A72,
4363 0x12766E, 0x0E726A, 0x0A6E66, 0x066A62, 0x02665E, 0x00635B, 0x006057, 0x005C54, 0x005950, 0x00564C, 0x005349,
4364 0x004F45, 0x004C42, 0x004A40, 0x00453A, 0x004237, 0x003F33, 0x003B2F> csFPmplBrBG;
4365 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4366 /** @class csFPmplOcean
4367 @ingroup cs
4368 @extends csFP_tpl */
4369 typedef csFP_tpl<0x007E01, 0x007B03, 0x007705, 0x007507, 0x007208, 0x006E0A, 0x006B0C, 0x00690F, 0x006611, 0x006411, 0x006015,
4370 0x005E16, 0x005918, 0x00581A, 0x00541C, 0x00521D, 0x004D21, 0x004B23, 0x004923, 0x004426, 0x004228, 0x003F2A,
4371 0x003D2B, 0x00382F, 0x003631, 0x003333, 0x003134, 0x002D36, 0x002A38, 0x00263B, 0x00253B, 0x00213F, 0x001D41,
4372 0x001A42, 0x001844, 0x001546, 0x001149, 0x001049, 0x000C4D, 0x00084F, 0x000550, 0x000352, 0x000054, 0x000356,
4373 0x000559, 0x000759, 0x000C5D, 0x000F5E, 0x001160, 0x001562, 0x001864, 0x001A67, 0x001D69, 0x001F69, 0x00236D,
4374 0x00266E, 0x002A70, 0x002D72, 0x002F75, 0x003377, 0x003679, 0x003779, 0x003B7C, 0x003F7E, 0x004280, 0x004482,
4375 0x004885, 0x004B87, 0x004D89, 0x00508A, 0x00548C, 0x00568E, 0x005990, 0x005D93, 0x006095, 0x006195, 0x006699,
4376 0x00699A, 0x006B9C, 0x006E9E, 0x0072A1, 0x0075A3, 0x0077A5, 0x007BA7, 0x007EA8, 0x0380AA, 0x0883AC, 0x0F87AF,
4377 0x1589B1, 0x1A8CB3, 0x2190B5, 0x2391B5, 0x2D95B8, 0x3399BA, 0x389CBC, 0x3F9EBF, 0x44A1C1, 0x4BA5C3, 0x50A8C4,
4378 0x56AAC6, 0x5DAEC8, 0x62B1CA, 0x69B3CD, 0x6EB6CF, 0x75BAD1, 0x7BBCD3, 0x80BFD4, 0x83C1D6, 0x8CC6D8, 0x93C8DB,
4379 0x99CCDD, 0x9ECFDF, 0xA5D1E1, 0xAAD4E2, 0xB1D8E4, 0xB6DBE6, 0xBCDDE8, 0xC3E1EB, 0xC8E4ED, 0xCFE6EF, 0xD4E9F0,
4380 0xDBEDF2, 0xE1EFF4, 0xE4F1F6, 0xEDF6F9, 0xF2F9FB, 0xF9FBFD, 0xFFFFFF> csFPmplOcean;
4381 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4382 /** @class csFPmplOranges
4383 @ingroup cs
4384 @extends csFP_tpl */
4385 typedef csFP_tpl<0xFEF4EA, 0xFEF3E8, 0xFEF2E6, 0xFEF1E4, 0xFEF0E2, 0xFEEFE0, 0xFEEEDF, 0xFEEDDD, 0xFEEDDB, 0xFEECDA, 0xFEEBD7,
4386 0xFEEAD6, 0xFEE9D4, 0xFEE8D3, 0xFEE7D0, 0xFEE6CF, 0xFDE5CC, 0xFDE3C9, 0xFDE3C8, 0xFDE1C4, 0xFDDFC1, 0xFDDEBE,
4387 0xFDDDBD, 0xFDDBB9, 0xFDDAB6, 0xFDD8B3, 0xFDD8B2, 0xFDD6AE, 0xFDD4AB, 0xFDD3A8, 0xFDD2A7, 0xFDD0A3, 0xFDCE9F,
4388 0xFDCC9C, 0xFDCA98, 0xFDC895, 0xFDC692, 0xFDC590, 0xFDC18B, 0xFDBF87, 0xFDBD84, 0xFDBB80, 0xFDB97D, 0xFDB779,
4389 0xFDB576, 0xFDB374, 0xFDB06F, 0xFDAE6C, 0xFDAC68, 0xFDAA66, 0xFDA863, 0xFDA660, 0xFDA45D, 0xFDA35B, 0xFDA057,
4390 0xFD9E54, 0xFD9C51, 0xFD994E, 0xFD974B, 0xFD9548, 0xFD9345, 0xFD9244, 0xFD8F3F, 0xFD8D3C, 0xFC8B3A, 0xFB8937,
4391 0xFA8634, 0xFA8432, 0xF9822F, 0xF8802D, 0xF77D2A, 0xF77B28, 0xF67925, 0xF57622, 0xF47420, 0xF4731F, 0xF3701B,
4392 0xF26D18, 0xF16B16, 0xF16913, 0xEF6712, 0xEE6510, 0xEC630F, 0xEB610E, 0xE95F0D, 0xE85C0C, 0xE65A0B, 0xE5580A,
4393 0xE35609, 0xE25407, 0xE05206, 0xDF5106, 0xDD4E04, 0xDC4C03, 0xDA4A02, 0xD94801, 0xD64701, 0xD34501, 0xCF4401,
4394 0xCC4301, 0xC94201, 0xC64101, 0xC34001, 0xBF3F01, 0xBC3D02, 0xB93C02, 0xB63B02, 0xB43B02, 0xAF3902, 0xAC3802,
4395 0xA93702, 0xA63602, 0xA33503, 0xA13403, 0x9E3303, 0x9C3203, 0x993103, 0x973003, 0x952F03, 0x922E03, 0x902D03,
4396 0x8D2C03, 0x8B2B03, 0x8A2B03, 0x862903, 0x832803, 0x812703, 0x7E2603> csFPmplOranges;
4397 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4398 /** @class csFPneoDdivVegetationA
4399 @ingroup cs
4400 @extends csFP_tpl */
4401 typedef csFP_tpl<0x530000, 0x540000, 0x540000, 0x550000, 0x560000, 0x560000, 0x570000, 0x580000, 0x5A0000, 0x5A0000, 0x5B0000,
4402 0x5B0000, 0x5D0000, 0x5E0000, 0x5F0000, 0x600000, 0x610000, 0x610000, 0x620000, 0x630000, 0x640000, 0x650000,
4403 0x670000, 0x670000, 0x690000, 0x6A0000, 0x6B0000, 0x6C0000, 0x6D0000, 0x6E0000, 0x700000, 0x710000, 0x720000,
4404 0x740000, 0x740000, 0x760000, 0x770000, 0x790000, 0x790000, 0x7B0000, 0x7C0000, 0x7D0000, 0x7F0000, 0x800000,
4405 0x830401, 0x830702, 0x860B04, 0x870D05, 0x8A1106, 0x8C1507, 0x8E1908, 0x901D0A, 0x921F0B, 0x93220C, 0x96270D,
4406 0x972A0E, 0x992E0F, 0x9C3211, 0x9E3512, 0x9F3913, 0xA13C14, 0xA23F15, 0xA54417, 0xA74818, 0xA94B19, 0xAB501A,
4407 0xAD531B, 0xB0571D, 0xB25B1E, 0xB35D1F, 0xB66321, 0xB86722, 0xBB6C24, 0xBD6F25, 0xBF7326, 0xC0762A, 0xC1782D,
4408 0xC2792F, 0xC37C33, 0xC57F37, 0xC6813A, 0xC7843E, 0xC88641, 0xC98945, 0xCB8C49, 0xCC8E4C, 0xCC904F, 0xCE9252,
4409 0xCF9656, 0xD09859, 0xD19B5D, 0xD29D60, 0xD49F64, 0xD5A368, 0xD6A56B, 0xD7A86F, 0xD9AA73, 0xD9AC75, 0xDBB07A,
4410 0xDCB27D, 0xDDB581, 0xDFB885, 0xE0BA88, 0xE1BD8D, 0xE2C090, 0xE3C293, 0xE5C597, 0xE6C79A, 0xE7CA9E, 0xE9CDA3,
4411 0xEAD0A6, 0xEBD2A9, 0xECD5AC, 0xEDD7B0, 0xEFDAB4, 0xF0DDB8, 0xF1E1BD, 0xF2E3C0, 0xF3E5C3, 0xF5E8C7, 0xF6EBCB,
4412 0xF7EDCE, 0xF8EFD1, 0xFAF4D6, 0xFBF5D9, 0xFCF8DD, 0xFDFBE1, 0xFFFFE5, 0xFEFFE5, 0xFAFDE0, 0xF8FBDD, 0xF6FBDB,
4413 0xF4F9D7, 0xF1F8D4, 0xEFF7D1, 0xECF6CD, 0xEAF4CA, 0xE7F3C6, 0xE5F2C3, 0xE2F1BF, 0xE0EFBB, 0xDDEEB9, 0xDAEDB5,
4414 0xD8ECB1, 0xD6EAAF, 0xD2E9AB, 0xD0E8A8, 0xCDE7A5, 0xCBE5A1, 0xC8E49F, 0xC6E39B, 0xC3E297, 0xC1E194, 0xBFDF91,
4415 0xBCDE8D, 0xBADD8B, 0xB7DB86, 0xB5DA83, 0xB3D981, 0xB0D87D, 0xAED77A, 0xABD576, 0xA9D574, 0xA6D371, 0xA3D26D,
4416 0xA1D16A, 0x9ED066, 0x9CCE64, 0x9ACD60, 0x97CC5D, 0x96CB5B, 0x93CA57, 0x90C954, 0x8EC750, 0x8CC74E, 0x89C54A,
4417 0x87C448, 0x85C344, 0x83C242, 0x80C03D, 0x7FC03C, 0x7BBE39, 0x77BC37, 0x72B935, 0x6EB733, 0x6BB532, 0x67B331,
4418 0x63B02F, 0x5FAE2D, 0x5BAC2C, 0x58AB2B, 0x54A829, 0x51A628, 0x4DA426, 0x4AA325, 0x46A124, 0x429F22, 0x409D20,
4419 0x3B9A1E, 0x38991D, 0x34971C, 0x31951A, 0x2D9319, 0x299118, 0x278F17, 0x238D15, 0x1F8B13, 0x1B8913, 0x198711,
4420 0x168510, 0x13840F, 0x0F810D, 0x0C800C, 0x0C7E0C, 0x0C7D0C, 0x0B7B0B, 0x0B790B, 0x0B780B, 0x0B770B, 0x0B750B,
4421 0x0B750B, 0x0A730A, 0x0A710A, 0x0A700A, 0x0A6E0A, 0x0A6D0A, 0x0A6C0A, 0x0A6B0A, 0x096909, 0x096709, 0x096609,
4422 0x096609, 0x096409, 0x096309, 0x086108, 0x086108, 0x085F08, 0x085F08, 0x085D08, 0x085C08, 0x085A08, 0x085A08,
4423 0x075907, 0x075807, 0x075607, 0x075507, 0x075507, 0x075407, 0x075207, 0x075107, 0x065106, 0x065006, 0x064F06,
4424 0x064E06, 0x064D06, 0x064C06> csFPneoDdivVegetationA;
4425 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4426 /** @class csFPneoDivVegetationC
4427 @ingroup cs
4428 @extends csFP_tpl */
4429 typedef csFP_tpl<0x795B13, 0x865614, 0x8A5513, 0x8A5513, 0x875715, 0x875715, 0x895A0A, 0x8C590A, 0x935711, 0x945812, 0x945812,
4430 0x955913, 0x965A14, 0x975B15, 0x985C16, 0x985C16, 0x9B5F19, 0x9B5F19, 0x9C601A, 0x9C601A, 0x9D611B, 0x9E621C,
4431 0x9F631D, 0x9F631D, 0xAA681A, 0xAA681A, 0xAA681A, 0xAB691B, 0xAC6A1C, 0xAD6B1D, 0xAE6C1E, 0xAE6C1E, 0xB47224,
4432 0xB57325, 0xB67426, 0xB87628, 0xBA782A, 0xBB792B, 0xBD7B2D, 0xBD7B2D, 0xBB8231, 0xBB8231, 0xBD8433, 0xBF8635,
4433 0xC28737, 0xC38838, 0xC58A3A, 0xC58A3A, 0xC38A3B, 0xC48B3C, 0xC48D3D, 0xC68F3F, 0xC49140, 0xC69342, 0xC59543,
4434 0xC69548, 0xC89E52, 0xC99F53, 0xC9A255, 0xCAA356, 0xCDA65B, 0xCFA85D, 0xCFA95E, 0xD0AA5F, 0xD5AF66, 0xD6B067,
4435 0xD7B26B, 0xD8B36C, 0xD9B76F, 0xDBB971, 0xDCBA72, 0xDDBB73, 0xDCBE78, 0xDDBF79, 0xDEC07A, 0xE0C27C, 0xE1C47E,
4436 0xE3C684, 0xE4C785, 0xE5C789, 0xE6CA89, 0xE7CA8E, 0xE6CC8F, 0xE7CC94, 0xE9CE96, 0xEACF97, 0xEBD098, 0xECD199,
4437 0xEAD9A5, 0xEBD9A9, 0xEBDBAA, 0xEDDDAC, 0xEEDDAF, 0xF0DFB1, 0xEFE1B2, 0xF0E1B6, 0xECDFB3, 0xECDEB7, 0xEEE0B9,
4438 0xEFE1BA, 0xF0E4BE, 0xF2E6C0, 0xF3E7C1, 0xF4E8C2, 0xF0EAD0, 0xF0EAD4, 0xF1EBD5, 0xF1EBD5, 0xF1EBD5, 0xF2ECD6,
4439 0xF1ECD6, 0xF1ECD9, 0xF0EDDA, 0xF1EEDF, 0xF0EEDF, 0xF0EEDF, 0xF1EFE0, 0xF1EFE0, 0xF1EFE0, 0xF1EFE3, 0xF1F1E9,
4440 0xF1F0EC, 0xF2F1ED, 0xF2F1ED, 0xF2F3EE, 0xF2F3EE, 0xF2F4F1, 0xF2F4F1, 0xF1F3F2, 0xF1F3F2, 0xEEF2F1, 0xEEF2F1,
4441 0xEDF1F2, 0xECF0F1, 0xEBF1F1, 0xEBF1F1, 0xE5EEED, 0xE5EEED, 0xE4EDEC, 0xE4EDEC, 0xE2ECED, 0xE2ECED, 0xE0ECEC,
4442 0xE0ECEC, 0xD9E7E7, 0xD9E7E7, 0xD7E7E7, 0xD7E7E7, 0xD4E6E6, 0xD3E5E5, 0xD3E5E5, 0xD3E5E5, 0xC3EEE5, 0xC3EEE5,
4443 0xC2EDE4, 0xC0EBE2, 0xBDEBE1, 0xBBE9DF, 0xB7E9DE, 0xB7E9DE, 0xB0E4D8, 0xAFE3D7, 0xADE3D6, 0xABE1D4, 0xA8E0D3,
4444 0xA6DED1, 0xA4DED0, 0xA3DDCF, 0x9BDDCF, 0x9ADCCE, 0x97DBCC, 0x94D8C9, 0x92D6C7, 0x8FD3C4, 0x8BD2C2, 0x8AD1C1,
4445 0x8BD4C3, 0x8AD3C2, 0x89D2C1, 0x87D0BF, 0x84CEBD, 0x82CCBB, 0x81CBBA, 0x80CAB9, 0x74C7B5, 0x74C7B5, 0x71C6B3,
4446 0x6FC4B1, 0x6DC2AF, 0x6BC0AD, 0x68BFAC, 0x67BEAB, 0x60B7A6, 0x5FB6A5, 0x5CB5A3, 0x5BB4A2, 0x57B2A0, 0x55B09E,
4447 0x53AE9C, 0x53AE9C, 0x52A9A0, 0x51A89F, 0x4FA69D, 0x4EA59C, 0x4AA49A, 0x48A298, 0x47A197, 0x46A096, 0x3E9A8F,
4448 0x3D998E, 0x3B988D, 0x39968B, 0x379489, 0x369388, 0x359287, 0x349186, 0x2C9183, 0x2C9183, 0x2A8F81, 0x298E80,
4449 0x278C7E, 0x258A7C, 0x24897B, 0x23887A, 0x1F8476, 0x1F8476, 0x1E8375, 0x1D8274, 0x1C8173, 0x1C8173, 0x1B8072,
4450 0x1B8072, 0x197D71, 0x187C70, 0x177B6F, 0x167A6E, 0x14786C, 0x13776B, 0x12766A, 0x117569, 0x0F7367, 0x0F7367,
4451 0x0F7367, 0x0E7266, 0x0D7165, 0x0D7165, 0x0C7064, 0x0C7064, 0x066B5B, 0x066B5B, 0x066B59, 0x086958, 0x0B6655,
4452 0x0B6655, 0x056951, 0x056951> csFPneoDivVegetationC;
4453 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4454 /** @class csFPneoModisNdvi
4455 @ingroup cs
4456 @extends csFP_tpl */
4457 typedef csFP_tpl<0xECE0D7, 0xEBDFD6, 0xEADED4, 0xEADDD3, 0xE9DDD1, 0xE8DCD0, 0xE7DBCE, 0xE7DACD, 0xE6D9CC, 0xE5D8CA, 0xE4D7C9,
4458 0xE3D6C7, 0xE3D6C6, 0xE2D5C5, 0xE1D4C3, 0xE0D3C2, 0xE0D2C0, 0xDFD1BF, 0xDED0BD, 0xDDCFBC, 0xDDCFBB, 0xDCCEB9,
4459 0xDBCDB8, 0xDACCB6, 0xD9CBB5, 0xD9CAB4, 0xD8C9B2, 0xD7C8B1, 0xD6C8AF, 0xD6C7AE, 0xD5C6AC, 0xD4C5AB, 0xD3C4AA,
4460 0xD2C3A8, 0xD1C3A7, 0xD1C2A5, 0xD0C1A4, 0xCFC0A2, 0xCEC0A1, 0xCDBF9F, 0xCCBE9E, 0xCCBD9C, 0xCBBC9B, 0xCABC99,
4461 0xC9BB98, 0xC8BA96, 0xC7B995, 0xC7B994, 0xC6B892, 0xC5B791, 0xC4B68F, 0xC3B58E, 0xC2B58C, 0xC1B48B, 0xC1B389,
4462 0xC0B288, 0xBFB186, 0xBEB185, 0xBDB083, 0xBCAF82, 0xBCAE80, 0xBBAE7F, 0xBAAD7D, 0xB9AC7C, 0xB8AB7A, 0xB7AB79,
4463 0xB6AA77, 0xB5A975, 0xB4A974, 0xB3A872, 0xB2A770, 0xB1A76F, 0xB0A66D, 0xAFA56B, 0xAEA469, 0xADA468, 0xACA366,
4464 0xABA264, 0xAAA263, 0xAAA161, 0xA9A05F, 0xA8A05E, 0xA79F5C, 0xA69E5A, 0xA59E59, 0xA49D57, 0xA39C55, 0xA29C54,
4465 0xA19B52, 0xA09A50, 0x9F994E, 0x9E994D, 0x9D984B, 0x9C9749, 0x9B9748, 0x9A9646, 0x999545, 0x989544, 0x979442,
4466 0x969341, 0x959340, 0x93923F, 0x92913D, 0x91913C, 0x90903B, 0x8F8F3A, 0x8E8E38, 0x8D8E37, 0x8C8D36, 0x8B8C35,
4467 0x8A8C33, 0x898B32, 0x878A31, 0x868A30, 0x85892E, 0x84882D, 0x83882C, 0x82872B, 0x818629, 0x808628, 0x7F8527,
4468 0x7E8426, 0x7C8324, 0x7B8323, 0x7A8222, 0x798121, 0x78811F, 0x77801E, 0x767F1E, 0x757F1E, 0x747E1E, 0x737D1E,
4469 0x727C1E, 0x717C1F, 0x707B1F, 0x6F7A1F, 0x6E791F, 0x6D791F, 0x6C781F, 0x6B771F, 0x6A761F, 0x69761F, 0x68751F,
4470 0x677420, 0x667320, 0x657320, 0x647220, 0x637120, 0x627020, 0x617020, 0x606F20, 0x5F6E20, 0x5E6D20, 0x5D6D20,
4471 0x5C6C21, 0x5B6B21, 0x5A6A21, 0x596A21, 0x586921, 0x576821, 0x566721, 0x556621, 0x556621, 0x546521, 0x536421,
4472 0x526321, 0x516321, 0x516221, 0x506121, 0x4F6021, 0x4E5F21, 0x4D5F21, 0x4C5E21, 0x4C5D21, 0x4B5C21, 0x4A5C21,
4473 0x495B21, 0x485A21, 0x485921, 0x475821, 0x465821, 0x455721, 0x445621, 0x445521, 0x435421, 0x425421, 0x415321,
4474 0x405221, 0x3F5121, 0x3F5121, 0x3E5021, 0x3D4F21, 0x3C4E20, 0x3B4E1F, 0x3A4D1E, 0x394C1D, 0x384C1C, 0x374B1B,
4475 0x364A1A, 0x354A19, 0x344918, 0x334817, 0x324816, 0x314715, 0x304614, 0x2F4613, 0x2E4512, 0x2E4511, 0x2D440F,
4476 0x2C430E, 0x2B430D, 0x2A420C, 0x29410B, 0x28410A, 0x274009, 0x263F08, 0x253F07, 0x243E06, 0x233D05, 0x223D04,
4477 0x213C03, 0x203B02, 0x1F3B01, 0x1E3A00, 0x1D3900, 0x1D3900, 0x1C3800, 0x1C3700, 0x1B3600, 0x1A3601, 0x1A3501,
4478 0x193401, 0x183401, 0x183301, 0x173201, 0x173101, 0x163101, 0x153001, 0x152F01, 0x142F02, 0x132E02, 0x132D02,
4479 0x122C02, 0x122C02, 0x112B02, 0x102A02, 0x102902, 0x0F2902, 0x0E2802, 0x0E2702, 0x0D2703, 0x0D2603, 0x0C2503,
4480 0x0B2403, 0x0B2403, 0x000000> csFPneoModisNdvi;
4481 //@}
4482
4483
4484 //========================================================================================================================================================
4485 /** @name ColorBrewer2 Color Schemes */
4486 //@{
4487 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4488 /** @class csCBSpectral
4489 @ingroup cs
4490 @extends csCB_tpl
4491 ColorBrewer2 "Spectral" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4492 typedef csCB_tpl<11,
4493 0xFC8D59, 0xFFFFBF, 0x99D594,
4494 0xD7191C, 0xFDAE61, 0xABDDA4, 0x2B83BA,
4495 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xABDDA4, 0x2B83BA,
4496 0xD53E4F, 0xFC8D59, 0xFEE08B, 0xE6F598, 0x99D594, 0x3288BD,
4497 0xD53E4F, 0xFC8D59, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0x99D594, 0x3288BD,
4498 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD,
4499 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD,
4500 0x9E0142, 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD, 0x5E4FA2,
4501 0x9E0142, 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD, 0x5E4FA2> csCBSpectral;
4502 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4503 /** @class csCBRdYlGn
4504 @ingroup cs
4505 @extends csCB_tpl
4506 ColorBrewer2 "RdYlGn" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4507 typedef csCB_tpl<11,
4508 0xFC8D59, 0xFFFFBF, 0x91CF60,
4509 0xD7191C, 0xFDAE61, 0xA6D96A, 0x1A9641,
4510 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xA6D96A, 0x1A9641,
4511 0xD73027, 0xFC8D59, 0xFEE08B, 0xD9EF8B, 0x91CF60, 0x1A9850,
4512 0xD73027, 0xFC8D59, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0x91CF60, 0x1A9850,
4513 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850,
4514 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850,
4515 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850, 0x006837,
4516 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xD9EF8B, 0xA6D96A, 0x66BD63, 0x1A9850, 0x006837> csCBRdYlGn;
4517 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4518 /** @class csCBRdBu
4519 @ingroup cs
4520 @extends csCB_tpl
4521 ColorBrewer2 "RdBu" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4522 typedef csCB_tpl<11,
4523 0xEF8A62, 0xF7F7F7, 0x67A9CF,
4524 0xCA0020, 0xF4A582, 0x92C5DE, 0x0571B0,
4525 0xCA0020, 0xF4A582, 0xF7F7F7, 0x92C5DE, 0x0571B0,
4526 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xD1E5F0, 0x67A9CF, 0x2166AC,
4527 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x67A9CF, 0x2166AC,
4528 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC,
4529 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC,
4530 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC, 0x053061,
4531 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xF7F7F7, 0xD1E5F0, 0x92C5DE, 0x4393C3, 0x2166AC, 0x053061> csCBRdBu;
4532 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4533 /** @class csCBPiYG
4534 @ingroup cs
4535 @extends csCB_tpl
4536 ColorBrewer2 "PiYG" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4537 typedef csCB_tpl<11,
4538 0xE9A3C9, 0xF7F7F7, 0xA1D76A,
4539 0xD01C8B, 0xF1B6DA, 0xB8E186, 0x4DAC26,
4540 0xD01C8B, 0xF1B6DA, 0xF7F7F7, 0xB8E186, 0x4DAC26,
4541 0xC51B7D, 0xE9A3C9, 0xFDE0EF, 0xE6F5D0, 0xA1D76A, 0x4D9221,
4542 0xC51B7D, 0xE9A3C9, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xA1D76A, 0x4D9221,
4543 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221,
4544 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221,
4545 0x8E0152, 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221, 0x276419,
4546 0x8E0152, 0xC51B7D, 0xDE77AE, 0xF1B6DA, 0xFDE0EF, 0xF7F7F7, 0xE6F5D0, 0xB8E186, 0x7FBC41, 0x4D9221, 0x276419> csCBPiYG;
4547 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4548 /** @class csCBPRGn
4549 @ingroup cs
4550 @extends csCB_tpl
4551 ColorBrewer2 "PRGn" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4552 typedef csCB_tpl<11,
4553 0xAF8DC3, 0xF7F7F7, 0x7FBF7B,
4554 0x7B3294, 0xC2A5CF, 0xA6DBA0, 0x008837,
4555 0x7B3294, 0xC2A5CF, 0xF7F7F7, 0xA6DBA0, 0x008837,
4556 0x762A83, 0xAF8DC3, 0xE7D4E8, 0xD9F0D3, 0x7FBF7B, 0x1B7837,
4557 0x762A83, 0xAF8DC3, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0x7FBF7B, 0x1B7837,
4558 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837,
4559 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837,
4560 0x40004B, 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837, 0x00441B,
4561 0x40004B, 0x762A83, 0x9970AB, 0xC2A5CF, 0xE7D4E8, 0xF7F7F7, 0xD9F0D3, 0xA6DBA0, 0x5AAE61, 0x1B7837, 0x00441B> csCBPRGn;
4562 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4563 /** @class csCBRdYlBu
4564 @ingroup cs
4565 @extends csCB_tpl
4566 ColorBrewer2 "RdYlBu" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4567 typedef csCB_tpl<11,
4568 0xFC8D59, 0xFFFFBF, 0x91BFDB,
4569 0xD7191C, 0xFDAE61, 0xABD9E9, 0x2C7BB6,
4570 0xD7191C, 0xFDAE61, 0xFFFFBF, 0xABD9E9, 0x2C7BB6,
4571 0xD73027, 0xFC8D59, 0xFEE090, 0xE0F3F8, 0x91BFDB, 0x4575B4,
4572 0xD73027, 0xFC8D59, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0x91BFDB, 0x4575B4,
4573 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4,
4574 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4,
4575 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4, 0x313695,
4576 0xA50026, 0xD73027, 0xF46D43, 0xFDAE61, 0xFEE090, 0xFFFFBF, 0xE0F3F8, 0xABD9E9, 0x74ADD1, 0x4575B4, 0x313695> csCBRdYlBu;
4577 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4578 /** @class csCBBrBG
4579 @ingroup cs
4580 @extends csCB_tpl
4581 ColorBrewer2 "BrBG" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4582 typedef csCB_tpl<11,
4583 0xD8B365, 0xF5F5F5, 0x5AB4AC,
4584 0xA6611A, 0xDFC27D, 0x80CDC1, 0x018571,
4585 0xA6611A, 0xDFC27D, 0xF5F5F5, 0x80CDC1, 0x018571,
4586 0x8C510A, 0xD8B365, 0xF6E8C3, 0xC7EAE5, 0x5AB4AC, 0x01665E,
4587 0x8C510A, 0xD8B365, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x5AB4AC, 0x01665E,
4588 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E,
4589 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E,
4590 0x543005, 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E, 0x003C30,
4591 0x543005, 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E, 0x003C30> csCBBrBG;
4592 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4593 /** @class csCBRdGy
4594 @ingroup cs
4595 @extends csCB_tpl
4596 ColorBrewer2 "RdGy" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4597 typedef csCB_tpl<11,
4598 0xEF8A62, 0xFFFFFF, 0x999999,
4599 0xCA0020, 0xF4A582, 0xBABABA, 0x404040,
4600 0xCA0020, 0xF4A582, 0xFFFFFF, 0xBABABA, 0x404040,
4601 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xE0E0E0, 0x999999, 0x4D4D4D,
4602 0xB2182B, 0xEF8A62, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0x999999, 0x4D4D4D,
4603 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D,
4604 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D,
4605 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D, 0x1A1A1A,
4606 0x67001F, 0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xFFFFFF, 0xE0E0E0, 0xBABABA, 0x878787, 0x4D4D4D, 0x1A1A1A> csCBRdGy;
4607 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4608 /** @class csCBPuOr
4609 @ingroup cs
4610 @extends csCB_tpl
4611 ColorBrewer2 "PuOr" color scheme of 3 to 11 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4612 typedef csCB_tpl<11,
4613 0xF1A340, 0xF7F7F7, 0x998EC3,
4614 0xE66101, 0xFDB863, 0xB2ABD2, 0x5E3C99,
4615 0xE66101, 0xFDB863, 0xF7F7F7, 0xB2ABD2, 0x5E3C99,
4616 0xB35806, 0xF1A340, 0xFEE0B6, 0xD8DAEB, 0x998EC3, 0x542788,
4617 0xB35806, 0xF1A340, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0x998EC3, 0x542788,
4618 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788,
4619 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788,
4620 0x7F3B08, 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788, 0x2D004B,
4621 0x7F3B08, 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788, 0x2D004B> csCBPuOr;
4622 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4623 /** @class csCBSet2
4624 @ingroup cs
4625 @extends csCB_tpl
4626 ColorBrewer2 "Set2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4627 typedef csCB_tpl<8,
4628 0x66C2A5, 0xFC8D62, 0x8DA0CB,
4629 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3,
4630 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854,
4631 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F,
4632 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F, 0xE5C494,
4633 0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F, 0xE5C494, 0xB3B3B3> csCBSet2;
4634 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4635 /** @class csCBAccent
4636 @ingroup cs
4637 @extends csCB_tpl
4638 ColorBrewer2 "Accent" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4639 typedef csCB_tpl<8,
4640 0x7FC97F, 0xBEAED4, 0xFDC086,
4641 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99,
4642 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0,
4643 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F,
4644 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F, 0xBF5B17,
4645 0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F, 0xBF5B17, 0x666666> csCBAccent;
4646 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4647 /** @class csCBSet1
4648 @ingroup cs
4649 @extends csCB_tpl
4650 ColorBrewer2 "Set1" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4651 typedef csCB_tpl<9,
4652 0xE41A1C, 0x377EB8, 0x4DAF4A,
4653 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3,
4654 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00,
4655 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33,
4656 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628,
4657 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628, 0xF781BF,
4658 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628, 0xF781BF, 0x999999> csCBSet1;
4659 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4660 /** @class csCBSet3
4661 @ingroup cs
4662 @extends csCB_tpl
4663 ColorBrewer2 "Set3" color scheme of 3 to 12 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4664 typedef csCB_tpl<12,
4665 0x8DD3C7, 0xFFFFB3, 0xBEBADA,
4666 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072,
4667 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3,
4668 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462,
4669 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69,
4670 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5,
4671 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9,
4672 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD,
4673 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD, 0xCCEBC5,
4674 0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD, 0xCCEBC5, 0xFFED6F> csCBSet3;
4675 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4676 /** @class csCBDark2
4677 @ingroup cs
4678 @extends csCB_tpl
4679 ColorBrewer2 "Dark2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4680 typedef csCB_tpl<8,
4681 0x1B9E77, 0xD95F02, 0x7570B3,
4682 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A,
4683 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E,
4684 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02,
4685 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02, 0xA6761D,
4686 0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02, 0xA6761D, 0x666666> csCBDark2;
4687 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4688 /** @class csCBPaired
4689 @ingroup cs
4690 @extends csCB_tpl
4691 ColorBrewer2 "Paired" color scheme of 3 to 12 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4692 typedef csCB_tpl<12,
4693 0xA6CEE3, 0x1F78B4, 0xB2DF8A,
4694 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C,
4695 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99,
4696 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C,
4697 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F,
4698 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00,
4699 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6,
4700 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A,
4701 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A, 0xFFFF99,
4702 0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A, 0xFFFF99, 0xB15928> csCBPaired;
4703 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4704 /** @class csCBPastel2
4705 @ingroup cs
4706 @extends csCB_tpl
4707 ColorBrewer2 "Pastel2" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4708 typedef csCB_tpl<8,
4709 0xB3E2CD, 0xFDCDAC, 0xCBD5E8,
4710 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4,
4711 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9,
4712 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE,
4713 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE, 0xF1E2CC,
4714 0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE, 0xF1E2CC, 0xCCCCCC> csCBPastel2;
4715 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4716 /** @class csCBPastel1
4717 @ingroup cs
4718 @extends csCB_tpl
4719 ColorBrewer2 "Pastel1" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4720 typedef csCB_tpl<9,
4721 0xFBB4AE, 0xB3CDE3, 0xCCEBC5,
4722 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4,
4723 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6,
4724 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC,
4725 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD,
4726 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD, 0xFDDAEC,
4727 0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD, 0xFDDAEC, 0xF2F2F2> csCBPastel1;
4728 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4729 /** @class csCBOrRd
4730 @ingroup cs
4731 @extends csCB_tpl
4732 ColorBrewer2 "RdYlGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4733 typedef csCB_tpl<9,
4734 0xFEE8C8, 0xFDBB84, 0xE34A33,
4735 0xFEF0D9, 0xFDCC8A, 0xFC8D59, 0xD7301F,
4736 0xFEF0D9, 0xFDCC8A, 0xFC8D59, 0xE34A33, 0xB30000,
4737 0xFEF0D9, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xE34A33, 0xB30000,
4738 0xFEF0D9, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0x990000,
4739 0xFFF7EC, 0xFEE8C8, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0x990000,
4740 0xFFF7EC, 0xFEE8C8, 0xFDD49E, 0xFDBB84, 0xFC8D59, 0xEF6548, 0xD7301F, 0xB30000, 0x7F0000> csCBOrRd;
4741 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4742 /** @class csCBPuBu
4743 @ingroup cs
4744 @extends csCB_tpl
4745 ColorBrewer2 "PuBu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4746 typedef csCB_tpl<9,
4747 0xECE7F2, 0xA6BDDB, 0x2B8CBE,
4748 0xF1EEF6, 0xBDC9E1, 0x74A9CF, 0x0570B0,
4749 0xF1EEF6, 0xBDC9E1, 0x74A9CF, 0x2B8CBE, 0x045A8D,
4750 0xF1EEF6, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x2B8CBE, 0x045A8D,
4751 0xF1EEF6, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x034E7B,
4752 0xFFF7FB, 0xECE7F2, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x034E7B,
4753 0xFFF7FB, 0xECE7F2, 0xD0D1E6, 0xA6BDDB, 0x74A9CF, 0x3690C0, 0x0570B0, 0x045A8D, 0x023858> csCBPuBu;
4754 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4755 /** @class csCBBuPu
4756 @ingroup cs
4757 @extends csCB_tpl
4758 ColorBrewer2 "CbBuPu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4759 typedef csCB_tpl<9,
4760 0xE0ECF4, 0x9EBCDA, 0x8856A7,
4761 0xEDF8FB, 0xB3CDE3, 0x8C96C6, 0x88419D,
4762 0xEDF8FB, 0xB3CDE3, 0x8C96C6, 0x8856A7, 0x810F7C,
4763 0xEDF8FB, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8856A7, 0x810F7C,
4764 0xEDF8FB, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x6E016B,
4765 0xF7FCFD, 0xE0ECF4, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x6E016B,
4766 0xF7FCFD, 0xE0ECF4, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x810F7C, 0x4D004B> csCBBuPu;
4767 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4768 /** @class csCBOranges
4769 @ingroup cs
4770 @extends csCB_tpl
4771 ColorBrewer2 "Oranges" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4772 typedef csCB_tpl<9,
4773 0xFEE6CE, 0xFDAE6B, 0xE6550D,
4774 0xFEEDDE, 0xFDBE85, 0xFD8D3C, 0xD94701,
4775 0xFEEDDE, 0xFDBE85, 0xFD8D3C, 0xE6550D, 0xA63603,
4776 0xFEEDDE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xE6550D, 0xA63603,
4777 0xFEEDDE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0x8C2D04,
4778 0xFFF5EB, 0xFEE6CE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0x8C2D04,
4779 0xFFF5EB, 0xFEE6CE, 0xFDD0A2, 0xFDAE6B, 0xFD8D3C, 0xF16913, 0xD94801, 0xA63603, 0x7F2704> csCBOranges;
4780 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4781 /** @class csCBBuGn
4782 @ingroup cs
4783 @extends csCB_tpl
4784 ColorBrewer2 "BuGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4785 typedef csCB_tpl<9,
4786 0xE5F5F9, 0x99D8C9, 0x2CA25F,
4787 0xEDF8FB, 0xB2E2E2, 0x66C2A4, 0x238B45,
4788 0xEDF8FB, 0xB2E2E2, 0x66C2A4, 0x2CA25F, 0x006D2C,
4789 0xEDF8FB, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x2CA25F, 0x006D2C,
4790 0xEDF8FB, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x005824,
4791 0xF7FCFD, 0xE5F5F9, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x005824,
4792 0xF7FCFD, 0xE5F5F9, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x006D2C, 0x00441B> csCBBuGn;
4793 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4794 /** @class csCBYlOrBr
4795 @ingroup cs
4796 @extends csCB_tpl
4797 ColorBrewer2 "YlOrBr" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4798 typedef csCB_tpl<9,
4799 0xFFF7BC, 0xFEC44F, 0xD95F0E,
4800 0xFFFFD4, 0xFED98E, 0xFE9929, 0xCC4C02,
4801 0xFFFFD4, 0xFED98E, 0xFE9929, 0xD95F0E, 0x993404,
4802 0xFFFFD4, 0xFEE391, 0xFEC44F, 0xFE9929, 0xD95F0E, 0x993404,
4803 0xFFFFD4, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x8C2D04,
4804 0xFFFFE5, 0xFFF7BC, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x8C2D04,
4805 0xFFFFE5, 0xFFF7BC, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x993404, 0x662506> csCBYlOrBr;
4806 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4807 /** @class csCBYlGn
4808 @ingroup cs
4809 @extends csCB_tpl
4810 ColorBrewer2 "csCBYlGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4811 typedef csCB_tpl<9,
4812 0xF7FCB9, 0xADDD8E, 0x31A354,
4813 0xFFFFCC, 0xC2E699, 0x78C679, 0x238443,
4814 0xFFFFCC, 0xC2E699, 0x78C679, 0x31A354, 0x006837,
4815 0xFFFFCC, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x31A354, 0x006837,
4816 0xFFFFCC, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x005A32,
4817 0xFFFFE5, 0xF7FCB9, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x005A32,
4818 0xFFFFE5, 0xF7FCB9, 0xD9F0A3, 0xADDD8E, 0x78C679, 0x41AB5D, 0x238443, 0x006837, 0x004529> csCBYlGn;
4819 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4820 /** @class csCBReds
4821 @ingroup cs
4822 @extends csCB_tpl
4823 ColorBrewer2 "Reds" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4824 typedef csCB_tpl<9,
4825 0xFEE0D2, 0xFC9272, 0xDE2D26,
4826 0xFEE5D9, 0xFCAE91, 0xFB6A4A, 0xCB181D,
4827 0xFEE5D9, 0xFCAE91, 0xFB6A4A, 0xDE2D26, 0xA50F15,
4828 0xFEE5D9, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xDE2D26, 0xA50F15,
4829 0xFEE5D9, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0x99000D,
4830 0xFFF5F0, 0xFEE0D2, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0x99000D,
4831 0xFFF5F0, 0xFEE0D2, 0xFCBBA1, 0xFC9272, 0xFB6A4A, 0xEF3B2C, 0xCB181D, 0xA50F15, 0x67000D> csCBReds;
4832 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4833 /** @class csCBRdPu
4834 @ingroup cs
4835 @extends csCB_tpl
4836 ColorBrewer2 "RdPu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4837 typedef csCB_tpl<9,
4838 0xFDE0DD, 0xFA9FB5, 0xC51B8A,
4839 0xFEEBE2, 0xFBB4B9, 0xF768A1, 0xAE017E,
4840 0xFEEBE2, 0xFBB4B9, 0xF768A1, 0xC51B8A, 0x7A0177,
4841 0xFEEBE2, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xC51B8A, 0x7A0177,
4842 0xFEEBE2, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177,
4843 0xFFF7F3, 0xFDE0DD, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177,
4844 0xFFF7F3, 0xFDE0DD, 0xFCC5C0, 0xFA9FB5, 0xF768A1, 0xDD3497, 0xAE017E, 0x7A0177, 0x49006A> csCBRdPu;
4845 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4846 /** @class csCBGreens
4847 @ingroup cs
4848 @extends csCB_tpl
4849 ColorBrewer2 "Greens" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4850 typedef csCB_tpl<9,
4851 0xE5F5E0, 0xA1D99B, 0x31A354,
4852 0xEDF8E9, 0xBAE4B3, 0x74C476, 0x238B45,
4853 0xEDF8E9, 0xBAE4B3, 0x74C476, 0x31A354, 0x006D2C,
4854 0xEDF8E9, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x31A354, 0x006D2C,
4855 0xEDF8E9, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x005A32,
4856 0xF7FCF5, 0xE5F5E0, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x005A32,
4857 0xF7FCF5, 0xE5F5E0, 0xC7E9C0, 0xA1D99B, 0x74C476, 0x41AB5D, 0x238B45, 0x006D2C, 0x00441B> csCBGreens;
4858 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4859 /** @class csCBYlGnBu
4860 @ingroup cs
4861 @extends csCB_tpl
4862 ColorBrewer2 "YlGnBu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4863 typedef csCB_tpl<9,
4864 0xEDF8B1, 0x7FCDBB, 0x2C7FB8,
4865 0xFFFFCC, 0xA1DAB4, 0x41B6C4, 0x225EA8,
4866 0xFFFFCC, 0xA1DAB4, 0x41B6C4, 0x2C7FB8, 0x253494,
4867 0xFFFFCC, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x2C7FB8, 0x253494,
4868 0xFFFFCC, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x0C2C84,
4869 0xFFFFD9, 0xEDF8B1, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x0C2C84,
4870 0xFFFFD9, 0xEDF8B1, 0xC7E9B4, 0x7FCDBB, 0x41B6C4, 0x1D91C0, 0x225EA8, 0x253494, 0x081D58> csCBYlGnBu;
4871 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4872 /** @class csCBPurples
4873 @ingroup cs
4874 @extends csCB_tpl
4875 ColorBrewer2 "Purples" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4876 typedef csCB_tpl<9,
4877 0xEFEDF5, 0xBCBDDC, 0x756BB1,
4878 0xF2F0F7, 0xCBC9E2, 0x9E9AC8, 0x6A51A3,
4879 0xF2F0F7, 0xCBC9E2, 0x9E9AC8, 0x756BB1, 0x54278F,
4880 0xF2F0F7, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x756BB1, 0x54278F,
4881 0xF2F0F7, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x4A1486,
4882 0xFCFBFD, 0xEFEDF5, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x4A1486,
4883 0xFCFBFD, 0xEFEDF5, 0xDADAEB, 0xBCBDDC, 0x9E9AC8, 0x807DBA, 0x6A51A3, 0x54278F, 0x3F007D> csCBPurples;
4884 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4885 /** @class csCBGnBu
4886 @ingroup cs
4887 @extends csCB_tpl
4888 ColorBrewer2 "GnBu" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4889 typedef csCB_tpl<9,
4890 0xE0F3DB, 0xA8DDB5, 0x43A2CA,
4891 0xF0F9E8, 0xBAE4BC, 0x7BCCC4, 0x2B8CBE,
4892 0xF0F9E8, 0xBAE4BC, 0x7BCCC4, 0x43A2CA, 0x0868AC,
4893 0xF0F9E8, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x43A2CA, 0x0868AC,
4894 0xF0F9E8, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x08589E,
4895 0xF7FCF0, 0xE0F3DB, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x08589E,
4896 0xF7FCF0, 0xE0F3DB, 0xCCEBC5, 0xA8DDB5, 0x7BCCC4, 0x4EB3D3, 0x2B8CBE, 0x0868AC, 0x084081> csCBGnBu;
4897 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4898 /** @class csCBGreys
4899 @ingroup cs
4900 @extends csCB_tpl
4901 ColorBrewer2 "Greys" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4902 typedef csCB_tpl<9,
4903 0xF0F0F0, 0xBDBDBD, 0x636363,
4904 0xF7F7F7, 0xCCCCCC, 0x969696, 0x525252,
4905 0xF7F7F7, 0xCCCCCC, 0x969696, 0x636363, 0x252525,
4906 0xF7F7F7, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x636363, 0x252525,
4907 0xF7F7F7, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525,
4908 0xFFFFFF, 0xF0F0F0, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525,
4909 0xFFFFFF, 0xF0F0F0, 0xD9D9D9, 0xBDBDBD, 0x969696, 0x737373, 0x525252, 0x252525, 0x000000> csCBGreys;
4910 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4911 /** @class csCBYlOrRd
4912 @ingroup cs
4913 @extends csCB_tpl
4914 ColorBrewer2 "YlOrRd" color scheme of 3 to 8 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4915 typedef csCB_tpl<8,
4916 0xFFEDA0, 0xFEB24C, 0xF03B20,
4917 0xFFFFB2, 0xFECC5C, 0xFD8D3C, 0xE31A1C,
4918 0xFFFFB2, 0xFECC5C, 0xFD8D3C, 0xF03B20, 0xBD0026,
4919 0xFFFFB2, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xF03B20, 0xBD0026,
4920 0xFFFFB2, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xFC4E2A, 0xE31A1C, 0xB10026,
4921 0xFFFFCC, 0xFFEDA0, 0xFED976, 0xFEB24C, 0xFD8D3C, 0xFC4E2A, 0xE31A1C, 0xB10026> csCBYlOrRd;
4922 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4923 /** @class csCBPuRd
4924 @ingroup cs
4925 @extends csCB_tpl
4926 ColorBrewer2 "PuRd" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4927 typedef csCB_tpl<9,
4928 0xE7E1EF, 0xC994C7, 0xDD1C77,
4929 0xF1EEF6, 0xD7B5D8, 0xDF65B0, 0xCE1256,
4930 0xF1EEF6, 0xD7B5D8, 0xDF65B0, 0xDD1C77, 0x980043,
4931 0xF1EEF6, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xDD1C77, 0x980043,
4932 0xF1EEF6, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x91003F,
4933 0xF7F4F9, 0xE7E1EF, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x91003F,
4934 0xF7F4F9, 0xE7E1EF, 0xD4B9DA, 0xC994C7, 0xDF65B0, 0xE7298A, 0xCE1256, 0x980043, 0x67001F> csCBPuRd;
4935 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4936 /** @class csCBBlues
4937 @ingroup cs
4938 @extends csCB_tpl
4939 ColorBrewer2 "Blues" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4940 typedef csCB_tpl<9,
4941 0xDEEBF7, 0x9ECAE1, 0x3182BD,
4942 0xEFF3FF, 0xBDD7E7, 0x6BAED6, 0x2171B5,
4943 0xEFF3FF, 0xBDD7E7, 0x6BAED6, 0x3182BD, 0x08519C,
4944 0xEFF3FF, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x3182BD, 0x08519C,
4945 0xEFF3FF, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x084594,
4946 0xF7FBFF, 0xDEEBF7, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x084594,
4947 0xF7FBFF, 0xDEEBF7, 0xC6DBEF, 0x9ECAE1, 0x6BAED6, 0x4292C6, 0x2171B5, 0x08519C, 0x08306B> csCBBlues;
4948 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4949 /** @class csCBPuBuGn
4950 @ingroup cs
4951 @extends csCB_tpl
4952 ColorBrewer2 "PuBuGn" color scheme of 3 to 9 colors. Credit: Brewer, Cynthia A., 2022. http://www.ColorBrewer.org2, 2022-07-30. */
4953 typedef csCB_tpl<9,
4954 0xECE2F0, 0xA6BDDB, 0x1C9099,
4955 0xF6EFF7, 0xBDC9E1, 0x67A9CF, 0x02818A,
4956 0xF6EFF7, 0xBDC9E1, 0x67A9CF, 0x1C9099, 0x016C59,
4957 0xF6EFF7, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x1C9099, 0x016C59,
4958 0xF6EFF7, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016450,
4959 0xFFF7FB, 0xECE2F0, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016450,
4960 0xFFF7FB, 0xECE2F0, 0xD0D1E6, 0xA6BDDB, 0x67A9CF, 0x3690C0, 0x02818A, 0x016C59, 0x014636> csCBPuBuGn;
4961 //@}
4962
4963 /** @endcond */
4964
4965 //========================================================================================================================================================
4966 /** @name 2D Color Schemes */
4967 //@{
4968#if !(MISSING_P1907R1)
4969 //--------------------------------------------------------------------------------------------------------------------------------------------------------
4970 /** Compute a color from Richardson's 2D complex number coloring scheme.
4971 See: Richardson (1991); Visualizing quantum scattering on the CM-2 supercomputer; Computer Physics Communications 63; pp 84-94"
4972 This is a continuous, 2D color scheme!
4973 @tparam cutDepth See: tfrmComplexCut()
4974 @tparam argCuts See: tfrmComplexCut()
4975 @tparam absCuts See: tfrmComplexCut()
4976 @tparam logAbs See: tfrmComplexCut() */
4977 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
4979 public:
4980 /** Set given colorTpl instance to the selected color in the color scheme.
4981 @param aColor color object to set.
4982 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
4983 @param csY A value that, along with csX, identifies the color in the scheme.
4984 @return Returns a reference to \a aColor. */
4985 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
4986 csFltType c_abs2 = csX*csX+csY*csY;
4987 csFltType c_abs = std::sqrt(c_abs2);
4988 csFltType c_abs2p1 = 1 + c_abs2;
4989 csFltType x_scl = csX / std::sqrt(30.0/5.0);
4990 csFltType y_scl = csY / std::sqrt(2.0);
4991 csFltType ofs = (c_abs<1 ? -1.0 : 1.0) * (0.5 - c_abs/c_abs2p1);
4992 aColor.setChansRGB_dbl(std::clamp(ofs + (0.5 + (std::sqrt(2.0/3.0) * csX) / c_abs2p1), 0.0, 1.0),
4993 std::clamp(ofs + (0.5 - (x_scl - y_scl) / c_abs2p1), 0.0, 1.0),
4994 std::clamp(ofs + (0.5 - (x_scl + y_scl) / c_abs2p1), 0.0, 1.0));
4995 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
4996 }
4997 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
4998 @param csX A value that, along with csY, identifies the color in the scheme.
4999 @param csY A value that, along with csX, identifies the color in the scheme.
5000 @return Returns a colorTpl value */
5001 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5002 /** Set given colorTpl instance to the selected color in the color scheme.
5003 @param aColor color object to set.
5004 @param csZ A value that identifies the color in the scheme.
5005 @return Returns a reference to \a aColor. */
5006 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5007 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5008 @param csZ A value that identifies the color in the scheme.
5009 @return Returns a colorTpl value */
5010 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5011 };
5012 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5013 /** Compute a color for a point in @f$\mathbb{R}^2@f$ using a discrete color scheme for the phase angle.
5014 This is a continuous, 2D color scheme!
5015 @tparam colorScheme Integer indexed color scheme to use for the argument. csCColdeRainbow is a traditional choice.
5016 @tparam argWrap Number of times to wrap around the color ramp for arg
5017 @tparam cutDepth See: tfrmComplexCut()
5018 @tparam argCuts See: tfrmComplexCut()
5019 @tparam absCuts See: tfrmComplexCut()
5020 @tparam logAbs See: tfrmComplexCut() */
5021 template<typename colorScheme, int argWrap, double cutDepth, double argCuts, double absCuts, bool logAbs>
5023 public:
5024 /** Set given colorTpl instance to the selected color in the color scheme.
5025 @param aColor color object to set.
5026 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5027 @param csY A value that, along with csX, identifies the color in the scheme.
5028 @return Returns a reference to \a aColor. */
5029 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5030 csIntType numC = colorScheme::numC;
5031 double tau = std::numbers::pi * 2; // 2*Pi
5032 double zArg = std::atan2(csY, csX); // Arg
5033 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
5034 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)));
5035 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5036 }
5037 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5038 @param csX A value that, along with csY, identifies the color in the scheme.
5039 @param csY A value that, along with csX, identifies the color in the scheme.
5040 @return Returns a colorTpl value */
5041 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5042 /** Set given colorTpl instance to the selected color in the color scheme.
5043 @param aColor color object to set.
5044 @param csZ A value that identifies the color in the scheme.
5045 @return Returns a reference to \a aColor. */
5046 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5047 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5048 @param csZ A value that identifies the color in the scheme.
5049 @return Returns a colorTpl value */
5050 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5051 };
5052 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5053 /** Compute a color for a point in @f$\mathbb{R}^2@f$ using a continuous color scheme for the phase angle.
5054 This is a continuous, 2D color scheme!
5055 @tparam colorScheme Integer indexed color scheme to use for the argument. csCColdeRainbow is a traditional choice.
5056 @tparam argWrap Number of times to wrap around the color ramp for arg
5057 @tparam cutDepth See: tfrmComplexCut()
5058 @tparam argCuts See: tfrmComplexCut()
5059 @tparam absCuts See: tfrmComplexCut()
5060 @tparam logAbs See: tfrmComplexCut() */
5061 template<typename colorScheme, int argWrap, double cutDepth, double argCuts, double absCuts, bool logAbs>
5063 public:
5064 /** Set given colorTpl instance to the selected color in the color scheme.
5065 @param aColor color object to set.
5066 @param csX A value in @f$(-\infty, \infty)@f$ that, along with csY, identifies the color in the scheme.
5067 @param csY A value that, along with csX, identifies the color in the scheme.
5068 @return Returns a reference to \a aColor. */
5069 static inline colorTpl& c(colorRefType aColor, csFltType csX, csFltType csY) {
5070 double tau = std::numbers::pi * 2; // 2*Pi
5071 double zArg = std::atan2(csY, csX); // Arg
5072 double pzArg = (zArg < 0.0 ? tau + zArg : zArg) / tau; // Arg mapped to [0, 1]
5073 aColor.csSet<colorScheme>(static_cast<csFltType>(mjr::math::ivl::wrapCC(mjr::math::ivl::unit_clamp(pzArg)*argWrap, 1.0)));
5074 return aColor.tfrmComplexCut(std::complex<double>(csX, csY), cutDepth, argCuts, absCuts, logAbs);
5075 }
5076 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5077 @param csX A value that, along with csY, identifies the color in the scheme.
5078 @param csY A value that, along with csX, identifies the color in the scheme.
5079 @return Returns a colorTpl value */
5080 static inline colorTpl c(csFltType csX, csFltType csY) { colorTpl tmp; return c(tmp, csX, csY); }
5081 /** Set given colorTpl instance to the selected color in the color scheme.
5082 @param aColor color object to set.
5083 @param csZ A value that identifies the color in the scheme.
5084 @return Returns a reference to \a aColor. */
5085 static inline colorTpl& c(colorRefType aColor, csCplxType csZ) { return c(aColor, std::real(csZ), std::imag(csZ)); }
5086 /** Create a new colorTpl object and set it's color to the selected color in the color scheme.
5087 @param csZ A value that identifies the color in the scheme.
5088 @return Returns a colorTpl value */
5089 static inline colorTpl c(csCplxType csZ) { colorTpl tmp; return c(tmp, std::real(csZ), std::imag(csZ)); }
5090 };
5091 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5092 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSL.
5093 See: Bernd Thaller (2000); Visual Quantum Mechanics; pp 2-8
5094 This is a continuous, 2D color scheme!
5095 @tparam cutDepth See: tfrmComplexCut()
5096 @tparam argCuts See: tfrmComplexCut()
5097 @tparam absCuts See: tfrmComplexCut()
5098 @tparam logAbs See: tfrmComplexCut() */
5099 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5101 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5102 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSV and maximum value.
5103 See: Bernd Thaller (2000); Visual Quantum Mechanics; pp 2-8
5104 This is a continuous, 2D color scheme!
5105 @tparam cutDepth See: tfrmComplexCut()
5106 @tparam argCuts See: tfrmComplexCut()
5107 @tparam absCuts See: tfrmComplexCut()
5108 @tparam logAbs See: tfrmComplexCut() */
5109 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5111 //--------------------------------------------------------------------------------------------------------------------------------------------------------
5112 /** Compute a color from Bernd Thaller's 2D complex number coloring scheme with HSV and dynamic value.
5113 See: Bernd Thaller (2000); Visual Quantum Mechanics; pp 2-8
5114 This is a continuous, 2D color scheme!
5115 @tparam cutDepth See: tfrmComplexCut()
5116 @tparam argCuts See: tfrmComplexCut()
5117 @tparam absCuts See: tfrmComplexCut()
5118 @tparam logAbs See: tfrmComplexCut() */
5119 template<double cutDepth, double argCuts, double absCuts, bool logAbs>
5121#endif
5122 //@}
5123
5124 template <class csT, class csAT> colorTpl& csSet(csAT csArg) { return csT::c(*this, csArg); }
5125 template <class csT, class csAT> colorTpl& csSet(csAT csArg1, csAT csArg2) { return csT::c(*this, csArg1, csArg2); }
5126
5127 };
5128
5129////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5130 /** i/O stream output operator for colorTpl types. */
5131 template <class clrChanT, int numChan, int redChanIdx = -1, int blueChanIdx = -1, int greenChanIdx = -1, int alphaChanIdx = -1>
5132 requires ((numChan>0) && // Must have at least 1 chan
5133 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
5134 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
5135 (redChanIdx < numChan) &&
5136 (blueChanIdx < numChan) &&
5137 (greenChanIdx < numChan) &&
5138 (alphaChanIdx < numChan) &&
5139 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
5140 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
5141 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
5142 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
5143 (redChanIdx != blueChanIdx) &&
5144 (redChanIdx != alphaChanIdx) &&
5145 (greenChanIdx != blueChanIdx) &&
5146 (greenChanIdx != alphaChanIdx) &&
5147 (blueChanIdx != alphaChanIdx)))) // Chans can't be teh same if non-negative
5148 inline std::ostream&
5149 operator<< (std::ostream &out, colorTpl<clrChanT, numChan> const& color) {
5150 // 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..
5151 out << "<";
5152 if (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) > sizeof(uint64_t))) {
5153 for(int i=0; i<(numChan-1); i++)
5154 out << color.getChan(i) << ", ";
5155 out << color.getChan(numChan-1) << ">";
5156 } else {
5157 for(int i=0; i<(numChan-1); i++)
5158 out << static_cast<uint64_t>(color.getChan(i)) << ", ";
5159 out << static_cast<uint64_t>(color.getChan(numChan-1)) << ">";
5160 }
5161 return out;
5162 }
5163
5164////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5165 /** Inequality operator for colorTpl types. */
5166 template <class clrChanT, int numChan, int redChanIdx = -1, int blueChanIdx = -1, int greenChanIdx = -1, int alphaChanIdx = -1>
5167 requires ((numChan>0) && // Must have at least 1 chan
5168 (std::is_unsigned<clrChanT>::value || std::is_floating_point<clrChanT>::value) && // unsigned integral or floating point
5169 (std::is_floating_point<clrChanT>::value || (sizeof(clrChanT) >= 1)) && // If clrChanT int, then must be >= 1 char size
5170 (redChanIdx < numChan) &&
5171 (blueChanIdx < numChan) &&
5172 (greenChanIdx < numChan) &&
5173 (alphaChanIdx < numChan) &&
5174 (((blueChanIdx < 0) && (redChanIdx < 0) && (greenChanIdx < 0)) ||
5175 ((blueChanIdx >= 0) && (redChanIdx >= 0) && (greenChanIdx >= 0))) && // R, G, & B all non-negative or all negative
5176 ((alphaChanIdx < 0) || (redChanIdx >= 0)) && // If A is non-negative, then all non-negative
5177 ((redChanIdx < 0) || ((redChanIdx != greenChanIdx) &&
5178 (redChanIdx != blueChanIdx) &&
5179 (redChanIdx != alphaChanIdx) &&
5180 (greenChanIdx != blueChanIdx) &&
5181 (greenChanIdx != alphaChanIdx) &&
5182 (blueChanIdx != alphaChanIdx)))) // Chans can't be teh same if non-negative
5183 inline bool
5184 operator!= (colorTpl<clrChanT, numChan> const& color1, colorTpl<clrChanT, numChan> const& color2) {
5185 return color1.isNotEqual(color2);
5186 }
5187
5188} // end namespace mjr
5189
5190#define MJR_INCLUDE_MRcolorTpl
5191#endif
uint64_t mjr_uintBiggest_t
The largest unsigned integer supported on the platform.
int64_t mjr_intBiggest_t
The largest signed integer supported on the platform.
Compute a color for a point in using a continuous color scheme for the phase angle.
static colorTpl & c(colorRefType aColor, csCplxType csZ)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csFltType csX, csFltType csY)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl c(csCplxType csZ)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csFltType csX, csFltType csY)
Set given colorTpl instance to the selected color in the color scheme.
Compute a color for a point in using a discrete color scheme for the phase angle.
static colorTpl c(csFltType csX, csFltType csY)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csCplxType csZ)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csCplxType csZ)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csFltType csX, csFltType csY)
Set given colorTpl instance to the selected color in the color scheme.
Compute a color from Richardson's 2D complex number coloring scheme.
static colorTpl & c(colorRefType aColor, csCplxType csZ)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csFltType csX, csFltType csY)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csCplxType csZ)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl c(csFltType csX, csFltType csY)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
Template for Thaller 2D color schemes.
static colorTpl & c(colorRefType aColor, csFltType csX, csFltType csY)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csCplxType csZ)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csCplxType csZ)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csFltType csX, csFltType csY)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
Binary color scheme.
static colorTpl c(csIntType csIdx)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csIntType csIdx)
Set given colorTpl instance to the selected color in the color scheme.
Template for Color Brewer 2 variable sized pallets.
static colorTpl c(saT csG, csIntType numC=maxNumC)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, saT csG, csIntType numC=maxNumC)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, saT csG, csIntType numC=maxNumC)
Set given colorTpl instance to the selected color in the color scheme.
Template providing RGB color cube gradiant color schemes.
static colorTpl & c(colorRefType aColor, saT csG)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, saT csG)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(saT csG)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
Compute a color from Dave Green's cubehelix scheme.
static colorTpl c(csFltType csX)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csFltType csX)
Set given colorTpl instance to the selected color in the color scheme.
Template for fixed size pallets.
static colorTpl & c(colorRefType aColor, saT csG)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(saT csG)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, saT csG)
Set given colorTpl instance to the selected color in the color scheme.
Template for HSL color schemes.
static colorTpl & c(colorRefType aColor, csNatType csVal)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(csNatType csVal)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
Compute a color from a polynomial space curve in the RGB color space.
static colorTpl c(csFltType csX)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csFltType csX)
Set given colorTpl instance to the selected color in the color scheme.
Wrapper for Color Brewer 2 variable sized pallet template to produce a simple fixed color scheme with...
static colorTpl c(saT csG)
static colorTpl & c(colorRefType aColor, saT csG)
static colorTpl & c(colorRefType aColor, saT csG)
Template for web safe 216 pallets.
static colorTpl c(csIntType csIdx)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, csIntType csIdx)
Set given colorTpl instance to the selected color in the color scheme.
static colorTpl c(colorRefType csCol)
Create a new colorTpl object and set it's color to the selected color in the color scheme.
static colorTpl & c(colorRefType aColor, colorRefType csCol)
Set given colorTpl instance to the selected color in the color scheme.
Template Class used to house colors for ramCanvas objects.
colorTpl & tfrmShiftR(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & setRGBAfromLogPackIntABGR(packed4Cint anInt)
colorTpl & setChans_byte(colConALLbyte byteColor)
uint8_t getChan_byte(int chan) const
colorTpl & setChansRGBA_dbl(colConRGBAdbl dblColor)
double getC0_dbl() const
colorTpl & tfrmGreyScaleRGB(void)
Transform the current color by rendering it into a true grey via the same method used by the luminanc...
colorTpl & tfrmStdPowSqr(void)
The Standard Power Transform with p=2.
colorTpl & tfrmNegDiffClamp(colorArgType aCol)
Computes the negative of the arithmetic difference of the given color from the current one.
colorTpl & tfrmMod(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colConDbl3 rgb2colorSpace(colorSpaceEnum space) const
Compute channels for given color space coordinates for the current color.
colorTpl & tfrmStdPowSqrt(void)
The Standard Power Transform with p=1/2.
colorTpl & setToBlack()
colorTpl & setRGBfromColorSpace(colorSpaceEnum space, double inCh1, double inCh2, double inCh3)
Set the color indicated by the color space and values.
void setChansToMean()
Set all channels to meanChanVal.
clrChanT getRed() const
colorTpl & setChansRGB_byte(colConRGBbyte byteColor)
colorTpl & setRGBAfromLogPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx, uint8_t aIdx)
Set the color based upon the bytes of the given integer ordered from LSB to MSB.
colorTpl & csSet(csAT csArg1, csAT csArg2)
clrChanT getMaxC() const
Returns the value of the largest component.
uint8_t getC3_byte() const
colConRGBAdbl getColConRGBA_dbl()
bool isBlackRGB() const
LIke isBlack(), but only checks the R, G, & B channels.
clrChanT getC1() const
colorTpl & setChansRGBA(clrChanTup4 chanValues)
colorTpl & tfrmShiftR(colorArgType aCol)
The Shift Right Transform modifies the current color.
colorTpl & tfrmPow(double p)
Power: c=maxChanVal*(c/maxChanVal)^p.
colorTpl(std::string colorString)
Uses the setColorFromString() method to set the initialize the object.
clrChanT thePartsA[numChan]
std::tuple< clrChanT, clrChanT, clrChanT, clrChanT > clrChanTup4
colorTpl & linearInterpolateRGB(double aDouble, colorArgType col1, colorArgType col2)
Set the RGB channels of the current color to a value linearly interpolated between the two given colo...
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< clrChanT > clrChanVec
std::tuple< clrChanT, clrChanT, clrChanT, clrChanT > clrChanTup6
colConRGBdbl getColConRGB_dbl()
colorTpl & tfrmDiv(colorArgType aCol)
Computes the arithmetic division of the current color by the given color.
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
Color with the same number of challens as colorT, but with uint8_t channels.
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
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.
clrChanT getBlue() const
colorTpl< double, 3 > colConRGBdbl
RGB with double channels.
colConRGBAbyte getColConRGBA_byte()
colorTpl & setChansRGBA_byte(colConRGBAbyte byteColor)
colorType const & colorCRefType
Reference to const colorTpl.
double getBlue_dbl() const
colorTpl & tfrmWebSafeRGB()
The 216 Palate Web Safe Transform modifies the current color into the closest web safe color from the...
colorTpl & tfrmOr(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & setChansRGBA_byte(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
colorTpl & setToBlue()
maskType getMaskNC() const
Return the mask value.
colorTpl & setC1(clrChanT cVal)
colorTpl & interplColorSpace(colorSpaceEnum space, double aDouble, colorArgType col1, colorArgType col2)
Set the current color to a value linearly interpolated between the two given colors.
colorTpl< uint8_t, 3 > colConRGBbyte
RGB with uint8_t channels.
bool isNotEqual(colorArgType aColor) const
Returns non-zero if the given color is logically NOT the same as the current color.
uint32_t packed4Cint
Used for passing & returning integers with packed 8-bit channels.
colorTpl & cmpGradiant(csFltType csX, csIntType numColors, const packed4Cint *colors)
Identical to the other equidistant cmpGradiant() function except that this one works on just the RGB ...
colorTpl & setToMagenta()
double distDeltaE1976(colorArgType aColor) const
LAB Delta E* distance between current color and given one.
std::tuple< clrChanT, clrChanT > 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...
union mjr::colorTpl::@0 theColor
Holds the color channel data.
bool isEqualRGB(colorArgType aColor) const
Like isEqual(), but only checks the R, G, & B channels.
clrChanT clampAll(iT arithValue)
Clamp a value to [minChanVal, maxChanVal].
colorTpl & setChansRGB_dbl(double r, double g, double b)
colConALLbyte getColCon_byte()
colorTpl< double, 3 > colConDbl3
Used for color space computations. Type identical to colConRGBdbl, but might not be RGB.
colorTpl & setToHalf()
clrChanT clampTop(iT arithValue)
Clamp a value to (infinity, maxChanVal].
colorTpl(clrChanT r, clrChanT g, clrChanT b, clrChanT a)
colorTpl & uMean(channelArithFltType w1, colorArgType col1, colorArgType col2)
This is an overloaded member function, provided for convenience. It differs from the above function o...
clrChanT convertHexStringToChan(std::string hexString) const
Convert hex CString to clrChanT (for floating point clrChanT)
double distDeltaE1994(colorArgType aColor) const
LAB Delta E* 1994 (graphic arts) distance between current color and given one.
colorTpl & setBlue(clrChanT cVal)
colorTpl & setRGBfromLogPackIntARGB(packed4Cint anInt)
channelArithFltType intensityScaledRGB() const
Compute the scaled intensity (sum of the first three components divided by the maximum intensity poss...
colorTpl & setChans_byte(uint8_t cVal)
colorTpl & tfrmComplexCut(std::complex< double > z, double cutDepth, double argCuts, double absCuts, bool logAbs=true)
Perform a tfrmLinearGreyLevelScale based on a complex number.
colorTpl & setC1_dbl(double cVal)
colorTpl & tfrmNor(colorArgType aCol)
Performs a logical NOR with the current object and the given object and places the value in the curre...
colorTpl & tfrmStdPowRGB(double rp, double gp, double bp)
The Standard Power Transform modifies the current color such that: R=maxChanVal*(R/maxChanVal)**rp,...
colorTpl & cmpRGBcornerDGradiant(csIntType csIdx, csIntType numColors, const ccT *cornerColors)
Color value based upon a color ramp passing through the given sequence of corner colors at equal inte...
colorTpl & setRGBfromPackIntGen(packed4Cint anInt, uint8_t rIdx, uint8_t gIdx, uint8_t bIdx)
Just like setRGBAfromPackIntGen, but no A.
colorTpl & setChanNC(int chan, clrChanT cVal)
Sets the specified color channel value with no index check.
colorTpl & tfrmShiftL(colorArgType aCol)
The Shift Left Transform modifies the current color.
colorTpl & setRGBfromLogPackIntBGRA(packed4Cint anInt)
maskType theInt
colorTpl & setToGreen()
clrChanT getMaxRGB() const
Returns the value of the largest component from R, G, and B.
colorTpl & setRGBAfromLogPackIntARGB(packed4Cint anInt)
~colorTpl()
The destructor for this class is a no-op.
channelArithSPType distSumAbs(colorArgType aColor) const
Distance between current color and given one (sum of absolute channel differences).
colorTpl & setRGBAfromLogPackIntRGBA(packed4Cint anInt)
colorTpl & tfrmDiracTot(colorArgType aCol)
The DiracTot (total) Transform modifies the current color: Set current color to white if it equals aC...
channelArithFltType intensityScaled() const
Compute the scaled intensity (sum of the components divided by the maximum intensity possible) of the...
colorTpl & tfrmMean(colorArgType aCol)
Computes the arithmetic mean of the given color and the current one.
colorTpl & setRGBfromLogPackIntABGR(packed4Cint anInt)
colorTpl colorType
This object type.
colorTpl & setColorFromString(std::string colorString)
Sets the current color based upon the contents of the given std::string.
colorTpl & tfrmMin(colorArgType aCol)
Makes each component of the current color the minimum of that component and the corresponding compone...
colorTpl(clrChanT r, clrChanT g, clrChanT b)
uint8_t getBlue_byte() const
clrChanT getChan(int chan) const
clrChanT getC3() const
colorTpl & wMean(channelArithFltType w1, channelArithFltType w2, colorArgType col1, colorArgType col2)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEqual(colorArgType aColor) const
Returns non-zero if the current color is precicely equal to aColor.
colorTpl & setBlue_byte(uint8_t cVal)
std::tuple< clrChanT, clrChanT, clrChanT, clrChanT > 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)
Set the mask value.
colorTpl & tfrmAbsDiff(colorArgType aCol)
Computes the absolute value of the difference for each channel between the given color and the curren...
colorTpl & setChans(clrChanTup3 chanValues)
Sets the first three channels current object.
colorTpl & setToWhite()
colorTpl & cmpGradiant(csFltType csX, std::vector< colorType > const &colors)
Identical to the other cmpGradiant() function except that equidistant anchors are automatically gener...
colorTpl< double, numChan > colConALLdbl
Color with the same number of challens as colorT, but with double channels.
clrChanT getC2() const
colorTpl & setRGBAfromLogPackIntABRG(packed4Cint anInt)
colorTpl & tfrmNot(void)
Template specialization member function differing from the above function only in supported template ...
colorTpl & setToCorner(char cornerColor)
Set the current color based upon the single character given – 0==black, R, G, B, M,...
clrChanT getChanNC(int chan) const
Provides access to an specified color channel value with no index check.
colorTpl()
The no arg constructor is a noop so we don't needlessly initialize millions of pixels – compiler warn...
colorTpl & tfrmMod(colorArgType aCol)
Computes the arithmetic modulus of the current by the given one.
colorTpl & setC0_byte(uint8_t cVal)
double getChan_dbl(int chan) const
colorTpl & tfrmNand(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & setRed(clrChanT cVal)
colorTpl & tfrmMultClamp(colorArgType aCol)
Computes the product of the given color and the current one.
colorTpl & tfrmNxor(colorArgType aCol)
Performs a logical NOT EXCLUSIVE OR (NXOR) with the current object and the given object and places th...
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< uint8_t, 4 > colConRGBAbyte
RGBA with uint8_t channels.
void setChansToMin()
Set all channels to minChanVal.
channelArithFltType luminanceRGB(void) const
Compute the luminance of the current color via the definition given in the ITU-R Recommendation BT....
colorTpl & setChans_dbl(double cVal)
colorTpl & cmpRGBcornerCGradiant(csFltType csX, const char *cornerColors)
This is simply a version of cmpRGBcornerCGradiant() that computes the length of the final argument as...
double getC3_dbl() const
colorTpl & cmpGradiant(csFltType csX, std::vector< csFltType > const &anchors, std::vector< colorType > const &colors)
Convert a double to a color value based upon a color ramp passing through the given sequence of corne...
colorTpl & setChansRGBA_dbl(double r, double g, double b, double a)
double getRed_dbl() const
uint8_t convertChanToByte(clrChanT cVal) const
Convert a clrChanT to a uint8_t (for integral clrChanT)
colorTpl & wMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3, channelArithFltType w4, colorArgType col1, colorArgType col2, colorArgType col3, colorArgType col4)
Compute the weighted mean of the given colors.
colorTpl & setAlpha_byte(uint8_t cVal)
uint8_t getGreen_byte() const
colorTpl & linearInterpolate(double aDouble, colorArgType col1, colorArgType col2)
Set the current color to a value linearly interpolated between the two given colors.
colorTpl(cornerColorEnum cornerColor)
Uses the setToCorner() method to set the initialize the object.
colorTpl & tfrmMinI(colorArgType aCol)
Makes the current color the minimum of the current color or the given color.
colorTpl & 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)
clrChanT getMinRGB() const
Returns the value of the smallest component from R, G, and B.
colorTpl & setToRed()
colorTpl & setRed_dbl(double cVal)
std::tuple< clrChanT, clrChanT, clrChanT > clrChanTup3
clrChanT channelType
Type for the channels (clrChanT)
colorTpl & tfrmNor(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & tfrmNxor(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
colorTpl & setRGBfromLogPackIntRGBA(packed4Cint anInt)
channelArithSPType distMaxAbs(colorArgType aColor) const
Distance between current color and given one (maximum of absolute value of channel differences).
colorTpl & csSet(csAT csArg)
colorSpaceEnum
Color spaces.
colorTpl & setChanToMin(int chan)
colorTpl & setToCorner(cornerColorEnum cornerColor)
Set the color to the given corner color.
colorTpl & setToCyan()
colorTpl & setRGBfromUnitHSL(double H, double S, double L)
Set the color indicated by the given HSL values.
channelArithSPType intensityRGB(void) const
Compute the unscaled intensity (sum of the R, G, & B components) of the current color.
uint8_t getC1_byte() const
colorTpl(const char *colorCString)
Uses the setColorFromString() method to set the initialize the object.
uint8_t getC0_byte() const
colorTpl & setGreen_byte(uint8_t cVal)
colorTpl & tfrmXor(colorArgType aCol)
Performs a logical EXCLUSIVE OR (XOR) with the current object and the given object and places the val...
colorTpl & tfrmDiffClamp(colorArgType aCol)
Computes the arithmetic difference of the given color from the current one.
clrChanT clampBot(iT arithValue)
Clamp a value to [minChanVal, infinity).
colorTpl & uMean(channelArithFltType w1, channelArithFltType w2, channelArithFltType w3, colorArgType col1, colorArgType col2, colorArgType col3, colorArgType col4)
Compute the unit weighted mean of the given colors – like wMean(), but last weight is computed such t...
colorTpl & setChansRGB(clrChanT r, clrChanT g, clrChanT b)
colorTpl & setRGBfromWavelengthCM(double wavelength, cmfInterpolationEnum interpMethod=cmfInterpolationEnum::LINEAR)
Set the color indicated by the given wavelength.
colorTpl & tfrmAddClamp(colorArgType aCol)
Computes the arithmetic sum of the given color from the current one.
colorTpl & tfrmMax(colorArgType aCol)
Makes each component of the current color the maximum of that component and the corresponding compone...
colorTpl & tfrmAddDivClamp(colorArgType aCol, colorArgType dCol)
Computes the arithmetic sum of the current color and aCol, then divids by dCol.
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
colorType & colorRefType
Reference to colorTpl)
colorTpl & setC0_dbl(double cVal)
colorTpl & cmpRGBcornerCGradiant(csFltType csX, csIntType numColors, const ccT *cornerColors)
Color value based upon a color ramp passing through the given sequence of corner colors at equal inte...
colorTpl(std::initializer_list< clrChanT > cVals)
Initializer list.
cmfInterpolationEnum
Interpolation methods for emperical color matching functions.
colorTpl & setChans(clrChanT cVal)
colorTpl & setChans(clrChanVec &chanValues)
This function sets color channels from the data in a std::vector.
colorTpl & setC2_dbl(double cVal)
colorTpl & tfrmGmean(colorArgType aCol)
Computes the geometric mean of the given color and the current one.
colorType * colorPtrType
Pointer to colorTpl.
colorTpl & tfrmLn(double scale)
Computes ln(c)*scale for each channel value c.
colorTpl & tfrmSaw(colorArgType lowCol, colorArgType highCol)
The Saw Transform modifies the current color: C_i = ifelse(ra<=C_i<=rb, C_i, 0)
colorTpl & tfrmLn1()
Adds 1.0 and takes the natural logarithm of each channel.
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< clrChanT > 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.
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
RGBA with double channels.
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 & tfrmDirac(colorArgType aCol)
The Dirac Transform modifies the current color: C_i = ifelse(C_i==aCol.C_i, maxChanVal,...
colorTpl & tfrmMix(double aDouble, colorArgType tooCol)
Linearly interpolate between the current color and the given color (at a point scaled the unit interv...
uint8_t getRed_byte() const
cornerColorEnum
Colors at the corners of the RGB color cube.
colorTpl & tfrmMaxI(colorArgType aCol)
Makes the current color the maximum of the current color or the given color.
colorTpl & tfrmOr(colorArgType aCol)
Performs a logical OR with the current object and the given object and places the value in the curren...
colorTpl & setChan_byte(int chan, uint8_t cVal)
colorTpl & tfrmAdd(colorArgType aCol)
Computes the arithmetic sum of the given color and the current one.
colorTpl & setRed_byte(uint8_t cVal)
colorTpl(clrChanT cVal)
Uses setChans() to set all channels to the given value.
colorTpl & setC0(clrChanT cVal)
colorTpl & setRGBfromUnitHSV(double H, double S, double V)
Set the color indicated by the given HSV values.
colorTpl & tfrmLinearGreyLevelScale(double c, double b)
The Linear Grey Level Scale transform modifies the current color such that: C_n=c*C_n+b.
colorTpl & setChans_dbl(colConALLdbl dblColor)
colorTpl & setChans(std::string colorHexString, bool clearUndefinedChannels=false)
Sets the current color based upon the contents of the given color hex string.
std::conditional< ptrIsSmaller, colorCRefType, colorType >::type colorArgType
A type for passing colorTpl objects to functions.
colorTpl & tfrmStdPow(double p)
The Standard Power Transform modifies the current color such that: C_i = maxChanVal*(C_i / maxChanVal...
clrChanT convertByteToChan(uint8_t cVal) const
Convert a uint8_t to a clrChanT (for floating point clrChanT)
colorTpl & setChansRGBA(clrChanT r, clrChanT g, clrChanT b, clrChanT a)
colorTpl & setRGBcmpGreyTGA16bit(uint32_t tga16val)
Computes a 24-bit truecolor value intended for use in producing 16-bit greyscale TGA.
colorTpl & tfrmXor(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...
clrChanT getMinC() const
Returns the value of the smallest component.
colorTpl & setToCorner(std::string cornerColor)
Set the color to the named corner color.
channelArithSPType intensity() const
Compute the sum of the components.
colorTpl & setRGBAfromLogPackIntBGRA(packed4Cint anInt)
colorTpl & copy(colorArgType aCol)
Copy the contents of the given color object into the current object.
colorTpl & tfrmAnd(colorArgType aCol)
Template specialization member function differing from the above function only in supported template ...