Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_color_gray.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 // Anti-Grain Geometry (AGG) - Version 2.5
00003 // A high quality rendering engine for C++
00004 // Copyright (C) 2002-2006 Maxim Shemanarev
00005 // Contact: mcseem@antigrain.com
00006 //          mcseemagg@yahoo.com
00007 //          http://antigrain.com
00008 // 
00009 // AGG is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 // 
00014 // AGG is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU General Public License
00020 // along with AGG; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00022 // MA 02110-1301, USA.
00023 //----------------------------------------------------------------------------
00024 //
00025 // Adaptation for high precision colors has been sponsored by 
00026 // Liberty Technology Systems, Inc., visit http://lib-sys.com
00027 //
00028 // Liberty Technology Systems, Inc. is the provider of
00029 // PostScript and PDF technology for software developers.
00030 // 
00031 //----------------------------------------------------------------------------
00032 //
00033 // color types gray8, gray16
00034 //
00035 //----------------------------------------------------------------------------
00036 
00037 #ifndef AGG_COLOR_GRAY_INCLUDED
00038 #define AGG_COLOR_GRAY_INCLUDED
00039 
00040 #include "agg_basics.h"
00041 #include "agg_color_rgba.h"
00042 
00043 namespace agg
00044 {
00045 
00046     //===================================================================gray8
00047     struct gray8
00048     {
00049         typedef int8u  value_type;
00050         typedef int32u calc_type;
00051         typedef int32  long_type;
00052         enum base_scale_e
00053         {
00054             base_shift = 8,
00055             base_scale = 1 << base_shift,
00056             base_mask  = base_scale - 1
00057         };
00058         typedef gray8 self_type;
00059 
00060         value_type v;
00061         value_type a;
00062 
00063         //--------------------------------------------------------------------
00064         gray8() {}
00065 
00066         //--------------------------------------------------------------------
00067         gray8(unsigned v_, unsigned a_=base_mask) :
00068             v(int8u(v_)), a(int8u(a_)) {}
00069 
00070         //--------------------------------------------------------------------
00071         gray8(const self_type& c, unsigned a_) :
00072             v(c.v), a(value_type(a_)) {}
00073 
00074         //--------------------------------------------------------------------
00075         gray8(const rgba& c) :
00076             v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
00077             a((value_type)uround(c.a * double(base_mask))) {}
00078 
00079         //--------------------------------------------------------------------
00080         gray8(const rgba& c, double a_) :
00081             v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
00082             a((value_type)uround(a_ * double(base_mask))) {}
00083 
00084         //--------------------------------------------------------------------
00085         gray8(const rgba8& c) :
00086             v((c.r*77 + c.g*150 + c.b*29) >> 8),
00087             a(c.a) {}
00088 
00089         //--------------------------------------------------------------------
00090         gray8(const rgba8& c, unsigned a_) :
00091             v((c.r*77 + c.g*150 + c.b*29) >> 8),
00092             a(a_) {}
00093 
00094         //--------------------------------------------------------------------
00095         void clear()
00096         {
00097             v = a = 0;
00098         }
00099 
00100         //--------------------------------------------------------------------
00101         const self_type& transparent()
00102         {
00103             a = 0;
00104             return *this;
00105         }
00106 
00107         //--------------------------------------------------------------------
00108         void opacity(double a_)
00109         {
00110             if(a_ < 0.0) a_ = 0.0;
00111             if(a_ > 1.0) a_ = 1.0;
00112             a = (value_type)uround(a_ * double(base_mask));
00113         }
00114 
00115         //--------------------------------------------------------------------
00116         double opacity() const
00117         {
00118             return double(a) / double(base_mask);
00119         }
00120 
00121 
00122         //--------------------------------------------------------------------
00123         const self_type& premultiply()
00124         {
00125             if(a == base_mask) return *this;
00126             if(a == 0)
00127             {
00128                 v = 0;
00129                 return *this;
00130             }
00131             v = value_type((calc_type(v) * a) >> base_shift);
00132             return *this;
00133         }
00134 
00135         //--------------------------------------------------------------------
00136         const self_type& premultiply(unsigned a_)
00137         {
00138             if(a == base_mask && a_ >= base_mask) return *this;
00139             if(a == 0 || a_ == 0)
00140             {
00141                 v = a = 0;
00142                 return *this;
00143             }
00144             calc_type v_ = (calc_type(v) * a_) / a;
00145             v = value_type((v_ > a_) ? a_ : v_);
00146             a = value_type(a_);
00147             return *this;
00148         }
00149 
00150         //--------------------------------------------------------------------
00151         const self_type& demultiply()
00152         {
00153             if(a == base_mask) return *this;
00154             if(a == 0)
00155             {
00156                 v = 0;
00157                 return *this;
00158             }
00159             calc_type v_ = (calc_type(v) * base_mask) / a;
00160             v = value_type((v_ > base_mask) ? (value_type)base_mask : v_);
00161             return *this;
00162         }
00163 
00164         //--------------------------------------------------------------------
00165         self_type gradient(self_type c, double k) const
00166         {
00167             self_type ret;
00168             calc_type ik = uround(k * base_scale);
00169             ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift));
00170             ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
00171             return ret;
00172         }
00173 
00174         //--------------------------------------------------------------------
00175         AGG_INLINE void add(const self_type& c, unsigned cover)
00176         {
00177             calc_type cv, ca;
00178             if(cover == cover_mask)
00179             {
00180                 if(c.a == base_mask) 
00181                 {
00182                     *this = c;
00183                 }
00184                 else
00185                 {
00186                     cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
00187                     ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
00188                 }
00189             }
00190             else
00191             {
00192                 cv = v + ((c.v * cover + cover_mask/2) >> cover_shift);
00193                 ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
00194                 v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
00195                 a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
00196             }
00197         }
00198 
00199         //--------------------------------------------------------------------
00200         static self_type no_color() { return self_type(0,0); }
00201     };
00202 
00203 
00204     //-------------------------------------------------------------gray8_pre
00205     inline gray8 gray8_pre(unsigned v, unsigned a = gray8::base_mask)
00206     {
00207         return gray8(v,a).premultiply();
00208     }
00209     inline gray8 gray8_pre(const gray8& c, unsigned a)
00210     {
00211         return gray8(c,a).premultiply();
00212     }
00213     inline gray8 gray8_pre(const rgba& c)
00214     {
00215         return gray8(c).premultiply();
00216     }
00217     inline gray8 gray8_pre(const rgba& c, double a)
00218     {
00219         return gray8(c,a).premultiply();
00220     }
00221     inline gray8 gray8_pre(const rgba8& c)
00222     {
00223         return gray8(c).premultiply();
00224     }
00225     inline gray8 gray8_pre(const rgba8& c, unsigned a)
00226     {
00227         return gray8(c,a).premultiply();
00228     }
00229 
00230 
00231 
00232 
00233     //==================================================================gray16
00234     struct gray16
00235     {
00236         typedef int16u value_type;
00237         typedef int32u calc_type;
00238         typedef int64  long_type;
00239         enum base_scale_e
00240         {
00241             base_shift = 16,
00242             base_scale = 1 << base_shift,
00243             base_mask  = base_scale - 1
00244         };
00245         typedef gray16 self_type;
00246 
00247         value_type v;
00248         value_type a;
00249 
00250         //--------------------------------------------------------------------
00251         gray16() {}
00252 
00253         //--------------------------------------------------------------------
00254         gray16(unsigned v_, unsigned a_=base_mask) :
00255             v(int16u(v_)), a(int16u(a_)) {}
00256 
00257         //--------------------------------------------------------------------
00258         gray16(const self_type& c, unsigned a_) :
00259             v(c.v), a(value_type(a_)) {}
00260 
00261         //--------------------------------------------------------------------
00262         gray16(const rgba& c) :
00263             v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
00264             a((value_type)uround(c.a * double(base_mask))) {}
00265 
00266         //--------------------------------------------------------------------
00267         gray16(const rgba& c, double a_) :
00268             v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
00269             a((value_type)uround(a_ * double(base_mask))) {}
00270 
00271         //--------------------------------------------------------------------
00272         gray16(const rgba8& c) :
00273             v(c.r*77 + c.g*150 + c.b*29),
00274             a((value_type(c.a) << 8) | c.a) {}
00275 
00276         //--------------------------------------------------------------------
00277         gray16(const rgba8& c, unsigned a_) :
00278             v(c.r*77 + c.g*150 + c.b*29),
00279             a((value_type(a_) << 8) | c.a) {}
00280 
00281         //--------------------------------------------------------------------
00282         void clear()
00283         {
00284             v = a = 0;
00285         }
00286 
00287         //--------------------------------------------------------------------
00288         const self_type& transparent()
00289         {
00290             a = 0;
00291             return *this;
00292         }
00293 
00294         //--------------------------------------------------------------------
00295         void opacity(double a_)
00296         {
00297             if(a_ < 0.0) a_ = 0.0;
00298             if(a_ > 1.0) a_ = 1.0;
00299             a = (value_type)uround(a_ * double(base_mask));
00300         }
00301 
00302         //--------------------------------------------------------------------
00303         double opacity() const
00304         {
00305             return double(a) / double(base_mask);
00306         }
00307 
00308 
00309         //--------------------------------------------------------------------
00310         const self_type& premultiply()
00311         {
00312             if(a == base_mask) return *this;
00313             if(a == 0)
00314             {
00315                 v = 0;
00316                 return *this;
00317             }
00318             v = value_type((calc_type(v) * a) >> base_shift);
00319             return *this;
00320         }
00321 
00322         //--------------------------------------------------------------------
00323         const self_type& premultiply(unsigned a_)
00324         {
00325             if(a == base_mask && a_ >= base_mask) return *this;
00326             if(a == 0 || a_ == 0)
00327             {
00328                 v = a = 0;
00329                 return *this;
00330             }
00331             calc_type v_ = (calc_type(v) * a_) / a;
00332             v = value_type((v_ > a_) ? a_ : v_);
00333             a = value_type(a_);
00334             return *this;
00335         }
00336 
00337         //--------------------------------------------------------------------
00338         const self_type& demultiply()
00339         {
00340             if(a == base_mask) return *this;
00341             if(a == 0)
00342             {
00343                 v = 0;
00344                 return *this;
00345             }
00346             calc_type v_ = (calc_type(v) * base_mask) / a;
00347             v = value_type((v_ > base_mask) ? base_mask : v_);
00348             return *this;
00349         }
00350 
00351         //--------------------------------------------------------------------
00352         self_type gradient(self_type c, double k) const
00353         {
00354             self_type ret;
00355             calc_type ik = uround(k * base_scale);
00356             ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift));
00357             ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
00358             return ret;
00359         }
00360 
00361         //--------------------------------------------------------------------
00362         AGG_INLINE void add(const self_type& c, unsigned cover)
00363         {
00364             calc_type cv, ca;
00365             if(cover == cover_mask)
00366             {
00367                 if(c.a == base_mask) 
00368                 {
00369                     *this = c;
00370                 }
00371                 else
00372                 {
00373                     cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
00374                     ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
00375                 }
00376             }
00377             else
00378             {
00379                 cv = v + ((c.v * cover + cover_mask/2) >> cover_shift);
00380                 ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
00381                 v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
00382                 a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
00383             }
00384         }
00385 
00386         //--------------------------------------------------------------------
00387         static self_type no_color() { return self_type(0,0); }
00388     };
00389 
00390 
00391     //------------------------------------------------------------gray16_pre
00392     inline gray16 gray16_pre(unsigned v, unsigned a = gray16::base_mask)
00393     {
00394         return gray16(v,a).premultiply();
00395     }
00396     inline gray16 gray16_pre(const gray16& c, unsigned a)
00397     {
00398         return gray16(c,a).premultiply();
00399     }
00400     inline gray16 gray16_pre(const rgba& c)
00401     {
00402         return gray16(c).premultiply();
00403     }
00404     inline gray16 gray16_pre(const rgba& c, double a)
00405     {
00406         return gray16(c,a).premultiply();
00407     }
00408     inline gray16 gray16_pre(const rgba8& c)
00409     {
00410         return gray16(c).premultiply();
00411     }
00412     inline gray16 gray16_pre(const rgba8& c, unsigned a)
00413     {
00414         return gray16(c,a).premultiply();
00415     }
00416 
00417 
00418 }
00419 
00420 
00421 
00422 
00423 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines