Magick++ 6.9.13
Loading...
Searching...
No Matches
Color.cpp
1// This may look like C code, but it is really -*- C++ -*-
2//
3// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
4// Copyright Dirk Lemstra 2014-2018
5//
6// Color Implementation
7//
8
9#define MAGICKCORE_IMPLEMENTATION
10#define MAGICK_PLUSPLUS_IMPLEMENTATION 1
11
12#include "Magick++/Include.h"
13#include <string>
14
15#include "Magick++/Color.h"
16#include "Magick++/Exception.h"
17
18using namespace std;
19
20MagickPPExport int Magick::operator == (const Magick::Color &left_,
21 const Magick::Color &right_)
22{
23#if defined(MAGICKCORE_HDRI_SUPPORT)
24 return((left_.isValid() == right_.isValid()) &&
25 (fabs(left_.redQuantum()-right_.redQuantum()) < MagickEpsilon) &&
26 (fabs(left_.greenQuantum()-right_.greenQuantum()) < MagickEpsilon) &&
27 (fabs(left_.blueQuantum()-right_.blueQuantum()) < MagickEpsilon));
28#else
29 return((left_.isValid() == right_.isValid()) &&
30 (left_.redQuantum() == right_.redQuantum()) &&
31 (left_.greenQuantum() == right_.greenQuantum()) &&
32 (left_.blueQuantum() == right_.blueQuantum()));
33#endif
34}
35
36MagickPPExport int Magick::operator != (const Magick::Color &left_,
37 const Magick::Color &right_)
38{
39 return(!(left_ == right_));
40}
41
42MagickPPExport int Magick::operator > (const Magick::Color &left_,
43 const Magick::Color &right_)
44{
45 return(!(left_ < right_ ) && (left_ != right_ ));
46}
47
48MagickPPExport int Magick::operator < (const Magick::Color &left_,
49 const Magick::Color &right_)
50{
51 if(left_.redQuantum() < right_.redQuantum())
52 return(true);
53 if(left_.redQuantum() > right_.redQuantum())
54 return(false);
55 if(left_.greenQuantum() < right_.greenQuantum())
56 return(true);
57 if(left_.greenQuantum() > right_.greenQuantum())
58 return(false);
59 if(left_.blueQuantum() < right_.blueQuantum())
60 return(true);
61 return(false);
62}
63
64MagickPPExport int Magick::operator >= (const Magick::Color &left_,
65 const Magick::Color &right_)
66{
67 return((left_ > right_) || (left_ == right_));
68}
69
70MagickPPExport int Magick::operator <= (const Magick::Color &left_,
71 const Magick::Color &right_)
72{
73 return((left_ < right_) || (left_ == right_));
74}
75
76Magick::Color::Color(void)
77 : _pixel(new PixelPacket),
78 _isValid(false),
79 _pixelOwn(true),
80 _pixelType(RGBAPixel)
81{
82 initPixel();
83
84 _pixel->opacity=TransparentOpacity;
85}
86
87Magick::Color::Color(Magick::Quantum red_,Magick::Quantum green_,
88 Magick::Quantum blue_)
89 : _pixel(new PixelPacket),
90 _isValid(true),
91 _pixelOwn(true),
92 _pixelType(RGBPixel)
93{
94 redQuantum(red_);
95 greenQuantum(green_);
96 blueQuantum(blue_);
97 alphaQuantum(OpaqueOpacity);
98}
99
100Magick::Color::Color(Magick::Quantum red_,Magick::Quantum green_,
101 Magick::Quantum blue_,Magick::Quantum alpha_)
102 : _pixel(new PixelPacket),
103 _isValid(true),
104 _pixelOwn(true),
105 _pixelType(RGBAPixel)
106{
107 redQuantum(red_);
108 greenQuantum(green_);
109 blueQuantum(blue_);
110 alphaQuantum(alpha_);
111}
112
113Magick::Color::Color(const char *x11color_)
114 : _pixel(new PixelPacket),
115 _isValid(true),
116 _pixelOwn(true),
117 _pixelType(RGBPixel)
118{
119 initPixel();
120
121 // Use operator = implementation
122 *this=x11color_;
123}
124
125Magick::Color::Color(const Magick::Color &color_)
126 : _pixel(new PixelPacket),
127 _isValid(color_._isValid),
128 _pixelOwn(true),
129 _pixelType(color_._pixelType)
130{
131 *_pixel=*color_._pixel;
132}
133
134Magick::Color::Color(const PixelPacket &color_)
135 : _pixel(new PixelPacket),
136 _isValid(true),
137 _pixelOwn(true),
138 _pixelType(RGBPixel)
139{
140 *_pixel=color_;
141
142 if (color_.opacity != OpaqueOpacity)
143 _pixelType=RGBAPixel;
144}
145
146Magick::Color::Color(const std::string &x11color_)
147 : _pixel(new PixelPacket),
148 _isValid(true),
149 _pixelOwn(true),
150 _pixelType(RGBPixel)
151{
152 initPixel();
153
154 // Use operator = implementation
155 *this=x11color_;
156}
157
158Magick::Color::~Color(void)
159{
160 if (_pixelOwn)
161 delete _pixel;
162
163 _pixel=(PixelPacket *)NULL;
164}
165
166const Magick::Color& Magick::Color::operator=(const char *x11color_)
167{
168 *this=std::string(x11color_);
169 return(*this);
170}
171
172Magick::Color& Magick::Color::operator=(const Magick::Color& color_)
173{
174 // If not being set to ourself
175 if (this != &color_)
176 {
177 // Copy pixel value
178 *_pixel=*color_._pixel;
179
180 // Validity
181 _isValid=color_._isValid;
182
183 // Copy pixel type
184 _pixelType=color_._pixelType;
185 }
186 return(*this);
187}
188
189const Magick::Color& Magick::Color::operator=
190 (const MagickCore::PixelPacket &color_)
191{
192 *_pixel=color_;
193 if (color_.opacity != OpaqueOpacity)
194 _pixelType=RGBAPixel;
195 else
196 _pixelType=RGBPixel;
197
198 return(*this);
199}
200
201// Set color via X11 color specification string
202const Magick::Color& Magick::Color::operator=(const std::string &x11color_)
203{
204 PixelPacket
205 target_color;
206
207 initPixel();
208 GetPPException;
209 if (QueryColorDatabase(x11color_.c_str(),&target_color,exceptionInfo))
210 {
211 redQuantum( target_color.red );
212 greenQuantum( target_color.green );
213 blueQuantum( target_color.blue );
214 alphaQuantum( target_color.opacity );
215
216 if (target_color.opacity > OpaqueOpacity)
217 _pixelType=RGBAPixel;
218 else
219 _pixelType=RGBPixel;
220 }
221 else
222 {
223 _isValid = false;
224 _pixelOwn = false;
225 delete _pixel;
226 _pixel = (PixelPacket *)NULL;
227 }
228 ThrowPPException(false);
229
230 return(*this);
231}
232
233Magick::Color::operator std::string() const
234{
235 char
236 colorbuf[MaxTextExtent];
237
238 MagickPixelPacket
239 pixel;
240
241 if (!isValid())
242 return std::string("none");
243
244 pixel.colorspace=sRGBColorspace;
245 pixel.matte=_pixelType == RGBAPixel ? MagickTrue : MagickFalse;
246 pixel.depth=MAGICKCORE_QUANTUM_DEPTH;
247 pixel.red=_pixel->red;
248 pixel.green=_pixel->green;
249 pixel.blue=_pixel->blue;
250 pixel.opacity=_pixel->opacity;
251 GetColorTuple(&pixel,MagickTrue,colorbuf);
252
253 return(std::string(colorbuf));
254}
255
256bool Magick::Color::isValid(void) const
257{
258 return(_isValid);
259}
260
261void Magick::Color::isValid(bool valid_)
262{
263 if (bool(valid_) == bool(isValid()))
264 return;
265
266 if (!_pixelOwn)
267 {
268 _pixel=new PixelPacket;
269 _pixelOwn=true;
270 }
271
272 _isValid=valid_;
273
274 initPixel();
275}
276
277Magick::Color::Color(PixelPacket *rep_,PixelType pixelType_)
278 : _pixel(rep_),
279 _isValid(true),
280 _pixelOwn(false),
281 _pixelType(pixelType_)
282{
283}
284
285void Magick::Color::pixel(PixelPacket *rep_,PixelType pixelType_)
286{
287 if (_pixelOwn)
288 delete _pixel;
289
290 _pixel=rep_;
291 _pixelOwn=false;
292 _isValid=true;
293 _pixelType=pixelType_;
294}
295
296Magick::ColorGray::ColorGray(void)
297 : Color()
298{
299}
300
301Magick::ColorGray::ColorGray(const Magick::Color & color_)
302 : Color(color_)
303{
304}
305
306Magick::ColorGray::ColorGray(double shade_)
307 : Color(scaleDoubleToQuantum(shade_),scaleDoubleToQuantum(shade_),
308 scaleDoubleToQuantum(shade_))
309{
310 alphaQuantum(OpaqueOpacity);
311}
312
313Magick::ColorGray::~ColorGray()
314{
315}
316
317void Magick::ColorGray::shade(double shade_)
318{
319 Quantum gray=scaleDoubleToQuantum(shade_);
320 redQuantum(gray);
321 greenQuantum(gray);
322 blueQuantum(gray);
323}
324
325double Magick::ColorGray::shade(void) const
326{
327 return(scaleQuantumToDouble(greenQuantum()));
328}
329
330Magick::ColorGray& Magick::ColorGray::operator = ( const Magick::Color& color_ )
331{
332 *static_cast<Magick::Color*>(this)=color_;
333 return(*this);
334}
335
336Magick::ColorHSL::ColorHSL(void)
337 : Color()
338{
339}
340
341Magick::ColorHSL::ColorHSL(const Magick::Color & color_)
342 : Color( color_ )
343{
344}
345
346Magick::ColorHSL::ColorHSL(double hue_,double saturation_,double luminosity_)
347 : Color()
348{
349 Quantum
350 blue,
351 green,
352 red;
353
354 ConvertHSLToRGB(hue_,saturation_,luminosity_,&red,&green,&blue);
355
356 redQuantum(red);
357 greenQuantum(green);
358 blueQuantum(blue);
359 alphaQuantum(OpaqueOpacity);
360}
361
362Magick::ColorHSL::~ColorHSL()
363{
364}
365
366Magick::ColorHSL& Magick::ColorHSL::operator=(const Magick::Color &color_)
367{
368 *static_cast<Magick::Color*>(this)=color_;
369 return (*this);
370}
371
372void Magick::ColorHSL::hue(double hue_)
373{
374 double
375 hue,
376 luminosity,
377 saturation;
378
379 Quantum
380 blue,
381 green,
382 red;
383
384 ConvertRGBToHSL(redQuantum(),greenQuantum(),blueQuantum(),&hue,&saturation,
385 &luminosity);
386
387 hue=hue_;
388
389 ConvertHSLToRGB(hue,saturation,luminosity,&red,&green,&blue);
390
391 redQuantum(red);
392 greenQuantum(green);
393 blueQuantum(blue);
394}
395
396double Magick::ColorHSL::hue(void) const
397{
398 double
399 hue,
400 luminosity,
401 saturation;
402
403 ConvertRGBToHSL(redQuantum(),greenQuantum(),blueQuantum(),&hue,&saturation,
404 &luminosity);
405
406 return(hue);
407}
408
409void Magick::ColorHSL::luminosity(double luminosity_)
410{
411 double
412 hue,
413 luminosity,
414 saturation;
415
416 Quantum
417 blue,
418 green,
419 red;
420
421 ConvertRGBToHSL(redQuantum(),greenQuantum(),blueQuantum(),&hue,&saturation,
422 &luminosity);
423
424 luminosity=luminosity_;
425
426 ConvertHSLToRGB(hue,saturation,luminosity,&red,&green,&blue);
427
428 redQuantum(red);
429 greenQuantum(green);
430 blueQuantum(blue);
431}
432
433double Magick::ColorHSL::luminosity(void) const
434{
435 double
436 hue,
437 saturation,
438 luminosity;
439
440 ConvertRGBToHSL(redQuantum(),greenQuantum(),blueQuantum(),&hue,&saturation,
441 &luminosity);
442
443 return(luminosity);
444}
445
446void Magick::ColorHSL::saturation(double saturation_)
447{
448 double
449 hue,
450 luminosity,
451 saturation;
452
453 Quantum
454 blue,
455 green,
456 red;
457
458 ConvertRGBToHSL(redQuantum(),greenQuantum(),blueQuantum(),&hue,&saturation,
459 &luminosity);
460
461 saturation=saturation_;
462
463 ConvertHSLToRGB(hue,saturation,luminosity,&red,&green,&blue);
464
465 redQuantum(red);
466 greenQuantum(green);
467 blueQuantum(blue);
468}
469
470double Magick::ColorHSL::saturation(void) const
471{
472 double
473 hue,
474 luminosity,
475 saturation;
476
477 ConvertRGBToHSL(redQuantum(),greenQuantum(),blueQuantum(),&hue,&saturation,
478 &luminosity);
479
480 return(saturation);
481}
482
483Magick::ColorMono::ColorMono(void)
484 : Color()
485{
486}
487
488Magick::ColorMono::ColorMono(bool mono_)
489 : Color((mono_ ? QuantumRange : 0),
490 (mono_ ? QuantumRange : 0),
491 (mono_ ? QuantumRange : 0))
492{
493 alphaQuantum(OpaqueOpacity);
494}
495
496Magick::ColorMono::ColorMono(const Magick::Color &color_)
497 : Color(color_)
498{
499}
500
501Magick::ColorMono::~ColorMono()
502{
503}
504
505Magick::ColorMono& Magick::ColorMono::operator=(const Magick::Color &color_)
506{
507 *static_cast<Magick::Color*>(this)=color_;
508 return(*this);
509}
510
511void Magick::ColorMono::mono(bool mono_)
512{
513 redQuantum(mono_ ? QuantumRange : 0);
514 greenQuantum(mono_ ? QuantumRange : 0);
515 blueQuantum(mono_ ? QuantumRange : 0);
516}
517
518bool Magick::ColorMono::mono(void) const
519{
520 return(greenQuantum() == 0);
521}
522
523Magick::ColorRGB::ColorRGB(void)
524 : Color()
525{
526}
527
528Magick::ColorRGB::ColorRGB(const Magick::Color & color_)
529 : Color(color_)
530{
531}
532
533Magick::ColorRGB::ColorRGB(double red_,double green_,double blue_)
534 : Color(scaleDoubleToQuantum(red_),scaleDoubleToQuantum(green_),
535 scaleDoubleToQuantum(blue_))
536{
537 alphaQuantum(OpaqueOpacity);
538}
539
540Magick::ColorRGB::~ColorRGB(void)
541{
542}
543
544Magick::ColorRGB& Magick::ColorRGB::operator=(const Magick::Color& color_)
545{
546 *static_cast<Magick::Color*>(this)=color_;
547 return(*this);
548}
549
550Magick::ColorYUV::ColorYUV(void)
551 : Color()
552{
553}
554
555Magick::ColorYUV::ColorYUV(const Magick::Color &color_)
556 : Color(color_)
557{
558}
559
560Magick::ColorYUV::ColorYUV(double y_,double u_,double v_)
561 : Color(scaleDoubleToQuantum(y_ + 1.13980 * v_),
562 scaleDoubleToQuantum(y_ - (0.39380 * u_) - (0.58050 * v_)),
563 scaleDoubleToQuantum(y_ + 2.02790 * u_))
564{
565 alphaQuantum(OpaqueOpacity);
566}
567
568Magick::ColorYUV::~ColorYUV(void)
569{
570}
571
572Magick::ColorYUV& Magick::ColorYUV::operator=(const Magick::Color &color_)
573{
574 *static_cast<Magick::Color*>(this)=color_;
575 return(*this);
576}
577
578void Magick::ColorYUV::u(double u_)
579{
580 double V = v();
581 double Y = y();
582
583 redQuantum(scaleDoubleToQuantum(Y + 1.13980 * V ));
584 greenQuantum(scaleDoubleToQuantum( Y - (0.39380 * u_) - (0.58050 * V)));
585 blueQuantum(scaleDoubleToQuantum( Y + 2.02790 * u_));
586}
587
588double Magick::ColorYUV::u(void) const
589{
590 return scaleQuantumToDouble((-0.14740 * redQuantum()) - (0.28950 *
591 greenQuantum()) + (0.43690 * blueQuantum()));
592}
593
594void Magick::ColorYUV::v(double v_)
595{
596 double U = u();
597 double Y = y();
598
599 redQuantum(scaleDoubleToQuantum( Y + 1.13980 * v_ ));
600 greenQuantum(scaleDoubleToQuantum( Y - (0.39380 * U) - (0.58050 * v_) ));
601 blueQuantum(scaleDoubleToQuantum( Y + 2.02790 * U ));
602}
603
604double Magick::ColorYUV::v(void) const
605{
606 return scaleQuantumToDouble((0.61500 * redQuantum()) - (0.51500 *
607 greenQuantum()) - (0.10000 * blueQuantum()));
608}
609
610void Magick::ColorYUV::y(double y_)
611{
612 double U = u();
613 double V = v();
614
615 redQuantum(scaleDoubleToQuantum(y_ + 1.13980 * V));
616 greenQuantum(scaleDoubleToQuantum(y_ - (0.39380 * U) - (0.58050 * V)));
617 blueQuantum(scaleDoubleToQuantum(y_ + 2.02790 * U));
618}
619
620double Magick::ColorYUV::y(void) const
621{
622 return scaleQuantumToDouble((0.29900 * redQuantum()) + (0.58700 *
623 greenQuantum()) + (0.11400 * blueQuantum()));
624}