28 #ifndef AGG_COLOR_GRAY_INCLUDED 29 #define AGG_COLOR_GRAY_INCLUDED 31 #include "agg_basics.h" 32 #include "agg_color_rgba.h" 38 template<
class Colorspace>
41 typedef int8u value_type;
42 typedef int32u calc_type;
43 typedef int32 long_type;
47 base_scale = 1 << base_shift,
48 base_mask = base_scale - 1,
49 base_MSB = 1 << (base_shift - 1)
56 static value_type luminance(
const rgba& c)
59 return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask));
62 static value_type luminance(
const rgba8& c)
65 return value_type((55u * c.r + 184u * c.g + 18u * c.b) >> 8);
82 dst.v = luminance(src);
89 convert(dst,
rgba8(src));
101 convert(dst,
rgba8(src));
108 explicit gray8T(
unsigned v_,
unsigned a_ = base_mask) :
109 v(int8u(v_)), a(int8u(a_)) {}
112 gray8T(
const self_type& c,
unsigned a_) :
113 v(c.v), a(value_type(a_)) {}
118 a(value_type(uround(c.a * base_mask))) {}
136 T convert_from_sRGB()
const 143 T convert_to_sRGB()
const 152 return rgba8(v, v, v, a);
157 return convert_from_sRGB<srgba8>();
160 operator rgba8()
const 162 return make_rgba8(Colorspace());
168 return convert_to_sRGB<rgba8>();
173 return srgba8(v, v, v, a);
178 return make_rgba8(Colorspace());
184 rgba16::value_type rgb = (v << 8) | v;
185 return rgba16(rgb, rgb, rgb, (a << 8) | a);
190 return convert_from_sRGB<rgba16>();
195 return make_rgba16(Colorspace());
201 rgba32::value_type v32 = v / 255.0f;
202 return rgba32(v32, v32, v32, a / 255.0f);
207 return convert_from_sRGB<rgba32>();
212 return make_rgba32(Colorspace());
216 static AGG_INLINE
double to_double(value_type a)
218 return double(a) / base_mask;
222 static AGG_INLINE value_type from_double(
double a)
224 return value_type(uround(a * base_mask));
228 static AGG_INLINE value_type empty_value()
234 static AGG_INLINE value_type full_value()
240 AGG_INLINE
bool is_transparent()
const 246 AGG_INLINE
bool is_opaque()
const 248 return a == base_mask;
253 static AGG_INLINE value_type multiply(value_type a, value_type b)
255 calc_type t = a * b + base_MSB;
256 return value_type(((t >> base_shift) + t) >> base_shift);
260 static AGG_INLINE value_type demultiply(value_type a, value_type b)
270 else return value_type((a * base_mask + (b >> 1)) / b);
275 static AGG_INLINE T downscale(T a)
277 return a >> base_shift;
282 static AGG_INLINE T downshift(T a,
unsigned n)
290 static AGG_INLINE value_type mult_cover(value_type a, value_type b)
292 return multiply(a, b);
296 static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
298 return multiply(b, a);
303 static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
305 return p + q - multiply(p, a);
310 static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
312 int t = (q - p) * a + base_MSB - (p > q);
313 return value_type(p + (((t >> base_shift) + t) >> base_shift));
324 self_type& transparent()
331 self_type& opacity(
double a_)
334 else if (a_ > 1) a = 1;
335 else a = (value_type)uround(a_ *
double(base_mask));
340 double opacity()
const 342 return double(a) / double(base_mask);
346 self_type& premultiply()
351 else v = multiply(v, a);
357 self_type& demultiply()
367 calc_type v_ = (calc_type(v) * base_mask) / a;
368 v = value_type((v_ > base_mask) ? (value_type)base_mask : v_);
375 self_type gradient(self_type c,
double k)
const 378 calc_type ik = uround(k * base_scale);
379 ret.v = lerp(v, c.v, ik);
380 ret.a = lerp(a, c.a, ik);
385 AGG_INLINE
void add(
const self_type& c,
unsigned cover)
388 if (cover == cover_mask)
390 if (c.a == base_mask)
403 cv = v + mult_cover(c.v, cover);
404 ca = a + mult_cover(c.a, cover);
406 v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv);
407 a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
411 static self_type no_color() {
return self_type(0,0); }
421 typedef int16u value_type;
422 typedef int32u calc_type;
423 typedef int64 long_type;
427 base_scale = 1 << base_shift,
428 base_mask = base_scale - 1,
429 base_MSB = 1 << (base_shift - 1)
436 static value_type luminance(
const rgba& c)
439 return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask));
442 static value_type luminance(
const rgba16& c)
445 return value_type((13933u * c.r + 46872u * c.g + 4732u * c.b) >> 16);
448 static value_type luminance(
const rgba8& c)
450 return luminance(
rgba16(c));
453 static value_type luminance(
const srgba8& c)
455 return luminance(
rgba16(c));
458 static value_type luminance(
const rgba32& c)
460 return luminance(
rgba(c));
467 explicit gray16(
unsigned v_,
unsigned a_ = base_mask) :
468 v(int16u(v_)), a(int16u(a_)) {}
471 gray16(
const self_type& c,
unsigned a_) :
472 v(c.v), a(value_type(a_)) {}
477 a((value_type)uround(c.a *
double(base_mask))) {}
482 a((value_type(c.a) << 8) | c.a) {}
487 a((value_type(c.a) << 8) | c.a) {}
496 v((value_type(c.v) << 8) | c.v),
497 a((value_type(c.a) << 8) | c.a) {}
505 operator rgba8()
const 507 return rgba8(v >> 8, v >> 8, v >> 8, a >> 8);
520 return rgba16(v, v, v, a);
526 rgba32::value_type v32 = v / 65535.0f;
527 return rgba32(v32, v32, v32, a / 65535.0f);
531 operator gray8()
const 533 return gray8(v >> 8, a >> 8);
537 operator sgray8()
const 545 static AGG_INLINE
double to_double(value_type a)
547 return double(a) / base_mask;
551 static AGG_INLINE value_type from_double(
double a)
553 return value_type(uround(a * base_mask));
557 static AGG_INLINE value_type empty_value()
563 static AGG_INLINE value_type full_value()
569 AGG_INLINE
bool is_transparent()
const 575 AGG_INLINE
bool is_opaque()
const 577 return a == base_mask;
582 static AGG_INLINE value_type multiply(value_type a, value_type b)
584 calc_type t = a * b + base_MSB;
585 return value_type(((t >> base_shift) + t) >> base_shift);
589 static AGG_INLINE value_type demultiply(value_type a, value_type b)
599 else return value_type((a * base_mask + (b >> 1)) / b);
604 static AGG_INLINE T downscale(T a)
606 return a >> base_shift;
611 static AGG_INLINE T downshift(T a,
unsigned n)
619 static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
621 return multiply(a, b << 8 | b);
625 static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
627 return mult_cover(b, a) >> 8;
632 static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
634 return p + q - multiply(p, a);
639 static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
641 int t = (q - p) * a + base_MSB - (p > q);
642 return value_type(p + (((t >> base_shift) + t) >> base_shift));
653 self_type& transparent()
660 self_type& opacity(
double a_)
663 else if(a_ > 1) a = 1;
664 else a = (value_type)uround(a_ *
double(base_mask));
669 double opacity()
const 671 return double(a) / double(base_mask);
676 self_type& premultiply()
681 else v = multiply(v, a);
687 self_type& demultiply()
697 calc_type v_ = (calc_type(v) * base_mask) / a;
698 v = (v_ > base_mask) ? value_type(base_mask) : value_type(v_);
705 self_type gradient(self_type c,
double k)
const 708 calc_type ik = uround(k * base_scale);
709 ret.v = lerp(v, c.v, ik);
710 ret.a = lerp(a, c.a, ik);
715 AGG_INLINE
void add(
const self_type& c,
unsigned cover)
718 if (cover == cover_mask)
720 if (c.a == base_mask)
733 cv = v + mult_cover(c.v, cover);
734 ca = a + mult_cover(c.a, cover);
736 v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv);
737 a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
741 static self_type no_color() {
return self_type(0,0); }
748 typedef float value_type;
749 typedef double calc_type;
750 typedef double long_type;
757 static value_type luminance(
double r,
double g,
double b)
759 return value_type(0.2126 * r + 0.7152 * g + 0.0722 * b);
762 static value_type luminance(
const rgba& c)
764 return luminance(c.r, c.g, c.b);
767 static value_type luminance(
const rgba32& c)
769 return luminance(c.r, c.g, c.b);
772 static value_type luminance(
const rgba8& c)
774 return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0);
777 static value_type luminance(
const rgba16& c)
779 return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0);
786 explicit gray32(value_type v_, value_type a_ = 1) :
790 gray32(
const self_type& c, value_type a_) :
796 a(value_type(c.a)) {}
801 a(value_type(c.a / 255.0)) {}
806 a(value_type(c.a / 255.0)) {}
811 a(value_type(c.a / 65535.0)) {}
816 a(value_type(c.a)) {}
820 v(value_type(c.v / 255.0)),
821 a(value_type(c.a / 255.0)) {}
830 v(value_type(c.v / 65535.0)),
831 a(value_type(c.a / 65535.0)) {}
834 operator rgba()
const 836 return rgba(v, v, v, a);
840 operator gray8()
const 842 return gray8(uround(v * 255.0), uround(a * 255.0));
846 operator sgray8()
const 857 return gray16(uround(v * 65535.0), uround(a * 65535.0));
861 operator rgba8()
const 863 rgba8::value_type y = uround(v * 255.0);
864 return rgba8(y, y, y, uround(a * 255.0));
877 rgba16::value_type y = uround(v * 65535.0);
878 return rgba16(y, y, y, uround(a * 65535.0));
884 return rgba32(v, v, v, a);
888 static AGG_INLINE
double to_double(value_type a)
894 static AGG_INLINE value_type from_double(
double a)
896 return value_type(a);
900 static AGG_INLINE value_type empty_value()
906 static AGG_INLINE value_type full_value()
912 AGG_INLINE
bool is_transparent()
const 918 AGG_INLINE
bool is_opaque()
const 924 static AGG_INLINE value_type invert(value_type x)
930 static AGG_INLINE value_type multiply(value_type a, value_type b)
932 return value_type(a * b);
936 static AGG_INLINE value_type demultiply(value_type a, value_type b)
938 return (b == 0) ? 0 : value_type(a / b);
943 static AGG_INLINE T downscale(T a)
950 static AGG_INLINE T downshift(T a,
unsigned n)
952 return n > 0 ? a / (1 << n) : a;
956 static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
958 return value_type(a * b / cover_mask);
962 static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
964 return cover_type(uround(a * b));
969 static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
971 return (1 - a) * p + q;
976 static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
982 return (1 - a) * p + a * q;
993 self_type& transparent()
1000 self_type& opacity(
double a_)
1003 else if (a_ > 1) a = 1;
1004 else a = value_type(a_);
1009 double opacity()
const 1016 self_type& premultiply()
1019 else if(a < 1) v *= a;
1024 self_type& demultiply()
1027 else if (a < 1) v /= a;
1032 self_type gradient(self_type c,
double k)
const 1035 value_type(v + (c.v - v) * k),
1036 value_type(a + (c.a - a) * k));
1040 static self_type no_color() {
return self_type(0,0); }