From 047d3248896d375a8fbc80dbbf573b81a3e5a927 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 20 Mar 2009 04:06:39 +0000 Subject: Revamp color handling. --- libdimension/canvas.c | 166 +------------------------------------------------- 1 file changed, 2 insertions(+), 164 deletions(-) (limited to 'libdimension/canvas.c') diff --git a/libdimension/canvas.c b/libdimension/canvas.c index 4e3f89f..21d6d86 100644 --- a/libdimension/canvas.c +++ b/libdimension/canvas.c @@ -19,169 +19,7 @@ *************************************************************************/ #include "dimension.h" -#include -#include - -/* Conversions between CIE 1931 XYZ and sRGB color. */ - -dmnsn_pixel -dmnsn_pixel_from_color(dmnsn_color color) -{ - double X, Y, Z; /* CIE XYZ values */ - double Rlinear, Glinear, Blinear; /* Linear RGB values - no gamma */ - double R, G, B; /* sRGB values */ - dmnsn_pixel pixel; - - /* Convert from CIE xyY to CIE XYZ */ - Y = color.Y; - X = Y*color.x/color.y; - Z = Y*(1.0 - color.x - color.y)/color.y; - - /* - * First, the linear conversion. Expressed as matrix multiplication, it looks - * like this: - * - * [Rlinear] [ 3.2410 -1.5374 -0.4986] [X] - * [Glinear] = [-0.9692 1.8760 0.0416]*[Y] - * [Blinear] [ 0.0556 -0.2040 1.0570] [Z] - */ - Rlinear = 3.2410*X - 1.5374*Y - 0.4986*Z; - Glinear = -0.9692*X + 1.8760*Y + 0.0416*Z; - Blinear = 0.0556*X - 0.2040*Y + 1.0570*Z; - - /* - * If C represents R, G, and B, then the sRGB values are now found as follows: - * - * { 12.92*Clinear, Clinear <= 0.0031308 - * Csrgb = { 1/2.4 - * { (1.055)*Clinear - 0.055, Clinear > 0.0031308 - */ - - if (Rlinear <= 0.0031308) { - R = 12.92*Rlinear; - } else { - R = 1.055*pow(Rlinear, 1.0/2.4) - 0.055; - } - - if (Glinear <= 0.0031308) { - G = 12.92*Glinear; - } else { - G = 1.055*pow(Glinear, 1.0/2.4) - 0.055; - } - - if (Blinear <= 0.0031308) { - B = 12.92*Blinear; - } else { - B = 1.055*pow(Blinear, 1.0/2.4) - 0.055; - } - - /* Now we go from unlimited to limited light, saturating at UINT16_MAX */ - - if (R < 0.0) { - pixel.r = 0.0; - } else if (R > 1.0) { - pixel.r = UINT16_MAX; - } else { - pixel.r = UINT16_MAX*R; - } - - if (G < 0.0) { - pixel.g = 0.0; - } else if (G > 1.0) { - pixel.g = UINT16_MAX; - } else { - pixel.g = UINT16_MAX*G; - } - - if (B < 0.0) { - pixel.b = 0.0; - } else if (B > 1.0) { - pixel.b = UINT16_MAX; - } else { - pixel.b = UINT16_MAX*B; - } - - if (color.filter < 0.0) { - pixel.a = 0.0; - } else if (color.filter > 1.0) { - pixel.a = UINT16_MAX; - } else { - pixel.a = UINT16_MAX*color.filter; - } - - if (color.trans < 0.0) { - pixel.t = 0.0; - } else if (color.trans > 1.0) { - pixel.t = UINT16_MAX; - } else { - pixel.t = UINT16_MAX*color.trans; - } - - return pixel; -} - -dmnsn_color -dmnsn_color_from_pixel(dmnsn_pixel pixel) -{ - double R, G, B; /* sRGB values */ - double Rlinear, Glinear, Blinear; /* Linear RGB values - no gamma */ - double X, Y, Z; /* CIE XYZ values */ - dmnsn_color color; - - /* Conversion back to unlimited light */ - R = ((double)pixel.r)/UINT16_MAX; - G = ((double)pixel.g)/UINT16_MAX; - B = ((double)pixel.b)/UINT16_MAX; - - /* - * If C represents R, G, and B, then the Clinear values are now found as - * follows: - * - * { Csrgb/12.92, Csrgb <= 0.04045 - * Clinear = { 1/2.4 - * { ((Csrgb + 0.055)/1.055) , Csrgb > 0.04045 - */ - - if (R <= 0.04045) { - Rlinear = R/19.92; - } else { - Rlinear = pow((R + 0.055)/1.055, 2.4); - } - - if (G <= 0.04045) { - Glinear = G/19.92; - } else { - Glinear = pow((G + 0.055)/1.055, 2.4); - } - - if (B <= 0.04045) { - Blinear = B/19.92; - } else { - Blinear = pow((B + 0.055)/1.055, 2.4); - } - - /* - * Now, the linear conversion. Expressed as matrix multiplication, it looks - * like this: - * - * [X] [0.4124 0.3576 0.1805] [Rlinear] - * [Y] = [0.2126 0.7152 0.0722]*[Glinear] - * [X] [0.0193 0.1192 0.9505] [Blinear] - */ - - X = 0.4124*Rlinear + 0.3576*Glinear + 0.1805*Blinear; - Y = 0.2126*Rlinear + 0.7152*Glinear + 0.0722*Blinear; - Z = 0.0193*Rlinear + 0.1192*Glinear + 0.9505*Blinear; - - /* Now convert to CIE xyY colorspace */ - color.x = X/(X + Y + Z); - color.y = Y/(X + Y + Z); - color.Y = Y; - color.filter = ((double)pixel.a)/UINT16_MAX; - color.trans = ((double)pixel.t)/UINT16_MAX; - - return color; -} +#include /* For malloc(), free() */ dmnsn_canvas * dmnsn_new_canvas(unsigned int x, unsigned int y) @@ -191,7 +29,7 @@ dmnsn_new_canvas(unsigned int x, unsigned int y) if (canvas) { canvas->x = x; canvas->y = y; - canvas->pixels = malloc(sizeof(dmnsn_pixel)*x*y); + canvas->pixels = malloc(sizeof(dmnsn_color)*x*y); if (canvas->pixels) { return canvas; -- cgit v1.2.3