synfig-core  1.0.3
color.hpp
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
24 /* ========================================================================= */
25 
26 #ifndef __SYNFIG_COLOR_COLOR_HPP
27 #define __SYNFIG_COLOR_COLOR_HPP
28 
29 #include <cmath>
30 #include <cassert>
31 #include <stdint.h>
32 
33 #include <synfig/gamma.h>
34 #include <synfig/string.h>
35 #include <synfig/angle.h>
36 
37 
38 #ifdef USE_HALF_TYPE
39 #include <OpenEXR/half.h>
40 #endif
41 #ifdef USING_PCH
42 # include "pch.h"
43 #else
44 #ifdef HAVE_CONFIG_H
45 # include <config.h>
46 #endif
47 
48 #include <ETL/angle>
49 #include <cstdio>
50 
51 #endif
52 
53 namespace synfig {
54 
56 {
57  r_+=rhs.r_;
58  g_+=rhs.g_;
59  b_+=rhs.b_;
60  a_+=rhs.a_;
61  return *this;
62 }
63 
65 {
66  r_-=rhs.r_;
67  g_-=rhs.g_;
68  b_-=rhs.b_;
69  a_-=rhs.a_;
70  return *this;
71 }
72 
73 Color& Color::operator*=(const float &rhs)
74 {
75  r_*=rhs;
76  g_*=rhs;
77  b_*=rhs;
78  a_*=rhs;
79  return *this;
80 }
81 
82 Color& Color::operator/=(const float &rhs)
83 {
84  const float temp(value_type(1)/rhs);
85  r_*=temp;
86  g_*=temp;
87  b_*=temp;
88  a_*=temp;
89  return *this;
90 }
91 
92 Color Color::operator+(const Color &rhs) const
93 {
94  return Color(*this)+=rhs;
95 }
96 
97 Color Color::operator-(const Color &rhs) const
98 { return Color(*this)-=rhs; }
99 
100 Color Color::operator*(const float &rhs)const
101 { return Color(*this)*=rhs; }
102 
103 Color Color::operator/(const float &rhs)const
104 { return Color(*this)/=rhs; }
105 
106 bool Color::operator==(const Color &rhs)const
107 { return r_==rhs.r_ && g_==rhs.g_ && b_==rhs.b_ && a_==rhs.a_; }
108 
109 bool Color::operator!=(const Color &rhs)const
110 { return r_!=rhs.r_ || g_!=rhs.g_ || b_!=rhs.b_ || a_!=rhs.a_; }
111 
113 { return Color(-r_,-g_,-b_,-a_); }
114 
117 { return Color(1.0f-r_,1.0f-g_,1.0f-b_,a_); }
118 
119 bool Color::is_valid()const
120 { return !isnan(r_) && !isnan(g_) && !isnan(b_) && !isnan(a_); }
121 
123 {
124  return Color (r_*a_, g_*a_, b_*a_, a_);
125 }
126 
128 {
129  if(a_)
130  {
131  const value_type inva = 1/a_;
132  return Color (r_*inva, g_*inva, b_*inva, a_);
133  }else return alpha();
134 }
135 
136 Color::Color() :a_(0), r_(0), g_(0), b_(0) { }
137 Color::Color(const value_type &f) :a_(f),r_(f), g_(f), b_(f) { }
138 Color::Color(int f) :a_(f),r_(f), g_(f), b_(f) { }
139 
141  const value_type& G,
142  const value_type& B,
143  const value_type& A):
144  a_(A),
145  r_(R),
146  g_(G),
147  b_(B) { }
148 
149 Color::Color(const Color& c, const value_type& A):
150  a_(A),
151  r_(c.r_),
152  g_(c.g_),
153  b_(c.b_) { }
154 
155 Color::Color(const Color& c):
156  a_(c.a_),
157  r_(c.r_),
158  g_(c.g_),
159  b_(c.b_) { }
160 
161 #ifdef USE_HALF_TYPE
162  friend class ColorAccumulator;
164  Color(const ColorAccumulator& c);
165 #endif
166 
168  //Color(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); }
169 
170  /*const Color &operator=(const value_type &i)
171  {
172  r_ = g_ = b_ = a_ = i;
173  return *this;
174  }*/
175  //Color& operator=(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); return *this; }
176 
177 
178 const String Color::get_hex()const
179 {
180  return String(real2hex(r_) + real2hex(g_) + real2hex(b_));
181 }
182 
183 
185 float Color::get_y() const
186 {
187  return
188  (float)get_r()*EncodeYUV[0][0]+
189  (float)get_g()*EncodeYUV[0][1]+
190  (float)get_b()*EncodeYUV[0][2];
191 }
192 
193 
195 float Color::get_u() const
196 {
197  return
198  (float)get_r()*EncodeYUV[1][0]+
199  (float)get_g()*EncodeYUV[1][1]+
200  (float)get_b()*EncodeYUV[1][2];
201 }
202 
203 
205 float Color::get_v() const
206 {
207  return
208  (float)get_r()*EncodeYUV[2][0]+
209  (float)get_g()*EncodeYUV[2][1]+
210  (float)get_b()*EncodeYUV[2][2];
211 }
212 
214 
216 float Color::get_s() const
217 {
218  const float u(get_u()), v(get_v());
219  return sqrt(u*u+v*v);
220 }
221 
223 Color& Color::set_yuv(const float &y, const float &u, const float &v)
224 {
225  set_r(y*DecodeYUV[0][0]+u*DecodeYUV[0][1]+v*DecodeYUV[0][2]);
226  set_g(y*DecodeYUV[1][0]+u*DecodeYUV[1][1]+v*DecodeYUV[1][2]);
227  set_b(y*DecodeYUV[2][0]+u*DecodeYUV[2][1]+v*DecodeYUV[2][2]);
228  return *this;
229 }
230 
232 Color& Color::set_y(const float &y) { return set_yuv(y,get_u(),get_v()); }
233 
235 Color& Color::set_u(const float &u) { return set_yuv(get_y(),u,get_v()); }
236 
238 Color& Color::set_v(const float &v) { return set_yuv(get_y(),get_u(),v); }
239 
241 Color& Color::set_uv(const float& u, const float& v) { return set_yuv(get_y(),u,v); }
242 
244 
245 Color& Color::set_s(const float &x)
246 {
247  float u(get_u()), v(get_v());
248  const float s(sqrt(u*u+v*v));
249  if(s)
250  {
251  u=(u/s)*x;
252  v=(v/s)*x;
253  return set_uv(u,v);
254  }
255  return *this;
256 }
257 
259 Color Color::YUV(const float& y, const float& u, const float& v, const value_type& a)
260  { return Color().set_yuv(y,u,v).set_a(a); }
261 
263 
266  { return Angle::tan(get_u(),get_v()); }
267 
269 Angle Color::get_uv_angle() const { return get_hue(); }
270 
272 
273 Color& Color::set_hue(const Angle& theta)
274 {
275  const float s(get_s());
276  const float
277  u(s*(float)Angle::sin(theta).get()),
278  v(s*(float)Angle::cos(theta).get());
279  return set_uv(u,v);
280 }
281 
283 Color& Color::set_uv_angle(const Angle& theta) { return set_hue(theta); }
284 
287 {
288  const float a(Angle::sin(theta).get()), b(Angle::cos(theta).get());
289  const float u(get_u()), v(get_v());
290 
291  return set_uv(b*u-a*v,a*u+b*v);
292 }
293 
294 Color& Color::set_yuv(const float& y, const float& s, const Angle& theta)
295 {
296  return
297  set_yuv(
298  y,
299  s*(float)Angle::sin(theta).get(),
300  s*(float)Angle::cos(theta).get()
301  );
302 }
303 
304 Color Color::YUV(const float& y, const float& s, const Angle& theta, const value_type& a)
305  { return Color().set_yuv(y,s,theta).set_a(a); }
306 
307 
308 
309 /*protected:
310 
311  value_type& operator[](const int i)
312  {
313  assert(i>=0);
314  assert(i<(signed)(sizeof(Color)/sizeof(value_type)));
315  return (&r_)[i];
316  }
317 
318  const value_type& operator[](const int i)const
319  {
320  assert(i>=0);
321  assert(i<(signed)(sizeof(Color)/sizeof(value_type)));
322  return (&r_)[i];
323  }
324 */
325 
326 } // synfig namespace
327 
328 #endif // __SYNFIG_COLOR_COLOR_HPP
329