#ifndef RGBA_H
#define RGBA_H
#include <cmath>
#include "colour_sensitivity.h"
namespace mimas {
template <typename T>
class rgba
{
protected:
T b,g,r,a;
public:
rgba(void)
{
r=g=b=a=T();
}
template< class U >
rgba(const rgba< U > &rhs)
{
r = (T)rhs.getRed();
g = (T)rhs.getGreen();
b = (T)rhs.getBlue();
a = (T)rhs.getAlpha();
}
rgba( T _r, T _g, T _b, T _a = T() ):
b(_b), g(_g), r(_r), a(_a)
{
}
template< typename U >
explicit rgba(const U &val)
{
r=(T)val;
g=(T)val;
b=(T)val;
a=T();
}
//inline functions to avoid overhead of the call,
//especially used for convert_trait
inline T getRed(void) const
{
return r;
}
inline T getGreen(void) const
{
return g;
}
inline T getBlue(void) const
{
return b;
}
inline T getAlpha(void) const
{
return a;
}
void setRed(T val)
{
r=val;
}
void setGreen(T val)
{
g=val;
}
void setBlue(T val)
{
b=val;
}
void setAlpha(T val)
{
a=val;
}
void set(T val)
{
r=g=b=a=val;
}
//mixes the 2 colors according to the ammount of transparency
void overlay(T r_,T g_,T b_,T a_)
{
//assumption that alpha take a value between 0 and 255
//should be corrected according to the type T
r = ((255 - a_)* r + a_ * r_)/255;
g = ((255 - a_)* g + a_ * g_)/255;
b = ((255 - a_)* b + a_ * b_)/255;
}
//overload casting to double
operator double(void) const
{
return
SENSITIVITY_RED * r + SENSITIVITY_GREEN * g + SENSITIVITY_BLUE * b;
}
operator float(void) const
{
return
SENSITIVITY_RED * r + SENSITIVITY_GREEN * g + SENSITIVITY_BLUE * b;
}
operator short int(void) const
{
const int
rwgt = (int)( SENSITIVITY_RED * 65536 ),
gwgt = (int)( SENSITIVITY_GREEN * 65536 ),
bwgt = (int)( SENSITIVITY_BLUE * 65536 );
return (short int)( ( rwgt * r + gwgt * g + bwgt * b ) >> 16 );
}
operator int(void) const
{
return (int)operator double();
}
//overload casting to unsigned char
operator unsigned char(void) const
{
const int
rwgt = (int)( SENSITIVITY_RED * 65536 ),
gwgt = (int)( SENSITIVITY_GREEN * 65536 ),
bwgt = (int)( SENSITIVITY_BLUE * 65536 );
return (unsigned char)( ( rwgt * r + gwgt * g + bwgt * b ) >> 16 );
}
/// Equality of two pixels
bool operator==(const rgba<T> &rhs)
{
return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a;
}
/// Check for unequal pixels.
bool operator!=(const rgba<T> &rhs)
{
return !(r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a);
}
rgba< T > operator+( const rgba< T > &o ) const
{
return rgba< T >( r + o.r, g + o.g, b + o.b );
}
rgba< T > operator-( const rgba< T > &o ) const
{
return rgba< T >( r - o.r, g - o.g, b - o.b );
}
rgba< T > &operator+=( const rgba< T > &o )
{
r += o.r; g += o.g; b += o.b;
return *this;
}
rgba< T > &operator-=( const rgba< T > &o )
{
r -= o.r; g -= o.g; b -= o.b;
return *this;
}
double getHue(void) const;///< returns number in the range 0-360
double getSaturation(void) const; ///< returns saturation between 0 and 1.0
};
}
#include "rgba.tcc"
#endif