#pragma once
#include "Color.h"
#include <algorithm>
#include <math.h>
namespace WebCore {
struct FloatComponents {
FloatComponents(float a = 0, float b = 0, float c = 0, float d = 0)
{
components[0] = a;
components[1] = b;
components[2] = c;
components[3] = d;
}
FloatComponents(const Color&);
FloatComponents& operator+=(const FloatComponents& rhs)
{
components[0] += rhs.components[0];
components[1] += rhs.components[1];
components[2] += rhs.components[2];
components[3] += rhs.components[3];
return *this;
}
FloatComponents operator+(float rhs) const
{
FloatComponents result;
result.components[0] = components[0] + rhs;
result.components[1] = components[1] + rhs;
result.components[2] = components[2] + rhs;
result.components[3] = components[3] + rhs;
return result;
}
FloatComponents operator/(float denominator) const
{
FloatComponents result;
result.components[0] = components[0] / denominator;
result.components[1] = components[1] / denominator;
result.components[2] = components[2] / denominator;
result.components[3] = components[3] / denominator;
return result;
}
FloatComponents operator*(float factor) const
{
FloatComponents result;
result.components[0] = components[0] * factor;
result.components[1] = components[1] * factor;
result.components[2] = components[2] * factor;
result.components[3] = components[3] * factor;
return result;
}
FloatComponents abs() const
{
FloatComponents result;
result.components[0] = fabs(components[0]);
result.components[1] = fabs(components[1]);
result.components[2] = fabs(components[2]);
result.components[3] = fabs(components[3]);
return result;
}
float components[4];
};
struct ColorComponents {
ColorComponents(const FloatComponents&);
static ColorComponents fromRGBA(unsigned pixel)
{
return ColorComponents((pixel >> 24) & 0xFF, (pixel >> 16) & 0xFF, (pixel >> 8) & 0xFF, pixel & 0xFF);
}
ColorComponents(uint8_t a = 0, uint8_t b = 0, uint8_t c = 0, uint8_t d = 0)
{
components[0] = a;
components[1] = b;
components[2] = c;
components[3] = d;
}
unsigned toRGBA() const
{
return components[0] << 24 | components[1] << 16 | components[2] << 8 | components[3];
}
uint8_t components[4] { };
};
inline ColorComponents perComponentMax(const ColorComponents& a, const ColorComponents& b)
{
return {
std::max(a.components[0], b.components[0]),
std::max(a.components[1], b.components[1]),
std::max(a.components[2], b.components[2]),
std::max(a.components[3], b.components[3])
};
}
inline ColorComponents perComponentMin(const ColorComponents& a, const ColorComponents& b)
{
return {
std::min(a.components[0], b.components[0]),
std::min(a.components[1], b.components[1]),
std::min(a.components[2], b.components[2]),
std::min(a.components[3], b.components[3])
};
}
inline uint8_t clampedColorComponent(float f)
{
return std::max(0, std::min(static_cast<int>(lroundf(255.0f * f)), 255));
}
inline unsigned byteOffsetOfPixel(unsigned x, unsigned y, unsigned rowBytes)
{
const unsigned bytesPerPixel = 4;
return x * bytesPerPixel + y * rowBytes;
}
float linearToSRGBColorComponent(float);
float sRGBToLinearColorComponent(float);
FloatComponents sRGBColorToLinearComponents(const Color&);
FloatComponents sRGBToLinearComponents(const FloatComponents&);
FloatComponents linearToSRGBComponents(const FloatComponents&);
FloatComponents sRGBToHSL(const FloatComponents&);
FloatComponents HSLToSRGB(const FloatComponents&);
float luminance(const FloatComponents& sRGBCompontents);
class ColorMatrix {
public:
static ColorMatrix grayscaleMatrix(float);
static ColorMatrix saturationMatrix(float);
static ColorMatrix hueRotateMatrix(float angleInDegrees);
static ColorMatrix sepiaMatrix(float);
ColorMatrix();
ColorMatrix(float[20]);
void transformColorComponents(FloatComponents&) const;
private:
void makeIdentity();
float m_matrix[4][5];
};
}