1 // This may look like C code, but it is really -*- C++ -*-
3 // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
5 // Color Implementation
8 #define MAGICKCORE_IMPLEMENTATION
9 #define MAGICK_PLUSPLUS_IMPLEMENTATION 1
11 #include "Magick++/Include.h"
16 #include "Magick++/Color.h"
17 #include "Magick++/Exception.h"
20 // Color operator fuctions
22 int Magick::operator == ( const Magick::Color& left_,
23 const Magick::Color& right_ )
25 return ( ( left_.isValid() == right_.isValid() ) &&
26 ( left_.redQuantum() == right_.redQuantum() ) &&
27 ( left_.greenQuantum() == right_.greenQuantum() ) &&
28 ( left_.blueQuantum() == right_.blueQuantum() )
31 int Magick::operator != ( const Magick::Color& left_,
32 const Magick::Color& right_ )
34 return ( ! (left_ == right_) );
36 int Magick::operator > ( const Magick::Color& left_,
37 const Magick::Color& right_ )
39 return ( !( left_ < right_ ) && ( left_ != right_ ) );
41 int Magick::operator < ( const Magick::Color& left_,
42 const Magick::Color& right_ )
44 if(left_.redQuantum() < right_.redQuantum()) return true;
45 if(left_.redQuantum() > right_.redQuantum()) return false;
46 if(left_.greenQuantum() < right_.greenQuantum()) return true;
47 if(left_.greenQuantum() > right_.greenQuantum()) return false;
48 if(left_.blueQuantum() < right_.blueQuantum()) return true;
51 int Magick::operator >= ( const Magick::Color& left_,
52 const Magick::Color& right_ )
54 return ( ( left_ > right_ ) || ( left_ == right_ ) );
56 int Magick::operator <= ( const Magick::Color& left_,
57 const Magick::Color& right_ )
59 return ( ( left_ < right_ ) || ( left_ == right_ ) );
63 // Color Implementation
66 // Default constructor
67 Magick::Color::Color ( void )
68 : _pixel(new PixelInfo),
77 Magick::Color::Color ( Quantum red_,
80 : _pixel(new PixelInfo),
86 greenQuantum ( green_ );
87 blueQuantum ( blue_ );
88 alphaQuantum ( OpaqueAlpha );
91 // Construct from RGBA
92 Magick::Color::Color ( Quantum red_,
96 : _pixel(new PixelInfo),
102 greenQuantum ( green_ );
103 blueQuantum ( blue_ );
104 alphaQuantum ( alpha_ );
108 Magick::Color::Color ( const Magick::Color & color_ )
109 : _pixel( new PixelInfo ),
111 _isValid( color_._isValid ),
112 _pixelType( color_._pixelType )
114 *_pixel = *color_._pixel;
117 // Construct from color expressed as C++ string
118 Magick::Color::Color ( const std::string &x11color_ )
119 : _pixel(new PixelInfo),
126 // Use operator = implementation
130 // Construct from color expressed as C string
131 Magick::Color::Color ( const char * x11color_ )
132 : _pixel(new PixelInfo),
139 // Use operator = implementation
143 // Construct color via ImageMagick PixelInfo
144 Magick::Color::Color ( const PixelInfo &color_ )
145 : _pixel(new PixelInfo),
146 _pixelOwn(true), // We allocated this pixel
148 _pixelType(RGBPixel) // RGB pixel by default
152 if ( color_.alpha != OpaqueAlpha )
153 _pixelType = RGBAPixel;
156 // Protected constructor to construct with PixelInfo*
157 // Used to point Color at a pixel.
158 Magick::Color::Color ( PixelInfo* rep_, PixelType pixelType_ )
162 _pixelType(pixelType_)
167 Magick::Color::~Color( void )
174 // Assignment operator
175 Magick::Color& Magick::Color::operator = ( const Magick::Color& color_ )
177 // If not being set to ourself
178 if ( this != &color_ )
181 *_pixel = *color_._pixel;
184 _isValid = color_._isValid;
187 _pixelType = color_._pixelType;
192 // Set color via X11 color specification string
193 const Magick::Color& Magick::Color::operator = ( const std::string &x11color_ )
196 PixelInfo target_color;
197 ExceptionInfo exception;
198 GetExceptionInfo( &exception );
199 if ( QueryColorCompliance( x11color_.c_str(), AllCompliance, &target_color, &exception ) )
201 redQuantum( ClampToQuantum( target_color.red ) );
202 greenQuantum( ClampToQuantum( target_color.green ) );
203 blueQuantum( ClampToQuantum( target_color.blue ) );
204 alphaQuantum( ClampToQuantum( target_color.alpha ) );
206 if ( target_color.alpha != OpaqueAlpha )
207 _pixelType = RGBAPixel;
209 _pixelType = RGBPixel;
214 throwException(exception);
216 (void) DestroyExceptionInfo( &exception );
221 // Set color via X11 color specification C string
222 const Magick::Color& Magick::Color::operator = ( const char * x11color_ )
224 *this = std::string(x11color_);
228 // Return X11 color specification string
229 Magick::Color::operator std::string() const
232 return std::string("none");
234 char colorbuf[MaxTextExtent];
239 pixel.colorspace=RGBColorspace;
240 pixel.alpha_trait=_pixelType == RGBAPixel ? BlendPixelTrait :
242 pixel.depth=MAGICKCORE_QUANTUM_DEPTH;
243 pixel.red=_pixel->red;
244 pixel.green=_pixel->green;
245 pixel.blue=_pixel->blue;
246 pixel.alpha=_pixel->alpha;
247 GetColorTuple( &pixel, MagickTrue, colorbuf );
249 return std::string(colorbuf);
252 // Set color via ImageMagick PixelInfo
253 const Magick::Color& Magick::Color::operator= ( const MagickCore::PixelInfo &color_ )
256 if ( color_.alpha != OpaqueAlpha )
257 _pixelType = RGBAPixel;
259 _pixelType = RGBPixel;
264 // Used to point Color at a pixel in an image
265 void Magick::Color::pixel ( PixelInfo* rep_, PixelType pixelType_ )
272 _pixelType = pixelType_;
275 // Does object contain valid color?
276 bool Magick::Color::isValid ( void ) const
280 void Magick::Color::isValid ( bool valid_ )
282 if ( (valid_ && isValid()) || (!valid_ && !isValid()) )
287 _pixel = new PixelInfo;
297 // ColorHSL Implementation
300 Magick::ColorHSL::ColorHSL ( double hue_,
305 double red, green, blue;
307 ConvertHSLToRGB ( hue_,
314 redQuantum ( ClampToQuantum( red ) );
315 greenQuantum ( ClampToQuantum( green ) );
316 blueQuantum ( ClampToQuantum( blue ) );
317 alphaQuantum ( OpaqueAlpha );
321 Magick::ColorHSL::ColorHSL ( )
326 // Copy constructor from base class
327 Magick::ColorHSL::ColorHSL ( const Magick::Color & color_ )
333 Magick::ColorHSL::~ColorHSL ( )
338 void Magick::ColorHSL::hue ( double hue_ )
340 double hue_val, saturation_val, luminosity_val;
341 ConvertRGBToHSL ( redQuantum(),
350 double red, green, blue;
351 ConvertHSLToRGB ( hue_val,
359 redQuantum ( ClampToQuantum( red ) );
360 greenQuantum ( ClampToQuantum( green ) );
361 blueQuantum ( ClampToQuantum( blue ) );
364 double Magick::ColorHSL::hue ( void ) const
366 double hue_val, saturation_val, luminosity_val;
367 ConvertRGBToHSL ( redQuantum(),
376 void Magick::ColorHSL::saturation ( double saturation_ )
378 double hue_val, saturation_val, luminosity_val;
379 ConvertRGBToHSL ( redQuantum(),
386 saturation_val = saturation_;
388 double red, green, blue;
389 ConvertHSLToRGB ( hue_val,
397 redQuantum ( ClampToQuantum( red ) );
398 greenQuantum ( ClampToQuantum( green ) );
399 blueQuantum ( ClampToQuantum( blue ) );
402 double Magick::ColorHSL::saturation ( void ) const
404 double hue_val, saturation_val, luminosity_val;
405 ConvertRGBToHSL ( redQuantum(),
411 return saturation_val;
414 void Magick::ColorHSL::luminosity ( double luminosity_ )
416 double hue_val, saturation_val, luminosity_val;
417 ConvertRGBToHSL ( redQuantum(),
424 luminosity_val = luminosity_;
426 double red, green, blue;
427 ConvertHSLToRGB ( hue_val,
435 redQuantum ( ClampToQuantum( red ) );
436 greenQuantum ( ClampToQuantum( green ) );
437 blueQuantum ( ClampToQuantum( blue ) );
440 double Magick::ColorHSL::luminosity ( void ) const
442 double hue_val, saturation_val, luminosity_val;
443 ConvertRGBToHSL ( redQuantum(),
449 return luminosity_val;
452 // Assignment from base class
453 Magick::ColorHSL& Magick::ColorHSL::operator = ( const Magick::Color& color_ )
455 *static_cast<Magick::Color*>(this) = color_;
460 // ColorGray Implementation
462 Magick::ColorGray::ColorGray ( double shade_ )
463 : Color ( scaleDoubleToQuantum( shade_ ),
464 scaleDoubleToQuantum( shade_ ),
465 scaleDoubleToQuantum( shade_ ) )
467 alphaQuantum ( OpaqueAlpha );
471 Magick::ColorGray::ColorGray ( void )
476 // Copy constructor from base class
477 Magick::ColorGray::ColorGray ( const Magick::Color & color_ )
483 Magick::ColorGray::~ColorGray ()
488 void Magick::ColorGray::shade ( double shade_ )
490 Quantum gray = scaleDoubleToQuantum( shade_ );
492 greenQuantum ( gray );
493 blueQuantum ( gray );
496 double Magick::ColorGray::shade ( void ) const
498 return scaleQuantumToDouble ( greenQuantum() );
501 // Assignment from base class
502 Magick::ColorGray& Magick::ColorGray::operator = ( const Magick::Color& color_ )
504 *static_cast<Magick::Color*>(this) = color_;
509 // ColorMono Implementation
511 Magick::ColorMono::ColorMono ( bool mono_ )
512 : Color ( ( mono_ ? QuantumRange : 0 ),
513 ( mono_ ? QuantumRange : 0 ),
514 ( mono_ ? QuantumRange : 0 ) )
516 alphaQuantum ( OpaqueAlpha );
520 Magick::ColorMono::ColorMono ( void )
525 // Copy constructor from base class
526 Magick::ColorMono::ColorMono ( const Magick::Color & color_ )
532 Magick::ColorMono::~ColorMono ()
537 void Magick::ColorMono::mono ( bool mono_ )
539 redQuantum ( mono_ ? QuantumRange : 0 );
540 greenQuantum ( mono_ ? QuantumRange : 0 );
541 blueQuantum ( mono_ ? QuantumRange : 0 );
544 bool Magick::ColorMono::mono ( void ) const
546 if ( greenQuantum() )
552 // Assignment from base class
553 Magick::ColorMono& Magick::ColorMono::operator = ( const Magick::Color& color_ )
555 *static_cast<Magick::Color*>(this) = color_;
560 // ColorRGB Implementation
563 // Construct from red, green, and blue, components
564 Magick::ColorRGB::ColorRGB ( double red_,
567 : Color ( scaleDoubleToQuantum(red_),
568 scaleDoubleToQuantum(green_),
569 scaleDoubleToQuantum(blue_) )
571 alphaQuantum ( OpaqueAlpha );
574 Magick::ColorRGB::ColorRGB ( void )
578 // Copy constructor from base class
579 Magick::ColorRGB::ColorRGB ( const Magick::Color & color_ )
584 Magick::ColorRGB::~ColorRGB ( void )
589 // Assignment from base class
590 Magick::ColorRGB& Magick::ColorRGB::operator = ( const Magick::Color& color_ )
592 *static_cast<Magick::Color*>(this) = color_;
597 // ColorYUV Implementation
601 // G = Y-0.39380*U-0.58050*V
604 // U and V, normally -0.5 through 0.5, must be normalized to the range 0
605 // through QuantumRange.
607 // Y = 0.29900*R+0.58700*G+0.11400*B
608 // U = -0.14740*R-0.28950*G+0.43690*B
609 // V = 0.61500*R-0.51500*G-0.10000*B
611 // U and V, normally -0.5 through 0.5, are normalized to the range 0
612 // through QuantumRange. Note that U = 0.493*(B-Y), V = 0.877*(R-Y).
615 // Construct from color components
616 Magick::ColorYUV::ColorYUV ( double y_,
619 : Color ( scaleDoubleToQuantum(y_ + 1.13980 * v_ ),
620 scaleDoubleToQuantum(y_ - (0.39380 * u_) - (0.58050 * v_) ),
621 scaleDoubleToQuantum(y_ + 2.02790 * u_ ) )
623 alphaQuantum ( OpaqueAlpha );
626 Magick::ColorYUV::ColorYUV ( void )
630 // Copy constructor from base class
631 Magick::ColorYUV::ColorYUV ( const Magick::Color & color_ )
636 Magick::ColorYUV::~ColorYUV ( void )
641 void Magick::ColorYUV::u ( double u_ )
646 redQuantum ( scaleDoubleToQuantum( Y + 1.13980 * V ) );
647 greenQuantum ( scaleDoubleToQuantum( Y - (0.39380 * u_) - (0.58050 * V) ) );
648 blueQuantum ( scaleDoubleToQuantum( Y + 2.02790 * u_ ) );
651 double Magick::ColorYUV::u ( void ) const
653 return scaleQuantumToDouble( (-0.14740 * redQuantum()) - (0.28950 *
654 greenQuantum()) + (0.43690 * blueQuantum()) );
657 void Magick::ColorYUV::v ( double v_ )
662 redQuantum ( scaleDoubleToQuantum( Y + 1.13980 * v_ ) );
663 greenQuantum ( scaleDoubleToQuantum( Y - (0.39380 * U) - (0.58050 * v_) ) );
664 blueQuantum ( scaleDoubleToQuantum( Y + 2.02790 * U ) );
667 double Magick::ColorYUV::v ( void ) const
669 return scaleQuantumToDouble((0.61500 * redQuantum()) -
670 (0.51500 * greenQuantum()) -
671 (0.10000 * blueQuantum()));
674 void Magick::ColorYUV::y ( double y_ )
679 redQuantum ( scaleDoubleToQuantum( y_ + 1.13980 * V ) );
680 greenQuantum ( scaleDoubleToQuantum( y_ - (0.39380 * U) - (0.58050 * V) ) );
681 blueQuantum ( scaleDoubleToQuantum( y_ + 2.02790 * U ) );
684 double Magick::ColorYUV::y ( void ) const
686 return scaleQuantumToDouble((0.29900 * redQuantum()) +
687 (0.58700 * greenQuantum()) +
688 (0.11400 * blueQuantum()));
691 // Assignment from base class
692 Magick::ColorYUV& Magick::ColorYUV::operator = ( const Magick::Color& color_ )
694 *static_cast<Magick::Color*>(this) = color_;