X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftags%2Fsynfig_0_61_05%2Fsynfig-core%2Fsrc%2Fsynfig%2Fcolor.h;fp=synfig-core%2Ftags%2Fsynfig_0_61_05%2Fsynfig-core%2Fsrc%2Fsynfig%2Fcolor.h;h=c7b693d68b24e4a52a33b074552f327b2c6d48b7;hb=299aecad571ca490ce017004a0d7e555d6df0520;hp=0000000000000000000000000000000000000000;hpb=42861dc634bef4059ca95e5292033315a0b9ce30;p=synfig.git diff --git a/synfig-core/tags/synfig_0_61_05/synfig-core/src/synfig/color.h b/synfig-core/tags/synfig_0_61_05/synfig-core/src/synfig/color.h new file mode 100644 index 0000000..c7b693d --- /dev/null +++ b/synfig-core/tags/synfig_0_61_05/synfig-core/src/synfig/color.h @@ -0,0 +1,862 @@ +/* === S Y N F I G ========================================================= */ +/*! \file color.h +** \brief Color Class Implementation +** +** $Id: color.h,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $ +** +** \legal +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. +** +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** \endlegal +*/ +/* ========================================================================= */ + +/* === S T A R T =========================================================== */ + +#ifndef __SYNFIG_COLOR_H +#define __SYNFIG_COLOR_H + +/* === H E A D E R S ======================================================= */ + +#ifndef SYNFIG_NO_ANGLE +# include "angle.h" +#endif + +//#include +#include +#include +#include "gamma.h" +#include + +#ifdef USE_HALF_TYPE +#include +#endif + +/* === M A C R O S ========================================================= */ + +#ifndef isnan + +#ifdef WIN32 +#include +#ifndef isnan +extern "C" { int _isnan(double x); } +#define isnan _isnan +#endif +#endif + +#ifdef __APPLE__ +#define isnan __isnanf +#endif + +#endif + +namespace synfig { + +#ifdef USE_HALF_TYPE +typedef half ColorReal; +#else +typedef float ColorReal; +#endif + +static const float EncodeYUV[3][3]= +{ + { 0.299f, 0.587f, 0.114f }, + { -0.168736f, -0.331264f, 0.5f }, + { 0.5f, -0.418688f, -0.081312f } +}; + +static const float DecodeYUV[3][3]= +{ + { 1.0f, 0.0f, 1.402f }, + { 1.0f, -0.344136f, -0.714136f }, + { 1.0f, 1.772f, 0.0f } +}; + +/* === T Y P E D E F S ===================================================== */ + +/* === C L A S S E S & S T R U C T S ======================================= */ + +#ifdef USE_HALF_TYPE +class ColorAccumulator; +#endif + + + + +/*! \class Color +** \todo Writeme +** Future optimizations: lookup table for sqrt()? +*/ +class Color +{ +public: + typedef ColorReal value_type; + +private: + value_type a_, r_, g_, b_; + +public: + + Color & + operator+=(const Color &rhs) + { + r_+=rhs.r_; + g_+=rhs.g_; + b_+=rhs.b_; + a_+=rhs.a_; + return *this; + } + + Color & + operator-=(const Color &rhs) + { + r_-=rhs.r_; + g_-=rhs.g_; + b_-=rhs.b_; + a_-=rhs.a_; + return *this; + } + + Color & + operator*=(const float &rhs) + { + r_*=rhs; + g_*=rhs; + b_*=rhs; + a_*=rhs; + return *this; + } + + Color & + operator/=(const float &rhs) + { + const float temp(value_type(1)/rhs); + r_*=temp; + g_*=temp; + b_*=temp; + a_*=temp; + return *this; + } + + Color + operator+(const Color &rhs)const + { return Color(*this)+=rhs; } + + Color + operator-(const Color &rhs)const + { return Color(*this)-=rhs; } + + Color + operator*(const float &rhs)const + { return Color(*this)*=rhs; } + + Color + operator/(const float &rhs)const + { return Color(*this)/=rhs; } + + bool + operator==(const Color &rhs)const + { return r_==rhs.r_ && g_==rhs.g_ && b_==rhs.b_ && a_==rhs.a_; } + + bool + operator!=(const Color &rhs)const + { return r_!=rhs.r_ || g_!=rhs.g_ || b_!=rhs.b_ || a_!=rhs.a_; } + + Color + operator-()const + { return Color(-r_,-g_,-b_,-a_); } + + //! Effectively 1.0-color + Color + operator~()const + { return Color(1.0f-r_,1.0f-g_,1.0f-b_,a_); } + + bool is_valid()const + { return !isnan(r_) && !isnan(g_) && !isnan(b_) && !isnan(a_); } + + Color premult_alpha() const + { + return Color (r_*a_, g_*a_, b_*a_, a_); + } + + Color demult_alpha() const + { + if(a_) + { + const value_type inva = 1/a_; + return Color (r_*inva, g_*inva, b_*inva, a_); + }else return alpha(); + } + +public: + Color() /*:r_(0), g_(0), b_(0), a_(0)*/ { } + Color(const value_type &f) :a_(f),r_(f), g_(f), b_(f) { } + Color(int f) :a_(f),r_(f), g_(f), b_(f) { } + + /*! \param R Red + ** \param G Green + ** \param B Blue + ** \param A Opacity(alpha) */ + Color(const value_type& R, const value_type& G, const value_type& B, const value_type& A=1): + a_(A), + r_(R), + g_(G), + b_(B) { } + + /*! \param C Source for color components + ** \param A Opacity(alpha) */ + Color(const Color& c, const value_type& A): + a_(c.a_), + r_(c.r_), + g_(c.g_), + b_(c.b_) { } + + + //! Copy constructor + Color(const Color& c): + a_(c.a_), + r_(c.r_), + g_(c.g_), + b_(c.b_) { } + +#ifdef USE_HALF_TYPE + friend class ColorAccumulator; + //! Convert constructor + Color(const ColorAccumulator& c); +#endif + + //! Copy constructor + //Color(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); } + + /*const Color &operator=(const value_type &i) + { + r_ = g_ = b_ = a_ = i; + return *this; + }*/ + //Color& operator=(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); return *this; } + + //! Returns the RED component + const value_type& get_r()const { return r_; } + + //! Returns the GREEN component + const value_type& get_g()const { return g_; } + + //! Returns the BLUE component + const value_type& get_b()const { return b_; } + + //! Returns the amount of opacity (alpha) + const value_type& get_a()const { return a_; } + + //! Synonym for get_a(). \see get_a() + const value_type& get_alpha()const { return get_a(); } + + //! Sets the RED component to \a x + Color& set_r(const value_type& x) { r_ = x; return *this; } + + //! Sets the GREEN component to \a x + Color& set_g(const value_type& x) { g_ = x; return *this; } + + //! Sets the BLUE component to \a x + Color& set_b(const value_type& x) { b_ = x; return *this; } + + //! Sets the opacity (alpha) to \a x + Color& set_a(const value_type& x) { a_ = x; return *this; } + + //! Synonym for set_a(). \see set_a() + Color& set_alpha(const value_type& x) { return set_a(x); } + + //! Returns color's luminance + float + get_y() const + { + return + (float)get_r()*EncodeYUV[0][0]+ + (float)get_g()*EncodeYUV[0][1]+ + (float)get_b()*EncodeYUV[0][2]; + } + + + //! Returns U component of chromanance + float + get_u() const + { + return + (float)get_r()*EncodeYUV[1][0]+ + (float)get_g()*EncodeYUV[1][1]+ + (float)get_b()*EncodeYUV[1][2]; + } + + + //! Returns V component of chromanance + float + get_v() const + { + return + (float)get_r()*EncodeYUV[2][0]+ + (float)get_g()*EncodeYUV[2][1]+ + (float)get_b()*EncodeYUV[2][2]; + } + + //! Returns the color's saturation + /*! This is is the magnitude of the U and V components. + ** \see set_s() */ + float + get_s() const + { + const float u(get_u()), v(get_v()); + return sqrt(u*u+v*v); + } + + //! Sets the luminance (\a y) and chromanance (\a u and \a v) + Color& + set_yuv(const float &y, const float &u, const float &v) + { + set_r(y*DecodeYUV[0][0]+u*DecodeYUV[0][1]+v*DecodeYUV[0][2]); + set_g(y*DecodeYUV[1][0]+u*DecodeYUV[1][1]+v*DecodeYUV[1][2]); + set_b(y*DecodeYUV[2][0]+u*DecodeYUV[2][1]+v*DecodeYUV[2][2]); + return *this; + } + + //! Sets color luminance + Color& set_y(const float &y) { return set_yuv(y,get_u(),get_v()); } + + //! Set U component of chromanance + Color& set_u(const float &u) { return set_yuv(get_y(),u,get_v()); } + + //! Set V component of chromanance + Color& set_v(const float &v) { return set_yuv(get_y(),get_u(),v); } + + //! Set the U and V components of chromanance + Color& set_uv(const float& u, const float& v) { return set_yuv(get_y(),u,v); } + + //! Sets the color's saturation + /*! \see get_s() */ + Color& + set_s(const float &x) + { + float u(get_u()), v(get_v()); + const float s(sqrt(u*u+v*v)); + if(s) + { + u=(u/s)*x; + v=(v/s)*x; + return set_uv(u,v); + } + return *this; + } + + //! YUV Color constructor + static Color YUV(const float& y, const float& u, const float& v, const value_type& a=1) + { return Color().set_yuv(y,u,v).set_a(a); } + +#ifndef SYNFIG_NO_ANGLE + //! Returns the hue of the chromanance + /*! This is the angle of the U and V components. + ** \see set_hue() */ + Angle + get_hue() const + { return Angle::tan(get_u(),get_v()); } + + //! Synonym for get_hue(). \see get_hue() + Angle get_uv_angle() const { return get_hue(); } + + //! Sets the color's hue + /*! \see get_hue() */ + Color& + set_hue(const Angle& theta) + { + const float s(get_s()); + const float + u(s*(float)Angle::sin(theta).get()), + v(s*(float)Angle::cos(theta).get()); + return set_uv(u,v); + } + + //! Synonym for set_hue(). \see set_hue() + Color& set_uv_angle(const Angle& theta) { return set_hue(theta); } + + //! Rotates the chromanance vector by amount specified by \a theta + Color& rotate_uv(const Angle& theta) + { + const float a(Angle::sin(theta).get()), b(Angle::cos(theta).get()); + const float u(get_u()), v(get_v()); + + return set_uv(b*u-a*v,a*u+b*v); + } + + //! Sets the luminance (\a y) and chromanance (\a s and \a theta). + /*! \param y Luminance + ** \param s Saturation + ** \param theta Hue */ + Color& set_yuv(const float& y, const float& s, const Angle& theta) + { + return + set_yuv( + y, + s*(float)Angle::sin(theta).get(), + s*(float)Angle::cos(theta).get() + ); + } + + //! YUV color constructor where the chroma is in the saturation/hue form. + /*! \param y Luminance + ** \param s Saturation + ** \param theta Hue + ** \param a Opacity (alpha) */ + static Color YUV(const float& y, const float& s, const Angle& theta, const value_type& a=1) + { return Color().set_yuv(y,s,theta).set_a(a); } + +#endif + + //! Clamps a color so that its values are in range. Ignores attempting to visualize negative colors. + Color clamped()const; + + //! Clamps a color so that its values are in range. + Color clamped_negative()const; + + /* Preset Colors */ + + //! Preset Color Constructors + //@{ +#ifdef HAS_VIMAGE + static inline Color alpha() { return Color(0,0,0,0.0000001f); } +#else + static inline Color alpha() { return Color(0,0,0,0); } +#endif + static inline Color black() { return Color(0,0,0); } + static inline Color white() { return Color(1,1,1); } + static inline Color gray() { return Color(0.5f,0.5f,0.5f); } + static inline Color magenta() { return Color(1,0,1); } + static inline Color red() { return Color(1,0,0); } + static inline Color green() { return Color(0,1,0); } + static inline Color blue() { return Color(0,0,1); } + static inline Color cyan() { return Color(0,1,1); } + static inline Color yellow() { return Color(1,1,0); } + //@} + + //! \writeme + enum BlendMethod + { + BLEND_COMPOSITE=0, //!< Color A is composited onto B (Taking into about A's alpha) + BLEND_STRAIGHT=1, //!< Straight linear interpolation from A->B (Alpha ignored) + BLEND_BRIGHTEN=2, //!< If composite is brighter than B, use composite. B otherwise. + BLEND_DARKEN=3, //!< If composite is brighter than B, use composite. B otherwise. + BLEND_ADD=4, //!< Simple A+B. + BLEND_SUBTRACT=5, //!< Simple A-B. + BLEND_MULTIPLY=6, //!< Simple A*B. + BLEND_DIVIDE=7, //!< Simple B/A + BLEND_COLOR=8, //!< Preserves the U and V channels of color A + BLEND_HUE=9, //!< Preserves the angle of the UV vector of color A + BLEND_SATURATION=10,//!< Preserves the magnitude of the UV Vector of color A + BLEND_LUMINANCE=11, //!< Preserves the Y channel of color A + BLEND_BEHIND=12, //!< Similar to BLEND_COMPOSITE, except that B is composited onto A. + BLEND_ONTO=13, //!< Similar to BLEND_COMPOSITE, except that B's alpha is maintained + BLEND_SCREEN=16, //!< \writeme + BLEND_OVERLAY=20, //!< \writeme + BLEND_DIFFERENCE=18, //!< \writeme + BLEND_HARD_LIGHT=17, //!< \writeme + + //! Deprecated + BLEND_ALPHA_BRIGHTEN=14, //!< If A is less opaque than B, use A + BLEND_ALPHA_DARKEN=15, //!< If A is more opaque than B, use B + BLEND_ALPHA_OVER=19,//!< multiply alphas and then straight blends that using the amount + BLEND_STRAIGHT_ONTO=21,//!< \writeme + + BLEND_END=22 //!< \internal + }; + + /* Other */ + static Color blend(Color a, Color b,float amount,BlendMethod type=BLEND_COMPOSITE); + + static bool is_onto(BlendMethod x) + { + return x==BLEND_BRIGHTEN + || x==BLEND_DARKEN + || x==BLEND_ADD + || x==BLEND_SUBTRACT + || x==BLEND_MULTIPLY + || x==BLEND_DIVIDE + || x==BLEND_COLOR + || x==BLEND_HUE + || x==BLEND_SATURATION + || x==BLEND_LUMINANCE + || x==BLEND_ONTO + || x==BLEND_STRAIGHT_ONTO + || x==BLEND_SCREEN + || x==BLEND_OVERLAY + || x==BLEND_DIFFERENCE + || x==BLEND_HARD_LIGHT + ; + } +/*protected: + + value_type& operator[](const int i) + { + assert(i>=0); + assert(i<(signed)(sizeof(Color)/sizeof(value_type))); + return (&r_)[i]; + } + + const value_type& operator[](const int i)const + { + assert(i>=0); + assert(i<(signed)(sizeof(Color)/sizeof(value_type))); + return (&r_)[i]; + } +*/ +}; // END of class Color + +#ifndef USE_HALF_TYPE +typedef Color ColorAccumulator; +#else +class ColorAccumulator +{ + friend class Color; +public: + typedef float value_type; + +private: + value_type a_, r_, g_, b_; + +public: + + ColorAccumulator & + operator+=(const ColorAccumulator &rhs) + { + r_+=rhs.r_; + g_+=rhs.g_; + b_+=rhs.b_; + a_+=rhs.a_; + return *this; + } + + ColorAccumulator & + operator-=(const ColorAccumulator &rhs) + { + r_-=rhs.r_; + g_-=rhs.g_; + b_-=rhs.b_; + a_-=rhs.a_; + return *this; + } + + ColorAccumulator & + operator*=(const float &rhs) + { + r_*=rhs; + g_*=rhs; + b_*=rhs; + a_*=rhs; + return *this; + } + + ColorAccumulator & + operator/=(const float &rhs) + { + const float temp(value_type(1)/rhs); + r_*=temp; + g_*=temp; + b_*=temp; + a_*=temp; + return *this; + } + + ColorAccumulator + operator+(const ColorAccumulator &rhs)const + { return Color(*this)+=rhs; } + + ColorAccumulator + operator-(const ColorAccumulator &rhs)const + { return Color(*this)-=rhs; } + + ColorAccumulator + operator*(const float &rhs)const + { return Color(*this)*=rhs; } + + ColorAccumulator + operator/(const float &rhs)const + { return Color(*this)/=rhs; } + + bool + operator==(const ColorAccumulator &rhs)const + { return r_==rhs.r_ && g_==rhs.g_ && b_==rhs.b_ && a_!=rhs.a_; } + + bool + operator!=(const ColorAccumulator &rhs)const + { return r_!=rhs.r_ || g_!=rhs.g_ || b_!=rhs.b_ || a_!=rhs.a_; } + + Color + operator-()const + { return ColorAccumulator(-r_,-g_,-b_,-a_); } + + bool is_valid()const + { return !isnan(r_) && !isnan(g_) && !isnan(b_) && !isnan(a_); } + +public: + ColorAccumulator() { } + + /*! \param R Red + ** \param G Green + ** \param B Blue + ** \param A Opacity(alpha) */ + ColorAccumulator(const value_type& R, const value_type& G, const value_type& B, const value_type& A=1): + a_(A), + r_(R), + g_(G), + b_(B) { } + + //! Copy constructor + ColorAccumulator(const ColorAccumulator& c): + a_(c.a_), + r_(c.r_), + g_(c.g_), + b_(c.b_) { } + + //! Converter + ColorAccumulator(const Color& c): + a_(c.a_), + r_(c.r_), + g_(c.g_), + b_(c.b_) { } + + //! Returns the RED component + const value_type& get_r()const { return r_; } + + //! Returns the GREEN component + const value_type& get_g()const { return g_; } + + //! Returns the BLUE component + const value_type& get_b()const { return b_; } + + //! Returns the amount of opacity (alpha) + const value_type& get_a()const { return a_; } + + //! Synonym for get_a(). \see get_a() + const value_type& get_alpha()const { return get_a(); } + + //! Sets the RED component to \a x + ColorAccumulator& set_r(const value_type& x) { r_ = x; return *this; } + + //! Sets the GREEN component to \a x + ColorAccumulator& set_g(const value_type& x) { g_ = x; return *this; } + + //! Sets the BLUE component to \a x + ColorAccumulator& set_b(const value_type& x) { b_ = x; return *this; } + + //! Sets the opacity (alpha) to \a x + ColorAccumulator& set_a(const value_type& x) { a_ = x; return *this; } + + //! Synonym for set_a(). \see set_a() + ColorAccumulator& set_alpha(const value_type& x) { return set_a(x); } +}; + +inline +Color::Color(const ColorAccumulator& c): + a_(c.a_), + r_(c.r_), + g_(c.g_), + b_(c.b_) { } + +#endif + + + + + +enum PixelFormat +{ +/* Bit Descriptions (ON/OFF) +** ----+------------- +** 0 Color Channels (Gray/RGB) +** 1 Alpha Channel (WITH/WITHOUT) +** 2 ZDepth (WITH/WITHOUT) +** 3 Endian (BGR/RGB) +** 4 Alpha Location (Start/End) +** 5 ZDepth Location (Start/End) +** 6 Alpha/ZDepth Arangement (ZA,AZ) +** 7 Alpha Range (Inverted,Normal) +** 8 Z Range (Inverted,Normal) +*/ + PF_RGB=0, + PF_GRAY=(1<<0), //!< If set, use one grayscale channel. If clear, use three channels for RGB + PF_A=(1<<1), //!< If set, include alpha channel + PF_Z=(1<<2), //!< If set, include ZDepth channel + PF_BGR=(1<<3), //!< If set, reverse the order of the RGB channels + PF_A_START=(1<<4), //!< If set, alpha channel is before the color data. If clear, it is after. + PF_Z_START=(1<<5), //!< If set, ZDepth channel is before the color data. If clear, it is after. + PF_ZA=(1<<6), //!< If set, the ZDepth channel will be infront of the alpha channel. If clear, they are reversed. + + PF_A_INV=(1<<7), //!< If set, the alpha channel is stored as 1.0-a + PF_Z_INV=(1<<8), //!< If set, the ZDepth channel is stored as 1.0-z + PF_RAW_COLOR=(1<<9)+(1<<1) //!< If set, the data represents a raw Color datastructure, and all other bits are ignored. +}; + +inline PixelFormat operator|(PixelFormat lhs, PixelFormat rhs) + { return static_cast((int)lhs|(int)rhs); } + +inline PixelFormat operator&(PixelFormat lhs, PixelFormat rhs) + { return static_cast((int)lhs&(int)rhs); } +#define FLAGS(x,y) (((x)&(y))==(y)) + +//! Returns the number of channels that the given PixelFormat calls for +inline int +channels(PixelFormat x) +{ + int chan=0; + if(FLAGS(x,PF_GRAY)) + ++chan; + else + chan+=3; + if(FLAGS(x,PF_A)) + ++chan; + if(FLAGS(x,PF_Z)) + ++chan; + if(FLAGS(x,PF_RAW_COLOR)) + chan=sizeof(Color); + + return chan; +} + +inline unsigned char * +Color2PixelFormat(const Color &color, const PixelFormat &pf, unsigned char *out, const Gamma &gamma) +{ + if(FLAGS(pf,PF_RAW_COLOR)) + { + Color *outcol=reinterpret_cast(out); + *outcol=color; + out+=sizeof(color); + return out; + } + + int alpha=(int)((FLAGS(pf,PF_A_INV)?(-(float)color.get_a()+1):(float)color.get_a())*255); + if(alpha<0)alpha=0; + if(alpha>255)alpha=255; + + if(FLAGS(pf,PF_ZA|PF_A_START|PF_Z_START)) + { + if(FLAGS(pf,PF_Z_START)) + *out++/*=(unsigned char)(color.GetZ()*255.0f)*/; + if(FLAGS(pf,PF_A_START)) + *out++=static_cast(alpha); + } + else + { + if(FLAGS(pf,PF_A_START)) + *out++=static_cast(alpha); + if(FLAGS(pf,PF_Z_START)) + *out++/*=(unsigned char)(color.GetZ()*255.0f)*/; + + } + + if(FLAGS(pf,PF_GRAY)) + *out++=static_cast(gamma.g_F32_to_U8(color.get_y())); + else + { + if(FLAGS(pf,PF_BGR)) + { + *out++=static_cast(gamma.r_F32_to_U8(color.get_b())); + *out++=static_cast(gamma.g_F32_to_U8(color.get_g())); + *out++=static_cast(gamma.b_F32_to_U8(color.get_r())); + } + else + { + *out++=static_cast(gamma.r_F32_to_U8(color.get_r())); + *out++=static_cast(gamma.g_F32_to_U8(color.get_g())); + *out++=static_cast(gamma.b_F32_to_U8(color.get_b())); + } + } + + if(FLAGS(pf,PF_ZA)) + { + if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z)) + out++;//*out++=(unsigned char)(color.GetZ()*255.0f); + if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A)) + *out++=static_cast(alpha); + } + else + { + if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z)) + out++;//*out++=(unsigned char)(color.GetZ()*255.0f); + if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A)) + *out++=static_cast(alpha); + } + return out; +} + +inline void +convert_color_format(unsigned char *dest, const Color *src, int w, PixelFormat pf,const Gamma &gamma) +{ + assert(w>=0); + while(w--) + dest=Color2PixelFormat((*(src++)).clamped(),pf,dest,gamma); +} + +inline const unsigned char * +PixelFormat2Color(Color &color, const PixelFormat &pf,const unsigned char *out) +{ + if(FLAGS(pf,PF_ZA|PF_A_START|PF_Z_START)) + { + if(FLAGS(pf,PF_Z_START)) + out++;//color.SetZ((Color::value_type)*out++/255.0f); + if(FLAGS(pf,PF_A_START)) + color.set_a((float)*out++/255); + } + else + { + if(FLAGS(pf,PF_A_START)) + color.set_a((float)*out++/255); + if(FLAGS(pf,PF_Z_START)) + out++;//color.SetZ((Color::value_type)*out++/255.0f); + } + + if(FLAGS(pf,PF_GRAY)) + color.set_yuv((float)*out++/255,0,0); + else + { + if(FLAGS(pf,PF_BGR)) + { + color.set_b((float)*out++/255); + color.set_g((float)*out++/255); + color.set_r((float)*out++/255); + } + else + { + color.set_r((float)*out++/255); + color.set_g((float)*out++/255); + color.set_b((float)*out++/255); + } + } + + if(FLAGS(pf,PF_ZA)) + { + if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z)) + out++;//color.SetZ((Color::value_type)*out++/255.0f); + if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A)) + color.set_a((float)*out++/255); + } + else + { + if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A)) + color.set_a((float)*out++/255); + if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z)) + out++;//color.SetZ((Color::value_type)*out++/255.0f); + } + return out; +} + + + +}; // END of namespace synfig + +/* === E N D =============================================================== */ + +#endif