[cairo-commit] pycairo/cairo pycairo-surface.c,1.59,1.60
Steve Chaplin
commit at pdx.freedesktop.org
Sun Oct 16 19:31:33 PDT 2005
Committed by: stevech1097
Update of /cvs/cairo/pycairo/cairo
In directory gabe:/tmp/cvs-serv7419/cairo
Modified Files:
pycairo-surface.c
Log Message:
'SC'
Index: pycairo-surface.c
===================================================================
RCS file: /cvs/cairo/pycairo/cairo/pycairo-surface.c,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -d -r1.59 -r1.60
--- pycairo-surface.c 12 Oct 2005 03:13:47 -0000 1.59
+++ pycairo-surface.c 17 Oct 2005 02:31:31 -0000 1.60
@@ -34,6 +34,7 @@
# include <config.h>
#endif
+#include <stdint.h>
#include "pycairo-private.h"
@@ -214,7 +215,7 @@
static PyObject *
surface_write_to_png (PycairoSurface *o, PyObject *file)
{
- FILE *fp;
+ FILE *fp = NULL;
cairo_status_t status;
unsigned int mode = 0;
@@ -521,6 +522,70 @@
return Py_BuildValue("i", cairo_image_surface_get_width (o->surface));
}
+#ifdef HAVE_GETDATA
+/* This was modified from cairo/src/cairo-png.c unpremultiply_data() */
+/* ARGB32 (native-endian, premultiplied) => RGBA */
+static void
+_argb32_to_unpremultiplied_rgba (uint8_t *data, int length)
+{
+ unsigned int i;
+
+ for (i = 0; i < length; i += 4) {
+ uint8_t *b = &data[i];
+ uint32_t pixel;
+ uint8_t alpha;
+
+ memcpy (&pixel, b, sizeof (uint32_t));
+ alpha = (pixel & 0xff000000) >> 24;
+ if (alpha == 0) {
+ b[0] = b[1] = b[2] = b[3] = 0;
+ } else {
+ b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
+ b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
+ b[2] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
+ b[3] = alpha;
+ }
+ }
+}
+
+/* return a Python buffer object containing the ImageSurface data in RGBA
+ * format.
+ * It requires a patched version of cairo which provides:
+ * cairo_image_surface_get_data()
+ * cairo_image_surface_get_format()
+ * cairo_image_surface_get_stride()
+ */
+static PyObject *
+image_surface_to_rgba (PycairoImageSurface *o)
+{
+ PyObject *buf;
+ unsigned char *data;
+ uint8_t *buffer;
+ int height, stride, length;
+ cairo_surface_t *surface = o->surface;
+ cairo_format_t format = cairo_image_surface_get_format (surface);
+
+ if (format != CAIRO_FORMAT_ARGB32) {
+ PyErr_SetString(PyExc_TypeError, "ImageSurface.to_rgba() can only be "
+ "called on a cairo.FORMAT_ARGB32 surface");
+ return NULL;
+ }
+ data = cairo_image_surface_get_data (surface);
+ height = cairo_image_surface_get_height (surface);
+ stride = cairo_image_surface_get_stride (surface);
+
+ buf = PyBuffer_New(height * stride);
+ if (buf != NULL) {
+ if (PyObject_AsWriteBuffer(buf, (void **)&buffer, &length)) {
+ Py_DECREF(buf);
+ return NULL;
+ }
+ memcpy (buffer, data, length);
+ _argb32_to_unpremultiplied_rgba (buffer, length);
+ }
+ return buf;
+}
+#endif
static PyMethodDef image_surface_methods[] = {
#ifdef HAVE_NUMPY
@@ -533,8 +598,11 @@
{"create_from_png", (PyCFunction)image_surface_create_from_png,
METH_O | METH_CLASS },
#endif
- {"get_height", (PyCFunction)image_surface_get_height, METH_NOARGS},
- {"get_width", (PyCFunction)image_surface_get_width, METH_NOARGS},
+ {"get_height", (PyCFunction)image_surface_get_height, METH_NOARGS},
+ {"get_width", (PyCFunction)image_surface_get_width, METH_NOARGS},
+#ifdef HAVE_GETDATA
+ {"to_rgba", (PyCFunction)image_surface_to_rgba, METH_NOARGS},
+#endif
{NULL, NULL, 0, NULL},
};
More information about the cairo-commit
mailing list