1 /* === S Y N F I G ========================================================= */
3 ** \brief Color Class Implementation
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
11 ** This package is free software; you can redistribute it and/or
12 ** modify it under the terms of the GNU General Public License as
13 ** published by the Free Software Foundation; either version 2 of
14 ** the License, or (at your option) any later version.
16 ** This package is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ** General Public License for more details.
22 /* ========================================================================= */
24 /* === S T A R T =========================================================== */
26 #ifndef __SYNFIG_COLOR_H
27 #define __SYNFIG_COLOR_H
29 /* === H E A D E R S ======================================================= */
35 #include <synfig/string.h>
39 #include <OpenEXR/half.h>
42 /* === M A C R O S ========================================================= */
44 #define use_colorspace_gamma() App::use_colorspace_gamma
45 #define colorspace_gamma() (2.2f)
46 #define gamma_in(x) ((x>=0) ? pow((float)x,1.0f/colorspace_gamma()) : -pow((float)-x,1.0f/colorspace_gamma()))
47 #define gamma_out(x) ((x>=0) ? pow((float)x, colorspace_gamma()) : -pow((float)-x, colorspace_gamma()))
52 extern "C" { int _isnan(double x); }
57 // For some reason isnan() isn't working on macosx any more.
58 // This is a quick fix.
59 #if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX)
63 inline bool isnan(double x) { return x != x; }
64 inline bool isnan(float x) { return x != x; }
65 #define SYNFIG_ISNAN_FIX 1
71 typedef half ColorReal;
73 typedef float ColorReal;
76 static const float EncodeYUV[3][3]=
78 { 0.299f, 0.587f, 0.114f },
79 { -0.168736f, -0.331264f, 0.5f },
80 { 0.5f, -0.418688f, -0.081312f }
83 static const float DecodeYUV[3][3]=
85 { 1.0f, 0.0f, 1.402f },
86 { 1.0f, -0.344136f, -0.714136f },
87 { 1.0f, 1.772f, 0.0f }
90 /* === T Y P E D E F S ===================================================== */
92 /* === C L A S S E S & S T R U C T S ======================================= */
95 class ColorAccumulator;
103 ** Future optimizations: lookup table for sqrt()?
108 typedef ColorReal value_type;
111 value_type a_, r_, g_, b_;
115 const String get_string(void)const;
118 operator+=(const Color &rhs)
128 operator-=(const Color &rhs)
138 operator*=(const float &rhs)
148 operator/=(const float &rhs)
150 const float temp(value_type(1)/rhs);
159 operator+(const Color &rhs)const
160 { return Color(*this)+=rhs; }
163 operator-(const Color &rhs)const
164 { return Color(*this)-=rhs; }
167 operator*(const float &rhs)const
168 { return Color(*this)*=rhs; }
171 operator/(const float &rhs)const
172 { return Color(*this)/=rhs; }
175 operator==(const Color &rhs)const
176 { return r_==rhs.r_ && g_==rhs.g_ && b_==rhs.b_ && a_==rhs.a_; }
179 operator!=(const Color &rhs)const
180 { return r_!=rhs.r_ || g_!=rhs.g_ || b_!=rhs.b_ || a_!=rhs.a_; }
184 { return Color(-r_,-g_,-b_,-a_); }
186 //! Effectively 1.0-color
189 { return Color(1.0f-r_,1.0f-g_,1.0f-b_,a_); }
192 { return !isnan(r_) && !isnan(g_) && !isnan(b_) && !isnan(a_); }
194 Color premult_alpha() const
196 return Color (r_*a_, g_*a_, b_*a_, a_);
199 Color demult_alpha() const
203 const value_type inva = 1/a_;
204 return Color (r_*inva, g_*inva, b_*inva, a_);
205 }else return alpha();
209 // ETL/trunk/ETL/_gaussian.h does:
210 // SR1=SR2=SR3=typename T::value_type();
211 // and expects that to give it initialized colors
212 // Otherwise the 'gaussian' blur type is random.
213 Color() :a_(0), r_(0), g_(0), b_(0) { }
214 Color(const value_type &f) :a_(f),r_(f), g_(f), b_(f) { }
215 Color(int f) :a_(f),r_(f), g_(f), b_(f) { }
220 ** \param A Opacity(alpha) */
221 Color(const value_type& R, const value_type& G, const value_type& B, const value_type& A=1):
227 /*! \param c Source for color components
228 ** \param A Opacity(alpha) */
229 Color(const Color& c, const value_type& A):
237 Color(const Color& c):
244 friend class ColorAccumulator;
245 //! Convert constructor
246 Color(const ColorAccumulator& c);
250 //Color(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); }
252 /*const Color &operator=(const value_type &i)
254 r_ = g_ = b_ = a_ = i;
257 //Color& operator=(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); return *this; }
259 //! Returns the RED component
260 const value_type& get_r()const { return r_; }
262 //! Returns the GREEN component
263 const value_type& get_g()const { return g_; }
265 //! Returns the BLUE component
266 const value_type& get_b()const { return b_; }
268 //! Returns the amount of opacity (alpha)
269 const value_type& get_a()const { return a_; }
271 //! Synonym for get_a(). \see get_a()
272 const value_type& get_alpha()const { return get_a(); }
274 //! Converts a 2 character hex string \a s (00-ff) into a ColorReal (0.0-1.0)
275 static ColorReal hex2real(String s);
277 //! Converts a ColorReal \a c (0.0-1.0) into a 2 character hex string (00-ff)
278 static const String real2hex(ColorReal c);
280 //! Returns the color as a 6 character hex sting
281 const String get_hex()const { return String(real2hex(r_)+real2hex(g_)+real2hex(b_)); }
283 //! Sets the color's R, G, and B from a 3 or 6 character hex string
284 void set_hex(String& hex);
286 //! Sets the RED component to \a x
287 Color& set_r(const value_type& x) { r_ = x; return *this; }
289 //! Sets the GREEN component to \a x
290 Color& set_g(const value_type& x) { g_ = x; return *this; }
292 //! Sets the BLUE component to \a x
293 Color& set_b(const value_type& x) { b_ = x; return *this; }
295 //! Sets the opacity (alpha) to \a x
296 Color& set_a(const value_type& x) { a_ = x; return *this; }
298 //! Synonym for set_a(). \see set_a()
299 Color& set_alpha(const value_type& x) { return set_a(x); }
301 //! Returns color's luminance
306 (float)get_r()*EncodeYUV[0][0]+
307 (float)get_g()*EncodeYUV[0][1]+
308 (float)get_b()*EncodeYUV[0][2];
312 //! Returns U component of chromanance
317 (float)get_r()*EncodeYUV[1][0]+
318 (float)get_g()*EncodeYUV[1][1]+
319 (float)get_b()*EncodeYUV[1][2];
323 //! Returns V component of chromanance
328 (float)get_r()*EncodeYUV[2][0]+
329 (float)get_g()*EncodeYUV[2][1]+
330 (float)get_b()*EncodeYUV[2][2];
333 //! Returns the color's saturation
334 /*! This is is the magnitude of the U and V components.
339 const float u(get_u()), v(get_v());
340 return sqrt(u*u+v*v);
343 //! Sets the luminance (\a y) and chromanance (\a u and \a v)
345 set_yuv(const float &y, const float &u, const float &v)
347 set_r(y*DecodeYUV[0][0]+u*DecodeYUV[0][1]+v*DecodeYUV[0][2]);
348 set_g(y*DecodeYUV[1][0]+u*DecodeYUV[1][1]+v*DecodeYUV[1][2]);
349 set_b(y*DecodeYUV[2][0]+u*DecodeYUV[2][1]+v*DecodeYUV[2][2]);
353 //! Sets color luminance
354 Color& set_y(const float &y) { return set_yuv(y,get_u(),get_v()); }
356 //! Set U component of chromanance
357 Color& set_u(const float &u) { return set_yuv(get_y(),u,get_v()); }
359 //! Set V component of chromanance
360 Color& set_v(const float &v) { return set_yuv(get_y(),get_u(),v); }
362 //! Set the U and V components of chromanance
363 Color& set_uv(const float& u, const float& v) { return set_yuv(get_y(),u,v); }
365 //! Sets the color's saturation
368 set_s(const float &x)
370 float u(get_u()), v(get_v());
371 const float s(sqrt(u*u+v*v));
381 //! YUV Color constructor
382 static Color YUV(const float& y, const float& u, const float& v, const value_type& a=1)
383 { return Color().set_yuv(y,u,v).set_a(a); }
385 //! Returns the hue of the chromanance
386 /*! This is the angle of the U and V components.
390 { return Angle::tan(get_u(),get_v()); }
392 //! Synonym for get_hue(). \see get_hue()
393 Angle get_uv_angle() const { return get_hue(); }
395 //! Sets the color's hue
396 /*! \see get_hue() */
398 set_hue(const Angle& theta)
400 const float s(get_s());
402 u(s*(float)Angle::sin(theta).get()),
403 v(s*(float)Angle::cos(theta).get());
407 //! Synonym for set_hue(). \see set_hue()
408 Color& set_uv_angle(const Angle& theta) { return set_hue(theta); }
410 //! Rotates the chromanance vector by amount specified by \a theta
411 Color& rotate_uv(const Angle& theta)
413 const float a(Angle::sin(theta).get()), b(Angle::cos(theta).get());
414 const float u(get_u()), v(get_v());
416 return set_uv(b*u-a*v,a*u+b*v);
419 //! Sets the luminance (\a y) and chromanance (\a s and \a theta).
420 /*! \param y Luminance
421 ** \param s Saturation
422 ** \param theta Hue */
423 Color& set_yuv(const float& y, const float& s, const Angle& theta)
428 s*(float)Angle::sin(theta).get(),
429 s*(float)Angle::cos(theta).get()
433 //! YUV color constructor where the chroma is in the saturation/hue form.
434 /*! \param y Luminance
435 ** \param s Saturation
437 ** \param a Opacity (alpha) */
438 static Color YUV(const float& y, const float& s, const Angle& theta, const value_type& a=1)
439 { return Color().set_yuv(y,s,theta).set_a(a); }
442 //! Clamps a color so that its values are in range. Ignores attempting to visualize negative colors.
443 Color clamped()const;
445 //! Clamps a color so that its values are in range.
446 Color clamped_negative()const;
450 //! Preset Color Constructors
453 static inline Color alpha() { return Color(0,0,0,0.0000001f); }
455 static inline Color alpha() { return Color(0,0,0,0); }
457 static inline Color black() { return Color(0,0,0); }
458 static inline Color white() { return Color(1,1,1); }
459 static inline Color gray() { return Color(0.5f,0.5f,0.5f); }
460 static inline Color magenta() { return Color(1,0,1); }
461 static inline Color red() { return Color(1,0,0); }
462 static inline Color green() { return Color(0,1,0); }
463 static inline Color blue() { return Color(0,0,1); }
464 static inline Color cyan() { return Color(0,1,1); }
465 static inline Color yellow() { return Color(1,1,0); }
471 BLEND_COMPOSITE=0, //!< Color A is composited onto B (Taking A's alpha into account)
472 BLEND_STRAIGHT=1, //!< Straight linear interpolation from A->B (Alpha ignored)
473 BLEND_ONTO=13, //!< Similar to BLEND_COMPOSITE, except that B's alpha is maintained
474 BLEND_STRAIGHT_ONTO=21, //!< \deprecated \writeme
475 BLEND_BEHIND=12, //!< Similar to BLEND_COMPOSITE, except that B is composited onto A.
476 BLEND_SCREEN=16, //!< \writeme
477 BLEND_OVERLAY=20, //!< \writeme
478 BLEND_HARD_LIGHT=17, //!< \writeme
479 BLEND_MULTIPLY=6, //!< Simple A*B.
480 BLEND_DIVIDE=7, //!< Simple B/A
481 BLEND_ADD=4, //!< Simple A+B.
482 BLEND_SUBTRACT=5, //!< Simple A-B.
483 BLEND_DIFFERENCE=18, //!< Simple |A-B|.
484 BLEND_BRIGHTEN=2, //!< If composite is brighter than B, use composite. B otherwise.
485 BLEND_DARKEN=3, //!< If composite is darker than B, use composite. B otherwise.
486 BLEND_COLOR=8, //!< Preserves the U and V channels of color A
487 BLEND_HUE=9, //!< Preserves the angle of the UV vector of color A
488 BLEND_SATURATION=10, //!< Preserves the magnitude of the UV Vector of color A
489 BLEND_LUMINANCE=11, //!< Preserves the Y channel of color A
491 BLEND_ALPHA_BRIGHTEN=14, //!< \deprecated If A is less opaque than B, use A
492 BLEND_ALPHA_DARKEN=15, //!< \deprecated If A is more opaque than B, use B
493 BLEND_ALPHA_OVER=19, //!< \deprecated multiply alphas and then straight blends using the amount
495 BLEND_END=22, //!< \internal
496 BLEND_BY_LAYER=999 //! Used to let the layer decides what Blend Method use by
497 //! default when the layer is created
501 static Color blend(Color a, Color b,float amount,BlendMethod type=BLEND_COMPOSITE);
503 static bool is_onto(BlendMethod x)
505 return x==BLEND_BRIGHTEN
513 || x==BLEND_SATURATION
514 || x==BLEND_LUMINANCE
516 || x==BLEND_STRAIGHT_ONTO
519 || x==BLEND_DIFFERENCE
520 || x==BLEND_HARD_LIGHT
524 //! a blending method is considered 'straight' if transparent pixels in the upper layer can affect the result of the blend
525 static bool is_straight(BlendMethod x)
527 return x==BLEND_STRAIGHT
528 || x==BLEND_STRAIGHT_ONTO
529 || x==BLEND_ALPHA_BRIGHTEN
534 value_type& operator[](const int i)
537 assert(i<(signed)(sizeof(Color)/sizeof(value_type)));
541 const value_type& operator[](const int i)const
544 assert(i<(signed)(sizeof(Color)/sizeof(value_type)));
548 }; // END of class Color
550 #ifndef USE_HALF_TYPE
551 typedef Color ColorAccumulator;
553 class ColorAccumulator
557 typedef float value_type;
560 value_type a_, r_, g_, b_;
565 operator+=(const ColorAccumulator &rhs)
575 operator-=(const ColorAccumulator &rhs)
585 operator*=(const float &rhs)
595 operator/=(const float &rhs)
597 const float temp(value_type(1)/rhs);
606 operator+(const ColorAccumulator &rhs)const
607 { return Color(*this)+=rhs; }
610 operator-(const ColorAccumulator &rhs)const
611 { return Color(*this)-=rhs; }
614 operator*(const float &rhs)const
615 { return Color(*this)*=rhs; }
618 operator/(const float &rhs)const
619 { return Color(*this)/=rhs; }
622 operator==(const ColorAccumulator &rhs)const
623 { return r_==rhs.r_ && g_==rhs.g_ && b_==rhs.b_ && a_!=rhs.a_; }
626 operator!=(const ColorAccumulator &rhs)const
627 { return r_!=rhs.r_ || g_!=rhs.g_ || b_!=rhs.b_ || a_!=rhs.a_; }
631 { return ColorAccumulator(-r_,-g_,-b_,-a_); }
634 { return !isnan(r_) && !isnan(g_) && !isnan(b_) && !isnan(a_); }
637 ColorAccumulator() { }
642 ** \param A Opacity(alpha) */
643 ColorAccumulator(const value_type& R, const value_type& G, const value_type& B, const value_type& A=1):
650 ColorAccumulator(const ColorAccumulator& c):
657 ColorAccumulator(const Color& c):
664 ColorAccumulator(int c): a_(c),r_(c), g_(c), b_(c) { }
666 //! Returns the RED component
667 const value_type& get_r()const { return r_; }
669 //! Returns the GREEN component
670 const value_type& get_g()const { return g_; }
672 //! Returns the BLUE component
673 const value_type& get_b()const { return b_; }
675 //! Returns the amount of opacity (alpha)
676 const value_type& get_a()const { return a_; }
678 //! Synonym for get_a(). \see get_a()
679 const value_type& get_alpha()const { return get_a(); }
681 //! Sets the RED component to \a x
682 ColorAccumulator& set_r(const value_type& x) { r_ = x; return *this; }
684 //! Sets the GREEN component to \a x
685 ColorAccumulator& set_g(const value_type& x) { g_ = x; return *this; }
687 //! Sets the BLUE component to \a x
688 ColorAccumulator& set_b(const value_type& x) { b_ = x; return *this; }
690 //! Sets the opacity (alpha) to \a x
691 ColorAccumulator& set_a(const value_type& x) { a_ = x; return *this; }
693 //! Synonym for set_a(). \see set_a()
694 ColorAccumulator& set_alpha(const value_type& x) { return set_a(x); }
698 Color::Color(const ColorAccumulator& c):
712 /* Bit Descriptions (ON/OFF)
713 ** ----+-------------
714 ** 0 Color Channels (Gray/RGB)
715 ** 1 Alpha Channel (WITH/WITHOUT)
716 ** 2 ZDepth (WITH/WITHOUT)
717 ** 3 Endian (BGR/RGB)
718 ** 4 Alpha Location (Start/End)
719 ** 5 ZDepth Location (Start/End)
720 ** 6 Alpha/ZDepth Arrangement (ZA,AZ)
721 ** 7 Alpha Range (Inverted,Normal)
722 ** 8 Z Range (Inverted,Normal)
725 PF_GRAY=(1<<0), //!< If set, use one grayscale channel. If clear, use three channels for RGB
726 PF_A=(1<<1), //!< If set, include alpha channel
727 PF_Z=(1<<2), //!< If set, include ZDepth channel
728 PF_BGR=(1<<3), //!< If set, reverse the order of the RGB channels
729 PF_A_START=(1<<4), //!< If set, alpha channel is before the color data. If clear, it is after.
730 PF_Z_START=(1<<5), //!< If set, ZDepth channel is before the color data. If clear, it is after.
731 PF_ZA=(1<<6), //!< If set, the ZDepth channel will be in front of the alpha channel. If clear, they are reversed.
733 PF_A_INV=(1<<7), //!< If set, the alpha channel is stored as 1.0-a
734 PF_Z_INV=(1<<8), //!< If set, the ZDepth channel is stored as 1.0-z
735 PF_RAW_COLOR=(1<<9)+(1<<1) //!< If set, the data represents a raw Color data structure, and all other bits are ignored.
738 inline PixelFormat operator|(PixelFormat lhs, PixelFormat rhs)
739 { return static_cast<PixelFormat>((int)lhs|(int)rhs); }
741 inline PixelFormat operator&(PixelFormat lhs, PixelFormat rhs)
742 { return static_cast<PixelFormat>((int)lhs&(int)rhs); }
743 #define FLAGS(x,y) (((x)&(y))==(y))
745 //! Returns the number of channels that the given PixelFormat calls for
747 channels(PixelFormat x)
758 if(FLAGS(x,PF_RAW_COLOR))
764 inline unsigned char *
765 Color2PixelFormat(const Color &color, const PixelFormat &pf, unsigned char *out, const Gamma &gamma)
767 if(FLAGS(pf,PF_RAW_COLOR))
769 Color *outcol=reinterpret_cast<Color *>(out);
775 int alpha=(int)((FLAGS(pf,PF_A_INV)?(-(float)color.get_a()+1):(float)color.get_a())*255);
777 if(alpha>255)alpha=255;
779 if(FLAGS(pf,PF_ZA|PF_A_START|PF_Z_START))
781 if(FLAGS(pf,PF_Z_START))
782 *out++/*=(unsigned char)(color.GetZ()*255.0f)*/;
783 if(FLAGS(pf,PF_A_START))
784 *out++=static_cast<unsigned char>(alpha);
788 if(FLAGS(pf,PF_A_START))
789 *out++=static_cast<unsigned char>(alpha);
790 if(FLAGS(pf,PF_Z_START))
791 *out++/*=(unsigned char)(color.GetZ()*255.0f)*/;
795 if(FLAGS(pf,PF_GRAY))
796 *out++=static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_y()));
801 *out++=static_cast<unsigned char>(gamma.r_F32_to_U8(color.get_b()));
802 *out++=static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_g()));
803 *out++=static_cast<unsigned char>(gamma.b_F32_to_U8(color.get_r()));
807 *out++=static_cast<unsigned char>(gamma.r_F32_to_U8(color.get_r()));
808 *out++=static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_g()));
809 *out++=static_cast<unsigned char>(gamma.b_F32_to_U8(color.get_b()));
815 if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
816 out++;//*out++=(unsigned char)(color.GetZ()*255.0f);
817 if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
818 *out++=static_cast<unsigned char>(alpha);
822 if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
823 out++;//*out++=(unsigned char)(color.GetZ()*255.0f);
824 if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
825 *out++=static_cast<unsigned char>(alpha);
831 convert_color_format(unsigned char *dest, const Color *src, int w, PixelFormat pf,const Gamma &gamma)
835 dest=Color2PixelFormat((*(src++)).clamped(),pf,dest,gamma);
838 inline const unsigned char *
839 PixelFormat2Color(Color &color, const PixelFormat &pf,const unsigned char *out)
841 if(FLAGS(pf,PF_ZA|PF_A_START|PF_Z_START))
843 if(FLAGS(pf,PF_Z_START))
844 out++;//color.SetZ((Color::value_type)*out++/255.0f);
845 if(FLAGS(pf,PF_A_START))
846 color.set_a((float)*out++/255);
850 if(FLAGS(pf,PF_A_START))
851 color.set_a((float)*out++/255);
852 if(FLAGS(pf,PF_Z_START))
853 out++;//color.SetZ((Color::value_type)*out++/255.0f);
856 if(FLAGS(pf,PF_GRAY))
857 color.set_yuv((float)*out++/255,0,0);
862 color.set_b((float)*out++/255);
863 color.set_g((float)*out++/255);
864 color.set_r((float)*out++/255);
868 color.set_r((float)*out++/255);
869 color.set_g((float)*out++/255);
870 color.set_b((float)*out++/255);
876 if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
877 out++;//color.SetZ((Color::value_type)*out++/255.0f);
878 if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
879 color.set_a((float)*out++/255);
883 if(!FLAGS(pf,PF_A_START) && FLAGS(pf,PF_A))
884 color.set_a((float)*out++/255);
885 if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
886 out++;//color.SetZ((Color::value_type)*out++/255.0f);
893 }; // END of namespace synfig
895 /* === E N D =============================================================== */