Skip to content

Instantly share code, notes, and snippets.

@Cyberax
Last active August 29, 2015 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cyberax/4546471dcb026c141369 to your computer and use it in GitHub Desktop.
Save Cyberax/4546471dcb026c141369 to your computer and use it in GitHub Desktop.
static void ParseColorsTuple
(
PyObject * ColorTuple,
uint32_t * colors /* array of 4 elements */
)
/* parses ColorTuple as a tuple of 4 elements, each in turn being a tuple of
4 integers (r, g, b, a) each in the range [0 .. 255]. Puts the result as
Cairo-format pixel values into colors. */
{
PyObject * TheColors[4] = {0, 0, 0, 0};
unsigned int nrcolors, i, j, channel[4];
nrcolors = PyTuple_Size(ColorTuple);
if (PyErr_Occurred())
goto cleanup;
if (nrcolors > 4)
{
nrcolors = 4;
}
for (i = 0; i < nrcolors; ++i)
{
TheColors[i] = PyTuple_GetItem(ColorTuple, i);
//I'm not sure if it affects the global PyErr_Occurred state, let's assume that it doesn't
Py_INCREF(TheColors[i]);
if (PyErr_Occurred())
goto cleanup;
}
for (i = 0; i<nrcolors; ++i)
{
for (j = 0; j<4; ++j)
{
PyObject * ColorObj = PyTuple_GetItem(TheColors[i], j);
if (PyErr_Occurred())
goto cleanup;
const long chanval = PyInt_AsLong(ColorObj);
if (PyErr_Occurred())
goto cleanup;
if (chanval < 0 || chanval > 255)
{
PyErr_SetString
(
PyExc_ValueError,
"colour components must be in [0 .. 255]"
);
goto cleanup;
}
channel[(j + 1) % 4] = chanval;
}
colors[i] =
channel[0] << 24
|
channel[1] << 16
|
channel[2] << 8
|
channel[3];
}
}
for (; i < 4; ++i)
{
/* fill unused entries with transparent colour */
colors[i] = 0;
}
cleanup:
for (i = 0; i < nrcolors; ++i)
{
//I hope it can handle NULLs
Py_DECREF(TheColors[i]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment