[cairo-commit] pycairo/cairo pycairo-surface.c,1.61,1.62

Steve Chaplin commit at pdx.freedesktop.org
Thu Dec 15 08:20:50 PST 2005


Committed by: stevech1097

Update of /cvs/cairo/pycairo/cairo
In directory gabe:/tmp/cvs-serv18887/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.61
retrieving revision 1.62
diff -u -d -r1.61 -r1.62
--- pycairo-surface.c	14 Dec 2005 04:47:02 -0000	1.61
+++ pycairo-surface.c	15 Dec 2005 16:20:46 -0000	1.62
@@ -470,39 +470,70 @@
 
 #ifdef CAIRO_HAS_PNG_FUNCTIONS
 static cairo_status_t
-_read_func (void *closure, unsigned char *data, unsigned int length)
+_read_func1 (void *closure, unsigned char *data, unsigned int length)
 {
     if (fread (data, 1, (size_t) length, (FILE *)closure) != length)
 	return CAIRO_STATUS_READ_ERROR;
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_status_t
+_read_func2 (void *closure, unsigned char *data, unsigned int length)
+{
+    char *str;
+    PyObject *pystr = PyObject_CallMethod ((PyObject *)closure, "read", "(i)",
+					   length);
+    if (pystr == NULL)
+	return CAIRO_STATUS_READ_ERROR;
+    str = PyString_AsString(pystr);
+    Py_DECREF(pystr);
+    if (str == NULL)
+	return CAIRO_STATUS_READ_ERROR;
+    /* don't use strncpy() since png data may contain NUL bytes */
+    memcpy (data, str, length);
+    return CAIRO_STATUS_SUCCESS;
+}
+
 /* METH_O | METH_CLASS */
 static PyObject *
-image_surface_create_from_png (PyTypeObject *type, PyObject *o)
+image_surface_create_from_png (PyTypeObject *type, PyObject *file)
 {
-    FILE *fp;
+    FILE *fp = NULL;
     cairo_surface_t *surface;
+    unsigned int mode = 0;
 
-    if (PyObject_TypeCheck (o, &PyBaseString_Type)) {
-	fp = fopen (PyString_AsString(o), "rb");
+    if (PyObject_TypeCheck (file, &PyBaseString_Type)) {
+	fp = fopen (PyString_AsString(file), "rb");
 	if (fp == NULL) {
 	    PyErr_SetString(PyExc_IOError, "unable to open file for reading");
 	    return NULL;
 	}
-
-    } else if (PyObject_TypeCheck (o, &PyFile_Type)) {
-	fp = PyFile_AsFile(o);
-
+	mode = 1;
+    } else if (PyObject_TypeCheck (file, &PyFile_Type)) {
+	fp = PyFile_AsFile(file);
+	mode = 1;
+    } else {
+	PyObject* reader = PyObject_GetAttrString (file, "read");
+	if (reader) {
+	    if (PyCallable_Check (reader))
+		mode = 2;
+	    Py_DECREF(reader);
+	}
+    }
+    if (mode == 1) {
+	surface = cairo_image_surface_create_from_png_stream (_read_func1, fp);
+    } else if (mode == 2) {
+	surface = cairo_image_surface_create_from_png_stream (_read_func2,
+							      file);
     } else {
 	PyErr_SetString(PyExc_TypeError,
 			"ImageSurface.create_from_png takes one argument "
-			"which must be a filename (str) or file object");
+			"which must be a filename (str), file object, or an "
+			"object that has a \"read\" method (like StringIO)");
 	return NULL;
     }
 
-    surface = cairo_image_surface_create_from_png_stream (_read_func, fp);
-    if (PyObject_TypeCheck (o, &PyBaseString_Type))
+    if (PyObject_TypeCheck (file, &PyBaseString_Type))
 	fclose (fp);
 
     return PycairoSurface_FromSurface (surface, &PycairoImageSurface_Type,



More information about the cairo-commit mailing list