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/dimension/canvas.h | 11 +-------- libdimension/dimension/color.h | 51 +++++++++++++++++++++++++++++++++++---- libdimension/dimension/geometry.h | 16 ++++++------ 3 files changed, 55 insertions(+), 23 deletions(-) (limited to 'libdimension/dimension') diff --git a/libdimension/dimension/canvas.h b/libdimension/dimension/canvas.h index 8959e12..21d56e4 100644 --- a/libdimension/dimension/canvas.h +++ b/libdimension/dimension/canvas.h @@ -25,15 +25,6 @@ #ifndef DIMENSION_CANVAS_H #define DIMENSION_CANVAS_H -/* 48-bit sRGB color for pixels. */ -typedef struct { - uint16_t r, g, b; /* Red, green, blue */ - uint16_t a, t; /* Filtered transparancy, normal transparancy */ -} dmnsn_pixel; - -dmnsn_pixel dmnsn_pixel_from_color(dmnsn_color color); -dmnsn_color dmnsn_color_from_pixel(dmnsn_pixel pixel); - typedef struct { unsigned int x, y; @@ -41,7 +32,7 @@ typedef struct { * Stored in first-quadrant representation (origin is bottom-left). The pixel * at (a,b) is accessible as pixels[b*x + a]. */ - dmnsn_pixel *pixels; + dmnsn_color *pixels; } dmnsn_canvas; dmnsn_canvas *dmnsn_new_canvas(unsigned int x, unsigned int y); diff --git a/libdimension/dimension/color.h b/libdimension/dimension/color.h index 34668e3..d637a81 100644 --- a/libdimension/dimension/color.h +++ b/libdimension/dimension/color.h @@ -29,16 +29,57 @@ extern "C" { #endif -/* CIE 1931 xyY color. */ +/* Internally, we use CIE 1931 XYZ color. */ +typedef struct { + double X, Y, Z; + double filter, trans; /* Filter transparancy only lets light of this color + through; regular transparancy lets all colors + through. filter + trans should be <= 1.0. */ +} dmnsn_color; + +typedef struct { + double X, Y, Z; /* X, Y, and Z are tristimulus values, unbounded above zero. + Diffuse white is (0.9505, 1, 1.089). */ +} dmnsn_CIE_XYZ; + typedef struct { double x, y, Y; /* x and y are chromaticity coordinates, and Y is luminance, in the CIE 1931 xyZ color space. We use an unlimited light model, so x,y in [0, 1] and Y >= 0, with 1 = diffuse white */ - double filter, trans; /* Filter transparancy only lets light of this color - through; regular transparancy lets all colors - through */ -} dmnsn_color; +} dmnsn_CIE_xyY; + +typedef struct { + double L, a, b; /* L is luminence (100 = diffuse white); a and b are color- + opponent dimensions. This color space is used for color + arithmetic. */ +} dmnsn_CIE_Lab; + +typedef struct { + double L, u, v; /* L is luminence (100 = diffuse white); u and v are + chromaticity coordinates. */ +} dmnsn_CIE_Luv; + +typedef struct { + double R, G, B; /* sRGB R, G, and B values */ +} dmnsn_sRGB; + +/* Standard whitepoint, determined by the conversion of sRGB white to XYZ */ +extern dmnsn_CIE_XYZ whitepoint; + +dmnsn_color dmnsn_color_from_XYZ(dmnsn_CIE_XYZ XYZ); +dmnsn_color dmnsn_color_from_xyY(dmnsn_CIE_xyY xyY); +dmnsn_color dmnsn_color_from_Lab(dmnsn_CIE_Lab Lab, dmnsn_CIE_XYZ white); +dmnsn_color dmnsn_color_from_Luv(dmnsn_CIE_Luv Luv, dmnsn_CIE_XYZ white); +dmnsn_color dmnsn_color_from_sRGB(dmnsn_sRGB sRGB); + +dmnsn_CIE_XYZ dmnsn_XYZ_from_color(dmnsn_color color); +dmnsn_CIE_xyY dmnsn_xyY_from_color(dmnsn_color color); +dmnsn_CIE_Lab dmnsn_Lab_from_color(dmnsn_color color, dmnsn_CIE_XYZ white); +dmnsn_CIE_Luv dmnsn_Luv_from_color(dmnsn_color color, dmnsn_CIE_XYZ white); +dmnsn_sRGB dmnsn_sRGB_from_color(dmnsn_color color); + +dmnsn_color dmnsn_color_add(dmnsn_color color1, dmnsn_color color2); #ifdef __cplusplus } diff --git a/libdimension/dimension/geometry.h b/libdimension/dimension/geometry.h index 2c0c204..11a6daf 100644 --- a/libdimension/dimension/geometry.h +++ b/libdimension/dimension/geometry.h @@ -31,44 +31,44 @@ typedef struct { dmnsn_scalar x, y, z; } dmnsn_vector; /* Vector arithmetic */ -inline dmnsn_vector +DMNSN_INLINE dmnsn_vector dmnsn_vector_construct(dmnsn_scalar x, dmnsn_scalar y, dmnsn_scalar z) { dmnsn_vector v = { .x = x, .y = y, .z = z }; return v; } -inline dmnsn_vector +DMNSN_INLINE dmnsn_vector dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs) { return dmnsn_vector_construct(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z); } -inline dmnsn_vector +DMNSN_INLINE dmnsn_vector dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs) { return dmnsn_vector_construct(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z); } -inline dmnsn_vector +DMNSN_INLINE dmnsn_vector dmnsn_vector_mul(dmnsn_scalar lhs, dmnsn_vector rhs) { return dmnsn_vector_construct(lhs*rhs.x, lhs*rhs.y, lhs*rhs.z); } -inline dmnsn_vector +DMNSN_INLINE dmnsn_vector dmnsn_vector_div(dmnsn_vector lhs, dmnsn_scalar rhs) { return dmnsn_vector_construct(lhs.x/rhs, lhs.y/rhs, lhs.z/rhs); } -inline dmnsn_scalar +DMNSN_INLINE dmnsn_scalar dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs) { return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; } -inline dmnsn_vector +DMNSN_INLINE dmnsn_vector dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs) { return dmnsn_vector_construct(lhs.y*rhs.z - lhs.z*rhs.y, @@ -83,7 +83,7 @@ typedef struct { } dmnsn_line; /* A point on a line, defined by x0 + t*n */ -inline dmnsn_vector +DMNSN_INLINE dmnsn_vector dmnsn_line_point(dmnsn_line l, dmnsn_scalar t) { return dmnsn_vector_add(l.x0, dmnsn_vector_mul(t, l.n)); -- cgit v1.2.3