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