[PATCH] Adds basic support for ImageSurface data.
Jeremy Moles
cubicool at gmail.com
Tue Dec 13 09:13:03 PST 2011
Adds beginning support for get_data() and create_for_data()
back into the bindings. Also adds/cleans up tests to demonstrate
functionality.
Also modifies INSTALL to instruct users how to use different
versions of Python.
---
INSTALL | 2 +
src/surface.c | 25 ++++++++++--------
test/isurface_create_for_data2.py | 2 +-
test/isurface_create_from_png.py | 8 +++---
test/isurface_get_data.py | 50 -------------------------------------
test/isurface_get_data1.py | 50 +++++++++++++++++++++++++++++++++++++
test/isurface_get_data2.py | 47 ++++++++++++++++++++++++++++++++++
7 files changed, 118 insertions(+), 66 deletions(-)
delete mode 100755 test/isurface_get_data.py
create mode 100755 test/isurface_get_data1.py
create mode 100755 test/isurface_get_data2.py
diff --git a/INSTALL b/INSTALL
index 14357b8..0b96f0c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -9,7 +9,9 @@ $ ./waf install
Use
$ python3 ./waf ...
if you have python2 and python3 installed, and the default is python 2.
+However, you specify a full path to the python binary using a command like:
+$ PYTHON=/usr/bin/python3 ./waf configure
Testing
-------
diff --git a/src/surface.c b/src/surface.c
index 35ca169..74d9dbc 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -418,20 +418,15 @@ static PyObject *
image_surface_create_for_data (PyTypeObject *type, PyObject *args) {
cairo_surface_t *surface;
cairo_format_t format;
- unsigned char *buffer;
int width, height, stride = -1, res;
- Py_ssize_t buffer_len;
PyObject *obj;
-
- // buffer function disabled
- PyErr_SetString(PyExc_NotImplementedError, "Surface.create_for_data: Not Implemented yet.");
- return NULL;
+ Py_buffer buffer;
if (!PyArg_ParseTuple(args, "Oiii|i:Surface.create_for_data",
&obj, &format, &width, &height, &stride))
return NULL;
- res = PyObject_AsWriteBuffer (obj, (void **)&buffer, &buffer_len);
+ res = PyObject_GetBuffer (obj, &buffer, PyBUF_WRITABLE);
if (res == -1)
return NULL;
@@ -452,12 +447,12 @@ image_surface_create_for_data (PyTypeObject *type, PyObject *args) {
return NULL;
}
}
- if (height * stride > buffer_len) {
+ if (height * stride > buffer.len) {
PyErr_SetString(PyExc_TypeError, "buffer is not long enough");
return NULL;
}
Py_BEGIN_ALLOW_THREADS;
- surface = cairo_image_surface_create_for_data (buffer, format, width,
+ surface = cairo_image_surface_create_for_data (buffer.buf, format, width,
height, stride);
Py_END_ALLOW_THREADS;
return PycairoSurface_FromSurface(surface, obj);
@@ -546,9 +541,17 @@ image_surface_format_stride_for_width (PyObject *self, PyObject *args) {
static PyObject *
image_surface_get_data (PycairoImageSurface *o) {
- PyErr_SetString(PyExc_NotImplementedError, "Surface.get_data: Not Implemented yet.");
+ Py_buffer buffer;
+ void *data;
+ int height, stride;
+
+ height = cairo_image_surface_get_height (o->surface);
+ stride = cairo_image_surface_get_stride (o->surface);
+ data = cairo_image_surface_get_data (o->surface);
+
+ if(!PyBuffer_FillInfo(&buffer, NULL, data, height * stride, 0, PyBUF_CONTIG))
+ return PyMemoryView_FromBuffer(&buffer);
return NULL;
- // return PyBuffer_FromReadWriteObject((PyObject *)o, 0, Py_END_OF_BUFFER);
}
static PyObject *
diff --git a/test/isurface_create_for_data2.py b/test/isurface_create_for_data2.py
index c4f290b..29a9984 100755
--- a/test/isurface_create_for_data2.py
+++ b/test/isurface_create_for_data2.py
@@ -27,4 +27,4 @@ surface = cairo.ImageSurface.create_for_data (data, cairo.FORMAT_ARGB32,
width, height)
ctx = cairo.Context(surface)
surface.write_to_png(fileName)
-print "see %s output file" % fileName
+print("see %s output file" % fileName)
diff --git a/test/isurface_create_from_png.py b/test/isurface_create_from_png.py
index 8d1ce5d..ae8af18 100755
--- a/test/isurface_create_from_png.py
+++ b/test/isurface_create_from_png.py
@@ -18,7 +18,7 @@ surface = cairo.ImageSurface.create_from_png(inFileName)
# write to filename
_, outFileName = tempfile.mkstemp(prefix='pycairo_', suffix='.png')
surface.write_to_png(outFileName)
-print "see %s output file" % outFileName
+print("see %s output file" % outFileName)
# write to file object
h, outFileName = tempfile.mkstemp(prefix='pycairo_', suffix='.png')
@@ -26,7 +26,7 @@ os.close(h)
f=file(outFileName, "wb")
surface.write_to_png(f)
f.close()
-print "see %s output file" % outFileName
+print("see %s output file" % outFileName)
# write to object that has a "write" method
import StringIO
@@ -38,7 +38,7 @@ buf.close()
f=file(outFileName, "wb")
f.write(png_string)
f.close()
-print "see %s output file" % outFileName
+print("see %s output file" % outFileName)
# write to object that has a "write" method
_, outFileName = tempfile.mkstemp(prefix='pycairo_', suffix='.png')
@@ -50,7 +50,7 @@ buf.close()
f=file(outFileName, "wb")
f.write(png_string)
f.close()
-print "see %s output file" % outFileName
+print("see %s output file" % outFileName)
# error test - to check the error message, should raise TypeError
#surface.write_to_png(101)
diff --git a/test/isurface_get_data.py b/test/isurface_get_data.py
deleted file mode 100755
index f2662d4..0000000
--- a/test/isurface_get_data.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-"""
-Test ImageSurface.get_data()
-"""
-import tempfile
-
-import cairo
-import numpy
-
-if not (cairo.HAS_IMAGE_SURFACE and cairo.HAS_PNG_FUNCTIONS):
- raise SystemExit ('cairo was not compiled with ImageSurface and PNG support')
-
-w, h = 128, 128
-
-surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
-ctx = cairo.Context(surface)
-
-ctx.set_source_rgb(1, 1, 1) # white
-ctx.set_operator(cairo.OPERATOR_SOURCE)
-ctx.paint()
-
-# Draw out the triangle using absolute coordinates
-ctx.move_to(w/2, h/3)
-ctx.line_to(2*w/3, 2*h/3)
-ctx.rel_line_to(-1*w/3, 0)
-ctx.close_path()
-
-ctx.set_source_rgb(0, 0, 0) # black
-ctx.set_line_width(15)
-ctx.stroke()
-_, outFileName = tempfile.mkstemp(prefix='pycairo_', suffix='.png')
-surface.write_to_png(outFileName)
-print "see %s output file" % outFileName
-
-# modify surface using numpy
-buf = surface.get_data()
-# alternative which should work (?) but reports
-# TypeError: buffer is read-only
-# - is a Python bug?
-#buf = buffer (surface1)
-
-a = numpy.ndarray(shape=(w,h,4), dtype=numpy.uint8, buffer=buf)
-
-# draw a vertical line
-a[:,40,0] = 255 # byte 0 is blue on little-endian systems
-a[:,40,1] = 0
-a[:,40,2] = 0
-_, outFileName = tempfile.mkstemp(prefix='pycairo_', suffix='.png')
-surface.write_to_png(outFileName)
-print "see %s output file" % outFileName
diff --git a/test/isurface_get_data1.py b/test/isurface_get_data1.py
new file mode 100755
index 0000000..92d25cf
--- /dev/null
+++ b/test/isurface_get_data1.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+"""
+Test ImageSurface.get_data()
+"""
+import tempfile
+
+import cairo
+import numpy
+
+if not (cairo.HAS_IMAGE_SURFACE and cairo.HAS_PNG_FUNCTIONS):
+ raise SystemExit ('cairo was not compiled with ImageSurface and PNG support')
+
+w, h = 128, 128
+
+surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
+ctx = cairo.Context(surface)
+
+ctx.set_source_rgb(1, 1, 1) # white
+ctx.set_operator(cairo.OPERATOR_SOURCE)
+ctx.paint()
+
+# Draw out the triangle using absolute coordinates
+ctx.move_to(w/2, h/3)
+ctx.line_to(2*w/3, 2*h/3)
+ctx.rel_line_to(-1*w/3, 0)
+ctx.close_path()
+
+ctx.set_source_rgb(0, 0, 0) # black
+ctx.set_line_width(15)
+ctx.stroke()
+_, outFileName = tempfile.mkstemp(prefix='pycairo_', suffix='.png')
+surface.write_to_png(outFileName)
+print("see %s output file" % outFileName)
+
+# modify surface using numpy
+buf = surface.get_data()
+# alternative which should work (?) but reports
+# TypeError: buffer is read-only
+# - is a Python bug?
+#buf = buffer (surface1)
+
+a = numpy.ndarray(shape=(w,h,4), dtype=numpy.uint8, buffer=buf)
+
+# draw a vertical line
+a[:,40,0] = 255 # byte 0 is blue on little-endian systems
+a[:,40,1] = 0
+a[:,40,2] = 0
+_, outFileName = tempfile.mkstemp(prefix='pycairo_', suffix='.png')
+surface.write_to_png(outFileName)
+print("see %s output file" % outFileName)
diff --git a/test/isurface_get_data2.py b/test/isurface_get_data2.py
new file mode 100755
index 0000000..f4c6e0e
--- /dev/null
+++ b/test/isurface_get_data2.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+"""
+Test ImageSurface.get_data()
+"""
+import tempfile
+
+import cairo
+
+import IPython
+
+if not (cairo.HAS_IMAGE_SURFACE and cairo.HAS_PNG_FUNCTIONS):
+ raise SystemExit ('cairo was not compiled with ImageSurface and PNG support')
+
+w, h = 128, 128
+
+surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
+ctx = cairo.Context(surface)
+
+ctx.set_source_rgb(1, 1, 1) # white
+ctx.set_operator(cairo.OPERATOR_SOURCE)
+ctx.paint()
+
+# Draw out the triangle using absolute coordinates
+ctx.move_to(w/2, h/3)
+ctx.line_to(2*w/3, 2*h/3)
+ctx.rel_line_to(-1*w/3, 0)
+ctx.close_path()
+
+ctx.set_source_rgb(0, 0, 0) # black
+ctx.set_line_width(15)
+ctx.stroke()
+_, outFileName = tempfile.mkstemp(prefix='pycairo_', suffix='.png')
+surface.write_to_png(outFileName)
+print("see %s output file" % outFileName)
+
+buf = surface.get_data()
+
+for i in range(h):
+ offset = (i * surface.get_stride()) + 120
+ buf[offset] = b'\xFF'
+ buf[offset + 1] = b'\x00'
+ buf[offset + 2] = b'\x00'
+
+_, outFileName = tempfile.mkstemp(prefix='pycairo_', suffix='.png')
+surface.write_to_png(outFileName)
+print("see %s output file" % outFileName)
+
--
1.7.7.3
--=-VelUTNKD6tfkL6HdnyrG--
More information about the cairo
mailing list