summaryrefslogtreecommitdiff
path: root/agg/inc/agg_color_rgba.h
diff options
context:
space:
mode:
Diffstat (limited to 'agg/inc/agg_color_rgba.h')
-rwxr-xr-xagg/inc/agg_color_rgba.h618
1 files changed, 618 insertions, 0 deletions
diff --git a/agg/inc/agg_color_rgba.h b/agg/inc/agg_color_rgba.h
new file mode 100755
index 000000000000..e1f77206cc66
--- /dev/null
+++ b/agg/inc/agg_color_rgba.h
@@ -0,0 +1,618 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.3
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+//
+// Adaptation for high precision colors has been sponsored by
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
+//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+
+#ifndef AGG_COLOR_RGBA_INCLUDED
+#define AGG_COLOR_RGBA_INCLUDED
+
+#include <math.h>
+#include "agg_basics.h"
+
+namespace agg
+{
+ // Supported byte orders for RGB and RGBA pixel formats
+ //=======================================================================
+ struct order_rgb { enum { R=0, G=1, B=2, rgb_tag }; }; //----order_rgb
+ struct order_bgr { enum { B=0, G=1, R=2, rgb_tag }; }; //----order_bgr
+ struct order_rgba { enum { R=0, G=1, B=2, A=3, rgba_tag }; }; //----order_rgba
+ struct order_argb { enum { A=0, R=1, G=2, B=3, rgba_tag }; }; //----order_argb
+ struct order_abgr { enum { A=0, B=1, G=2, R=3, rgba_tag }; }; //----order_abgr
+ struct order_bgra { enum { B=0, G=1, R=2, A=3, rgba_tag }; }; //----order_bgra
+
+ //====================================================================rgba
+ struct rgba
+ {
+ typedef double value_type;
+
+ double r;
+ double g;
+ double b;
+ double a;
+
+ //--------------------------------------------------------------------
+ rgba() {}
+
+ //--------------------------------------------------------------------
+ rgba(double r_, double g_, double b_, double a_=1.0) :
+ r(r_), g(g_), b(b_), a(a_) {}
+
+ //--------------------------------------------------------------------
+ rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {}
+
+ //--------------------------------------------------------------------
+ void clear()
+ {
+ r = g = b = a = 0;
+ }
+
+ //--------------------------------------------------------------------
+ const rgba& transparent()
+ {
+ a = 0.0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ const rgba& opacity(double a_)
+ {
+ if(a_ < 0.0) a_ = 0.0;
+ if(a_ > 1.0) a_ = 1.0;
+ a = a_;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ double opacity() const
+ {
+ return a;
+ }
+
+ //--------------------------------------------------------------------
+ const rgba& premultiply()
+ {
+ r *= a;
+ g *= a;
+ b *= a;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ const rgba& premultiply(double a_)
+ {
+ if(a <= 0.0 || a_ <= 0.0)
+ {
+ r = g = b = a = 0.0;
+ return *this;
+ }
+ a_ /= a;
+ r *= a_;
+ g *= a_;
+ b *= a_;
+ a = a_;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ const rgba& demultiply()
+ {
+ if(a == 0)
+ {
+ r = g = b = 0;
+ return *this;
+ }
+ double a_ = 1.0 / a;
+ r *= a_;
+ g *= a_;
+ b *= a_;
+ return *this;
+ }
+
+
+ //--------------------------------------------------------------------
+ rgba gradient(rgba c, double k) const
+ {
+ rgba ret;
+ ret.r = r + (c.r - r) * k;
+ ret.g = g + (c.g - g) * k;
+ ret.b = b + (c.b - b) * k;
+ ret.a = a + (c.a - a) * k;
+ return ret;
+ }
+
+ //--------------------------------------------------------------------
+ static rgba no_color() { return rgba(0,0,0,0); }
+
+ //--------------------------------------------------------------------
+ static rgba from_wavelength(double wl, double gamma = 1.0);
+
+ //--------------------------------------------------------------------
+ rgba(double wavelen, double gamma=1.0)
+ {
+ *this = from_wavelength(wavelen, gamma);
+ }
+
+ };
+
+ //----------------------------------------------------------------rgba_pre
+ inline rgba rgba_pre(double r, double g, double b, double a=1.0)
+ {
+ return rgba(r, g, b, a).premultiply();
+ }
+ inline rgba rgba_pre(const rgba& c)
+ {
+ return rgba(c).premultiply();
+ }
+ inline rgba rgba_pre(const rgba& c, double a)
+ {
+ return rgba(c, a).premultiply();
+ }
+
+ //------------------------------------------------------------------------
+ inline rgba rgba::from_wavelength(double wl, double gamma)
+ {
+ rgba t(0.0, 0.0, 0.0);
+
+ if(wl >= 380.0 && wl <= 440.0)
+ {
+ t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0);
+ t.b = 1.0;
+ }
+ else
+ if(wl >= 440.0 && wl <= 490.0)
+ {
+ t.g = (wl - 440.0) / (490.0 - 440.0);
+ t.b = 1.0;
+ }
+ else
+ if(wl >= 490.0 && wl <= 510.0)
+ {
+ t.g = 1.0;
+ t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0);
+ }
+ else
+ if(wl >= 510.0 && wl <= 580.0)
+ {
+ t.r = (wl - 510.0) / (580.0 - 510.0);
+ t.g = 1.0;
+ }
+ else
+ if(wl >= 580.0 && wl <= 645.0)
+ {
+ t.r = 1.0;
+ t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0);
+ }
+ else
+ if(wl >= 645.0 && wl <= 780.0)
+ {
+ t.r = 1.0;
+ }
+
+ double s = 1.0;
+ if(wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0);
+ else if(wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0);
+
+ t.r = pow(t.r * s, gamma);
+ t.g = pow(t.g * s, gamma);
+ t.b = pow(t.b * s, gamma);
+ return t;
+ }
+
+
+
+
+ //===================================================================rgba8
+ struct rgba8
+ {
+ typedef int8u value_type;
+ typedef int32u calc_type;
+ typedef int32 long_type;
+ enum
+ {
+ base_shift = 8,
+ base_size = 1 << base_shift,
+ base_mask = base_size - 1
+ };
+ typedef rgba8 self_type;
+
+
+ value_type r;
+ value_type g;
+ value_type b;
+ value_type a;
+
+ //--------------------------------------------------------------------
+ rgba8() {}
+
+ //--------------------------------------------------------------------
+ rgba8(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) :
+ r(value_type(r_)),
+ g(value_type(g_)),
+ b(value_type(b_)),
+ a(value_type(a_)) {}
+
+ //--------------------------------------------------------------------
+ rgba8(const rgba& c, double a_) :
+ r(value_type(c.r * double(base_mask) + 0.5)),
+ g(value_type(c.g * double(base_mask) + 0.5)),
+ b(value_type(c.b * double(base_mask) + 0.5)),
+ a(value_type(a_ * double(base_mask) + 0.5)) {}
+
+ //--------------------------------------------------------------------
+ rgba8(const self_type& c, unsigned a_) :
+ r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
+
+ //--------------------------------------------------------------------
+ rgba8(const rgba& c) :
+ r(value_type(c.r * double(base_mask) + 0.5)),
+ g(value_type(c.g * double(base_mask) + 0.5)),
+ b(value_type(c.b * double(base_mask) + 0.5)),
+ a(value_type(c.a * double(base_mask) + 0.5)) {}
+
+ //--------------------------------------------------------------------
+ void clear()
+ {
+ r = g = b = a = 0;
+ }
+
+ //--------------------------------------------------------------------
+ const self_type& transparent()
+ {
+ a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ const self_type& opacity(double a_)
+ {
+ if(a_ < 0.0) a_ = 0.0;
+ if(a_ > 1.0) a_ = 1.0;
+ a = value_type(a_ * double(base_mask) + 0.5);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ double opacity() const
+ {
+ return double(a) / double(base_mask);
+ }
+
+ //--------------------------------------------------------------------
+ const self_type& premultiply()
+ {
+ if(a == base_mask) return *this;
+ if(a == 0)
+ {
+ r = g = b = 0;
+ return *this;
+ }
+ r = value_type((calc_type(r) * a) >> base_shift);
+ g = value_type((calc_type(g) * a) >> base_shift);
+ b = value_type((calc_type(b) * a) >> base_shift);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ const self_type& premultiply(unsigned a_)
+ {
+ if(a == base_mask && a_ >= base_mask) return *this;
+ if(a == 0 || a_ == 0)
+ {
+ r = g = b = a = 0;
+ return *this;
+ }
+ calc_type r_ = (calc_type(r) * a_) / a;
+ calc_type g_ = (calc_type(g) * a_) / a;
+ calc_type b_ = (calc_type(b) * a_) / a;
+ r = value_type((r_ > a_) ? a_ : r_);
+ g = value_type((g_ > a_) ? a_ : g_);
+ b = value_type((b_ > a_) ? a_ : b_);
+ a = value_type(a_);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ const self_type& demultiply()
+ {
+ if(a == base_mask) return *this;
+ if(a == 0)
+ {
+ r = g = b = 0;
+ return *this;
+ }
+ calc_type r_ = (calc_type(r) * base_mask) / a;
+ calc_type g_ = (calc_type(g) * base_mask) / a;
+ calc_type b_ = (calc_type(b) * base_mask) / a;
+ r = value_type((r_ > base_mask) ? base_mask : r_);
+ g = value_type((g_ > base_mask) ? base_mask : g_);
+ b = value_type((b_ > base_mask) ? base_mask : b_);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type gradient(const self_type& c, double k) const
+ {
+ self_type ret;
+ calc_type ik = calc_type(k * base_size);
+ ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift));
+ ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift));
+ ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift));
+ ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
+ return ret;
+ }
+
+ //--------------------------------------------------------------------
+ static self_type no_color() { return self_type(0,0,0,0); }
+
+ //--------------------------------------------------------------------
+ static self_type from_wavelength(double wl, double gamma = 1.0)
+ {
+ return self_type(rgba::from_wavelength(wl, gamma));
+ }
+ };
+
+
+ //-------------------------------------------------------------rgba8_pre
+ inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b,
+ unsigned a = rgba8::base_mask)
+ {
+ return rgba8(r,g,b,a).premultiply();
+ }
+ inline rgba8 rgba8_pre(const rgba8& c)
+ {
+ return rgba8(c).premultiply();
+ }
+ inline rgba8 rgba8_pre(const rgba8& c, unsigned a)
+ {
+ return rgba8(c,a).premultiply();
+ }
+ inline rgba8 rgba8_pre(const rgba& c)
+ {
+ return rgba8(c).premultiply();
+ }
+ inline rgba8 rgba8_pre(const rgba& c, double a)
+ {
+ return rgba8(c,a).premultiply();
+ }
+
+
+ //-----------------------------------------------------------rgb8_packed
+ inline rgba8 rgb8_packed(unsigned v)
+ {
+ return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF);
+ }
+
+ //-----------------------------------------------------------bgr8_packed
+ inline rgba8 bgr8_packed(unsigned v)
+ {
+ return rgba8(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF);
+ }
+
+ //----------------------------------------------------------argb8_packed
+ inline rgba8 argb8_packed(unsigned v)
+ {
+ return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF, v >> 24);
+ }
+
+
+
+
+
+
+
+
+ //=================================================================rgba16
+ struct rgba16
+ {
+ typedef int16u value_type;
+ typedef int32u calc_type;
+ typedef int64 long_type;
+ enum
+ {
+ base_shift = 16,
+ base_size = 1 << base_shift,
+ base_mask = base_size - 1
+ };
+ typedef rgba16 self_type;
+
+ value_type r;
+ value_type g;
+ value_type b;
+ value_type a;
+
+ //--------------------------------------------------------------------
+ rgba16() {}
+
+ //--------------------------------------------------------------------
+ rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) :
+ r(value_type(r_)),
+ g(value_type(g_)),
+ b(value_type(b_)),
+ a(value_type(a_)) {}
+
+ //--------------------------------------------------------------------
+ rgba16(const self_type& c, unsigned a_) :
+ r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
+
+ //--------------------------------------------------------------------
+ rgba16(const rgba& c) :
+ r(value_type(c.r * double(base_mask) + 0.5)),
+ g(value_type(c.g * double(base_mask) + 0.5)),
+ b(value_type(c.b * double(base_mask) + 0.5)),
+ a(value_type(c.a * double(base_mask) + 0.5)) {}
+
+ //--------------------------------------------------------------------
+ rgba16(const rgba& c, double a_) :
+ r(value_type(c.r * double(base_mask) + 0.5)),
+ g(value_type(c.g * double(base_mask) + 0.5)),
+ b(value_type(c.b * double(base_mask) + 0.5)),
+ a(value_type(a_ * double(base_mask) + 0.5)) {}
+
+ //--------------------------------------------------------------------
+ rgba16(const rgba8& c) :
+ r(value_type((value_type(c.r) << 8) | c.r)),
+ g(value_type((value_type(c.g) << 8) | c.g)),
+ b(value_type((value_type(c.b) << 8) | c.b)),
+ a(value_type((value_type(c.a) << 8) | c.a)) {}
+
+ //--------------------------------------------------------------------
+ rgba16(const rgba8& c, unsigned a_) :
+ r(value_type((value_type(c.r) << 8) | c.r)),
+ g(value_type((value_type(c.g) << 8) | c.g)),
+ b(value_type((value_type(c.b) << 8) | c.b)),
+ a(value_type(( a_ << 8) | c.a)) {}
+
+ //--------------------------------------------------------------------
+ void clear()
+ {
+ r = g = b = a = 0;
+ }
+
+ //--------------------------------------------------------------------
+ const self_type& transparent()
+ {
+ a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ const self_type& opacity(double a_)
+ {
+ if(a_ < 0.0) a_ = 0.0;
+ if(a_ > 1.0) a_ = 1.0;
+ a = value_type(a_ * double(base_mask) + 0.5);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ double opacity() const
+ {
+ return double(a) / double(base_mask);
+ }
+
+ //--------------------------------------------------------------------
+ const self_type& premultiply()
+ {
+ if(a == base_mask) return *this;
+ if(a == 0)
+ {
+ r = g = b = 0;
+ return *this;
+ }
+ r = value_type((calc_type(r) * a) >> base_shift);
+ g = value_type((calc_type(g) * a) >> base_shift);
+ b = value_type((calc_type(b) * a) >> base_shift);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ const self_type& premultiply(unsigned a_)
+ {
+ if(a == base_mask && a_ >= base_mask) return *this;
+ if(a == 0 || a_ == 0)
+ {
+ r = g = b = a = 0;
+ return *this;
+ }
+ calc_type r_ = (calc_type(r) * a_) / a;
+ calc_type g_ = (calc_type(g) * a_) / a;
+ calc_type b_ = (calc_type(b) * a_) / a;
+ r = value_type((r_ > a_) ? a_ : r_);
+ g = value_type((g_ > a_) ? a_ : g_);
+ b = value_type((b_ > a_) ? a_ : b_);
+ a = value_type(a_);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ const self_type& demultiply()
+ {
+ if(a == base_mask) return *this;
+ if(a == 0)
+ {
+ r = g = b = 0;
+ return *this;
+ }
+ calc_type r_ = (calc_type(r) * base_mask) / a;
+ calc_type g_ = (calc_type(g) * base_mask) / a;
+ calc_type b_ = (calc_type(b) * base_mask) / a;
+ r = value_type((r_ > base_mask) ? base_mask : r_);
+ g = value_type((g_ > base_mask) ? base_mask : g_);
+ b = value_type((b_ > base_mask) ? base_mask : b_);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type gradient(const self_type& c, double k) const
+ {
+ self_type ret;
+ calc_type ik = calc_type(k * base_size);
+ ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift));
+ ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift));
+ ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift));
+ ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
+ return ret;
+ }
+
+ //--------------------------------------------------------------------
+ static self_type no_color() { return self_type(0,0,0,0); }
+
+ //--------------------------------------------------------------------
+ static self_type from_wavelength(double wl, double gamma = 1.0)
+ {
+ return self_type(rgba::from_wavelength(wl, gamma));
+ }
+ };
+
+
+
+ //--------------------------------------------------------------rgba16_pre
+ inline rgba16 rgba16_pre(unsigned r, unsigned g, unsigned b,
+ unsigned a = rgba16::base_mask)
+ {
+ return rgba16(r,g,b,a).premultiply();
+ }
+ inline rgba16 rgba16_pre(const rgba16& c, unsigned a)
+ {
+ return rgba16(c,a).premultiply();
+ }
+ inline rgba16 rgba16_pre(const rgba& c)
+ {
+ return rgba16(c).premultiply();
+ }
+ inline rgba16 rgba16_pre(const rgba& c, double a)
+ {
+ return rgba16(c,a).premultiply();
+ }
+ inline rgba16 rgba16_pre(const rgba8& c)
+ {
+ return rgba16(c).premultiply();
+ }
+ inline rgba16 rgba16_pre(const rgba8& c, unsigned a)
+ {
+ return rgba16(c,a).premultiply();
+ }
+
+}
+
+
+
+#endif