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 + 2 files changed, 42 insertions(+), 32 deletions(-) (limited to 'libdimension-python') 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; -- cgit v1.2.3