1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.4 3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 4 // 5 // Permission to copy, use, modify, sell and distribute this software 6 // is granted provided this copyright notice appears in all copies. 7 // This software is provided "as is" without express or implied 8 // warranty, and with no claim as to its suitability for any purpose. 9 // 10 //---------------------------------------------------------------------------- 11 // 12 // Adaptation for high precision colors has been sponsored by 13 // Liberty Technology Systems, Inc., visit http://lib-sys.com 14 // 15 // Liberty Technology Systems, Inc. is the provider of 16 // PostScript and PDF technology for software developers. 17 // 18 //---------------------------------------------------------------------------- 19 // Contact: mcseem@antigrain.com 20 // mcseemagg@yahoo.com 21 // http://www.antigrain.com 22 //---------------------------------------------------------------------------- 23 24 #ifndef AGG_COLOR_RGBA_INCLUDED 25 #define AGG_COLOR_RGBA_INCLUDED 26 27 #include <math.h> 28 #include "agg_basics.h" 29 30 namespace agg 31 { 32 // Supported byte orders for RGB and RGBA pixel formats 33 //======================================================================= 34 struct order_rgb { enum rgb_e { R=0, G=1, B=2, rgb_tag }; }; //----order_rgb 35 struct order_bgr { enum bgr_e { B=0, G=1, R=2, rgb_tag }; }; //----order_bgr 36 struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, rgba_tag }; }; //----order_rgba 37 struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, rgba_tag }; }; //----order_argb 38 struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, rgba_tag }; }; //----order_abgr 39 struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, rgba_tag }; }; //----order_bgra 40 41 //====================================================================rgba 42 struct rgba 43 { 44 typedef double value_type; 45 46 double r; 47 double g; 48 double b; 49 double a; 50 51 //-------------------------------------------------------------------- rgbargba52 rgba() {} 53 54 //-------------------------------------------------------------------- 55 rgba(double r_, double g_, double b_, double a_=1.0) : rrgba56 r(r_), g(g_), b(b_), a(a_) {} 57 58 //-------------------------------------------------------------------- rgbargba59 rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {} 60 61 //-------------------------------------------------------------------- clearrgba62 void clear() 63 { 64 r = g = b = a = 0; 65 } 66 67 //-------------------------------------------------------------------- transparentrgba68 const rgba& transparent() 69 { 70 a = 0.0; 71 return *this; 72 } 73 74 //-------------------------------------------------------------------- opacityrgba75 const rgba& opacity(double a_) 76 { 77 if(a_ < 0.0) a_ = 0.0; 78 if(a_ > 1.0) a_ = 1.0; 79 a = a_; 80 return *this; 81 } 82 83 //-------------------------------------------------------------------- opacityrgba84 double opacity() const 85 { 86 return a; 87 } 88 89 //-------------------------------------------------------------------- premultiplyrgba90 const rgba& premultiply() 91 { 92 r *= a; 93 g *= a; 94 b *= a; 95 return *this; 96 } 97 98 //-------------------------------------------------------------------- premultiplyrgba99 const rgba& premultiply(double a_) 100 { 101 if(a <= 0.0 || a_ <= 0.0) 102 { 103 r = g = b = a = 0.0; 104 return *this; 105 } 106 a_ /= a; 107 r *= a_; 108 g *= a_; 109 b *= a_; 110 a = a_; 111 return *this; 112 } 113 114 //-------------------------------------------------------------------- demultiplyrgba115 const rgba& demultiply() 116 { 117 if(a == 0) 118 { 119 r = g = b = 0; 120 return *this; 121 } 122 double a_ = 1.0 / a; 123 r *= a_; 124 g *= a_; 125 b *= a_; 126 return *this; 127 } 128 129 130 //-------------------------------------------------------------------- gradientrgba131 rgba gradient(rgba c, double k) const 132 { 133 rgba ret; 134 ret.r = r + (c.r - r) * k; 135 ret.g = g + (c.g - g) * k; 136 ret.b = b + (c.b - b) * k; 137 ret.a = a + (c.a - a) * k; 138 return ret; 139 } 140 141 //-------------------------------------------------------------------- no_colorrgba142 static rgba no_color() { return rgba(0,0,0,0); } 143 144 //-------------------------------------------------------------------- 145 static rgba from_wavelength(double wl, double gamma = 1.0); 146 147 //-------------------------------------------------------------------- 148 explicit rgba(double wavelen, double gamma=1.0) 149 { 150 *this = from_wavelength(wavelen, gamma); 151 } 152 153 }; 154 155 //----------------------------------------------------------------rgba_pre 156 inline rgba rgba_pre(double r, double g, double b, double a=1.0) 157 { 158 return rgba(r, g, b, a).premultiply(); 159 } rgba_pre(const rgba & c)160 inline rgba rgba_pre(const rgba& c) 161 { 162 return rgba(c).premultiply(); 163 } rgba_pre(const rgba & c,double a)164 inline rgba rgba_pre(const rgba& c, double a) 165 { 166 return rgba(c, a).premultiply(); 167 } 168 169 //------------------------------------------------------------------------ from_wavelength(double wl,double gamma)170 inline rgba rgba::from_wavelength(double wl, double gamma) 171 { 172 rgba t(0.0, 0.0, 0.0); 173 174 if(wl >= 380.0 && wl <= 440.0) 175 { 176 t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0); 177 t.b = 1.0; 178 } 179 else 180 if(wl >= 440.0 && wl <= 490.0) 181 { 182 t.g = (wl - 440.0) / (490.0 - 440.0); 183 t.b = 1.0; 184 } 185 else 186 if(wl >= 490.0 && wl <= 510.0) 187 { 188 t.g = 1.0; 189 t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0); 190 } 191 else 192 if(wl >= 510.0 && wl <= 580.0) 193 { 194 t.r = (wl - 510.0) / (580.0 - 510.0); 195 t.g = 1.0; 196 } 197 else 198 if(wl >= 580.0 && wl <= 645.0) 199 { 200 t.r = 1.0; 201 t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0); 202 } 203 else 204 if(wl >= 645.0 && wl <= 780.0) 205 { 206 t.r = 1.0; 207 } 208 209 double s = 1.0; 210 if(wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0); 211 else if(wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0); 212 213 t.r = pow(t.r * s, gamma); 214 t.g = pow(t.g * s, gamma); 215 t.b = pow(t.b * s, gamma); 216 return t; 217 } 218 219 220 221 222 //===================================================================rgba8 223 struct rgba8 224 { 225 typedef int8u value_type; 226 typedef int32u calc_type; 227 typedef int32 long_type; 228 enum base_scale_e 229 { 230 base_shift = 8, 231 base_scale = 1 << base_shift, 232 base_mask = base_scale - 1 233 }; 234 typedef rgba8 self_type; 235 236 237 value_type r; 238 value_type g; 239 value_type b; 240 value_type a; 241 242 //-------------------------------------------------------------------- rgba8rgba8243 rgba8() {} 244 245 //-------------------------------------------------------------------- 246 rgba8(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) : rrgba8247 r(value_type(r_)), 248 g(value_type(g_)), 249 b(value_type(b_)), 250 a(value_type(a_)) {} 251 252 //-------------------------------------------------------------------- rgba8rgba8253 rgba8(const rgba& c, double a_) : 254 r((value_type)uround(c.r * double(base_mask))), 255 g((value_type)uround(c.g * double(base_mask))), 256 b((value_type)uround(c.b * double(base_mask))), 257 a((value_type)uround(a_ * double(base_mask))) {} 258 259 //-------------------------------------------------------------------- rgba8rgba8260 rgba8(const self_type& c, unsigned a_) : 261 r(c.r), g(c.g), b(c.b), a(value_type(a_)) {} 262 263 //-------------------------------------------------------------------- rgba8rgba8264 rgba8(const rgba& c) : 265 r((value_type)uround(c.r * double(base_mask))), 266 g((value_type)uround(c.g * double(base_mask))), 267 b((value_type)uround(c.b * double(base_mask))), 268 a((value_type)uround(c.a * double(base_mask))) {} 269 270 //-------------------------------------------------------------------- clearrgba8271 void clear() 272 { 273 r = g = b = a = 0; 274 } 275 276 //-------------------------------------------------------------------- transparentrgba8277 const self_type& transparent() 278 { 279 a = 0; 280 return *this; 281 } 282 283 //-------------------------------------------------------------------- opacityrgba8284 const self_type& opacity(double a_) 285 { 286 if(a_ < 0.0) a_ = 0.0; 287 if(a_ > 1.0) a_ = 1.0; 288 a = (value_type)uround(a_ * double(base_mask)); 289 return *this; 290 } 291 292 //-------------------------------------------------------------------- opacityrgba8293 double opacity() const 294 { 295 return double(a) / double(base_mask); 296 } 297 298 //-------------------------------------------------------------------- premultiplyrgba8299 AGG_INLINE const self_type& premultiply() 300 { 301 if(a == base_mask) return *this; 302 if(a == 0) 303 { 304 r = g = b = 0; 305 return *this; 306 } 307 r = value_type((calc_type(r) * a) >> base_shift); 308 g = value_type((calc_type(g) * a) >> base_shift); 309 b = value_type((calc_type(b) * a) >> base_shift); 310 return *this; 311 } 312 313 //-------------------------------------------------------------------- premultiplyrgba8314 AGG_INLINE const self_type& premultiply(unsigned a_) 315 { 316 if(a == base_mask && a_ >= base_mask) return *this; 317 if(a == 0 || a_ == 0) 318 { 319 r = g = b = a = 0; 320 return *this; 321 } 322 calc_type r_ = (calc_type(r) * a_) / a; 323 calc_type g_ = (calc_type(g) * a_) / a; 324 calc_type b_ = (calc_type(b) * a_) / a; 325 r = value_type((r_ > a_) ? a_ : r_); 326 g = value_type((g_ > a_) ? a_ : g_); 327 b = value_type((b_ > a_) ? a_ : b_); 328 a = value_type(a_); 329 return *this; 330 } 331 332 //-------------------------------------------------------------------- demultiplyrgba8333 AGG_INLINE const self_type& demultiply() 334 { 335 if(a == base_mask) return *this; 336 if(a == 0) 337 { 338 r = g = b = 0; 339 return *this; 340 } 341 calc_type r_ = (calc_type(r) * base_mask) / a; 342 calc_type g_ = (calc_type(g) * base_mask) / a; 343 calc_type b_ = (calc_type(b) * base_mask) / a; 344 r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); 345 g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); 346 b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); 347 return *this; 348 } 349 350 //-------------------------------------------------------------------- gradientrgba8351 AGG_INLINE self_type gradient(const self_type& c, double k) const 352 { 353 self_type ret; 354 calc_type ik = uround(k * base_scale); 355 ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift)); 356 ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift)); 357 ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift)); 358 ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift)); 359 return ret; 360 } 361 362 //-------------------------------------------------------------------- addrgba8363 AGG_INLINE void add(const self_type& c, unsigned cover) 364 { 365 calc_type cr, cg, cb, ca; 366 if(cover == cover_mask) 367 { 368 if(c.a == base_mask) 369 { 370 *this = c; 371 } 372 else 373 { 374 cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr; 375 cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg; 376 cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb; 377 ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; 378 } 379 } 380 else 381 { 382 cr = r + ((c.r * cover + cover_mask/2) >> cover_shift); 383 cg = g + ((c.g * cover + cover_mask/2) >> cover_shift); 384 cb = b + ((c.b * cover + cover_mask/2) >> cover_shift); 385 ca = a + ((c.a * cover + cover_mask/2) >> cover_shift); 386 r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr; 387 g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg; 388 b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb; 389 a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; 390 } 391 } 392 393 //-------------------------------------------------------------------- 394 template<class GammaLUT> apply_gamma_dirrgba8395 AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) 396 { 397 r = gamma.dir(r); 398 g = gamma.dir(g); 399 b = gamma.dir(b); 400 } 401 402 //-------------------------------------------------------------------- 403 template<class GammaLUT> apply_gamma_invrgba8404 AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) 405 { 406 r = gamma.inv(r); 407 g = gamma.inv(g); 408 b = gamma.inv(b); 409 } 410 411 //-------------------------------------------------------------------- no_colorrgba8412 static self_type no_color() { return self_type(0,0,0,0); } 413 414 //-------------------------------------------------------------------- 415 static self_type from_wavelength(double wl, double gamma = 1.0) 416 { 417 return self_type(rgba::from_wavelength(wl, gamma)); 418 } 419 }; 420 421 422 //-------------------------------------------------------------rgba8_pre 423 inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b, 424 unsigned a = rgba8::base_mask) 425 { 426 return rgba8(r,g,b,a).premultiply(); 427 } rgba8_pre(const rgba8 & c)428 inline rgba8 rgba8_pre(const rgba8& c) 429 { 430 return rgba8(c).premultiply(); 431 } rgba8_pre(const rgba8 & c,unsigned a)432 inline rgba8 rgba8_pre(const rgba8& c, unsigned a) 433 { 434 return rgba8(c,a).premultiply(); 435 } rgba8_pre(const rgba & c)436 inline rgba8 rgba8_pre(const rgba& c) 437 { 438 return rgba8(c).premultiply(); 439 } rgba8_pre(const rgba & c,double a)440 inline rgba8 rgba8_pre(const rgba& c, double a) 441 { 442 return rgba8(c,a).premultiply(); 443 } 444 445 446 //-----------------------------------------------------------rgb8_packed rgb8_packed(unsigned v)447 inline rgba8 rgb8_packed(unsigned v) 448 { 449 return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); 450 } 451 452 //-----------------------------------------------------------bgr8_packed bgr8_packed(unsigned v)453 inline rgba8 bgr8_packed(unsigned v) 454 { 455 return rgba8(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF); 456 } 457 458 //----------------------------------------------------------argb8_packed argb8_packed(unsigned v)459 inline rgba8 argb8_packed(unsigned v) 460 { 461 return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF, v >> 24); 462 } 463 464 465 466 467 468 469 470 471 //=================================================================rgba16 472 struct rgba16 473 { 474 typedef int16u value_type; 475 typedef int32u calc_type; 476 typedef int64 long_type; 477 enum base_scale_e 478 { 479 base_shift = 16, 480 base_scale = 1 << base_shift, 481 base_mask = base_scale - 1 482 }; 483 typedef rgba16 self_type; 484 485 value_type r; 486 value_type g; 487 value_type b; 488 value_type a; 489 490 //-------------------------------------------------------------------- rgba16rgba16491 rgba16() {} 492 493 //-------------------------------------------------------------------- 494 rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) : rrgba16495 r(value_type(r_)), 496 g(value_type(g_)), 497 b(value_type(b_)), 498 a(value_type(a_)) {} 499 500 //-------------------------------------------------------------------- rgba16rgba16501 rgba16(const self_type& c, unsigned a_) : 502 r(c.r), g(c.g), b(c.b), a(value_type(a_)) {} 503 504 //-------------------------------------------------------------------- rgba16rgba16505 rgba16(const rgba& c) : 506 r((value_type)uround(c.r * double(base_mask))), 507 g((value_type)uround(c.g * double(base_mask))), 508 b((value_type)uround(c.b * double(base_mask))), 509 a((value_type)uround(c.a * double(base_mask))) {} 510 511 //-------------------------------------------------------------------- rgba16rgba16512 rgba16(const rgba& c, double a_) : 513 r((value_type)uround(c.r * double(base_mask))), 514 g((value_type)uround(c.g * double(base_mask))), 515 b((value_type)uround(c.b * double(base_mask))), 516 a((value_type)uround(a_ * double(base_mask))) {} 517 518 //-------------------------------------------------------------------- rgba16rgba16519 rgba16(const rgba8& c) : 520 r(value_type((value_type(c.r) << 8) | c.r)), 521 g(value_type((value_type(c.g) << 8) | c.g)), 522 b(value_type((value_type(c.b) << 8) | c.b)), 523 a(value_type((value_type(c.a) << 8) | c.a)) {} 524 525 //-------------------------------------------------------------------- rgba16rgba16526 rgba16(const rgba8& c, unsigned a_) : 527 r(value_type((value_type(c.r) << 8) | c.r)), 528 g(value_type((value_type(c.g) << 8) | c.g)), 529 b(value_type((value_type(c.b) << 8) | c.b)), 530 a(value_type(( a_ << 8) | c.a)) {} 531 532 //-------------------------------------------------------------------- clearrgba16533 void clear() 534 { 535 r = g = b = a = 0; 536 } 537 538 //-------------------------------------------------------------------- transparentrgba16539 const self_type& transparent() 540 { 541 a = 0; 542 return *this; 543 } 544 545 //-------------------------------------------------------------------- opacityrgba16546 AGG_INLINE const self_type& opacity(double a_) 547 { 548 if(a_ < 0.0) a_ = 0.0; 549 if(a_ > 1.0) a_ = 1.0; 550 a = (value_type)uround(a_ * double(base_mask)); 551 return *this; 552 } 553 554 //-------------------------------------------------------------------- opacityrgba16555 double opacity() const 556 { 557 return double(a) / double(base_mask); 558 } 559 560 //-------------------------------------------------------------------- premultiplyrgba16561 AGG_INLINE const self_type& premultiply() 562 { 563 if(a == base_mask) return *this; 564 if(a == 0) 565 { 566 r = g = b = 0; 567 return *this; 568 } 569 r = value_type((calc_type(r) * a) >> base_shift); 570 g = value_type((calc_type(g) * a) >> base_shift); 571 b = value_type((calc_type(b) * a) >> base_shift); 572 return *this; 573 } 574 575 //-------------------------------------------------------------------- premultiplyrgba16576 AGG_INLINE const self_type& premultiply(unsigned a_) 577 { 578 if(a == base_mask && a_ >= base_mask) return *this; 579 if(a == 0 || a_ == 0) 580 { 581 r = g = b = a = 0; 582 return *this; 583 } 584 calc_type r_ = (calc_type(r) * a_) / a; 585 calc_type g_ = (calc_type(g) * a_) / a; 586 calc_type b_ = (calc_type(b) * a_) / a; 587 r = value_type((r_ > a_) ? a_ : r_); 588 g = value_type((g_ > a_) ? a_ : g_); 589 b = value_type((b_ > a_) ? a_ : b_); 590 a = value_type(a_); 591 return *this; 592 } 593 594 //-------------------------------------------------------------------- demultiplyrgba16595 AGG_INLINE const self_type& demultiply() 596 { 597 if(a == base_mask) return *this; 598 if(a == 0) 599 { 600 r = g = b = 0; 601 return *this; 602 } 603 calc_type r_ = (calc_type(r) * base_mask) / a; 604 calc_type g_ = (calc_type(g) * base_mask) / a; 605 calc_type b_ = (calc_type(b) * base_mask) / a; 606 r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); 607 g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); 608 b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); 609 return *this; 610 } 611 612 //-------------------------------------------------------------------- gradientrgba16613 AGG_INLINE self_type gradient(const self_type& c, double k) const 614 { 615 self_type ret; 616 calc_type ik = uround(k * base_scale); 617 ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift)); 618 ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift)); 619 ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift)); 620 ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift)); 621 return ret; 622 } 623 624 //-------------------------------------------------------------------- addrgba16625 AGG_INLINE void add(const self_type& c, unsigned cover) 626 { 627 calc_type cr, cg, cb, ca; 628 if(cover == cover_mask) 629 { 630 if(c.a == base_mask) 631 { 632 *this = c; 633 } 634 else 635 { 636 cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr; 637 cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg; 638 cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb; 639 ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; 640 } 641 } 642 else 643 { 644 cr = r + ((c.r * cover + cover_mask) >> cover_shift); 645 cg = g + ((c.g * cover + cover_mask) >> cover_shift); 646 cb = b + ((c.b * cover + cover_mask) >> cover_shift); 647 ca = a + ((c.a * cover + cover_mask) >> cover_shift); 648 r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr; 649 g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg; 650 b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb; 651 a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; 652 } 653 } 654 655 //-------------------------------------------------------------------- 656 template<class GammaLUT> apply_gamma_dirrgba16657 AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) 658 { 659 r = gamma.dir(r); 660 g = gamma.dir(g); 661 b = gamma.dir(b); 662 } 663 664 //-------------------------------------------------------------------- 665 template<class GammaLUT> apply_gamma_invrgba16666 AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) 667 { 668 r = gamma.inv(r); 669 g = gamma.inv(g); 670 b = gamma.inv(b); 671 } 672 673 //-------------------------------------------------------------------- no_colorrgba16674 static self_type no_color() { return self_type(0,0,0,0); } 675 676 //-------------------------------------------------------------------- 677 static self_type from_wavelength(double wl, double gamma = 1.0) 678 { 679 return self_type(rgba::from_wavelength(wl, gamma)); 680 } 681 }; 682 683 684 685 //--------------------------------------------------------------rgba16_pre 686 inline rgba16 rgba16_pre(unsigned r, unsigned g, unsigned b, 687 unsigned a = rgba16::base_mask) 688 { 689 return rgba16(r,g,b,a).premultiply(); 690 } rgba16_pre(const rgba16 & c,unsigned a)691 inline rgba16 rgba16_pre(const rgba16& c, unsigned a) 692 { 693 return rgba16(c,a).premultiply(); 694 } rgba16_pre(const rgba & c)695 inline rgba16 rgba16_pre(const rgba& c) 696 { 697 return rgba16(c).premultiply(); 698 } rgba16_pre(const rgba & c,double a)699 inline rgba16 rgba16_pre(const rgba& c, double a) 700 { 701 return rgba16(c,a).premultiply(); 702 } rgba16_pre(const rgba8 & c)703 inline rgba16 rgba16_pre(const rgba8& c) 704 { 705 return rgba16(c).premultiply(); 706 } rgba16_pre(const rgba8 & c,unsigned a)707 inline rgba16 rgba16_pre(const rgba8& c, unsigned a) 708 { 709 return rgba16(c,a).premultiply(); 710 } 711 712 } 713 714 715 716 #endif 717