From efd3c1c2b42ffda0c8f7e5cd9b03fba07eead1ea Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 28 May 2011 18:05:05 -0600 Subject: Handle sRGB gamma correctly. --- libdimension-python/Color.c | 73 +++++++++++++++++------------- libdimension-python/Color.h | 1 + libdimension/color.c | 95 ++++++++++++++++++++++++++++++++++++--- libdimension/color_map.c | 17 ++++++- libdimension/dimension/color.h | 4 ++ libdimension/dimension/pigments.h | 14 +++++- libdimension/gl.c | 9 +++- libdimension/pigment_map.c | 17 ++++++- libdimension/png.c | 6 ++- libdimension/tests/render.c | 24 ++++++---- 10 files changed, 204 insertions(+), 56 deletions(-) diff --git a/libdimension-python/Color.c b/libdimension-python/Color.c index 529aab2..3ac92ce 100644 --- a/libdimension-python/Color.c +++ b/libdimension-python/Color.c @@ -23,26 +23,27 @@ static int dmnsn_py_Color_init(dmnsn_py_Color *self, PyObject *args, PyObject *kwds) { - self->c.trans = 0.0; - self->c.filter = 0.0; + self->sRGB.trans = 0.0; + self->sRGB.filter = 0.0; static char *kwlist[] = { "red", "green", "blue", "trans", "filter", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "ddd|dd", kwlist, - &self->c.R, &self->c.G, &self->c.B, - &self->c.trans, &self->c.filter)) + &self->sRGB.R, &self->sRGB.G, &self->sRGB.B, + &self->sRGB.trans, &self->sRGB.filter)) return -1; + self->c = dmnsn_color_from_sRGB(self->sRGB); return 0; } static PyObject * dmnsn_py_Color_repr(dmnsn_py_Color *self) { - PyObject *R = PyFloat_FromDouble(self->c.R); - PyObject *G = PyFloat_FromDouble(self->c.G); - PyObject *B = PyFloat_FromDouble(self->c.B); - PyObject *trans = PyFloat_FromDouble(self->c.trans); - PyObject *filter = PyFloat_FromDouble(self->c.filter); + PyObject *R = PyFloat_FromDouble(self->sRGB.R); + PyObject *G = PyFloat_FromDouble(self->sRGB.G); + PyObject *B = PyFloat_FromDouble(self->sRGB.B); + PyObject *trans = PyFloat_FromDouble(self->sRGB.trans); + PyObject *filter = PyFloat_FromDouble(self->sRGB.filter); if (!R || !G || !B || !trans || !filter) { Py_XDECREF(filter); @@ -66,11 +67,11 @@ dmnsn_py_Color_repr(dmnsn_py_Color *self) static PyObject * dmnsn_py_Color_str(dmnsn_py_Color *self) { - PyObject *R = PyFloat_FromDouble(self->c.R); - PyObject *G = PyFloat_FromDouble(self->c.G); - PyObject *B = PyFloat_FromDouble(self->c.B); - PyObject *trans = PyFloat_FromDouble(self->c.trans); - PyObject *filter = PyFloat_FromDouble(self->c.filter); + PyObject *R = PyFloat_FromDouble(self->sRGB.R); + PyObject *G = PyFloat_FromDouble(self->sRGB.G); + PyObject *B = PyFloat_FromDouble(self->sRGB.B); + PyObject *trans = PyFloat_FromDouble(self->sRGB.trans); + PyObject *filter = PyFloat_FromDouble(self->sRGB.filter); if (!R || !G || !B || !trans || !filter) { Py_XDECREF(filter); @@ -82,7 +83,7 @@ dmnsn_py_Color_str(dmnsn_py_Color *self) } PyObject *str; - if (self->c.filter < dmnsn_epsilon && self->c.trans < dmnsn_epsilon) { + if (self->sRGB.filter < dmnsn_epsilon && self->sRGB.trans < dmnsn_epsilon) { str = PyUnicode_FromFormat("", R, G, B); } else { @@ -153,7 +154,8 @@ dmnsn_py_Color_add(PyObject *lhs, PyObject *rhs) if (ret) { dmnsn_py_Color *clhs = (dmnsn_py_Color *)lhs; dmnsn_py_Color *crhs = (dmnsn_py_Color *)rhs; - ret->c = dmnsn_color_add(clhs->c, crhs->c); + ret->sRGB = dmnsn_color_add(clhs->sRGB, crhs->sRGB); + ret->c = dmnsn_color_from_sRGB(ret->sRGB); } return (PyObject *)ret; } @@ -178,7 +180,8 @@ dmnsn_py_Color_mul(PyObject *lhs, PyObject *rhs) dmnsn_py_Color *ret = PyObject_New(dmnsn_py_Color, &dmnsn_py_ColorType); if (ret) { - ret->c = dmnsn_color_mul(dbl, col->c); + ret->sRGB = dmnsn_color_mul(dbl, col->sRGB); + ret->c = dmnsn_color_from_sRGB(ret->sRGB); } return (PyObject *)ret; } @@ -203,31 +206,31 @@ static PyMethodDef dmnsn_py_Color_methods[] = { static PyObject * dmnsn_py_Color_get_red(dmnsn_py_Color *self, void *closure) { - return PyFloat_FromDouble(self->c.R); + return PyFloat_FromDouble(self->sRGB.R); } static PyObject * dmnsn_py_Color_get_green(dmnsn_py_Color *self, void *closure) { - return PyFloat_FromDouble(self->c.G); + return PyFloat_FromDouble(self->sRGB.G); } static PyObject * dmnsn_py_Color_get_blue(dmnsn_py_Color *self, void *closure) { - return PyFloat_FromDouble(self->c.B); + return PyFloat_FromDouble(self->sRGB.B); } static PyObject * dmnsn_py_Color_get_trans(dmnsn_py_Color *self, void *closure) { - return PyFloat_FromDouble(self->c.trans); + return PyFloat_FromDouble(self->sRGB.trans); } static PyObject * dmnsn_py_Color_get_filter(dmnsn_py_Color *self, void *closure) { - return PyFloat_FromDouble(self->c.filter); + return PyFloat_FromDouble(self->sRGB.filter); } static PyGetSetDef dmnsn_py_Color_getsetters[] = { @@ -278,16 +281,22 @@ dmnsn_py_Color_global(dmnsn_py_Cyan); bool dmnsn_py_init_ColorType(void) { - dmnsn_py_Black.c = dmnsn_black; - dmnsn_py_White.c = dmnsn_white; - dmnsn_py_Clear.c = dmnsn_clear; - dmnsn_py_Red.c = dmnsn_red; - dmnsn_py_Green.c = dmnsn_green; - dmnsn_py_Blue.c = dmnsn_blue; - dmnsn_py_Magenta.c = dmnsn_magenta; - dmnsn_py_Orange.c = dmnsn_orange; - dmnsn_py_Yellow.c = dmnsn_yellow; - dmnsn_py_Cyan.c = dmnsn_cyan; +#define dmnsn_py_define_global(global, color) \ + do { \ + (global).c = color; \ + (global).sRGB = dmnsn_color_to_sRGB(color); \ + } while (0) + + dmnsn_py_define_global(dmnsn_py_Black, dmnsn_black); + dmnsn_py_define_global(dmnsn_py_White, dmnsn_white); + dmnsn_py_define_global(dmnsn_py_Clear, dmnsn_clear); + dmnsn_py_define_global(dmnsn_py_Red, dmnsn_red); + dmnsn_py_define_global(dmnsn_py_Green, dmnsn_green); + dmnsn_py_define_global(dmnsn_py_Blue, dmnsn_blue); + dmnsn_py_define_global(dmnsn_py_Magenta, dmnsn_magenta); + dmnsn_py_define_global(dmnsn_py_Orange, dmnsn_orange); + dmnsn_py_define_global(dmnsn_py_Yellow, dmnsn_yellow); + dmnsn_py_define_global(dmnsn_py_Cyan, dmnsn_cyan); dmnsn_py_ColorType.tp_new = PyType_GenericNew; return PyType_Ready(&dmnsn_py_ColorType) >= 0; diff --git a/libdimension-python/Color.h b/libdimension-python/Color.h index 2749f2f..533a9e5 100644 --- a/libdimension-python/Color.h +++ b/libdimension-python/Color.h @@ -21,6 +21,7 @@ typedef struct dmnsn_py_Color { PyObject_HEAD dmnsn_color c; + dmnsn_color sRGB; } dmnsn_py_Color; extern PyTypeObject dmnsn_py_ColorType; diff --git a/libdimension/color.c b/libdimension/color.c index 6de8d0a..eea005b 100644 --- a/libdimension/color.c +++ b/libdimension/color.c @@ -77,7 +77,7 @@ const dmnsn_color dmnsn_magenta = { }; const dmnsn_color dmnsn_orange = { .R = 1.0, - .G = 0.5, + .G = 0.21404114048223255, .B = 0.0, .trans = 0.0, .filter = 0.0, @@ -97,6 +97,75 @@ const dmnsn_color dmnsn_cyan = { .trans = 0.0, }; +/** Inverse function of sRGB's `C' function, for the reverse conversion. */ +static double +dmnsn_sRGB_C_inv(double CsRGB) +{ + /* + * 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 (CsRGB == 1.0) { + return 1.0; /* Map 1.0 to 1.0 instead of 0.9999999999999999 */ + } else if (CsRGB <= 0.040449936) { + return CsRGB/12.92; + } else { + return pow((CsRGB + 0.055)/1.055, 2.4); + } +} + +/* Convert from sRGB space */ +dmnsn_color +dmnsn_color_from_sRGB(dmnsn_color color) +{ + dmnsn_color ret = { + .R = dmnsn_sRGB_C_inv(color.R), + .G = dmnsn_sRGB_C_inv(color.G), + .B = dmnsn_sRGB_C_inv(color.B), + .trans = color.trans, + .filter = color.filter, + }; + return ret; +} + +/** sRGB's `C' function. */ +static double +dmnsn_sRGB_C(double Clinear) +{ + /* + * 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 (Clinear == 1.0) { + return 1.0; /* Map 1.0 to 1.0 instead of 0.9999999999999999 */ + } else if (Clinear <= 0.0031308) { + return 12.92*Clinear; + } else { + return 1.055*pow(Clinear, 1.0/2.4) - 0.055; + } +} + +/* Convert to sRGB space */ +dmnsn_color +dmnsn_color_to_sRGB(dmnsn_color color) +{ + dmnsn_color ret = { + .R = dmnsn_sRGB_C(color.R), + .G = dmnsn_sRGB_C(color.G), + .B = dmnsn_sRGB_C(color.B), + .trans = color.trans, + .filter = color.filter, + }; + return ret; +} + /* Greyscale color intensity */ double dmnsn_color_intensity(dmnsn_color color) @@ -111,7 +180,7 @@ dmnsn_color_add(dmnsn_color c1, dmnsn_color c2) { dmnsn_color ret = dmnsn_new_color(c1.R + c2.R, c1.G + c2.G, c1.B + c2.B); - /* Switch back into absolute filter and transmittance space */ + /* Switch into absolute filter and transmittance space */ double n1 = dmnsn_color_intensity(c1), n2 = dmnsn_color_intensity(c2); double f1 = c1.filter*c1.trans, f2 = c2.filter*c2.trans; double t1 = c1.trans - f1, t2 = c2.trans - f2; @@ -142,13 +211,25 @@ dmnsn_color_mul(double n, dmnsn_color color) dmnsn_color dmnsn_color_gradient(dmnsn_color c1, dmnsn_color c2, double n) { - return dmnsn_new_color5( + dmnsn_color ret = dmnsn_new_color( n*(c2.R - c1.R) + c1.R, n*(c2.G - c1.G) + c1.G, - n*(c2.B - c1.B) + c1.B, - n*(c2.trans - c1.trans) + c1.trans, - n*(c2.filter - c1.filter) + c1.filter + n*(c2.B - c1.B) + c1.B ); + + /* Switch into absolute filter and transmittance space */ + double f1 = c1.filter*c1.trans, f2 = c2.filter*c2.trans; + double t1 = c1.trans - f1, t2 = c2.trans - f2; + double f = n*(f2 - f1) + f1; + double t = n*(t2 - t1) + t1; + + /* Switch back */ + ret.trans = f + t; + ret.filter = 0.0; + if (ret.trans >= dmnsn_epsilon) + ret.filter = f/ret.trans; + + return ret; } /* Filters `light' through `filter' */ @@ -165,7 +246,7 @@ dmnsn_filter_light(dmnsn_color light, dmnsn_color filter) ); dmnsn_color ret = dmnsn_color_add(transmitted, filtered); - /* Switch back into absolute filter and transmittance space */ + /* Switch into absolute filter and transmittance space */ double lf = light.filter*light.trans, ff = filter.filter*filter.trans; double lt = light.trans - lf, ft = filter.trans - ff; double f = lf*(dmnsn_color_intensity(filtered) + ft) + lt*ff; diff --git a/libdimension/color_map.c b/libdimension/color_map.c index 6390fe5..e7a25a6 100644 --- a/libdimension/color_map.c +++ b/libdimension/color_map.c @@ -35,6 +35,7 @@ dmnsn_new_color_map(void) typedef struct dmnsn_color_map_payload { dmnsn_pattern *pattern; dmnsn_map *map; + dmnsn_pigment_map_flags flags; } dmnsn_color_map_payload; /** Free a color_map payload. */ @@ -56,7 +57,17 @@ dmnsn_color_map_pigment_fn(const dmnsn_pigment *pigment, dmnsn_vector v) dmnsn_color color1, color2; dmnsn_evaluate_map(payload->map, dmnsn_pattern_value(payload->pattern, v), &n, &color1, &color2); - return dmnsn_color_gradient(color1, color2, n); + + if (payload->flags == DMNSN_PIGMENT_MAP_SRGB) { + color1 = dmnsn_color_to_sRGB(color1); + color2 = dmnsn_color_to_sRGB(color2); + } + dmnsn_color ret = dmnsn_color_gradient(color1, color2, n); + if (payload->flags == DMNSN_PIGMENT_MAP_SRGB) { + ret = dmnsn_color_from_sRGB(ret); + } + + return ret; } /** color_map initialization callback. */ @@ -70,7 +81,8 @@ dmnsn_color_map_initialize_fn(dmnsn_pigment *pigment) } dmnsn_pigment * -dmnsn_new_color_map_pigment(dmnsn_pattern *pattern, dmnsn_map *map) +dmnsn_new_color_map_pigment(dmnsn_pattern *pattern, dmnsn_map *map, + dmnsn_pigment_map_flags flags) { dmnsn_pigment *pigment = dmnsn_new_pigment(); @@ -78,6 +90,7 @@ dmnsn_new_color_map_pigment(dmnsn_pattern *pattern, dmnsn_map *map) = dmnsn_malloc(sizeof(dmnsn_color_map_payload)); payload->pattern = pattern; payload->map = map; + payload->flags = flags; pigment->pigment_fn = dmnsn_color_map_pigment_fn; pigment->initialize_fn = dmnsn_color_map_initialize_fn; diff --git a/libdimension/dimension/color.h b/libdimension/dimension/color.h index 98d1530..d4e0402 100644 --- a/libdimension/dimension/color.h +++ b/libdimension/dimension/color.h @@ -77,6 +77,10 @@ dmnsn_color_is_black(dmnsn_color color) /* Perceptual color manipulation */ +/** Convert from sRGB space. */ +dmnsn_color dmnsn_color_from_sRGB(dmnsn_color color); +/** Convert to sRGB space. */ +dmnsn_color dmnsn_color_to_sRGB(dmnsn_color color); /** Greyscale color intensity. */ double dmnsn_color_intensity(dmnsn_color color); /** Add two colors together. */ diff --git a/libdimension/dimension/pigments.h b/libdimension/dimension/pigments.h index 26b75f8..e62963e 100644 --- a/libdimension/dimension/pigments.h +++ b/libdimension/dimension/pigments.h @@ -44,6 +44,14 @@ dmnsn_pigment *dmnsn_new_canvas_pigment(dmnsn_canvas *canvas); */ dmnsn_map *dmnsn_new_color_map(void); +/** + * pigment_map flags. + */ +typedef enum dmnsn_pigment_map_flags { + DMNSN_PIGMENT_MAP_REGULAR, /**< Calculate linear color gradients. */ + DMNSN_PIGMENT_MAP_SRGB /**< Calculate sRGB color gradients. */ +} dmnsn_pigment_map_flags; + /** * A color-mapped pigment. * @param[in,out] pattern The pattern of the pigment. @@ -51,7 +59,8 @@ dmnsn_map *dmnsn_new_color_map(void); * @return A pigment mapping the pattern to color values. */ dmnsn_pigment *dmnsn_new_color_map_pigment(dmnsn_pattern *pattern, - dmnsn_map *map); + dmnsn_map *map, + dmnsn_pigment_map_flags flags); /** * Construct a pigment map. @@ -66,4 +75,5 @@ dmnsn_map *dmnsn_new_pigment_map(void); * @return A pigment mapping the pattern to other pigments. */ dmnsn_pigment *dmnsn_new_pigment_map_pigment(dmnsn_pattern *pattern, - dmnsn_map *map); + dmnsn_map *map, + dmnsn_pigment_map_flags flags); diff --git a/libdimension/gl.c b/libdimension/gl.c index f5f1c92..a968d75 100644 --- a/libdimension/gl.c +++ b/libdimension/gl.c @@ -82,7 +82,9 @@ dmnsn_gl_write_canvas(const dmnsn_canvas *canvas) for (size_t x = 0; x < width; ++x) { pixel = pixels + 4*(y*width + x); - color = dmnsn_remove_filter(dmnsn_get_pixel(canvas, x, y)); + color = dmnsn_get_pixel(canvas, x, y); + color = dmnsn_remove_filter(color); + color = dmnsn_color_to_sRGB(color); /* Saturate R, G, and B to [0, UINT16_MAX] */ @@ -153,6 +155,7 @@ dmnsn_gl_read_canvas(size_t x0, size_t y0, (double)pixel[2]/UINT16_MAX, (double)pixel[3]/UINT16_MAX, 0.0); + color = dmnsn_color_from_sRGB(color); dmnsn_set_pixel(canvas, x, y, color); } } @@ -167,7 +170,9 @@ dmnsn_gl_optimizer_fn(const dmnsn_canvas *canvas, dmnsn_canvas_optimizer optimizer, size_t x, size_t y) { GLushort *pixel = (GLushort *)optimizer.ptr + 4*(y*canvas->width + x); - dmnsn_color color = dmnsn_remove_filter(dmnsn_get_pixel(canvas, x, y)); + dmnsn_color color = dmnsn_get_pixel(canvas, x, y); + color = dmnsn_remove_filter(color); + color = dmnsn_color_to_sRGB(color); /* Saturate R, G, and B to [0, UINT16_MAX] */ diff --git a/libdimension/pigment_map.c b/libdimension/pigment_map.c index 9864152..e97553f 100644 --- a/libdimension/pigment_map.c +++ b/libdimension/pigment_map.c @@ -53,6 +53,7 @@ dmnsn_new_pigment_map(void) typedef struct dmnsn_pigment_map_payload { dmnsn_pattern *pattern; dmnsn_map *map; + dmnsn_pigment_map_flags flags; } dmnsn_pigment_map_payload; /** Free a pigment_map payload. */ @@ -76,7 +77,17 @@ dmnsn_pigment_map_pigment_fn(const dmnsn_pigment *pigment, dmnsn_vector v) &n, &pigment1, &pigment2); dmnsn_color color1 = pigment1->pigment_fn(pigment1, v); dmnsn_color color2 = pigment2->pigment_fn(pigment2, v); - return dmnsn_color_gradient(color1, color2, n); + + if (payload->flags == DMNSN_PIGMENT_MAP_SRGB) { + color1 = dmnsn_color_to_sRGB(color1); + color2 = dmnsn_color_to_sRGB(color2); + } + dmnsn_color ret = dmnsn_color_gradient(color1, color2, n); + if (payload->flags == DMNSN_PIGMENT_MAP_SRGB) { + ret = dmnsn_color_from_sRGB(ret); + } + + return ret; } /** pigment_map initialization callback. */ @@ -91,7 +102,8 @@ dmnsn_pigment_map_initialize_fn(dmnsn_pigment *pigment) } dmnsn_pigment * -dmnsn_new_pigment_map_pigment(dmnsn_pattern *pattern, dmnsn_map *map) +dmnsn_new_pigment_map_pigment(dmnsn_pattern *pattern, dmnsn_map *map, + dmnsn_pigment_map_flags flags) { dmnsn_pigment *pigment = dmnsn_new_pigment(); @@ -99,6 +111,7 @@ dmnsn_new_pigment_map_pigment(dmnsn_pattern *pattern, dmnsn_map *map) = dmnsn_malloc(sizeof(dmnsn_pigment_map_payload)); payload->pattern = pattern; payload->map = map; + payload->flags = flags; pigment->pigment_fn = dmnsn_pigment_map_pigment_fn; pigment->initialize_fn = dmnsn_pigment_map_initialize_fn; diff --git a/libdimension/png.c b/libdimension/png.c index 5b7f625..6a56a87 100644 --- a/libdimension/png.c +++ b/libdimension/png.c @@ -64,7 +64,9 @@ dmnsn_png_optimizer_fn(const dmnsn_canvas *canvas, dmnsn_color color; uint16_t *pixel = (uint16_t *)optimizer.ptr + 4*(y*canvas->width + x); - color = dmnsn_remove_filter(dmnsn_get_pixel(canvas, x, y)); + color = dmnsn_get_pixel(canvas, x, y); + color = dmnsn_remove_filter(color); + color = dmnsn_color_to_sRGB(color); /* Saturate R, G, and B to [0, UINT16_MAX] */ @@ -272,6 +274,7 @@ dmnsn_png_write_canvas_thread(void *ptr) /* Invert the rows. PNG coordinates are fourth quadrant. */ dmnsn_color color = dmnsn_get_pixel(payload->canvas, x, height - y - 1); color = dmnsn_remove_filter(color); + color = dmnsn_color_to_sRGB(color); /* Saturate R, G, and B to [0, UINT16_MAX] */ @@ -477,6 +480,7 @@ dmnsn_png_read_canvas_thread(void *ptr) } } + color = dmnsn_color_from_sRGB(color); dmnsn_set_pixel(*payload->canvas, x, height - y - 1, color); } diff --git a/libdimension/tests/render.c b/libdimension/tests/render.c index a79c85c..de5b6a4 100644 --- a/libdimension/tests/render.c +++ b/libdimension/tests/render.c @@ -34,9 +34,9 @@ dmnsn_new_test_scene(void) /* Default finish */ scene->default_texture->finish = dmnsn_new_finish_combination( dmnsn_new_ambient_finish( - dmnsn_color_mul(0.1, dmnsn_white) + dmnsn_color_mul(0.01, dmnsn_white) ), - dmnsn_new_diffuse_finish(0.6) + dmnsn_new_diffuse_finish(0.3) ); /* Allocate a canvas */ @@ -74,10 +74,13 @@ dmnsn_new_test_scene(void) dmnsn_pattern *sky_gradient = dmnsn_new_gradient_pattern(dmnsn_y); dmnsn_map *sky_gradient_color_map = dmnsn_new_color_map(); dmnsn_add_map_entry(sky_gradient_color_map, 0.0, &dmnsn_orange); - dmnsn_color background = dmnsn_new_color5(0.0, 0.1, 0.2, 0.1, 1.0); + dmnsn_color background = dmnsn_color_from_sRGB( + dmnsn_new_color5(0.0, 0.1, 0.2, 0.1, 0.0) + ); dmnsn_add_map_entry(sky_gradient_color_map, 0.35, &background); dmnsn_pigment *sky_pigment - = dmnsn_new_color_map_pigment(sky_gradient, sky_gradient_color_map); + = dmnsn_new_color_map_pigment(sky_gradient, sky_gradient_color_map, + DMNSN_PIGMENT_MAP_SRGB); dmnsn_array_push(scene->sky_sphere->pigments, &sky_pigment); /* Light source */ @@ -144,7 +147,8 @@ dmnsn_new_test_scene(void) dmnsn_add_map_entry(gradient_color_map, 1.0, &dmnsn_red); arrow->texture = dmnsn_new_texture(); arrow->texture->pigment - = dmnsn_new_color_map_pigment(gradient, gradient_color_map); + = dmnsn_new_color_map_pigment(gradient, gradient_color_map, + DMNSN_PIGMENT_MAP_SRGB); arrow->texture->trans = dmnsn_matrix_mul( dmnsn_translation_matrix(dmnsn_new_vector(0.0, -1.25, 0.0)), @@ -186,15 +190,19 @@ dmnsn_new_test_scene(void) dmnsn_add_map_entry(checker_color_map, 1.0, &dmnsn_white); dmnsn_pigment *pigment1 = dmnsn_new_solid_pigment(dmnsn_white); dmnsn_pigment *pigment2 - = dmnsn_new_color_map_pigment(checker1, checker_color_map); + = dmnsn_new_color_map_pigment(checker1, checker_color_map, + DMNSN_PIGMENT_MAP_REGULAR); pigment2->trans = dmnsn_scale_matrix(dmnsn_new_vector(1.0/3.0, 1.0/3.0, 1.0/3.0)); dmnsn_map *checker_pigment_map = dmnsn_new_pigment_map(); dmnsn_add_map_entry(checker_pigment_map, 0.0, &pigment1); dmnsn_add_map_entry(checker_pigment_map, 1.0, &pigment2); plane->texture->pigment - = dmnsn_new_pigment_map_pigment(checker2, checker_pigment_map); - plane->texture->pigment->quick_color = dmnsn_new_color(1.0, 0.5, 0.75); + = dmnsn_new_pigment_map_pigment(checker2, checker_pigment_map, + DMNSN_PIGMENT_MAP_REGULAR); + plane->texture->pigment->quick_color = dmnsn_color_from_sRGB( + dmnsn_new_color(1.0, 0.5, 0.75) + ); dmnsn_scene_add_object(scene, plane); return scene; -- cgit v1.2.3