summaryrefslogtreecommitdiffstats
path: root/libdimension/canvas.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-03-20 04:06:39 +0000
committerTavian Barnes <tavianator@gmail.com>2009-03-20 04:06:39 +0000
commit047d3248896d375a8fbc80dbbf573b81a3e5a927 (patch)
treecdfdeebf0477ac62711683a5c267235f0a286ecd /libdimension/canvas.c
parent5ac6158f8ff999d4db18fb805c02b5c733e75ddb (diff)
downloaddimension-047d3248896d375a8fbc80dbbf573b81a3e5a927.tar.xz
Revamp color handling.
Diffstat (limited to 'libdimension/canvas.c')
-rw-r--r--libdimension/canvas.c166
1 files changed, 2 insertions, 164 deletions
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 <math.h>
-#include <stdlib.h>
-
-/* 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 <stdlib.h> /* 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;