color.h

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

Generated on Wed Dec 12 03:11:41 2007 for synfig by  doxygen 1.5.4