ACF $AcfVersion:0$
CFastColor.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ACF-Commercial
2#pragma once
3
4
5// Qt includes
6#include <QtCore/QtGlobal>
7#if QT_VERSION >= 0x050000
8#include <QtCore/QtMath>
9#else
10#include <QtCore/qmath.h>
11#endif
12
13// ACF includes
14#include <iser/ISerializable.h>
15#include <imath/IDoubleManip.h>
16#include <imath/TFastVector.h>
17#include <icmm/CVarColor.h>
18#include <icmm/CLab.h>
19
20
21namespace icmm
22{
23
24
25enum{
26#ifdef COLOR_COMPONENTS_COUNT
27 MAX_COLOR_COMPONENTS_COUNT=COLOR_COMPONENTS_COUNT
28#else
30#endif // COLOR_COMPONENTS_COUNT
31};
32
33
38class CFastColor: public imath::TFastVector<MAX_COLOR_COMPONENTS_COUNT>
39{
40public:
42
47 CFastColor();
48
52 explicit CFastColor(int componentsCount, double value = 0);
53
57 CFastColor(const CFastColor& color);
58
62 CFastColor(std::initializer_list<double> values);
63
64 template <int Size>
66 : BaseClass(vector)
67 {
68 }
69
73 #if __cplusplus >= 202002L
74 template <typename Iterator>
75 requires std::input_iterator<Iterator> // Require C++20 iterator concept to disambiguate from other constructors
76 CFastColor(Iterator first, Iterator last);
77 #endif // __cplusplus >= 202002L
78
80
82 void SetAsLab(const icmm::CLab& lab);
83
84 bool EnsureElementsCount(int count, double value = 0);
85
91 void GetRounded(const imath::IDoubleManip& manipulator, CFastColor& result);
92
98 bool IsRoundedEqual(const CFastColor& color, const imath::IDoubleManip& manipulator) const;
99
103 bool IsSimilar(const CFastColor& color, double tolerance = I_BIG_EPSILON) const;
104
109 bool IsNormalized() const;
110
115 void Normalize();
116
121 void GetNormalized(CFastColor& result) const;
122
123 operator icmm::CVarColor() const;
124
125 bool operator==(const CFastColor& vector) const;
126 bool operator!=(const CFastColor& vector) const;
127 bool operator<(const CFastColor& vector) const;
128 bool operator>(const CFastColor& vector) const;
129 bool operator<=(const CFastColor& vector) const;
130 bool operator>=(const CFastColor& vector) const;
131
132 CFastColor operator+(const CFastColor& color) const;
133 CFastColor operator-(const CFastColor& color) const;
134 CFastColor operator*(const CFastColor& color) const;
135 CFastColor operator/(const CFastColor& color) const;
136
137 CFastColor operator*(double value) const;
138 CFastColor operator/(double value) const;
139
140 CFastColor& operator=(const CFastColor& color);
141
142 const CFastColor& operator+=(const CFastColor& color);
143 const CFastColor& operator-=(const CFastColor& color);
144 const CFastColor& operator*=(const CFastColor& color);
145 const CFastColor& operator/=(const CFastColor& color);
146
147 const CFastColor& operator*=(double value);
148 const CFastColor& operator/=(double value);
149
150 // not reimplemented (iser::ISerializable)
151 bool Serialize(iser::IArchive& archive);
152};
153
154
155// inline methods
156
158{
159#ifdef COLOR_COMPONENTS_COUNT
160 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
161 m_elements[i] = 0;
162 }
163#endif // COLOR_COMPONENTS_COUNT
164}
165
166
167inline CFastColor::CFastColor(int componentsCount, double value)
168#ifndef COLOR_COMPONENTS_COUNT
169: BaseClass(componentsCount, value)
170#endif // !COLOR_COMPONENTS_COUNT
171{
172#ifdef COLOR_COMPONENTS_COUNT
173 m_elementsCount = componentsCount;
174
175 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
176 m_elements[i] = value;
177 }
178#endif // COLOR_COMPONENTS_COUNT
179}
180
181
183#ifndef COLOR_COMPONENTS_COUNT
184: BaseClass(color)
185#endif // !COLOR_COMPONENTS_COUNT
186{
187#ifdef COLOR_COMPONENTS_COUNT
188 m_elementsCount = color.m_elementsCount;
189
190 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
191 m_elements[i] = color.m_elements[i];
192 }
193#endif // COLOR_COMPONENTS_COUNT
194}
195
196
197inline CFastColor::CFastColor(std::initializer_list<double> values)
198#ifndef COLOR_COMPONENTS_COUNT
199: BaseClass(values)
200#endif // !COLOR_COMPONENTS_COUNT
201{
202#ifdef COLOR_COMPONENTS_COUNT
203 m_elementsCount = qMin(COLOR_COMPONENTS_COUNT, static_cast<int>(values.size()));
204 Q_ASSERT(values.size() <= COLOR_COMPONENTS_COUNT);
205
206 for (int i = 0; i < m_elementsCount; ++i){
207 m_elements[i] = *(values.begin() + i);
208 }
209
210 for (int i = m_elementsCount; i < COLOR_COMPONENTS_COUNT; ++i){
211 m_elements[i] = 0.0;
212 }
213#endif // COLOR_COMPONENTS_COUNT
214}
215
216
217#if __cplusplus >= 202002L
218template <typename Iterator>
219requires std::input_iterator<Iterator> // Require C++20 iterator concept to disambiguate from other constructors
220inline CFastColor::CFastColor(Iterator first, Iterator last)
221{
222 const size_t size = last - first;
223 if (EnsureElementsCount(size)) {
224 for (size_t i = 0; i < size; ++i, ++first) {
225 operator[](i) = *first;
226 }
227 }
228}
229#endif // __cplusplus >= 202002L
230
231
232inline bool CFastColor::EnsureElementsCount(int count, double value)
233{
234 if (count > GetElementsCount()){
235 return SetElementsCount(count, value);
236 }
237
238 return true;
239}
240
241
242inline bool CFastColor::IsSimilar(const CFastColor& color, double tolerance) const
243{
244 return GetDistance(color) <= tolerance;
245}
246
247
248inline bool CFastColor::IsNormalized() const
249{
250 int elementsCount = GetElementsCount();
251
252 for (int i = 0; i < elementsCount; ++i){
253 double component = m_elements[i];
254
255 if ((component < 0) || (component > 1)){
256 return false;
257 }
258 }
259
260 return true;
261}
262
263
264inline CFastColor::operator icmm::CVarColor() const
265{
266 int elementsCount = GetElementsCount();
267
268 icmm::CVarColor retVal(elementsCount);
269
270 for (int i = 0; i < elementsCount; ++i){
271 retVal[i] = GetElement(i);
272 }
273
274 return retVal;
275}
276
277
278inline bool CFastColor::operator==(const CFastColor& vector) const
279{
280 int elementsCount = GetElementsCount();
281
282 if (elementsCount != vector.GetElementsCount()){
283 return false;
284 }
285
286 for (int i = 0; i < elementsCount; ++i){
287 if ( (operator[](i) > vector[i] + I_BIG_EPSILON) ||
288 (operator[](i) < vector[i] - I_BIG_EPSILON)){
289 return false;
290 }
291 }
292
293 return true;
294}
295
296
297inline bool CFastColor::operator!=(const CFastColor& vector) const
298{
299 return !operator==(vector);
300}
301
302
303inline bool CFastColor::operator<(const CFastColor& vector) const
304{
305 int commonSize = qMin(GetElementsCount(), vector.GetElementsCount());
306
307 for (int i = 0; i < commonSize; ++i){
308 if (operator[](i) > vector[i] + I_BIG_EPSILON){
309 return false;
310 }
311 else if (operator[](i) < vector[i] - I_BIG_EPSILON){
312 return true;
313 }
314 }
315
316 return GetElementsCount() < vector.GetElementsCount();
317}
318
319
320inline bool CFastColor::operator>(const CFastColor& vector) const
321{
322 int commonSize = qMin(GetElementsCount(), vector.GetElementsCount());
323 for (int i = 0; i < commonSize; ++i){
324 if (operator[](i) > vector[i] + I_BIG_EPSILON){
325 return true;
326 }
327 else if (operator[](i) < vector[i] - I_BIG_EPSILON){
328 return false;
329 }
330 }
331
332 return GetElementsCount() > vector.GetElementsCount();
333}
334
335
336inline bool CFastColor::operator<=(const CFastColor& vector) const
337{
338 int commonSize = qMin(GetElementsCount(), vector.GetElementsCount());
339 for (int i = 0; i < commonSize; ++i){
340 if (operator[](i) > vector[i] + I_BIG_EPSILON){
341 return false;
342 }
343 else if (operator[](i) < vector[i] - I_BIG_EPSILON){
344 return true;
345 }
346 }
347
348 return GetElementsCount() <= vector.GetElementsCount();
349}
350
351
352inline bool CFastColor::operator>=(const CFastColor& vector) const
353{
354 int commonSize = qMin(GetElementsCount(), vector.GetElementsCount());
355 for (int i = 0; i < commonSize; ++i){
356 if (operator[](i) > vector[i] + I_BIG_EPSILON){
357 return true;
358 }
359 else if (operator[](i) < vector[i] - I_BIG_EPSILON){
360 return false;
361 }
362 }
363
364 return GetElementsCount() >= vector.GetElementsCount();
365}
366
367
369{
370 CFastColor retVal(*this);
371
372 retVal += color;
373
374 return retVal;
375}
376
377
379{
380 CFastColor retVal(*this);
381
382 retVal -= color;
383
384 return retVal;
385}
386
387
389{
390 CFastColor retVal(*this);
391
392 retVal *= color;
393
394 return retVal;
395}
396
397
399{
400 CFastColor retVal(*this);
401
402 retVal /= color;
403
404 return retVal;
405}
406
407
408inline CFastColor CFastColor::operator*(double value) const
409{
410 int elementsCount = GetElementsCount();
411
412 CFastColor retVal(elementsCount);
413
414#ifdef COLOR_COMPONENTS_COUNT
415 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
416#else
417 for (int i = 0; i < elementsCount; ++i){
418#endif // COLOR_COMPONENTS_COUNT
419 retVal.m_elements[i] = m_elements[i] * value;
420 }
421
422 return retVal;
423}
424
425
426inline CFastColor CFastColor::operator/(double value) const
427{
428 int elementsCount = GetElementsCount();
429
430 CFastColor retVal(elementsCount);
431
432#ifdef COLOR_COMPONENTS_COUNT
433 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
434#else
435 for (int i = 0; i < elementsCount; ++i){
436#endif // COLOR_COMPONENTS_COUNT
437 retVal.m_elements[i] = m_elements[i] / value;
438 }
439
440 return retVal;
441}
442
443
445{
446#ifdef COLOR_COMPONENTS_COUNT
448 Q_ASSERT(m_elementsCount <= COLOR_COMPONENTS_COUNT);
449
450 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
451 m_elements[i] = color.m_elements[i];
452 }
453#else
455#endif // COLOR_COMPONENTS_COUNT
456
457 return *this;
458}
459
460
462{
463#ifdef COLOR_COMPONENTS_COUNT
465 Q_ASSERT(m_elementsCount <= COLOR_COMPONENTS_COUNT);
466
467 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
468 m_elements[i] += color.m_elements[i];
469 }
470#else
472#endif // COLOR_COMPONENTS_COUNT
473
474 return *this;
475}
476
477
479{
480#ifdef COLOR_COMPONENTS_COUNT
482 Q_ASSERT(m_elementsCount <= COLOR_COMPONENTS_COUNT);
483
484 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
485 m_elements[i] -= color.m_elements[i];
486 }
487#else
489#endif // COLOR_COMPONENTS_COUNT
490
491 return *this;
492}
493
494
496{
497#ifdef COLOR_COMPONENTS_COUNT
498 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
499#else
500 int elementsCount = qMin(GetElementsCount(), color.GetElementsCount());
501 for (int i = 0; i < elementsCount; ++i){
502#endif // COLOR_COMPONENTS_COUNT
503 m_elements[i] *= color.m_elements[i];
504 }
505
506 return *this;
507}
508
509
511{
512#ifdef COLOR_COMPONENTS_COUNT
513 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
514#else
515 int elementsCount = qMin(GetElementsCount(), color.GetElementsCount());
516 for (int i = 0; i < elementsCount; ++i){
517#endif // COLOR_COMPONENTS_COUNT
518 m_elements[i] /= color.m_elements[i];
519 }
520
521 return *this;
522}
523
524
525inline const CFastColor& CFastColor::operator*=(double value)
526{
527#ifdef COLOR_COMPONENTS_COUNT
528 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
529 m_elements[i] *= value;
530 }
531#else
533#endif // COLOR_COMPONENTS_COUNT
534
535 return *this;
536}
537
538
539inline const CFastColor& CFastColor::operator/=(double value)
540{
541#ifdef COLOR_COMPONENTS_COUNT
542 for (int i = 0; i < COLOR_COMPONENTS_COUNT; ++i){
543 m_elements[i] /= value;
544 }
545#else
547#endif // COLOR_COMPONENTS_COUNT
548
549 return *this;
550}
551
552
553// related global functions
554
555uint qHash(const CFastColor& color, uint seed = 0);
556
557
558} // namespace icmm
559
560
Color implementation with variable components number and fixed maximal number of components.
Definition CFastColor.h:39
void SetAsLab(const icmm::CLab &lab)
void GetRounded(const imath::IDoubleManip &manipulator, CFastColor &result)
Get color after components value rounding with specified precision.
CFastColor(const icmm::CVarColor &color)
Constructor from iterator pair.
void GetNormalized(CFastColor &result) const
Get normalized color.
bool IsRoundedEqual(const CFastColor &color, const imath::IDoubleManip &manipulator) const
Check if two values are equal after rounding.
CFastColor operator*(const CFastColor &color) const
Definition CFastColor.h:388
bool operator>(const CFastColor &vector) const
Definition CFastColor.h:320
const CFastColor & operator*=(const CFastColor &color)
Definition CFastColor.h:495
const CFastColor & operator/=(const CFastColor &color)
Definition CFastColor.h:510
const CFastColor & operator+=(const CFastColor &color)
Definition CFastColor.h:461
const CFastColor & operator-=(const CFastColor &color)
Definition CFastColor.h:478
void Normalize()
Make this color to be normalized.
icmm::CLab GetAsLab() const
CFastColor operator/(const CFastColor &color) const
Definition CFastColor.h:398
bool operator<(const CFastColor &vector) const
Definition CFastColor.h:303
bool operator!=(const CFastColor &vector) const
Definition CFastColor.h:297
bool Serialize(iser::IArchive &archive)
CFastColor()
Default constructor.
Definition CFastColor.h:157
CFastColor & operator=(const CFastColor &color)
Definition CFastColor.h:444
bool operator<=(const CFastColor &vector) const
Definition CFastColor.h:336
bool IsSimilar(const CFastColor &color, double tolerance=I_BIG_EPSILON) const
Allows to compare two colors with tolerance.
Definition CFastColor.h:242
CFastColor operator+(const CFastColor &color) const
Definition CFastColor.h:368
bool IsNormalized() const
Check if this color value is normalized.
Definition CFastColor.h:248
CFastColor(const imath::TVector< Size > &vector)
Definition CFastColor.h:65
bool operator==(const CFastColor &vector) const
Definition CFastColor.h:278
bool EnsureElementsCount(int count, double value=0)
Definition CFastColor.h:232
imath::TFastVector< MAX_COLOR_COMPONENTS_COUNT > BaseClass
Definition CFastColor.h:41
bool operator>=(const CFastColor &vector) const
Definition CFastColor.h:352
Primitive for representation of CIE Lab color values.
Definition CLab.h:215
Generic color implementation with variable number of color components.
Definition CVarColor.h:176
Interface for all manipulation using values represent as double.
Optimized implementation of a variable-size vector with compile-time maximum capacity.
TFastVector< MaxSize, double > operator-() const
double GetDistance(const TFastVector< MaxSize, double > &vector) const
Return distance between two vectors.
TFastVector< MaxSize, double > & operator-=(const TFastVector< MaxSize, double > &vector)
TFastVector< MaxSize, double > & operator/=(double scalar)
bool SetElementsCount(int count, const double &value=double())
Set number of elements.
int GetElementsCount() const
Get number of elements.
TFastVector< MaxSize, double > & operator=(const TFastVector< MaxSize, double > &vector)
TFastVector< MaxSize, double > & operator+=(const TFastVector< MaxSize, double > &vector)
TFastVector< MaxSize, double > & operator*=(double scalar)
Implementation of fixed-size mathematical vector with specified type of elements.
Definition TVector.h:95
Represents an input/output persistence archive for object serialization.
Definition IArchive.h:164
static const double I_BIG_EPSILON
Definition istd.h:26
Contains color management classes.
uint qHash(const CFastColor &color, uint seed=0)
@ MAX_COLOR_COMPONENTS_COUNT
Definition CFastColor.h:29