Color.cpp revision 067638f702a3e35c44bcc3ba9593c1e24951a781
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 19MagickPPExport int 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 28MagickPPExport int Magick::operator != (const Magick::Color &left_, 29 const Magick::Color &right_) 30{ 31 return(!(left_ == right_)); 32} 33 34MagickPPExport int Magick::operator > (const Magick::Color &left_, 35 const Magick::Color &right_) 36{ 37 return(!(left_ < right_ ) && (left_ != right_ )); 38} 39 40MagickPPExport int 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 56MagickPPExport int Magick::operator >= (const Magick::Color &left_, 57 const Magick::Color &right_) 58{ 59 return((left_ > right_) || (left_ == right_)); 60} 61 62MagickPPExport int 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), 70 _isValid(false), 71 _pixelOwn(true), 72 _pixelType(RGBPixel) 73{ 74 initPixel(); 75} 76 77Magick::Color::Color(const Quantum red_,const Quantum green_, 78 const Quantum blue_) 79 : _pixel(new PixelInfo), 80 _isValid(true), 81 _pixelOwn(true), 82 _pixelType(RGBPixel) 83{ 84 quantumRed(red_); 85 quantumGreen(green_); 86 quantumBlue(blue_); 87 quantumAlpha(OpaqueAlpha); 88} 89 90Magick::Color::Color(const Quantum red_,const Quantum green_, 91 const Quantum blue_, const Quantum alpha_) 92 : _pixel(new PixelInfo), 93 _isValid(true), 94 _pixelOwn(true), 95 _pixelType(RGBAPixel) 96{ 97 quantumRed(red_); 98 quantumGreen(green_); 99 quantumBlue(blue_); 100 quantumAlpha(alpha_); 101} 102 103Magick::Color::Color(const char *color_) 104 : _pixel(new PixelInfo), 105 _isValid(true), 106 _pixelOwn(true), 107 _pixelType(RGBPixel) 108{ 109 initPixel(); 110 111 // Use operator = implementation 112 *this=color_; 113} 114 115Magick::Color::Color(const Magick::Color &color_) 116 : _pixel(new PixelInfo), 117 _isValid(color_._isValid), 118 _pixelOwn(true), 119 _pixelType(color_._pixelType) 120{ 121 *_pixel=*color_._pixel; 122} 123 124Magick::Color::Color(const PixelInfo &color_) 125 : _pixel(new PixelInfo), 126 _isValid(true), 127 _pixelOwn(true), 128 _pixelType(RGBPixel) 129{ 130 *_pixel=color_; 131 132 if (color_.alpha != OpaqueAlpha) 133 _pixelType=RGBAPixel; 134} 135 136Magick::Color::Color(const std::string &color_) 137 : _pixel(new PixelInfo), 138 _isValid(true), 139 _pixelOwn(true), 140 _pixelType(RGBPixel) 141{ 142 initPixel(); 143 144 // Use operator = implementation 145 *this=color_; 146} 147 148Magick::Color::~Color(void) 149{ 150 if (_pixelOwn) 151 delete _pixel; 152 153 _pixel=(PixelInfo *)NULL; 154} 155 156Magick::Color& Magick::Color::operator=(const Magick::Color& color_) 157{ 158 // If not being set to ourself 159 if (this != &color_) 160 { 161 // Copy pixel value 162 *_pixel=*color_._pixel; 163 164 // Validity 165 _isValid=color_._isValid; 166 167 // Copy pixel type 168 _pixelType=color_._pixelType; 169 } 170 return(*this); 171} 172 173const Magick::Color& Magick::Color::operator=(const char *color_) 174{ 175 *this=std::string(color_); 176 return(*this); 177} 178 179const Magick::Color& Magick::Color::operator=(const MagickCore::PixelInfo &color_) 180{ 181 *_pixel=color_; 182 if (color_.alpha != OpaqueAlpha) 183 _pixelType=RGBAPixel; 184 else 185 _pixelType=RGBPixel; 186 187 return(*this); 188} 189 190const Magick::Color& Magick::Color::operator=(const std::string &color_) 191{ 192 PixelInfo 193 target_color; 194 195 initPixel(); 196 GetPPException; 197 if (QueryColorCompliance(color_.c_str(),AllCompliance,&target_color, 198 exceptionInfo)) 199 { 200 quantumRed(target_color.red); 201 quantumGreen(target_color.green); 202 quantumBlue(target_color.blue); 203 quantumAlpha(target_color.alpha); 204 205 if (quantumAlpha() != OpaqueAlpha) 206 _pixelType=RGBAPixel; 207 else 208 _pixelType=RGBPixel; 209 } 210 else 211 _isValid = false; 212 ThrowPPException; 213 214 return(*this); 215} 216 217Magick::Color::operator MagickCore::PixelInfo() const 218{ 219 return *_pixel; 220} 221 222Magick::Color::operator std::string() const 223{ 224 char 225 colorbuf[MaxTextExtent]; 226 227 PixelInfo 228 pixel; 229 230 if (!isValid()) 231 return std::string("none"); 232 233 pixel.colorspace=RGBColorspace; 234 pixel.alpha_trait=_pixelType == RGBAPixel ? BlendPixelTrait : 235 UndefinedPixelTrait; 236 pixel.depth=MAGICKCORE_QUANTUM_DEPTH; 237 pixel.red=_pixel->red; 238 pixel.green=_pixel->green; 239 pixel.blue=_pixel->blue; 240 pixel.alpha=_pixel->alpha; 241 GetColorTuple(&pixel,MagickTrue,colorbuf); 242 243 return(std::string(colorbuf)); 244} 245 246void Magick::Color::alpha(const double alpha_) 247{ 248 quantumAlpha(scaleDoubleToQuantum(alpha_)); 249} 250 251double Magick::Color::alpha(void) const 252{ 253 return scaleQuantumToDouble(quantumAlpha()); 254} 255 256bool Magick::Color::isValid(void) const 257{ 258 return(_isValid); 259} 260 261void Magick::Color::isValid(bool valid_) 262{ 263 if ((valid_ && isValid()) || (!valid_ && !isValid())) 264 return; 265 266 if (!_pixelOwn) 267 { 268 _pixel=new PixelInfo; 269 _pixelOwn=true; 270 } 271 272 _isValid=valid_; 273 274 initPixel(); 275} 276 277void Magick::Color::quantumAlpha(const Magick::Quantum alpha_) 278{ 279 _pixel->alpha=alpha_; 280 _isValid=true ; 281} 282 283Magick::Quantum Magick::Color::quantumAlpha(void) const 284{ 285 return _pixel->alpha; 286} 287 288void Magick::Color::quantumBlue(const Magick::Quantum blue_) 289{ 290 _pixel->blue=blue_; 291 _isValid=true; 292} 293 294Magick::Quantum Magick::Color::quantumBlue(void) const 295{ 296 return _pixel->blue; 297} 298 299void Magick::Color::quantumGreen(const Magick::Quantum green_) 300{ 301 _pixel->green=green_; 302 _isValid=true; 303} 304 305Magick::Quantum Magick::Color::quantumGreen(void) const 306{ 307 return _pixel->green; 308} 309 310void Magick::Color::quantumRed(const Magick::Quantum red_) 311{ 312 _pixel->red=red_; 313 _isValid=true; 314} 315 316Magick::Quantum Magick::Color::quantumRed(void) const 317{ 318 return _pixel->red; 319} 320 321Magick::Color::Color(PixelInfo* rep_,PixelType pixelType_) 322 : _pixel(rep_),_pixelOwn(false),_isValid(true),_pixelType(pixelType_) 323{ 324} 325 326void Magick::Color::pixel(PixelInfo *rep_,PixelType pixelType_) 327{ 328 if (_pixelOwn) 329 delete _pixel; 330 331 _pixel=rep_; 332 _pixelOwn=false; 333 _isValid=true; 334 _pixelType=pixelType_; 335} 336 337Magick::Quantum Magick::Color::scaleDoubleToQuantum(const double double_) 338{ 339 return (static_cast<Magick::Quantum>(double_*QuantumRange)); 340} 341 342double Magick::Color::scaleQuantumToDouble(const Magick::Quantum quantum_) 343{ 344#if (MAGICKCORE_QUANTUM_DEPTH < 32) 345 return (static_cast<double>(quantum_)/QuantumRange); 346#else 347 return (quantum_/QuantumRange); 348#endif 349} 350 351void Magick::Color::initPixel() 352{ 353 _pixel->red=0; 354 _pixel->green=0; 355 _pixel->blue=0; 356 _pixel->alpha=TransparentAlpha; 357} 358 359Magick::ColorGray::ColorGray(void) 360 : Color() 361{ 362} 363 364Magick::ColorGray::ColorGray(const Magick::Color & color_) 365 : Color(color_) 366{ 367} 368 369Magick::ColorGray::ColorGray(double shade_) 370 : Color(scaleDoubleToQuantum(shade_),scaleDoubleToQuantum(shade_), 371 scaleDoubleToQuantum(shade_)) 372{ 373 quantumAlpha(OpaqueAlpha); 374} 375 376Magick::ColorGray::~ColorGray() 377{ 378} 379 380void Magick::ColorGray::shade(double shade_) 381{ 382 Quantum gray=scaleDoubleToQuantum(shade_); 383 quantumRed(gray); 384 quantumGreen(gray); 385 quantumBlue(gray); 386} 387 388double Magick::ColorGray::shade(void) const 389{ 390 return(scaleQuantumToDouble(quantumGreen())); 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(ClampToQuantum(red)); 461 quantumGreen(ClampToQuantum(green)); 462 quantumBlue(ClampToQuantum(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(ClampToQuantum(red)); 498 quantumGreen(ClampToQuantum(green)); 499 quantumBlue(ClampToQuantum(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(ClampToQuantum(red)); 535 quantumGreen(ClampToQuantum(green)); 536 quantumBlue(ClampToQuantum(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((mono_ ? QuantumRange : 0),(mono_ ? QuantumRange : 0), 559 (mono_ ? QuantumRange : 0)) 560{ 561 quantumAlpha(OpaqueAlpha); 562} 563 564Magick::ColorMono::ColorMono(const Magick::Color &color_) 565 : Color(color_) 566{ 567} 568 569Magick::ColorMono::~ColorMono() 570{ 571} 572 573Magick::ColorMono& Magick::ColorMono::operator=(const Magick::Color& color_) 574{ 575 *static_cast<Magick::Color*>(this)=color_; 576 return(*this); 577} 578 579void Magick::ColorMono::mono(bool mono_) 580{ 581 quantumRed(mono_ ? QuantumRange : 0); 582 quantumGreen(mono_ ? QuantumRange : 0); 583 quantumBlue(mono_ ? QuantumRange : 0); 584} 585 586bool Magick::ColorMono::mono(void) const 587{ 588 return(quantumGreen() == 0); 589} 590 591Magick::ColorMono::ColorMono(PixelInfo *rep_,PixelType pixelType_) 592 : Color(rep_,pixelType_) 593{ 594} 595 596Magick::ColorRGB::ColorRGB(void) 597 : Color() 598{ 599} 600 601Magick::ColorRGB::ColorRGB(const Magick::Color &color_) 602 : Color(color_) 603{ 604} 605 606Magick::ColorRGB::ColorRGB(const double red_,const double green_, 607 const double blue_) 608 : Color(scaleDoubleToQuantum(red_),scaleDoubleToQuantum(green_), 609 scaleDoubleToQuantum(blue_)) 610{ 611 quantumAlpha(OpaqueAlpha); 612} 613 614Magick::ColorRGB::ColorRGB(const double red_,const double green_, 615 const double blue_,const double alpha_) 616 : Color(scaleDoubleToQuantum(red_),scaleDoubleToQuantum(green_), 617 scaleDoubleToQuantum(blue_),scaleDoubleToQuantum(alpha_)) 618{ 619} 620 621Magick::ColorRGB::~ColorRGB(void) 622{ 623} 624 625Magick::ColorRGB& Magick::ColorRGB::operator=(const Magick::Color& color_) 626{ 627 *static_cast<Magick::Color*>(this)=color_; 628 return(*this); 629} 630 631void Magick::ColorRGB::blue(const double blue_) 632{ 633 quantumBlue(scaleDoubleToQuantum(blue_)); 634} 635 636double Magick::ColorRGB::blue(void) const 637{ 638 return scaleQuantumToDouble(quantumBlue()); 639} 640 641void Magick::ColorRGB::green(const double green_) 642{ 643 quantumGreen(scaleDoubleToQuantum(green_)); 644} 645 646double Magick::ColorRGB::green(void) const 647{ 648 return scaleQuantumToDouble(quantumGreen()); 649} 650 651void Magick::ColorRGB::red(const double red_) 652{ 653 quantumRed(scaleDoubleToQuantum(red_)); 654} 655 656double Magick::ColorRGB::red(void) const 657{ 658 return scaleQuantumToDouble(quantumRed()); 659} 660 661Magick::ColorRGB::ColorRGB(PixelInfo *rep_,PixelType pixelType_) 662 : Color(rep_,pixelType_) 663{ 664} 665 666Magick::ColorYUV::ColorYUV(void) 667 : Color() 668{ 669} 670 671Magick::ColorYUV::ColorYUV(const Magick::Color &color_) 672 : Color(color_) 673{ 674} 675 676Magick::ColorYUV::ColorYUV(const double y_,const double u_,const double v_) 677 : Color() 678{ 679 convert(y_, u_, v_); 680 quantumAlpha(OpaqueAlpha); 681} 682 683Magick::ColorYUV::~ColorYUV(void) 684{ 685} 686 687Magick::ColorYUV& Magick::ColorYUV::operator=(const Magick::Color &color_) 688{ 689 *static_cast<Magick::Color*>(this)=color_; 690 return(*this); 691} 692 693void Magick::ColorYUV::u(const double u_) 694{ 695 convert(y(), u_, v()); 696} 697 698double Magick::ColorYUV::u(void) const 699{ 700 return scaleQuantumToDouble((-0.14740 * quantumRed()) - (0.28950 * 701 quantumGreen()) + (0.43690 * quantumBlue())); 702} 703 704void Magick::ColorYUV::v(const double v_) 705{ 706 convert(y(), u(), v_); 707} 708 709double Magick::ColorYUV::v(void) const 710{ 711 return scaleQuantumToDouble((0.61500 * quantumRed()) - (0.51500 * 712 quantumGreen()) - (0.10000 * quantumBlue())); 713} 714 715void Magick::ColorYUV::y(const double y_) 716{ 717 convert(y_, u(), v()); 718} 719 720double Magick::ColorYUV::y ( void ) const 721{ 722 return scaleQuantumToDouble((0.29900 * quantumRed()) + (0.58700 * 723 quantumGreen()) + (0.11400 * quantumBlue())); 724} 725 726void Magick::ColorYUV::convert(const double y_,const double u_,const double v_) 727{ 728 quantumRed(scaleDoubleToQuantum(y_ + 1.13980 * v_)); 729 quantumGreen(scaleDoubleToQuantum(y_ - (0.39380 * u_) - (0.58050 * v_))); 730 quantumBlue(scaleDoubleToQuantum(y_ + 2.02790 * u_)); 731} 732 733Magick::ColorYUV::ColorYUV(PixelInfo *rep_,PixelType pixelType_) 734 : Color(rep_,pixelType_) 735{ 736} 737