|
Diego Barrios Romero |
3570f3 |
/* === S Y N F I G ========================================================= */
|
|
Diego Barrios Romero |
3570f3 |
/*! \file
|
|
Diego Barrios Romero |
3570f3 |
** \brief Color class function implementation
|
|
Diego Barrios Romero |
3570f3 |
**
|
|
Diego Barrios Romero |
3570f3 |
** $Id$
|
|
Diego Barrios Romero |
3570f3 |
**
|
|
Diego Barrios Romero |
3570f3 |
** \legal
|
|
Diego Barrios Romero |
3570f3 |
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
|
|
Diego Barrios Romero |
3570f3 |
** Copyright (c) 2007, 2008 Chris Moore
|
|
Diego Barrios Romero |
3570f3 |
** Copyright (c) 2012-2013 Carlos Lรณpez
|
|
Diego Barrios Romero |
3570f3 |
** Copyright (c) 2015 Diego Barrios Romero
|
|
Diego Barrios Romero |
3570f3 |
**
|
|
Diego Barrios Romero |
3570f3 |
** This package is free software; you can redistribute it and/or
|
|
Diego Barrios Romero |
3570f3 |
** modify it under the terms of the GNU General Public License as
|
|
Diego Barrios Romero |
3570f3 |
** published by the Free Software Foundation; either version 2 of
|
|
Diego Barrios Romero |
3570f3 |
** the License, or (at your option) any later version.
|
|
Diego Barrios Romero |
3570f3 |
**
|
|
Diego Barrios Romero |
3570f3 |
** This package is distributed in the hope that it will be useful,
|
|
Diego Barrios Romero |
3570f3 |
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Diego Barrios Romero |
3570f3 |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Diego Barrios Romero |
3570f3 |
** General Public License for more details.
|
|
Diego Barrios Romero |
3570f3 |
** \endlegal
|
|
Diego Barrios Romero |
3570f3 |
*/
|
|
Diego Barrios Romero |
3570f3 |
/* ========================================================================= */
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
#ifndef __SYNFIG_COLOR_COLOR_HPP
|
|
Diego Barrios Romero |
3570f3 |
#define __SYNFIG_COLOR_COLOR_HPP
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
#include <cmath></cmath>
|
|
Diego Barrios Romero |
3570f3 |
#include <cassert></cassert>
|
|
Diego Barrios Romero |
3570f3 |
#include <stdint.h></stdint.h>
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
#include <synfig string.h=""></synfig>
|
|
Diego Barrios Romero |
3570f3 |
#include <synfig angle.h=""></synfig>
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
#ifdef USING_PCH
|
|
Diego Barrios Romero |
3570f3 |
# include "pch.h"
|
|
Diego Barrios Romero |
3570f3 |
#else
|
|
Diego Barrios Romero |
3570f3 |
#ifdef HAVE_CONFIG_H
|
|
Diego Barrios Romero |
3570f3 |
# include <config.h></config.h>
|
|
Diego Barrios Romero |
3570f3 |
#endif
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
#include <etl angle=""></etl>
|
|
Diego Barrios Romero |
3570f3 |
#include <cstdio></cstdio>
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
#endif
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
namespace synfig {
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::operator+=(const Color &rhs)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
r_+=rhs.r_;
|
|
Diego Barrios Romero |
3570f3 |
g_+=rhs.g_;
|
|
Diego Barrios Romero |
3570f3 |
b_+=rhs.b_;
|
|
Diego Barrios Romero |
3570f3 |
a_+=rhs.a_;
|
|
Diego Barrios Romero |
3570f3 |
return *this;
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::operator-=(const Color &rhs)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
r_-=rhs.r_;
|
|
Diego Barrios Romero |
3570f3 |
g_-=rhs.g_;
|
|
Diego Barrios Romero |
3570f3 |
b_-=rhs.b_;
|
|
Diego Barrios Romero |
3570f3 |
a_-=rhs.a_;
|
|
Diego Barrios Romero |
3570f3 |
return *this;
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::operator*=(const float &rhs)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
r_*=rhs;
|
|
Diego Barrios Romero |
3570f3 |
g_*=rhs;
|
|
Diego Barrios Romero |
3570f3 |
b_*=rhs;
|
|
Diego Barrios Romero |
3570f3 |
a_*=rhs;
|
|
Diego Barrios Romero |
3570f3 |
return *this;
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::operator/=(const float &rhs)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
const float temp(value_type(1)/rhs);
|
|
Diego Barrios Romero |
3570f3 |
r_*=temp;
|
|
Diego Barrios Romero |
3570f3 |
g_*=temp;
|
|
Diego Barrios Romero |
3570f3 |
b_*=temp;
|
|
Diego Barrios Romero |
3570f3 |
a_*=temp;
|
|
Diego Barrios Romero |
3570f3 |
return *this;
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color Color::operator+(const Color &rhs) const
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
return Color(*this)+=rhs;
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color Color::operator-(const Color &rhs) const
|
|
Diego Barrios Romero |
3570f3 |
{ return Color(*this)-=rhs; }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color Color::operator*(const float &rhs)const
|
|
Diego Barrios Romero |
3570f3 |
{ return Color(*this)*=rhs; }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color Color::operator/(const float &rhs)const
|
|
Diego Barrios Romero |
3570f3 |
{ return Color(*this)/=rhs; }
|
|
Diego Barrios Romero |
3570f3 |
|
|
|
5ccd0a |
bool Color::operator<(const Color &rhs)const
|
|
|
5ccd0a |
{
|
|
|
5ccd0a |
return r_
|
|
|
5ccd0a |
: g_
|
|
|
5ccd0a |
: b_
|
|
|
5ccd0a |
: a_
|
|
|
5ccd0a |
}
|
|
|
5ccd0a |
|
|
Diego Barrios Romero |
3570f3 |
bool Color::operator==(const Color &rhs)const
|
|
Diego Barrios Romero |
3570f3 |
{ return r_==rhs.r_ && g_==rhs.g_ && b_==rhs.b_ && a_==rhs.a_; }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
bool Color::operator!=(const Color &rhs)const
|
|
Diego Barrios Romero |
3570f3 |
{ return r_!=rhs.r_ || g_!=rhs.g_ || b_!=rhs.b_ || a_!=rhs.a_; }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color Color::operator-()const
|
|
Diego Barrios Romero |
3570f3 |
{ return Color(-r_,-g_,-b_,-a_); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Effectively 1.0-color
|
|
Diego Barrios Romero |
3570f3 |
Color Color::operator~()const
|
|
Diego Barrios Romero |
3570f3 |
{ return Color(1.0f-r_,1.0f-g_,1.0f-b_,a_); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
bool Color::is_valid()const
|
|
[d.j.a.y] Jerome Blanchi |
c14c8d |
{ return !std::isnan(r_) && !std::isnan(g_) && !std::isnan(b_) && !std::isnan(a_); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color Color::premult_alpha() const
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
return Color (r_*a_, g_*a_, b_*a_, a_);
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color Color::demult_alpha() const
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
if(a_)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
const value_type inva = 1/a_;
|
|
Diego Barrios Romero |
3570f3 |
return Color (r_*inva, g_*inva, b_*inva, a_);
|
|
Diego Barrios Romero |
3570f3 |
}else return alpha();
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
|
55af16 |
Color::Color() :r_(0), g_(0), b_(0),a_(0) { }
|
|
|
55af16 |
Color::Color(const value_type &f) :r_(f), g_(f), b_(f),a_(f) { }
|
|
|
55af16 |
Color::Color(int f) :r_(f), g_(f), b_(f),a_(f) { }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color::Color(const value_type& R,
|
|
Diego Barrios Romero |
3570f3 |
const value_type& G,
|
|
Diego Barrios Romero |
3570f3 |
const value_type& B,
|
|
Diego Barrios Romero |
3570f3 |
const value_type& A):
|
|
Diego Barrios Romero |
3570f3 |
r_(R),
|
|
Diego Barrios Romero |
3570f3 |
g_(G),
|
|
|
55af16 |
b_(B),
|
|
|
55af16 |
a_(A) { }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color::Color(const Color& c, const value_type& A):
|
|
Diego Barrios Romero |
3570f3 |
r_(c.r_),
|
|
Diego Barrios Romero |
3570f3 |
g_(c.g_),
|
|
|
55af16 |
b_(c.b_),
|
|
|
55af16 |
a_(A) { }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color::Color(const Color& c):
|
|
Diego Barrios Romero |
3570f3 |
r_(c.r_),
|
|
Diego Barrios Romero |
3570f3 |
g_(c.g_),
|
|
|
55af16 |
b_(c.b_),
|
|
|
55af16 |
a_(c.a_) { }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
const String Color::get_hex()const
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
return String(real2hex(r_) + real2hex(g_) + real2hex(b_));
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Returns color's luminance
|
|
Diego Barrios Romero |
3570f3 |
float Color::get_y() const
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
return
|
|
Diego Barrios Romero |
3570f3 |
(float)get_r()*EncodeYUV[0][0]+
|
|
Diego Barrios Romero |
3570f3 |
(float)get_g()*EncodeYUV[0][1]+
|
|
Diego Barrios Romero |
3570f3 |
(float)get_b()*EncodeYUV[0][2];
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Returns U component of chromanance
|
|
Diego Barrios Romero |
3570f3 |
float Color::get_u() const
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
return
|
|
Diego Barrios Romero |
3570f3 |
(float)get_r()*EncodeYUV[1][0]+
|
|
Diego Barrios Romero |
3570f3 |
(float)get_g()*EncodeYUV[1][1]+
|
|
Diego Barrios Romero |
3570f3 |
(float)get_b()*EncodeYUV[1][2];
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Returns V component of chromanance
|
|
Diego Barrios Romero |
3570f3 |
float Color::get_v() const
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
return
|
|
Diego Barrios Romero |
3570f3 |
(float)get_r()*EncodeYUV[2][0]+
|
|
Diego Barrios Romero |
3570f3 |
(float)get_g()*EncodeYUV[2][1]+
|
|
Diego Barrios Romero |
3570f3 |
(float)get_b()*EncodeYUV[2][2];
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Returns the color's saturation
|
|
Diego Barrios Romero |
3570f3 |
/*! This is is the magnitude of the U and V components.
|
|
Diego Barrios Romero |
3570f3 |
** \see set_s() */
|
|
Diego Barrios Romero |
3570f3 |
float Color::get_s() const
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
const float u(get_u()), v(get_v());
|
|
Diego Barrios Romero |
3570f3 |
return sqrt(u*u+v*v);
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Sets the luminance (\a y) and chromanance (\a u and \a v)
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::set_yuv(const float &y, const float &u, const float &v)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
set_r(y*DecodeYUV[0][0]+u*DecodeYUV[0][1]+v*DecodeYUV[0][2]);
|
|
Diego Barrios Romero |
3570f3 |
set_g(y*DecodeYUV[1][0]+u*DecodeYUV[1][1]+v*DecodeYUV[1][2]);
|
|
Diego Barrios Romero |
3570f3 |
set_b(y*DecodeYUV[2][0]+u*DecodeYUV[2][1]+v*DecodeYUV[2][2]);
|
|
Diego Barrios Romero |
3570f3 |
return *this;
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Sets color luminance
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::set_y(const float &y) { return set_yuv(y,get_u(),get_v()); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Set U component of chromanance
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::set_u(const float &u) { return set_yuv(get_y(),u,get_v()); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Set V component of chromanance
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::set_v(const float &v) { return set_yuv(get_y(),get_u(),v); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Set the U and V components of chromanance
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::set_uv(const float& u, const float& v) { return set_yuv(get_y(),u,v); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Sets the color's saturation
|
|
Diego Barrios Romero |
3570f3 |
/*! \see get_s() */
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::set_s(const float &x)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
float u(get_u()), v(get_v());
|
|
Diego Barrios Romero |
3570f3 |
const float s(sqrt(u*u+v*v));
|
|
Diego Barrios Romero |
3570f3 |
if(s)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
u=(u/s)*x;
|
|
Diego Barrios Romero |
3570f3 |
v=(v/s)*x;
|
|
Diego Barrios Romero |
3570f3 |
return set_uv(u,v);
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
return *this;
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! YUV Color constructor
|
|
Diego Barrios Romero |
3570f3 |
Color Color::YUV(const float& y, const float& u, const float& v, const value_type& a)
|
|
Diego Barrios Romero |
3570f3 |
{ return Color().set_yuv(y,u,v).set_a(a); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Returns the hue of the chromanance
|
|
Diego Barrios Romero |
3570f3 |
/*! This is the angle of the U and V components.
|
|
Diego Barrios Romero |
3570f3 |
** \see set_hue() */
|
|
Diego Barrios Romero |
3570f3 |
Angle Color::get_hue() const
|
|
Diego Barrios Romero |
3570f3 |
{ return Angle::tan(get_u(),get_v()); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Synonym for get_hue(). \see get_hue()
|
|
Diego Barrios Romero |
3570f3 |
Angle Color::get_uv_angle() const { return get_hue(); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Sets the color's hue
|
|
Diego Barrios Romero |
3570f3 |
/*! \see get_hue() */
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::set_hue(const Angle& theta)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
const float s(get_s());
|
|
Diego Barrios Romero |
3570f3 |
const float
|
|
Diego Barrios Romero |
3570f3 |
u(s*(float)Angle::sin(theta).get()),
|
|
Diego Barrios Romero |
3570f3 |
v(s*(float)Angle::cos(theta).get());
|
|
Diego Barrios Romero |
3570f3 |
return set_uv(u,v);
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Synonym for set_hue(). \see set_hue()
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::set_uv_angle(const Angle& theta) { return set_hue(theta); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
//! Rotates the chromanance vector by amount specified by \a theta
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::rotate_uv(const Angle& theta)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
const float a(Angle::sin(theta).get()), b(Angle::cos(theta).get());
|
|
Diego Barrios Romero |
3570f3 |
const float u(get_u()), v(get_v());
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
return set_uv(b*u-a*v,a*u+b*v);
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color& Color::set_yuv(const float& y, const float& s, const Angle& theta)
|
|
Diego Barrios Romero |
3570f3 |
{
|
|
Diego Barrios Romero |
3570f3 |
return
|
|
Diego Barrios Romero |
3570f3 |
set_yuv(
|
|
Diego Barrios Romero |
3570f3 |
y,
|
|
Diego Barrios Romero |
3570f3 |
s*(float)Angle::sin(theta).get(),
|
|
Diego Barrios Romero |
3570f3 |
s*(float)Angle::cos(theta).get()
|
|
Diego Barrios Romero |
3570f3 |
);
|
|
Diego Barrios Romero |
3570f3 |
}
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
Color Color::YUV(const float& y, const float& s, const Angle& theta, const value_type& a)
|
|
Diego Barrios Romero |
3570f3 |
{ return Color().set_yuv(y,s,theta).set_a(a); }
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
} // synfig namespace
|
|
Diego Barrios Romero |
3570f3 |
|
|
Diego Barrios Romero |
3570f3 |
#endif // __SYNFIG_COLOR_COLOR_HPP
|
|
Diego Barrios Romero |
3570f3 |
|