color.h

Go to the documentation of this file.
00001 /* === S Y N F I G ========================================================= */
00021 /* ========================================================================= */
00022 
00023 /* === S T A R T =========================================================== */
00024 
00025 #ifndef __SYNFIG_COLOR_H
00026 #define __SYNFIG_COLOR_H
00027 
00028 /* === H E A D E R S ======================================================= */
00029 
00030 
00031 //#include <cmath>
00032 #include <math.h>
00033 #include <cassert>
00034 #include "gamma.h"
00035 #include <synfig/string.h>
00036 
00037 #ifdef USE_HALF_TYPE
00038 #include <OpenEXR/half.h>
00039 #endif
00040 
00041 #ifndef SYNFIG_NO_ANGLE
00042 # include "angle.h"
00043 #endif
00044 
00045 /* === M A C R O S ========================================================= */
00046 
00047 #ifdef WIN32
00048 #include <float.h>
00049 #ifndef isnan
00050 extern "C" { int _isnan(double x); }
00051 #define isnan _isnan
00052 #endif
00053 #endif
00054 
00055 // For some reason isnan() isn't working on macosx any more.
00056 // This is a quick fix.
00057 #if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX)
00058 #ifdef isnan
00059 #undef isnan
00060 #endif
00061 inline bool isnan(double x) { return x != x; }
00062 inline bool isnan(float x) { return x != x; }
00063 #define SYNFIG_ISNAN_FIX 1
00064 #endif
00065 
00066 namespace synfig {
00067 
00068 #ifdef USE_HALF_TYPE
00069 typedef half ColorReal;
00070 #else
00071 typedef float ColorReal;
00072 #endif
00073 
00074 static const float EncodeYUV[3][3]=
00075 {
00076     { 0.299f, 0.587f, 0.114f },
00077     { -0.168736f, -0.331264f, 0.5f },
00078     { 0.5f, -0.418688f, -0.081312f }
00079 };
00080 
00081 static const float DecodeYUV[3][3]=
00082 {
00083     { 1.0f, 0.0f, 1.402f },
00084     { 1.0f, -0.344136f, -0.714136f },
00085     { 1.0f, 1.772f, 0.0f }
00086 };
00087 
00088 /* === T Y P E D E F S ===================================================== */
00089 
00090 /* === C L A S S E S & S T R U C T S ======================================= */
00091 
00092 #ifdef USE_HALF_TYPE
00093 class ColorAccumulator;
00094 #endif
00095 
00096 
00097 
00098 
00103 class Color
00104 {
00105 public:
00106     typedef ColorReal value_type;
00107 
00108 private:
00109     value_type a_, r_, g_, b_;
00110     static String hex_;
00111 
00112 public:
00113 
00114     Color &
00115     operator+=(const Color &rhs)
00116     {
00117         r_+=rhs.r_;
00118         g_+=rhs.g_;
00119         b_+=rhs.b_;
00120         a_+=rhs.a_;
00121         return *this;
00122     }
00123 
00124     Color &
00125     operator-=(const Color &rhs)
00126     {
00127         r_-=rhs.r_;
00128         g_-=rhs.g_;
00129         b_-=rhs.b_;
00130         a_-=rhs.a_;
00131         return *this;
00132     }
00133 
00134     Color &
00135     operator*=(const float &rhs)
00136     {
00137         r_*=rhs;
00138         g_*=rhs;
00139         b_*=rhs;
00140         a_*=rhs;
00141         return *this;
00142     }
00143 
00144     Color &
00145     operator/=(const float &rhs)
00146     {
00147         const float temp(value_type(1)/rhs);
00148         r_*=temp;
00149         g_*=temp;
00150         b_*=temp;
00151         a_*=temp;
00152         return *this;
00153     }
00154 
00155     Color
00156     operator+(const Color &rhs)const
00157     { return Color(*this)+=rhs; }
00158 
00159     Color
00160     operator-(const Color &rhs)const
00161     { return Color(*this)-=rhs; }
00162 
00163     Color
00164     operator*(const float &rhs)const
00165     { return Color(*this)*=rhs; }
00166 
00167     Color
00168     operator/(const float &rhs)const
00169     { return Color(*this)/=rhs; }
00170 
00171     bool
00172     operator==(const Color &rhs)const
00173     { return r_==rhs.r_ && g_==rhs.g_ && b_==rhs.b_ && a_==rhs.a_; }
00174 
00175     bool
00176     operator!=(const Color &rhs)const
00177     { return r_!=rhs.r_ || g_!=rhs.g_ || b_!=rhs.b_ || a_!=rhs.a_; }
00178 
00179     Color
00180     operator-()const
00181     { return Color(-r_,-g_,-b_,-a_); }
00182 
00184     Color
00185     operator~()const
00186     { return Color(1.0f-r_,1.0f-g_,1.0f-b_,a_); }
00187 
00188     bool is_valid()const
00189     { return !isnan(r_) && !isnan(g_) && !isnan(b_) && !isnan(a_); }
00190 
00191     Color premult_alpha() const
00192     {
00193         return Color (r_*a_, g_*a_, b_*a_, a_);
00194     }
00195 
00196     Color demult_alpha() const
00197     {
00198         if(a_)
00199         {
00200             const value_type inva = 1/a_;
00201             return Color (r_*inva, g_*inva, b_*inva, a_);
00202         }else return alpha();
00203     }
00204 
00205 public:
00206     Color() /*:r_(0), g_(0), b_(0), a_(0)*/ { }
00207     Color(const value_type &f) :a_(f),r_(f), g_(f), b_(f) { }
00208     Color(int f) :a_(f),r_(f), g_(f), b_(f) { }
00209 
00214     Color(const value_type& R, const value_type& G, const value_type& B, const value_type& A=1):
00215         a_(A),
00216         r_(R),
00217         g_(G),
00218         b_(B) { }
00219 
00222     Color(const Color& c, const value_type& A):
00223         a_(A),
00224         r_(c.r_),
00225         g_(c.g_),
00226         b_(c.b_) { }
00227 
00228 
00230     Color(const Color& c):
00231         a_(c.a_),
00232         r_(c.r_),
00233         g_(c.g_),
00234         b_(c.b_) { }
00235 
00236 #ifdef USE_HALF_TYPE
00237     friend class ColorAccumulator;
00239     Color(const ColorAccumulator& c);
00240 #endif
00241 
00243     //Color(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); }
00244 
00245     /*const Color &operator=(const value_type &i)
00246     {
00247         r_ = g_ = b_ = a_ = i;
00248         return *this;
00249     }*/
00250     //Color& operator=(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); return *this; }
00251 
00253     const value_type& get_r()const { return r_; }
00254 
00256     const value_type& get_g()const { return g_; }
00257 
00259     const value_type& get_b()const { return b_; }
00260 
00262     const value_type& get_a()const { return a_; }
00263 
00265     const value_type& get_alpha()const { return get_a(); }
00266 
00268     static ColorReal hex2real(String s);
00269 
00271     static const String real2hex(ColorReal c);
00272 
00274     const String& get_hex()const { return hex_ = real2hex(r_)+real2hex(g_)+real2hex(b_); }
00275 
00277     void set_hex(String& hex);
00278 
00280     Color& set_r(const value_type& x) { r_ = x; return *this; }
00281 
00283     Color& set_g(const value_type& x) { g_ = x; return *this; }
00284 
00286     Color& set_b(const value_type& x) { b_ = x; return *this; }
00287 
00289     Color& set_a(const value_type& x) { a_ = x; return *this; }
00290 
00292     Color& set_alpha(const value_type& x) { return set_a(x); }
00293 
00295     float
00296     get_y() const
00297     {
00298         return
00299             (float)get_r()*EncodeYUV[0][0]+
00300             (float)get_g()*EncodeYUV[0][1]+
00301             (float)get_b()*EncodeYUV[0][2];
00302     }
00303 
00304 
00306     float
00307     get_u() const
00308     {
00309         return
00310             (float)get_r()*EncodeYUV[1][0]+
00311             (float)get_g()*EncodeYUV[1][1]+
00312             (float)get_b()*EncodeYUV[1][2];
00313     }
00314 
00315 
00317     float
00318     get_v() const
00319     {
00320         return
00321             (float)get_r()*EncodeYUV[2][0]+
00322             (float)get_g()*EncodeYUV[2][1]+
00323             (float)get_b()*EncodeYUV[2][2];
00324     }
00325 
00327 
00329     float
00330     get_s() const
00331     {
00332         const float u(get_u()), v(get_v());
00333         return sqrt(u*u+v*v);
00334     }
00335 
00337     Color&
00338     set_yuv(const float &y, const float &u, const float &v)
00339     {
00340         set_r(y*DecodeYUV[0][0]+u*DecodeYUV[0][1]+v*DecodeYUV[0][2]);
00341         set_g(y*DecodeYUV[1][0]+u*DecodeYUV[1][1]+v*DecodeYUV[1][2]);
00342         set_b(y*DecodeYUV[2][0]+u*DecodeYUV[2][1]+v*DecodeYUV[2][2]);
00343         return *this;
00344     }
00345 
00347     Color& set_y(const float &y) { return set_yuv(y,get_u(),get_v()); }
00348 
00350     Color& set_u(const float &u) { return set_yuv(get_y(),u,get_v()); }
00351 
00353     Color& set_v(const float &v) { return set_yuv(get_y(),get_u(),v); }
00354 
00356     Color& set_uv(const float& u, const float& v) { return set_yuv(get_y(),u,v); }
00357 
00359 
00360     Color&
00361     set_s(const float &x)
00362     {
00363         float u(get_u()), v(get_v());
00364         const float s(sqrt(u*u+v*v));
00365         if(s)
00366         {
00367             u=(u/s)*x;
00368             v=(v/s)*x;
00369             return set_uv(u,v);
00370         }
00371         return *this;
00372     }
00373 
00375     static Color YUV(const float& y, const float& u, const float& v, const value_type& a=1)
00376         { return Color().set_yuv(y,u,v).set_a(a); }
00377 
00378 #ifndef SYNFIG_NO_ANGLE
00380 
00382     Angle
00383     get_hue() const
00384         { return Angle::tan(get_u(),get_v()); }
00385 
00387     Angle get_uv_angle() const { return get_hue(); }
00388 
00390 
00391     Color&
00392     set_hue(const Angle& theta)
00393     {
00394         const float s(get_s());
00395         const float
00396             u(s*(float)Angle::sin(theta).get()),
00397             v(s*(float)Angle::cos(theta).get());
00398         return set_uv(u,v);
00399     }
00400 
00402     Color& set_uv_angle(const Angle& theta) { return set_hue(theta); }
00403 
00405     Color& rotate_uv(const Angle& theta)
00406     {
00407         const float a(Angle::sin(theta).get()), b(Angle::cos(theta).get());
00408         const float u(get_u()), v(get_v());
00409 
00410         return set_uv(b*u-a*v,a*u+b*v);
00411     }
00412 
00414 
00417     Color& set_yuv(const float& y, const float& s, const Angle& theta)
00418     {
00419         return
00420             set_yuv(
00421                 y,
00422                 s*(float)Angle::sin(theta).get(),
00423                 s*(float)Angle::cos(theta).get()
00424             );
00425     }
00426 
00428 
00432     static Color YUV(const float& y, const float& s, const Angle& theta, const value_type& a=1)
00433         { return Color().set_yuv(y,s,theta).set_a(a); }
00434 
00435 #endif
00436 
00438     Color clamped()const;
00439 
00441     Color clamped_negative()const;
00442 
00443     /* Preset Colors */
00444 
00446 
00447 #ifdef HAS_VIMAGE
00448     static inline Color alpha() { return Color(0,0,0,0.0000001f); }
00449 #else
00450     static inline Color alpha() { return Color(0,0,0,0); }
00451 #endif
00452     static inline Color black() { return Color(0,0,0); }
00453     static inline Color white() { return Color(1,1,1); }
00454     static inline Color gray() { return Color(0.5f,0.5f,0.5f); }
00455     static inline Color magenta() { return Color(1,0,1); }
00456     static inline Color red() { return Color(1,0,0); }
00457     static inline Color green() { return Color(0,1,0); }
00458     static inline Color blue() { return Color(0,0,1); }
00459     static inline Color cyan() { return Color(0,1,1); }
00460     static inline Color yellow() { return Color(1,1,0); }
00462 
00464     enum BlendMethod
00465     {
00466         BLEND_COMPOSITE=0,  
00467         BLEND_STRAIGHT=1,   
00468         BLEND_BRIGHTEN=2,   
00469         BLEND_DARKEN=3,     
00470         BLEND_ADD=4,        
00471         BLEND_SUBTRACT=5,   
00472         BLEND_MULTIPLY=6,   
00473         BLEND_DIVIDE=7,     
00474         BLEND_COLOR=8,      
00475         BLEND_HUE=9,        
00476         BLEND_SATURATION=10,
00477         BLEND_LUMINANCE=11, 
00478         BLEND_BEHIND=12,    
00479         BLEND_ONTO=13,      
00480         BLEND_SCREEN=16,        
00481         BLEND_OVERLAY=20,       
00482         BLEND_DIFFERENCE=18,        
00483         BLEND_HARD_LIGHT=17,        
00484 
00486         BLEND_ALPHA_BRIGHTEN=14,    
00487         BLEND_ALPHA_DARKEN=15,      
00488         BLEND_ALPHA_OVER=19,
00489         BLEND_STRAIGHT_ONTO=21,
00490 
00491         BLEND_END=22            
00492     };
00493 
00494     /* Other */
00495     static Color blend(Color a, Color b,float amount,BlendMethod type=BLEND_COMPOSITE);
00496 
00497     static bool is_onto(BlendMethod x)
00498     {
00499         return x==BLEND_BRIGHTEN
00500             || x==BLEND_DARKEN
00501             || x==BLEND_ADD
00502             || x==BLEND_SUBTRACT
00503             || x==BLEND_MULTIPLY
00504             || x==BLEND_DIVIDE
00505             || x==BLEND_COLOR
00506             || x==BLEND_HUE
00507             || x==BLEND_SATURATION
00508             || x==BLEND_LUMINANCE
00509             || x==BLEND_ONTO
00510             || x==BLEND_STRAIGHT_ONTO
00511             || x==BLEND_SCREEN
00512             || x==BLEND_OVERLAY
00513             || x==BLEND_DIFFERENCE
00514             || x==BLEND_HARD_LIGHT
00515         ;
00516     }
00517 /*protected:
00518 
00519     value_type& operator[](const int i)
00520     {
00521         assert(i>=0);
00522         assert(i<(signed)(sizeof(Color)/sizeof(value_type)));
00523         return (&r_)[i];
00524     }
00525 
00526     const value_type& operator[](const int i)const
00527     {
00528         assert(i>=0);
00529         assert(i<(signed)(sizeof(Color)/sizeof(value_type)));
00530         return (&r_)[i];
00531     }
00532 */
00533 }; // END of class Color
00534 
00535 #ifndef USE_HALF_TYPE
00536 typedef Color ColorAccumulator;
00537 #else
00538 class ColorAccumulator
00539 {
00540     friend class Color;
00541 public:
00542     typedef float value_type;
00543 
00544 private:
00545     value_type a_, r_, g_, b_;
00546 
00547 public:
00548 
00549     ColorAccumulator &
00550     operator+=(const ColorAccumulator &rhs)
00551     {
00552         r_+=rhs.r_;
00553         g_+=rhs.g_;
00554         b_+=rhs.b_;
00555         a_+=rhs.a_;
00556         return *this;
00557     }
00558 
00559     ColorAccumulator &
00560     operator-=(const ColorAccumulator &rhs)
00561     {
00562         r_-=rhs.r_;
00563         g_-=rhs.g_;
00564         b_-=rhs.b_;
00565         a_-=rhs.a_;
00566         return *this;
00567     }
00568 
00569     ColorAccumulator &
00570     operator*=(const float &rhs)
00571     {
00572         r_*=rhs;
00573         g_*=rhs;
00574         b_*=rhs;
00575         a_*=rhs;
00576         return *this;
00577     }
00578 
00579     ColorAccumulator &
00580     operator/=(const float &rhs)
00581     {
00582         const float temp(value_type(1)/rhs);
00583         r_*=temp;
00584         g_*=temp;
00585         b_*=temp;
00586         a_*=temp;
00587         return *this;
00588     }
00589 
00590     ColorAccumulator
00591     operator+(const ColorAccumulator &rhs)const
00592     { return Color(*this)+=rhs; }
00593 
00594     ColorAccumulator
00595     operator-(const ColorAccumulator &rhs)const
00596     { return Color(*this)-=rhs; }
00597 
00598     ColorAccumulator
00599     operator*(const float &rhs)const
00600     { return Color(*this)*=rhs; }
00601 
00602     ColorAccumulator
00603     operator/(const float &rhs)const
00604     { return Color(*this)/=rhs; }
00605 
00606     bool
00607     operator==(const ColorAccumulator &rhs)const
00608     { return r_==rhs.r_ && g_==rhs.g_ && b_==rhs.b_ && a_!=rhs.a_; }
00609 
00610     bool
00611     operator!=(const ColorAccumulator &rhs)const
00612     { return r_!=rhs.r_ || g_!=rhs.g_ || b_!=rhs.b_ || a_!=rhs.a_; }
00613 
00614     Color
00615     operator-()const
00616     { return ColorAccumulator(-r_,-g_,-b_,-a_); }
00617 
00618     bool is_valid()const
00619     { return !isnan(r_) && !isnan(g_) && !isnan(b_) && !isnan(a_); }
00620 
00621 public:
00622     ColorAccumulator() { }
00623 
00628     ColorAccumulator(const value_type& R, const value_type& G, const value_type& B, const value_type& A=1):
00629         a_(A),
00630         r_(R),
00631         g_(G),
00632         b_(B) { }
00633 
00635     ColorAccumulator(const ColorAccumulator& c):
00636         a_(c.a_),
00637         r_(c.r_),
00638         g_(c.g_),
00639         b_(c.b_) { }
00640 
00642     ColorAccumulator(const Color& c):
00643         a_(c.a_),
00644         r_(c.r_),
00645         g_(c.g_),
00646         b_(c.b_) { }
00647 
00649     ColorAccumulator(int c): a_(c),r_(c), g_(c), b_(c) { }
00650 
00652     const value_type& get_r()const { return r_; }
00653 
00655     const value_type& get_g()const { return g_; }
00656 
00658     const value_type& get_b()const { return b_; }
00659 
00661     const value_type& get_a()const { return a_; }
00662 
00664     const value_type& get_alpha()const { return get_a(); }
00665 
00667     ColorAccumulator& set_r(const value_type& x) { r_ = x; return *this; }
00668 
00670     ColorAccumulator& set_g(const value_type& x) { g_ = x; return *this; }
00671 
00673     ColorAccumulator& set_b(const value_type& x) { b_ = x; return *this; }
00674 
00676     ColorAccumulator& set_a(const value_type& x) { a_ = x; return *this; }
00677 
00679     ColorAccumulator& set_alpha(const value_type& x) { return set_a(x); }
00680 };
00681 
00682 inline
00683 Color::Color(const ColorAccumulator& c):
00684     a_(c.a_),
00685     r_(c.r_),
00686     g_(c.g_),
00687     b_(c.b_) { }
00688 
00689 #endif
00690 
00691 
00692 
00693 
00694 
00695 enum PixelFormat
00696 {
00697 /* Bit  Descriptions (ON/OFF)
00698 ** ----+-------------
00699 ** 0    Color Channels (Gray/RGB)
00700 ** 1    Alpha Channel (WITH/WITHOUT)
00701 ** 2    ZDepth  (WITH/WITHOUT)
00702 ** 3    Endian (BGR/RGB)
00703 ** 4    Alpha Location (Start/End)
00704 ** 5    ZDepth Location (Start/End)
00705 ** 6    Alpha/ZDepth Arangement (ZA,AZ)
00706 ** 7    Alpha Range (Inverted,Normal)
00707 ** 8    Z Range (Inverted,Normal)
00708 */
00709     PF_RGB=0,
00710     PF_GRAY=(1<<0),         
00711     PF_A=(1<<1),            
00712     PF_Z=(1<<2),            
00713     PF_BGR=(1<<3),          
00714     PF_A_START=(1<<4),      
00715     PF_Z_START=(1<<5),      
00716     PF_ZA=(1<<6),           
00717 
00718     PF_A_INV=(1<<7),        
00719     PF_Z_INV=(1<<8),        
00720     PF_RAW_COLOR=(1<<9)+(1<<1)  
00721 };
00722 
00723 inline PixelFormat operator|(PixelFormat lhs, PixelFormat rhs)
00724     { return static_cast<PixelFormat>((int)lhs|(int)rhs); }
00725 
00726 inline PixelFormat operator&(PixelFormat lhs, PixelFormat rhs)
00727     { return static_cast<PixelFormat>((int)lhs&(int)rhs); }
00728 #define FLAGS(x,y)      (((x)&(y))==(y))
00729 
00731 inline int
00732 channels(PixelFormat x)
00733 {
00734     int chan=0;
00735     if(FLAGS(x,PF_GRAY))
00736         ++chan;
00737     else
00738         chan+=3;
00739     if(FLAGS(x,PF_A))
00740         ++chan;
00741     if(FLAGS(x,PF_Z))
00742         ++chan;
00743     if(FLAGS(x,PF_RAW_COLOR))
00744         chan=sizeof(Color);
00745 
00746     return chan;
00747 }
00748 
00749 inline unsigned char *
00750 Color2PixelFormat(const Color &color, const PixelFormat &pf, unsigned char *out, const Gamma &gamma)
00751 {
00752     if(FLAGS(pf,PF_RAW_COLOR))
00753     {
00754         Color *outcol=reinterpret_cast<Color *>(out);
00755         *outcol=color;
00756         out+=sizeof(color);
00757         return out;
00758     }
00759 
00760     int alpha=(int)((FLAGS(pf,PF_A_INV)?(-(float)color.get_a()+1):(float)color.get_a())*255);
00761     if(alpha<0)alpha=0;
00762     if(alpha>255)alpha=255;
00763 
00764     if(FLAGS(pf,PF_ZA|PF_A_START|PF_Z_START))
00765     {
00766         if(FLAGS(pf,PF_Z_START))
00767             *out++/*=(unsigned char)(color.GetZ()*255.0f)*/;
00768         if(FLAGS(pf,PF_A_START))
00769             *out++=static_cast<unsigned char>(alpha);
00770     }
00771     else
00772     {
00773         if(FLAGS(pf,PF_A_START))
00774             *out++=static_cast<unsigned char>(alpha);
00775         if(FLAGS(pf,PF_Z_START))
00776             *out++/*=(unsigned char)(color.GetZ()*255.0f)*/;
00777 
00778     }
00779 
00780     if(FLAGS(pf,PF_GRAY))
00781         *out++=static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_y()));
00782     else
00783     {
00784         if(FLAGS(pf,PF_BGR))
00785         {
00786             *out++=static_cast<unsigned char>(gamma.r_F32_to_U8(color.get_b()));
00787             *out++=static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_g()));
00788             *out++=static_cast<unsigned char>(gamma.b_F32_to_U8(color.get_r()));
00789         }
00790         else
00791         {
00792             *out++=static_cast<unsigned char>(gamma.r_F32_to_U8(color.get_r()));
00793             *out++=static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_g()));
00794             *out++=static_cast<unsigned char>(gamma.b_F32_to_U8(color.get_b()));
00795         }
00796     }
00797 
00798     if(FLAGS(pf,PF_ZA))
00799     {
00800         if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
00801             out++;//*out++=(unsigned char)(color.GetZ()*255.0f);
00802         if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
00803             *out++=static_cast<unsigned char>(alpha);
00804     }
00805     else
00806     {
00807         if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
00808             out++;//*out++=(unsigned char)(color.GetZ()*255.0f);
00809         if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
00810             *out++=static_cast<unsigned char>(alpha);
00811     }
00812     return out;
00813 }
00814 
00815 inline void
00816 convert_color_format(unsigned char *dest, const Color *src, int w, PixelFormat pf,const Gamma &gamma)
00817 {
00818     assert(w>=0);
00819     while(w--)
00820         dest=Color2PixelFormat((*(src++)).clamped(),pf,dest,gamma);
00821 }
00822 
00823 inline const unsigned char *
00824 PixelFormat2Color(Color &color, const PixelFormat &pf,const unsigned char *out)
00825 {
00826     if(FLAGS(pf,PF_ZA|PF_A_START|PF_Z_START))
00827     {
00828         if(FLAGS(pf,PF_Z_START))
00829             out++;//color.SetZ((Color::value_type)*out++/255.0f);
00830         if(FLAGS(pf,PF_A_START))
00831             color.set_a((float)*out++/255);
00832     }
00833     else
00834     {
00835         if(FLAGS(pf,PF_A_START))
00836             color.set_a((float)*out++/255);
00837         if(FLAGS(pf,PF_Z_START))
00838             out++;//color.SetZ((Color::value_type)*out++/255.0f);
00839     }
00840 
00841     if(FLAGS(pf,PF_GRAY))
00842         color.set_yuv((float)*out++/255,0,0);
00843     else
00844     {
00845         if(FLAGS(pf,PF_BGR))
00846         {
00847             color.set_b((float)*out++/255);
00848             color.set_g((float)*out++/255);
00849             color.set_r((float)*out++/255);
00850         }
00851         else
00852         {
00853             color.set_r((float)*out++/255);
00854             color.set_g((float)*out++/255);
00855             color.set_b((float)*out++/255);
00856         }
00857     }
00858 
00859     if(FLAGS(pf,PF_ZA))
00860     {
00861         if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
00862             out++;//color.SetZ((Color::value_type)*out++/255.0f);
00863         if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
00864             color.set_a((float)*out++/255);
00865     }
00866     else
00867     {
00868         if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
00869             color.set_a((float)*out++/255);
00870         if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
00871             out++;//color.SetZ((Color::value_type)*out++/255.0f);
00872     }
00873     return out;
00874 }
00875 
00876 
00877 
00878 }; // END of namespace synfig
00879 
00880 /* === E N D =============================================================== */
00881 
00882 #endif

Generated on Wed Aug 15 05:00:23 2007 for synfig by  doxygen 1.5.3