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 // Contact: mcseem@antigrain.com 12 // mcseemagg@yahoo.com 13 // http://www.antigrain.com 14 //---------------------------------------------------------------------------- 15 // 16 // Adaptation for high precision colors has been sponsored by 17 // Liberty Technology Systems, Inc., visit http://lib-sys.com 18 // 19 // Liberty Technology Systems, Inc. is the provider of 20 // PostScript and PDF technology for software developers. 21 // 22 //---------------------------------------------------------------------------- 23 24 #ifndef AGG_PIXFMT_RGB_INCLUDED 25 #define AGG_PIXFMT_RGB_INCLUDED 26 27 #include <string.h> 28 #include "agg_basics.h" 29 #include "agg_color_rgba.h" 30 #include "agg_rendering_buffer.h" 31 32 namespace agg 33 { 34 35 //=====================================================apply_gamma_dir_rgb 36 template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgb 37 { 38 public: 39 typedef typename ColorT::value_type value_type; 40 41 apply_gamma_dir_rgb(const GammaLut& gamma) : m_gamma(gamma) {} 42 43 AGG_INLINE void operator () (value_type* p) 44 { 45 p[Order::R] = m_gamma.dir(p[Order::R]); 46 p[Order::G] = m_gamma.dir(p[Order::G]); 47 p[Order::B] = m_gamma.dir(p[Order::B]); 48 } 49 50 private: 51 const GammaLut& m_gamma; 52 }; 53 54 55 56 //=====================================================apply_gamma_inv_rgb 57 template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgb 58 { 59 public: 60 typedef typename ColorT::value_type value_type; 61 62 apply_gamma_inv_rgb(const GammaLut& gamma) : m_gamma(gamma) {} 63 64 AGG_INLINE void operator () (value_type* p) 65 { 66 p[Order::R] = m_gamma.inv(p[Order::R]); 67 p[Order::G] = m_gamma.inv(p[Order::G]); 68 p[Order::B] = m_gamma.inv(p[Order::B]); 69 } 70 71 private: 72 const GammaLut& m_gamma; 73 }; 74 75 76 //=========================================================blender_rgb 77 template<class ColorT, class Order> struct blender_rgb 78 { 79 typedef ColorT color_type; 80 typedef Order order_type; 81 typedef typename color_type::value_type value_type; 82 typedef typename color_type::calc_type calc_type; 83 enum base_scale_e { base_shift = color_type::base_shift }; 84 85 //-------------------------------------------------------------------- 86 static AGG_INLINE void blend_pix(value_type* p, 87 unsigned cr, unsigned cg, unsigned cb, 88 unsigned alpha, 89 unsigned cover=0) 90 { 91 p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >> base_shift); 92 p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha) >> base_shift); 93 p[Order::B] += (value_type)(((cb - p[Order::B]) * alpha) >> base_shift); 94 } 95 }; 96 97 98 //======================================================blender_rgb_pre 99 template<class ColorT, class Order> struct blender_rgb_pre 100 { 101 typedef ColorT color_type; 102 typedef Order order_type; 103 typedef typename color_type::value_type value_type; 104 typedef typename color_type::calc_type calc_type; 105 enum base_scale_e { base_shift = color_type::base_shift }; 106 107 //-------------------------------------------------------------------- 108 static AGG_INLINE void blend_pix(value_type* p, 109 unsigned cr, unsigned cg, unsigned cb, 110 unsigned alpha, 111 unsigned cover) 112 { 113 alpha = color_type::base_mask - alpha; 114 cover = (cover + 1) << (base_shift - 8); 115 p[Order::R] = (value_type)((p[Order::R] * alpha + cr * cover) >> base_shift); 116 p[Order::G] = (value_type)((p[Order::G] * alpha + cg * cover) >> base_shift); 117 p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift); 118 } 119 120 //-------------------------------------------------------------------- 121 static AGG_INLINE void blend_pix(value_type* p, 122 unsigned cr, unsigned cg, unsigned cb, 123 unsigned alpha) 124 { 125 alpha = color_type::base_mask - alpha; 126 p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr); 127 p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg); 128 p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb); 129 } 130 131 }; 132 133 134 135 //===================================================blender_rgb_gamma 136 template<class ColorT, class Order, class Gamma> class blender_rgb_gamma 137 { 138 public: 139 typedef ColorT color_type; 140 typedef Order order_type; 141 typedef Gamma gamma_type; 142 typedef typename color_type::value_type value_type; 143 typedef typename color_type::calc_type calc_type; 144 enum base_scale_e { base_shift = color_type::base_shift }; 145 146 //-------------------------------------------------------------------- 147 blender_rgb_gamma() : m_gamma(0) {} 148 void gamma(const gamma_type& g) { m_gamma = &g; } 149 150 //-------------------------------------------------------------------- 151 AGG_INLINE void blend_pix(value_type* p, 152 unsigned cr, unsigned cg, unsigned cb, 153 unsigned alpha, 154 unsigned cover=0) 155 { 156 calc_type r = m_gamma->dir(p[Order::R]); 157 calc_type g = m_gamma->dir(p[Order::G]); 158 calc_type b = m_gamma->dir(p[Order::B]); 159 p[Order::R] = m_gamma->inv((((m_gamma->dir(cr) - r) * alpha) >> base_shift) + r); 160 p[Order::G] = m_gamma->inv((((m_gamma->dir(cg) - g) * alpha) >> base_shift) + g); 161 p[Order::B] = m_gamma->inv((((m_gamma->dir(cb) - b) * alpha) >> base_shift) + b); 162 } 163 164 private: 165 const gamma_type* m_gamma; 166 }; 167 168 169 170 171 //==================================================pixfmt_alpha_blend_rgb 172 template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb 173 { 174 public: 175 typedef RenBuf rbuf_type; 176 typedef Blender blender_type; 177 typedef typename rbuf_type::row_data row_data; 178 typedef typename blender_type::color_type color_type; 179 typedef typename blender_type::order_type order_type; 180 typedef typename color_type::value_type value_type; 181 typedef typename color_type::calc_type calc_type; 182 enum base_scale_e 183 { 184 base_shift = color_type::base_shift, 185 base_scale = color_type::base_scale, 186 base_mask = color_type::base_mask, 187 pix_width = sizeof(value_type) * 3 188 }; 189 190 private: 191 //-------------------------------------------------------------------- 192 AGG_INLINE void copy_or_blend_pix(value_type* p, 193 const color_type& c, 194 unsigned cover) 195 { 196 if (c.a) 197 { 198 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; 199 if(alpha == base_mask) 200 { 201 p[order_type::R] = c.r; 202 p[order_type::G] = c.g; 203 p[order_type::B] = c.b; 204 } 205 else 206 { 207 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); 208 } 209 } 210 } 211 212 //-------------------------------------------------------------------- 213 AGG_INLINE void copy_or_blend_pix(value_type* p, 214 const color_type& c) 215 { 216 if (c.a) 217 { 218 if(c.a == base_mask) 219 { 220 p[order_type::R] = c.r; 221 p[order_type::G] = c.g; 222 p[order_type::B] = c.b; 223 } 224 else 225 { 226 m_blender.blend_pix(p, c.r, c.g, c.b, c.a); 227 } 228 } 229 } 230 231 232 public: 233 //-------------------------------------------------------------------- 234 pixfmt_alpha_blend_rgb(rbuf_type& rb) : 235 m_rbuf(&rb) 236 {} 237 void attach(rbuf_type& rb) { m_rbuf = &rb; } 238 239 //-------------------------------------------------------------------- 240 template<class PixFmt> 241 bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) 242 { 243 rect_i r(x1, y1, x2, y2); 244 if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) 245 { 246 int stride = pixf.stride(); 247 m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), 248 (r.x2 - r.x1) + 1, 249 (r.y2 - r.y1) + 1, 250 stride); 251 return true; 252 } 253 return false; 254 } 255 256 //-------------------------------------------------------------------- 257 Blender& blender() { return m_blender; } 258 259 //-------------------------------------------------------------------- 260 AGG_INLINE unsigned width() const { return m_rbuf->width(); } 261 AGG_INLINE unsigned height() const { return m_rbuf->height(); } 262 AGG_INLINE int stride() const { return m_rbuf->stride(); } 263 264 //-------------------------------------------------------------------- 265 AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } 266 AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } 267 AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } 268 269 //-------------------------------------------------------------------- 270 AGG_INLINE int8u* pix_ptr(int x, int y) 271 { 272 return m_rbuf->row_ptr(y) + x * pix_width; 273 } 274 275 AGG_INLINE const int8u* pix_ptr(int x, int y) const 276 { 277 return m_rbuf->row_ptr(y) + x * pix_width; 278 } 279 280 //-------------------------------------------------------------------- 281 AGG_INLINE static void make_pix(int8u* p, const color_type& c) 282 { 283 ((value_type*)p)[order_type::R] = c.r; 284 ((value_type*)p)[order_type::G] = c.g; 285 ((value_type*)p)[order_type::B] = c.b; 286 } 287 288 //-------------------------------------------------------------------- 289 AGG_INLINE color_type pixel(int x, int y) const 290 { 291 value_type* p = (value_type*)m_rbuf->row_ptr(y) + x + x + x; 292 return color_type(p[order_type::R], 293 p[order_type::G], 294 p[order_type::B]); 295 } 296 297 //-------------------------------------------------------------------- 298 AGG_INLINE void copy_pixel(int x, int y, const color_type& c) 299 { 300 value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x; 301 p[order_type::R] = c.r; 302 p[order_type::G] = c.g; 303 p[order_type::B] = c.b; 304 } 305 306 //-------------------------------------------------------------------- 307 AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) 308 { 309 copy_or_blend_pix((value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x, c, cover); 310 } 311 312 313 //-------------------------------------------------------------------- 314 AGG_INLINE void copy_hline(int x, int y, 315 unsigned len, 316 const color_type& c) 317 { 318 value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + x + x + x; 319 do 320 { 321 p[order_type::R] = c.r; 322 p[order_type::G] = c.g; 323 p[order_type::B] = c.b; 324 p += 3; 325 } 326 while(--len); 327 } 328 329 330 //-------------------------------------------------------------------- 331 AGG_INLINE void copy_vline(int x, int y, 332 unsigned len, 333 const color_type& c) 334 { 335 do 336 { 337 value_type* p = (value_type*) 338 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 339 p[order_type::R] = c.r; 340 p[order_type::G] = c.g; 341 p[order_type::B] = c.b; 342 } 343 while(--len); 344 } 345 346 347 //-------------------------------------------------------------------- 348 void blend_hline(int x, int y, 349 unsigned len, 350 const color_type& c, 351 int8u cover) 352 { 353 if (c.a) 354 { 355 value_type* p = (value_type*) 356 m_rbuf->row_ptr(x, y, len) + x + x + x; 357 358 calc_type alpha = (calc_type(c.a) * (calc_type(cover) + 1)) >> 8; 359 if(alpha == base_mask) 360 { 361 do 362 { 363 p[order_type::R] = c.r; 364 p[order_type::G] = c.g; 365 p[order_type::B] = c.b; 366 p += 3; 367 } 368 while(--len); 369 } 370 else 371 { 372 do 373 { 374 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); 375 p += 3; 376 } 377 while(--len); 378 } 379 } 380 } 381 382 383 //-------------------------------------------------------------------- 384 void blend_vline(int x, int y, 385 unsigned len, 386 const color_type& c, 387 int8u cover) 388 { 389 if (c.a) 390 { 391 value_type* p; 392 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; 393 if(alpha == base_mask) 394 { 395 do 396 { 397 p = (value_type*) 398 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 399 400 p[order_type::R] = c.r; 401 p[order_type::G] = c.g; 402 p[order_type::B] = c.b; 403 } 404 while(--len); 405 } 406 else 407 { 408 do 409 { 410 p = (value_type*) 411 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 412 413 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); 414 } 415 while(--len); 416 } 417 } 418 } 419 420 421 //-------------------------------------------------------------------- 422 void blend_solid_hspan(int x, int y, 423 unsigned len, 424 const color_type& c, 425 const int8u* covers) 426 { 427 if (c.a) 428 { 429 value_type* p = (value_type*) 430 m_rbuf->row_ptr(x, y, len) + x + x + x; 431 432 do 433 { 434 calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8; 435 if(alpha == base_mask) 436 { 437 p[order_type::R] = c.r; 438 p[order_type::G] = c.g; 439 p[order_type::B] = c.b; 440 } 441 else 442 { 443 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers); 444 } 445 p += 3; 446 ++covers; 447 } 448 while(--len); 449 } 450 } 451 452 453 //-------------------------------------------------------------------- 454 void blend_solid_vspan(int x, int y, 455 unsigned len, 456 const color_type& c, 457 const int8u* covers) 458 { 459 if (c.a) 460 { 461 do 462 { 463 value_type* p = (value_type*) 464 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 465 466 calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8; 467 if(alpha == base_mask) 468 { 469 p[order_type::R] = c.r; 470 p[order_type::G] = c.g; 471 p[order_type::B] = c.b; 472 } 473 else 474 { 475 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers); 476 } 477 ++covers; 478 } 479 while(--len); 480 } 481 } 482 483 484 //-------------------------------------------------------------------- 485 void copy_color_hspan(int x, int y, 486 unsigned len, 487 const color_type* colors) 488 { 489 value_type* p = (value_type*) 490 m_rbuf->row_ptr(x, y, len) + x + x + x; 491 492 do 493 { 494 p[order_type::R] = colors->r; 495 p[order_type::G] = colors->g; 496 p[order_type::B] = colors->b; 497 ++colors; 498 p += 3; 499 } 500 while(--len); 501 } 502 503 504 //-------------------------------------------------------------------- 505 void copy_color_vspan(int x, int y, 506 unsigned len, 507 const color_type* colors) 508 { 509 do 510 { 511 value_type* p = (value_type*) 512 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 513 p[order_type::R] = colors->r; 514 p[order_type::G] = colors->g; 515 p[order_type::B] = colors->b; 516 ++colors; 517 } 518 while(--len); 519 } 520 521 522 //-------------------------------------------------------------------- 523 void blend_color_hspan(int x, int y, 524 unsigned len, 525 const color_type* colors, 526 const int8u* covers, 527 int8u cover) 528 { 529 value_type* p = (value_type*) 530 m_rbuf->row_ptr(x, y, len) + x + x + x; 531 532 if(covers) 533 { 534 do 535 { 536 copy_or_blend_pix(p, *colors++, *covers++); 537 p += 3; 538 } 539 while(--len); 540 } 541 else 542 { 543 if(cover == 255) 544 { 545 do 546 { 547 copy_or_blend_pix(p, *colors++); 548 p += 3; 549 } 550 while(--len); 551 } 552 else 553 { 554 do 555 { 556 copy_or_blend_pix(p, *colors++, cover); 557 p += 3; 558 } 559 while(--len); 560 } 561 } 562 } 563 564 565 566 //-------------------------------------------------------------------- 567 void blend_color_vspan(int x, int y, 568 unsigned len, 569 const color_type* colors, 570 const int8u* covers, 571 int8u cover) 572 { 573 value_type* p; 574 if(covers) 575 { 576 do 577 { 578 p = (value_type*) 579 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 580 581 copy_or_blend_pix(p, *colors++, *covers++); 582 } 583 while(--len); 584 } 585 else 586 { 587 if(cover == 255) 588 { 589 do 590 { 591 p = (value_type*) 592 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 593 594 copy_or_blend_pix(p, *colors++); 595 } 596 while(--len); 597 } 598 else 599 { 600 do 601 { 602 p = (value_type*) 603 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 604 605 copy_or_blend_pix(p, *colors++, cover); 606 } 607 while(--len); 608 } 609 } 610 } 611 612 //-------------------------------------------------------------------- 613 template<class Function> void for_each_pixel(Function f) 614 { 615 unsigned y; 616 for(y = 0; y < height(); ++y) 617 { 618 row_data r = m_rbuf->row(y); 619 if(r.ptr) 620 { 621 unsigned len = r.x2 - r.x1 + 1; 622 value_type* p = (value_type*) 623 m_rbuf->row_ptr(r.x1, y, len) + r.x1 * 3; 624 do 625 { 626 f(p); 627 p += 3; 628 } 629 while(--len); 630 } 631 } 632 } 633 634 //-------------------------------------------------------------------- 635 template<class GammaLut> void apply_gamma_dir(const GammaLut& g) 636 { 637 for_each_pixel(apply_gamma_dir_rgb<color_type, order_type, GammaLut>(g)); 638 } 639 640 //-------------------------------------------------------------------- 641 template<class GammaLut> void apply_gamma_inv(const GammaLut& g) 642 { 643 for_each_pixel(apply_gamma_inv_rgb<color_type, order_type, GammaLut>(g)); 644 } 645 646 //-------------------------------------------------------------------- 647 template<class RenBuf2> 648 void copy_from(const RenBuf2& from, 649 int xdst, int ydst, 650 int xsrc, int ysrc, 651 unsigned len) 652 { 653 const int8u* p = from.row_ptr(ysrc); 654 if(p) 655 { 656 memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, 657 p + xsrc * pix_width, 658 len * pix_width); 659 } 660 } 661 662 663 //-------------------------------------------------------------------- 664 template<class SrcPixelFormatRenderer> 665 void blend_from(const SrcPixelFormatRenderer& from, 666 int xdst, int ydst, 667 int xsrc, int ysrc, 668 unsigned len, 669 int8u cover) 670 { 671 typedef typename SrcPixelFormatRenderer::order_type src_order; 672 673 const value_type* psrc = (const value_type*)from.row_ptr(ysrc); 674 if(psrc) 675 { 676 psrc += xsrc * 4; 677 value_type* pdst = 678 (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3; 679 680 if(cover == 255) 681 { 682 do 683 { 684 value_type alpha = psrc[src_order::A]; 685 if(alpha) 686 { 687 if(alpha == base_mask) 688 { 689 pdst[order_type::R] = psrc[src_order::R]; 690 pdst[order_type::G] = psrc[src_order::G]; 691 pdst[order_type::B] = psrc[src_order::B]; 692 } 693 else 694 { 695 m_blender.blend_pix(pdst, 696 psrc[src_order::R], 697 psrc[src_order::G], 698 psrc[src_order::B], 699 alpha); 700 } 701 } 702 psrc += 4; 703 pdst += 3; 704 } 705 while(--len); 706 } 707 else 708 { 709 color_type color; 710 do 711 { 712 color.r = psrc[src_order::R]; 713 color.g = psrc[src_order::G]; 714 color.b = psrc[src_order::B]; 715 color.a = psrc[src_order::A]; 716 copy_or_blend_pix(pdst, color, cover); 717 psrc += 4; 718 pdst += 3; 719 } 720 while(--len); 721 } 722 } 723 } 724 725 private: 726 rbuf_type* m_rbuf; 727 Blender m_blender; 728 }; 729 730 typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8, order_rgb>, rendering_buffer> pixfmt_rgb24; //----pixfmt_rgb24 731 typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8, order_bgr>, rendering_buffer> pixfmt_bgr24; //----pixfmt_bgr24 732 typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48; //----pixfmt_rgb48 733 typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48; //----pixfmt_bgr48 734 735 typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8, order_rgb>, rendering_buffer> pixfmt_rgb24_pre; //----pixfmt_rgb24_pre 736 typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8, order_bgr>, rendering_buffer> pixfmt_bgr24_pre; //----pixfmt_bgr24_pre 737 typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48_pre; //----pixfmt_rgb48_pre 738 typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48_pre; //----pixfmt_bgr48_pre 739 740 //-----------------------------------------------------pixfmt_rgb24_gamma 741 template<class Gamma> class pixfmt_rgb24_gamma : 742 public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer> 743 { 744 public: 745 pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) : 746 pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer>(rb) 747 { 748 this->blender().gamma(g); 749 } 750 }; 751 752 //-----------------------------------------------------pixfmt_bgr24_gamma 753 template<class Gamma> class pixfmt_bgr24_gamma : 754 public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer> 755 { 756 public: 757 pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) : 758 pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer>(rb) 759 { 760 this->blender().gamma(g); 761 } 762 }; 763 764 //-----------------------------------------------------pixfmt_rgb48_gamma 765 template<class Gamma> class pixfmt_rgb48_gamma : 766 public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer> 767 { 768 public: 769 pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) : 770 pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer>(rb) 771 { 772 this->blender().gamma(g); 773 } 774 }; 775 776 //-----------------------------------------------------pixfmt_bgr48_gamma 777 template<class Gamma> class pixfmt_bgr48_gamma : 778 public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer> 779 { 780 public: 781 pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) : 782 pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer>(rb) 783 { 784 this->blender().gamma(g); 785 } 786 }; 787 788 789 } 790 791 #endif 792 793