[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