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 PixelPacket),
77 Magick::Color::Color ( Quantum red_,
80 : _pixel(new PixelPacket),
86 greenQuantum ( green_ );
87 blueQuantum ( blue_ );
88 alphaQuantum ( OpaqueOpacity );
91 // Construct from RGBA
92 Magick::Color::Color ( Quantum red_,
96 : _pixel(new PixelPacket),
102 greenQuantum ( green_ );
103 blueQuantum ( blue_ );
104 alphaQuantum ( alpha_ );
108 Magick::Color::Color ( const Magick::Color & color_ )
109 : _pixel( new PixelPacket ),
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 PixelPacket),
126 // Use operator = implementation
130 // Construct from color expressed as C string
131 Magick::Color::Color ( const char * x11color_ )
132 : _pixel(new PixelPacket),
139 // Use operator = implementation
143 // Construct color via ImageMagick PixelPacket
144 Magick::Color::Color ( const PixelPacket &color_ )
145 : _pixel(new PixelPacket),
146 _pixelOwn(true), // We allocated this pixel
148 _pixelType(RGBPixel) // RGB pixel by default
152 if ( color_.opacity != OpaqueOpacity )
153 _pixelType = RGBAPixel;
156 // Protected constructor to construct with PixelPacket*
157 // Used to point Color at a pixel.
158 Magick::Color::Color ( PixelPacket* 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 PixelPacket target_color;
197 ExceptionInfo exception;
198 GetExceptionInfo( &exception );
199 if ( QueryColorDatabase( x11color_.c_str(), &target_color, &exception ) )
201 redQuantum( target_color.red );
202 greenQuantum( target_color.green );
203 blueQuantum( target_color.blue );
204 alphaQuantum( target_color.opacity );
206 if ( target_color.opacity > OpaqueOpacity )
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.matte=_pixelType == RGBAPixel ? MagickTrue : MagickFalse;
241 pixel.depth=MAGICKCORE_QUANTUM_DEPTH;
242 pixel.red=_pixel->red;
243 pixel.green=_pixel->green;
244 pixel.blue=_pixel->blue;
245 pixel.opacity=_pixel->opacity;
246 GetColorTuple( &pixel, MagickTrue, colorbuf );
248 return std::string(colorbuf);
251 // Set color via ImageMagick PixelPacket
252 const Magick::Color& Magick::Color::operator= ( const MagickCore::PixelPacket &color_ )
255 if ( color_.opacity != OpaqueOpacity )
256 _pixelType = RGBAPixel;
258 _pixelType = RGBPixel;
263 // Used to point Color at a pixel in an image
264 void Magick::Color::pixel ( PixelPacket* rep_, PixelType pixelType_ )
271 _pixelType = pixelType_;
274 // Does object contain valid color?
275 bool Magick::Color::isValid ( void ) const
279 void Magick::Color::isValid ( bool valid_ )
281 if ( (valid_ && isValid()) || (!valid_ && !isValid()) )
286 _pixel = new PixelPacket;
296 // ColorHSL Implementation
299 Magick::ColorHSL::ColorHSL ( double hue_,
304 Quantum red, green, blue;
306 ConvertHSLToRGB ( hue_,
314 greenQuantum ( green );
315 blueQuantum ( blue );
316 alphaQuantum ( OpaqueOpacity );
320 Magick::ColorHSL::ColorHSL ( )
325 // Copy constructor from base class
326 Magick::ColorHSL::ColorHSL ( const Magick::Color & color_ )
332 Magick::ColorHSL::~ColorHSL ( )
337 void Magick::ColorHSL::hue ( double hue_ )
339 double hue_val, saturation_val, luminosity_val;
340 ConvertRGBToHSL ( redQuantum(),
349 Quantum red, green, blue;
350 ConvertHSLToRGB ( hue_val,
359 greenQuantum ( green );
360 blueQuantum ( blue );
363 double Magick::ColorHSL::hue ( void ) const
365 double hue_val, saturation_val, luminosity_val;
366 ConvertRGBToHSL ( redQuantum(),
375 void Magick::ColorHSL::saturation ( double saturation_ )
377 double hue_val, saturation_val, luminosity_val;
378 ConvertRGBToHSL ( redQuantum(),
385 saturation_val = saturation_;
387 Quantum red, green, blue;
388 ConvertHSLToRGB ( hue_val,
397 greenQuantum ( green );
398 blueQuantum ( blue );
401 double Magick::ColorHSL::saturation ( void ) const
403 double hue_val, saturation_val, luminosity_val;
404 ConvertRGBToHSL ( redQuantum(),
410 return saturation_val;
413 void Magick::ColorHSL::luminosity ( double luminosity_ )
415 double hue_val, saturation_val, luminosity_val;
416 ConvertRGBToHSL ( redQuantum(),
423 luminosity_val = luminosity_;
425 Quantum red, green, blue;
426 ConvertHSLToRGB ( hue_val,
435 greenQuantum ( green );
436 blueQuantum ( blue );
439 double Magick::ColorHSL::luminosity ( void ) const
441 double hue_val, saturation_val, luminosity_val;
442 ConvertRGBToHSL ( redQuantum(),
448 return luminosity_val;
451 // Assignment from base class
452 Magick::ColorHSL& Magick::ColorHSL::operator = ( const Magick::Color& color_ )
454 *static_cast<Magick::Color*>(this) = color_;
459 // ColorGray Implementation
461 Magick::ColorGray::ColorGray ( double shade_ )
462 : Color ( scaleDoubleToQuantum( shade_ ),
463 scaleDoubleToQuantum( shade_ ),
464 scaleDoubleToQuantum( shade_ ) )
466 alphaQuantum ( OpaqueOpacity );
470 Magick::ColorGray::ColorGray ( void )
475 // Copy constructor from base class
476 Magick::ColorGray::ColorGray ( const Magick::Color & color_ )
482 Magick::ColorGray::~ColorGray ()
487 void Magick::ColorGray::shade ( double shade_ )
489 Quantum gray = scaleDoubleToQuantum( shade_ );
491 greenQuantum ( gray );
492 blueQuantum ( gray );
495 double Magick::ColorGray::shade ( void ) const
497 return scaleQuantumToDouble ( greenQuantum() );
500 // Assignment from base class
501 Magick::ColorGray& Magick::ColorGray::operator = ( const Magick::Color& color_ )
503 *static_cast<Magick::Color*>(this) = color_;
508 // ColorMono Implementation
510 Magick::ColorMono::ColorMono ( bool mono_ )
511 : Color ( ( mono_ ? QuantumRange : 0 ),
512 ( mono_ ? QuantumRange : 0 ),
513 ( mono_ ? QuantumRange : 0 ) )
515 alphaQuantum ( OpaqueOpacity );
519 Magick::ColorMono::ColorMono ( void )
524 // Copy constructor from base class
525 Magick::ColorMono::ColorMono ( const Magick::Color & color_ )
531 Magick::ColorMono::~ColorMono ()
536 void Magick::ColorMono::mono ( bool mono_ )
538 redQuantum ( mono_ ? QuantumRange : 0 );
539 greenQuantum ( mono_ ? QuantumRange : 0 );
540 blueQuantum ( mono_ ? QuantumRange : 0 );
543 bool Magick::ColorMono::mono ( void ) const
545 if ( greenQuantum() )
551 // Assignment from base class
552 Magick::ColorMono& Magick::ColorMono::operator = ( const Magick::Color& color_ )
554 *static_cast<Magick::Color*>(this) = color_;
559 // ColorRGB Implementation
562 // Construct from red, green, and blue, components
563 Magick::ColorRGB::ColorRGB ( double red_,
566 : Color ( scaleDoubleToQuantum(red_),
567 scaleDoubleToQuantum(green_),
568 scaleDoubleToQuantum(blue_) )
570 alphaQuantum ( OpaqueOpacity );
573 Magick::ColorRGB::ColorRGB ( void )
577 // Copy constructor from base class
578 Magick::ColorRGB::ColorRGB ( const Magick::Color & color_ )
583 Magick::ColorRGB::~ColorRGB ( void )
588 // Assignment from base class
589 Magick::ColorRGB& Magick::ColorRGB::operator = ( const Magick::Color& color_ )
591 *static_cast<Magick::Color*>(this) = color_;
596 // ColorYUV Implementation
600 // G = Y-0.39380*U-0.58050*V
603 // U and V, normally -0.5 through 0.5, must be normalized to the range 0
604 // through QuantumRange.
606 // Y = 0.29900*R+0.58700*G+0.11400*B
607 // U = -0.14740*R-0.28950*G+0.43690*B
608 // V = 0.61500*R-0.51500*G-0.10000*B
610 // U and V, normally -0.5 through 0.5, are normalized to the range 0
611 // through QuantumRange. Note that U = 0.493*(B-Y), V = 0.877*(R-Y).
614 // Construct from color components
615 Magick::ColorYUV::ColorYUV ( double y_,
618 : Color ( scaleDoubleToQuantum(y_ + 1.13980 * v_ ),
619 scaleDoubleToQuantum(y_ - (0.39380 * u_) - (0.58050 * v_) ),
620 scaleDoubleToQuantum(y_ + 2.02790 * u_ ) )
622 alphaQuantum ( OpaqueOpacity );
625 Magick::ColorYUV::ColorYUV ( void )
629 // Copy constructor from base class
630 Magick::ColorYUV::ColorYUV ( const Magick::Color & color_ )
635 Magick::ColorYUV::~ColorYUV ( void )
640 void Magick::ColorYUV::u ( double u_ )
645 redQuantum ( scaleDoubleToQuantum( Y + 1.13980 * V ) );
646 greenQuantum ( scaleDoubleToQuantum( Y - (0.39380 * u_) - (0.58050 * V) ) );
647 blueQuantum ( scaleDoubleToQuantum( Y + 2.02790 * u_ ) );
650 double Magick::ColorYUV::u ( void ) const
652 return scaleQuantumToDouble( (-0.14740 * redQuantum()) - (0.28950 *
653 greenQuantum()) + (0.43690 * blueQuantum()) );
656 void Magick::ColorYUV::v ( double v_ )
661 redQuantum ( scaleDoubleToQuantum( Y + 1.13980 * v_ ) );
662 greenQuantum ( scaleDoubleToQuantum( Y - (0.39380 * U) - (0.58050 * v_) ) );
663 blueQuantum ( scaleDoubleToQuantum( Y + 2.02790 * U ) );
666 double Magick::ColorYUV::v ( void ) const
668 return scaleQuantumToDouble((0.61500 * redQuantum()) -
669 (0.51500 * greenQuantum()) -
670 (0.10000 * blueQuantum()));
673 void Magick::ColorYUV::y ( double y_ )
678 redQuantum ( scaleDoubleToQuantum( y_ + 1.13980 * V ) );
679 greenQuantum ( scaleDoubleToQuantum( y_ - (0.39380 * U) - (0.58050 * V) ) );
680 blueQuantum ( scaleDoubleToQuantum( y_ + 2.02790 * U ) );
683 double Magick::ColorYUV::y ( void ) const
685 return scaleQuantumToDouble((0.29900 * redQuantum()) +
686 (0.58700 * greenQuantum()) +
687 (0.11400 * blueQuantum()));
690 // Assignment from base class
691 Magick::ColorYUV& Magick::ColorYUV::operator = ( const Magick::Color& color_ )
693 *static_cast<Magick::Color*>(this) = color_;