summaryrefslogtreecommitdiffstats
path: root/plug-ins/pygimp/gimpcolormodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'plug-ins/pygimp/gimpcolormodule.c')
-rw-r--r--plug-ins/pygimp/gimpcolormodule.c433
1 files changed, 433 insertions, 0 deletions
diff --git a/plug-ins/pygimp/gimpcolormodule.c b/plug-ins/pygimp/gimpcolormodule.c
new file mode 100644
index 0000000..8b4a478
--- /dev/null
+++ b/plug-ins/pygimp/gimpcolormodule.c
@@ -0,0 +1,433 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * Gimp-Python - allows the writing of Gimp plugins in Python.
+ * Copyright (C) 2005-2006 Manish Singh <yosh@gimp.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "pygimpcolor.h"
+
+#define _INSIDE_PYGIMPCOLOR_
+#include "pygimpcolor-api.h"
+
+#include "pygimp-util.h"
+
+
+static PyObject *
+pygimp_rgb_parse_name(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ char *name;
+ int len;
+ GimpRGB rgb;
+ gboolean success;
+ static char *kwlist[] = { "name", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:rgb_parse_name", kwlist,
+ &name, &len))
+ return NULL;
+
+ rgb.a = 1.0;
+ success = gimp_rgb_parse_name(&rgb, name, len);
+
+ if (!success) {
+ PyErr_SetString(PyExc_ValueError, "unable to parse color name");
+ return NULL;
+ }
+
+ return pygimp_rgb_new(&rgb);
+}
+
+static PyObject *
+pygimp_rgb_parse_hex(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ char *hex;
+ int len;
+ GimpRGB rgb;
+ gboolean success;
+ static char *kwlist[] = { "hex", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:rgb_parse_hex", kwlist,
+ &hex, &len))
+ return NULL;
+
+ rgb.a = 1.0;
+ success = gimp_rgb_parse_hex(&rgb, hex, len);
+
+ if (!success) {
+ PyErr_SetString(PyExc_ValueError, "unable to parse hex value");
+ return NULL;
+ }
+
+ return pygimp_rgb_new(&rgb);
+}
+
+static PyObject *
+pygimp_rgb_parse_css(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ char *css;
+ int len;
+ GimpRGB rgb;
+ gboolean success, with_alpha = FALSE;
+ static char *kwlist[] = { "css", "with_alpha", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "s#|i:rgb_parse_css", kwlist,
+ &css, &len, &with_alpha))
+ return NULL;
+
+ if (with_alpha)
+ success = gimp_rgba_parse_css(&rgb, css, len);
+ else {
+ rgb.a = 1.0;
+ success = gimp_rgb_parse_css(&rgb, css, len);
+ }
+
+ if (!success) {
+ PyErr_SetString(PyExc_ValueError, "unable to parse CSS color");
+ return NULL;
+ }
+
+ return pygimp_rgb_new(&rgb);
+}
+
+static PyObject *
+pygimp_rgb_list_names(PyObject *self)
+{
+ int num_names, i;
+ const char **names;
+ GimpRGB *colors;
+ PyObject *dict, *color;
+
+ num_names = gimp_rgb_list_names(&names, &colors);
+
+ dict = PyDict_New();
+ if (!dict)
+ goto cleanup;
+
+ for (i = 0; i < num_names; i++) {
+ color = pygimp_rgb_new(&colors[i]);
+
+ if (!color)
+ goto bail;
+
+ if (PyDict_SetItemString(dict, names[i], color) < 0) {
+ Py_DECREF(color);
+ goto bail;
+ }
+
+ Py_DECREF(color);
+ }
+
+ goto cleanup;
+
+bail:
+ Py_DECREF(dict);
+ dict = NULL;
+
+cleanup:
+ g_free(names);
+ g_free(colors);
+
+ return dict;
+}
+
+static PyObject *
+pygimp_bilinear(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ gdouble x, y;
+ gdouble values[4];
+ PyObject *py_values;
+ static char *kwlist[] = { "x", "y", "values", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "ddO:bilinear", kwlist,
+ &x, &y, &py_values))
+ return NULL;
+
+ if (PyString_Check(py_values)) {
+ if (PyString_Size(py_values) == 4) {
+ guchar ret;
+ ret = gimp_bilinear_8(x, y, (guchar *)PyString_AsString(py_values));
+ return PyString_FromStringAndSize((char *)&ret, 1);
+ }
+ } else if (PySequence_Check(py_values)) {
+ if (PySequence_Size(py_values) == 4) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ PyObject *v;
+ v = PySequence_GetItem(py_values, i);
+ values[i] = PyFloat_AsDouble(v);
+ Py_DECREF(v);
+ }
+ return PyFloat_FromDouble(gimp_bilinear(x, y, values));
+ }
+ }
+
+ PyErr_SetString(PyExc_TypeError, "values is not a sequence of 4 items");
+ return NULL;
+}
+
+static PyObject *
+pygimp_bilinear_color(PyObject *self, PyObject *args, PyObject *kwargs, gboolean with_alpha)
+{
+ gdouble x, y;
+ GimpRGB values[4];
+ GimpRGB rgb;
+ PyObject *py_values, *v;
+ int i, success;
+ static char *kwlist[] = { "x", "y", "values", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ with_alpha ? "ddO:bilinear_rgba"
+ : "ddO:bilinear_rgb",
+ kwlist,
+ &x, &y, &py_values))
+ return NULL;
+
+ if (!PySequence_Check(py_values) || PySequence_Size(py_values) != 4) {
+ PyErr_SetString(PyExc_TypeError, "values is not a sequence of 4 items");
+ return NULL;
+ }
+
+ for (i = 0; i < 4; i++) {
+ v = PySequence_GetItem(py_values, i);
+ success = pygimp_rgb_from_pyobject(v, &values[i]);
+ Py_DECREF(v);
+ if (!success) {
+ PyErr_Format(PyExc_TypeError, "values[%d] is not a GimpRGB", i);
+ return NULL;
+ }
+ }
+
+ if (with_alpha)
+ rgb = gimp_bilinear_rgba(x, y, values);
+ else
+ rgb = gimp_bilinear_rgb(x, y, values);
+
+ return pygimp_rgb_new(&rgb);
+}
+
+static PyObject *
+pygimp_bilinear_rgb(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ return pygimp_bilinear_color(self, args, kwargs, FALSE);
+}
+
+static PyObject *
+pygimp_bilinear_rgba(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ return pygimp_bilinear_color(self, args, kwargs, TRUE);
+}
+
+#if 0
+static PyObject *
+pygimp_bilinear_pixels_8(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+typedef struct
+{
+ PyObject *func;
+ PyObject *data;
+} ProxyData;
+
+static void
+proxy_render(gdouble x, gdouble y, GimpRGB *color, gpointer pdata)
+{
+ ProxyData *data = pdata;
+
+ if (data->data)
+ PyObject_CallFunction(data->func, "ddO&O", x, y, pygimp_rgb_new, color,
+ data->data);
+ else
+ PyObject_CallFunction(data->func, "ddO&", x, y, pygimp_rgb_new, color);
+}
+
+static void
+proxy_put_pixel(gint x, gint y, GimpRGB *color, gpointer pdata)
+{
+ ProxyData *data = pdata;
+
+ if (data->data)
+ PyObject_CallFunction(data->func, "iiO&O", x, y, pygimp_rgb_new, color,
+ data->data);
+ else
+ PyObject_CallFunction(data->func, "iiO&", x, y, pygimp_rgb_new, color);
+}
+
+static void
+proxy_progress(gint min, gint max, gint current, gpointer pdata)
+{
+ ProxyData *data = pdata;
+
+ if (data->data)
+ PyObject_CallFunction(data->func, "iiiO", min, max, current,
+ data->data);
+ else
+ PyObject_CallFunction(data->func, "iii", min, max, current);
+}
+
+static PyObject *
+pygimp_adaptive_supersample_area(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ gulong r;
+
+ gint x1, y1, x2, y2, max_depth;
+ gdouble threshold;
+ PyObject *py_func_render = NULL, *py_data_render = NULL;
+ PyObject *py_func_put_pixel = NULL, *py_data_put_pixel = NULL;
+ PyObject *py_func_progress = NULL, *py_data_progress = NULL;
+
+ GimpRenderFunc proxy_func_render = NULL;
+ GimpPutPixelFunc proxy_func_put_pixel = NULL;
+ GimpProgressFunc proxy_func_progress = NULL;
+
+ ProxyData proxy_data_render, proxy_data_put_pixel, proxy_data_progress;
+
+ static char *kwlist[] = {
+ "x1", "y1", "x2", "y2", "max_depth", "threshold",
+ "render_func", "render_data",
+ "put_pixel_func", "put_pixel_data",
+ "progress_func", "progress_data",
+ NULL
+ };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "iiiiid|OOOOOO"
+ ":adaptive_supersample_area",
+ kwlist,
+ &x1, &y1, &x2, &y2, &max_depth, &threshold,
+ &py_func_render, &py_data_render,
+ &py_func_put_pixel, &py_data_put_pixel,
+ &py_func_progress, &py_data_progress))
+ return NULL;
+
+#define PROCESS_FUNC(n) G_STMT_START { \
+ if (py_func_##n != NULL) { \
+ if (!PyCallable_Check(py_func_##n)) { \
+ PyErr_SetString(PyExc_TypeError, #n "_func " \
+ "must be callable"); \
+ return NULL; \
+ } \
+ \
+ proxy_func_##n = proxy_##n; \
+ \
+ proxy_data_##n.func = py_func_##n; \
+ proxy_data_##n.data = py_data_##n; \
+ } \
+} G_STMT_END
+
+ PROCESS_FUNC(render);
+ PROCESS_FUNC(put_pixel);
+ PROCESS_FUNC(progress);
+
+#undef PROCESS_FUNC
+
+#define PASS_FUNC(n) proxy_func_##n, &proxy_data_##n
+
+ r = gimp_adaptive_supersample_area (x1, y1, x2, y2, max_depth, threshold,
+ PASS_FUNC(render),
+ PASS_FUNC(put_pixel),
+ PASS_FUNC(progress));
+
+#undef PASS_FUNC
+
+ return PyInt_FromLong(r);
+}
+#endif
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef gimpcolor_methods[] = {
+ {"rgb_parse_name", (PyCFunction)pygimp_rgb_parse_name, METH_VARARGS | METH_KEYWORDS},
+ {"rgb_parse_hex", (PyCFunction)pygimp_rgb_parse_hex, METH_VARARGS | METH_KEYWORDS},
+ {"rgb_parse_css", (PyCFunction)pygimp_rgb_parse_css, METH_VARARGS | METH_KEYWORDS},
+ {"rgb_names", (PyCFunction)pygimp_rgb_list_names, METH_NOARGS},
+ {"bilinear", (PyCFunction)pygimp_bilinear, METH_VARARGS | METH_KEYWORDS},
+ {"bilinear_rgb", (PyCFunction)pygimp_bilinear_rgb, METH_VARARGS | METH_KEYWORDS},
+ {"bilinear_rgba", (PyCFunction)pygimp_bilinear_rgba, METH_VARARGS | METH_KEYWORDS},
+#if 0
+ {"bilinear_pixels_8", (PyCFunction)pygimp_bilinear_pixels_8, METH_VARARGS | METH_KEYWORDS},
+ {"adaptive_supersample_area", (PyCFunction)pygimp_adaptive_supersample_area, METH_VARARGS | METH_KEYWORDS},
+#endif
+ {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
+};
+
+
+static struct _PyGimpColor_Functions pygimpcolor_api_functions = {
+ &PyGimpRGB_Type,
+ pygimp_rgb_new,
+ &PyGimpHSV_Type,
+ pygimp_hsv_new,
+ &PyGimpHSL_Type,
+ pygimp_hsl_new,
+ &PyGimpCMYK_Type,
+ pygimp_cmyk_new,
+ pygimp_rgb_from_pyobject
+};
+
+
+/* Initialization function for the module (*must* be called initgimpcolor) */
+
+static char gimpcolor_doc[] =
+"This module provides interfaces to allow you to write gimp plug-ins"
+;
+
+void initgimpcolor(void);
+
+PyMODINIT_FUNC
+initgimpcolor(void)
+{
+ PyObject *m, *d;
+
+ pygimp_init_pygobject();
+
+ /* Create the module and add the functions */
+ m = Py_InitModule3("gimpcolor", gimpcolor_methods, gimpcolor_doc);
+
+ d = PyModule_GetDict(m);
+
+ pyg_register_boxed(d, "RGB", GIMP_TYPE_RGB, &PyGimpRGB_Type);
+ pyg_register_boxed(d, "HSV", GIMP_TYPE_HSV, &PyGimpHSV_Type);
+ pyg_register_boxed(d, "HSL", GIMP_TYPE_HSL, &PyGimpHSL_Type);
+ pyg_register_boxed(d, "CMYK", GIMP_TYPE_CMYK, &PyGimpCMYK_Type);
+
+ PyModule_AddObject(m, "RGB_COMPOSITE_NONE",
+ PyInt_FromLong(GIMP_RGB_COMPOSITE_NONE));
+ PyModule_AddObject(m, "RGB_COMPOSITE_NORMAL",
+ PyInt_FromLong(GIMP_RGB_COMPOSITE_NORMAL));
+ PyModule_AddObject(m, "RGB_COMPOSITE_BEHIND",
+ PyInt_FromLong(GIMP_RGB_COMPOSITE_BEHIND));
+
+ PyModule_AddObject(m, "RGB_LUMINANCE_RED",
+ PyFloat_FromDouble(GIMP_RGB_LUMINANCE_RED));
+ PyModule_AddObject(m, "RGB_LUMINANCE_GREEN",
+ PyFloat_FromDouble(GIMP_RGB_LUMINANCE_GREEN));
+ PyModule_AddObject(m, "RGB_LUMINANCE_BLUE",
+ PyFloat_FromDouble(GIMP_RGB_LUMINANCE_BLUE));
+
+ /* for other modules */
+ PyModule_AddObject(m, "_PyGimpColor_API",
+ PyCObject_FromVoidPtr(&pygimpcolor_api_functions, NULL));
+
+ /* Check for errors */
+ if (PyErr_Occurred())
+ Py_FatalError("can't initialize module gimpcolor");
+}