Color.cpp revision aa3ec099d81e5660a5452ad0fd76d10722ea313a
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 char *color_) 145{ 146 *this=std::string(color_); 147 return(*this); 148} 149 150const Magick::Color& Magick::Color::operator=(const MagickCore::PixelInfo &color_) 151{ 152 *_pixel=color_; 153 if (color_.alpha != OpaqueAlpha) 154 _pixelType=RGBAPixel; 155 else 156 _pixelType=RGBPixel; 157 158 return(*this); 159} 160 161const Magick::Color& Magick::Color::operator=(const std::string &color_) 162{ 163 ExceptionInfo 164 exception; 165 166 PixelInfo 167 target_color; 168 169 initPixel(); 170 GetExceptionInfo(&exception); 171 if (QueryColorCompliance(color_.c_str(),AllCompliance,&target_color, 172 &exception)) 173 { 174 quantumRed(target_color.red); 175 quantumGreen(target_color.green); 176 quantumBlue(target_color.blue); 177 quantumAlpha(target_color.alpha); 178 179 if (quantumAlpha() != OpaqueAlpha) 180 _pixelType=RGBAPixel; 181 else 182 _pixelType=RGBPixel; 183 } 184 else 185 { 186 _isValid = false; 187 throwException(exception); 188 } 189 (void) DestroyExceptionInfo( &exception ); 190 191 return(*this); 192} 193 194Magick::Color::operator MagickCore::PixelInfo() const 195{ 196 return *_pixel; 197} 198 199Magick::Color::operator std::string() const 200{ 201 char 202 colorbuf[MaxTextExtent]; 203 204 PixelInfo 205 pixel; 206 207 if (!isValid()) 208 return std::string("none"); 209 210 pixel.colorspace=RGBColorspace; 211 pixel.alpha_trait=_pixelType == RGBAPixel ? BlendPixelTrait : 212 UndefinedPixelTrait; 213 pixel.depth=MAGICKCORE_QUANTUM_DEPTH; 214 pixel.red=_pixel->red; 215 pixel.green=_pixel->green; 216 pixel.blue=_pixel->blue; 217 pixel.alpha=_pixel->alpha; 218 GetColorTuple(&pixel,MagickTrue,colorbuf); 219 220 return(std::string(colorbuf)); 221} 222 223void Magick::Color::alpha(const double alpha_) 224{ 225 quantumAlpha(scaleDoubleToQuantum(alpha_)); 226} 227 228double Magick::Color::alpha(void) const 229{ 230 return scaleQuantumToDouble(quantumAlpha()); 231} 232 233void Magick::Color::blue(const double blue_) 234{ 235 quantumBlue(scaleDoubleToQuantum(blue_)); 236} 237 238double Magick::Color::blue(void) const 239{ 240 return scaleQuantumToDouble(quantumBlue()); 241} 242 243void Magick::Color::green(const double green_) 244{ 245 quantumGreen(scaleDoubleToQuantum(green_)); 246} 247 248double Magick::Color::green(void) const 249{ 250 return scaleQuantumToDouble(quantumGreen()); 251} 252 253bool Magick::Color::isValid(void) const 254{ 255 return(_isValid); 256} 257 258void Magick::Color::isValid(bool valid_) 259{ 260 if ((valid_ && isValid()) || (!valid_ && !isValid())) 261 return; 262 263 if (!_pixelOwn) 264 { 265 _pixel=new PixelInfo; 266 _pixelOwn=true; 267 } 268 269 _isValid=valid_; 270 271 initPixel(); 272} 273 274void Magick::Color::quantumAlpha(const Magick::Quantum alpha_) 275{ 276 _pixel->alpha=alpha_; 277 _isValid=true ; 278} 279 280Magick::Quantum Magick::Color::quantumAlpha(void) const 281{ 282 return _pixel->alpha; 283} 284 285void Magick::Color::quantumBlue(const Magick::Quantum blue_) 286{ 287 _pixel->blue=blue_; 288 _isValid=true; 289} 290 291Magick::Quantum Magick::Color::quantumBlue(void) const 292{ 293 return _pixel->blue; 294} 295 296void Magick::Color::quantumGreen(const Magick::Quantum green_) 297{ 298 _pixel->green=green_; 299 _isValid=true; 300} 301 302Magick::Quantum Magick::Color::quantumGreen(void) const 303{ 304 return _pixel->green; 305} 306 307void Magick::Color::quantumRed(const Magick::Quantum red_) 308{ 309 _pixel->red=red_; 310 _isValid=true; 311} 312 313Magick::Quantum Magick::Color::quantumRed(void) const 314{ 315 return _pixel->red; 316} 317 318void Magick::Color::red(const double red_) 319{ 320 quantumRed(scaleDoubleToQuantum(red_)); 321} 322 323double Magick::Color::red(void) const 324{ 325 return scaleQuantumToDouble(quantumRed()); 326} 327 328Magick::Color::Color(PixelInfo* rep_,PixelType pixelType_) 329 : _pixel(rep_),_pixelOwn(false),_isValid(true),_pixelType(pixelType_) 330{ 331} 332 333void Magick::Color::pixel(PixelInfo *rep_,PixelType pixelType_) 334{ 335 if (_pixelOwn) 336 delete _pixel; 337 338 _pixel=rep_; 339 _pixelOwn=false; 340 _isValid=true; 341 _pixelType=pixelType_; 342} 343 344Magick::Quantum Magick::Color::scaleDoubleToQuantum(const double double_) 345{ 346 return (static_cast<Magick::Quantum>(double_*QuantumRange)); 347} 348 349double Magick::Color::scaleQuantumToDouble(const Magick::Quantum quantum_) 350{ 351#if (MAGICKCORE_QUANTUM_DEPTH != 64) 352 return (static_cast<double>(quantum_)/QuantumRange); 353#else 354 return (quantum_/QuantumRange); 355#endif 356} 357 358void Magick::Color::initPixel() 359{ 360 _pixel->red=0; 361 _pixel->green=0; 362 _pixel->blue=0; 363 _pixel->alpha=TransparentAlpha; 364} 365 366Magick::ColorGray::ColorGray(void) 367 : Color() 368{ 369} 370 371Magick::ColorGray::ColorGray(const Magick::Color & color_) 372 : Color(color_) 373{ 374} 375 376Magick::ColorGray::ColorGray(double shade_) 377 : Color(scaleDoubleToQuantum(shade_),scaleDoubleToQuantum(shade_), 378 scaleDoubleToQuantum(shade_)) 379{ 380 quantumAlpha(OpaqueAlpha); 381} 382 383Magick::ColorGray::~ColorGray() 384{ 385} 386 387void Magick::ColorGray::shade(double shade_) 388{ 389 red(shade_); 390 green(shade_); 391 blue(shade_); 392} 393 394double Magick::ColorGray::shade(void) const 395{ 396 return(green()); 397} 398 399Magick::ColorGray& Magick::ColorGray::operator=(const Magick::Color& color_) 400{ 401 *static_cast<Magick::Color*>(this)=color_; 402 return(*this); 403} 404 405Magick::ColorGray::ColorGray(PixelInfo *rep_,PixelType pixelType_) 406: Color(rep_,pixelType_) 407{ 408} 409 410Magick::ColorHSL::ColorHSL(void) 411 : Color() 412{ 413} 414 415Magick::ColorHSL::ColorHSL(const Magick::Color &color_) 416 : Color(color_) 417{ 418} 419 420Magick::ColorHSL::ColorHSL(const double hue_,const double saturation_, 421 const double luminosity_) 422 : Color() 423{ 424 double 425 blue, 426 green, 427 red; 428 429 ConvertHSLToRGB(hue_,saturation_,luminosity_,&red,&green,&blue); 430 431 quantumRed(red); 432 quantumGreen(green); 433 quantumBlue(blue); 434 quantumAlpha(OpaqueAlpha); 435} 436 437Magick::ColorHSL::~ColorHSL() 438{ 439} 440 441Magick::ColorHSL& Magick::ColorHSL::operator=(const Magick::Color& color_) 442{ 443 *static_cast<Magick::Color*>(this) = color_; 444 return(*this); 445} 446 447void Magick::ColorHSL::hue(const double hue_) 448{ 449 double 450 hue, 451 luminosity, 452 saturation; 453 454 double 455 blue, 456 green, 457 red; 458 459 ConvertRGBToHSL(quantumRed(),quantumGreen(),quantumBlue(),&hue,&saturation, 460 &luminosity); 461 462 hue=hue_; 463 464 ConvertHSLToRGB(hue,saturation,luminosity,&red,&green,&blue); 465 466 quantumRed(red); 467 quantumGreen(green); 468 quantumBlue(blue); 469} 470 471double Magick::ColorHSL::hue(void) const 472{ 473 double 474 hue, 475 luminosity, 476 saturation; 477 478 ConvertRGBToHSL(quantumRed(),quantumGreen(),quantumBlue(),&hue,&saturation, 479 &luminosity); 480 481 return(hue); 482} 483 484void Magick::ColorHSL::luminosity(const double luminosity_) 485{ 486 double 487 hue, 488 luminosity, 489 saturation; 490 491 double 492 blue, 493 green, 494 red; 495 496 ConvertRGBToHSL(quantumRed(),quantumGreen(),quantumBlue(),&hue,&saturation, 497 &luminosity); 498 499 luminosity=luminosity_; 500 501 ConvertHSLToRGB(hue,saturation,luminosity,&red,&green,&blue); 502 503 quantumRed(red); 504 quantumGreen(green); 505 quantumBlue(blue); 506} 507 508double Magick::ColorHSL::luminosity ( void ) const 509{ 510 double 511 hue, 512 luminosity, 513 saturation; 514 515 ConvertRGBToHSL(quantumRed(),quantumGreen(),quantumBlue(),&hue,&saturation, 516 &luminosity); 517 518 return(luminosity); 519} 520 521void Magick::ColorHSL::saturation(const double saturation_) 522{ 523 double 524 hue, 525 luminosity, 526 saturation; 527 528 double 529 blue, 530 green, 531 red; 532 533 ConvertRGBToHSL(quantumRed(),quantumGreen(),quantumBlue(),&hue,&saturation, 534 &luminosity); 535 536 saturation=saturation_; 537 538 ConvertHSLToRGB(hue,saturation,luminosity,&red,&green,&blue); 539 540 quantumRed(red); 541 quantumGreen(green); 542 quantumBlue(blue); 543} 544 545double Magick::ColorHSL::saturation(void) const 546{ 547 double 548 hue, 549 luminosity, 550 saturation; 551 552 ConvertRGBToHSL(quantumRed(),quantumGreen(),quantumBlue(),&hue,&saturation, 553 &luminosity); 554 555 return(saturation); 556} 557 558Magick::ColorMono::ColorMono(void) 559 : Color() 560{ 561} 562 563Magick::ColorMono::ColorMono(const bool mono_) 564 : Color((Quantum)(mono_ ? QuantumRange : 0), 565 (Quantum)(mono_ ? QuantumRange : 0), 566 (Quantum)(mono_ ? QuantumRange : 0)) 567{ 568 quantumAlpha(OpaqueAlpha); 569} 570 571Magick::ColorMono::ColorMono(const Magick::Color &color_) 572 : Color(color_) 573{ 574} 575 576Magick::ColorMono::~ColorMono() 577{ 578} 579 580Magick::ColorMono& Magick::ColorMono::operator = ( const Magick::Color& color_ ) 581{ 582 *static_cast<Magick::Color*>(this) = color_; 583 return *this; 584} 585 586void Magick::ColorMono::mono(bool mono_) 587{ 588 quantumRed(mono_ ? QuantumRange : 0); 589 quantumGreen(mono_ ? QuantumRange : 0); 590 quantumBlue(mono_ ? QuantumRange : 0); 591} 592 593bool Magick::ColorMono::mono(void) const 594{ 595 return(quantumGreen() == 0); 596} 597 598Magick::ColorMono::ColorMono(PixelInfo *rep_,PixelType pixelType_) 599 : Color(rep_,pixelType_) 600{ 601} 602 603Magick::ColorRGBA::ColorRGBA(void) 604 : Color() 605{ 606} 607 608Magick::ColorRGBA::ColorRGBA(const Magick::Color & color_) 609 : Color(color_) 610{ 611} 612 613Magick::ColorRGBA::ColorRGBA(const double red_,const double green_, 614 const double blue_) 615 : Color(scaleDoubleToQuantum(red_),scaleDoubleToQuantum(green_), 616 scaleDoubleToQuantum(blue_)) 617{ 618 quantumAlpha(OpaqueAlpha); 619} 620 621Magick::ColorRGBA::ColorRGBA(const double red_,const double green_, 622 const double blue_,const double alpha_) 623 : Color(scaleDoubleToQuantum(red_),scaleDoubleToQuantum(green_), 624 scaleDoubleToQuantum(blue_),scaleDoubleToQuantum(alpha_)) 625{ 626} 627 628Magick::ColorRGBA::~ColorRGBA(void) 629{ 630} 631 632Magick::ColorRGBA& Magick::ColorRGBA::operator=(const Magick::Color& color_) 633{ 634 *static_cast<Magick::Color*>(this)=color_; 635 return(*this); 636} 637 638Magick::ColorYUV::ColorYUV(void) 639 : Color() 640{ 641} 642 643Magick::ColorYUV::ColorYUV(const Magick::Color &color_) 644 : Color(color_) 645{ 646} 647 648Magick::ColorYUV::ColorYUV(const double y_,const double u_,const double v_) 649 : Color() 650{ 651 convert(y_, u_, v_); 652 quantumAlpha(OpaqueAlpha); 653} 654 655Magick::ColorYUV::~ColorYUV(void) 656{ 657} 658 659Magick::ColorYUV& Magick::ColorYUV::operator=(const Magick::Color &color_) 660{ 661 *static_cast<Magick::Color*>(this)=color_; 662 return(*this); 663} 664 665void Magick::ColorYUV::u(const double u_) 666{ 667 convert(y(), u_, v()); 668} 669 670double Magick::ColorYUV::u(void) const 671{ 672 return scaleQuantumToDouble((-0.14740 * quantumRed()) - (0.28950 * 673 quantumGreen()) + (0.43690 * quantumBlue())); 674} 675 676void Magick::ColorYUV::v(const double v_) 677{ 678 convert(y(), u(), v_); 679} 680 681double Magick::ColorYUV::v(void) const 682{ 683 return scaleQuantumToDouble((0.61500 * quantumRed()) - (0.51500 * 684 quantumGreen()) - (0.10000 * quantumBlue())); 685} 686 687void Magick::ColorYUV::y(const double y_) 688{ 689 convert(y_, u(), v()); 690} 691 692double Magick::ColorYUV::y ( void ) const 693{ 694 return scaleQuantumToDouble((0.29900 * quantumRed()) + (0.58700 * 695 quantumGreen()) + (0.11400 * quantumBlue())); 696} 697 698void Magick::ColorYUV::convert(const double y_,const double u_,const double v_) 699{ 700 quantumRed(scaleDoubleToQuantum(y_ + 1.13980 * v_)); 701 quantumGreen(scaleDoubleToQuantum(y_ - (0.39380 * u_) - (0.58050 * v_))); 702 quantumBlue(scaleDoubleToQuantum(y_ + 2.02790 * u_)); 703} 704 705Magick::ColorYUV::ColorYUV(PixelInfo *rep_,PixelType pixelType_) 706 : Color(rep_,pixelType_) 707{ 708}