123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- /*
- * The Python Imaging Library.
- *
- * standard memory mapping interface for the Imaging library
- *
- * history:
- * 1998-03-05 fl added Win32 read mapping
- * 1999-02-06 fl added "I;16" support
- * 2003-04-21 fl added PyImaging_MapBuffer primitive
- *
- * Copyright (c) 1998-2003 by Secret Labs AB.
- * Copyright (c) 2003 by Fredrik Lundh.
- *
- * See the README file for information on usage and redistribution.
- */
- /*
- * FIXME: should move the memory mapping primitives into libImaging!
- */
- #include "Python.h"
- #include "libImaging/Imaging.h"
- /* compatibility wrappers (defined in _imaging.c) */
- extern int
- PyImaging_CheckBuffer(PyObject *buffer);
- extern int
- PyImaging_GetBuffer(PyObject *buffer, Py_buffer *view);
- extern PyObject *
- PyImagingNew(Imaging im);
- /* -------------------------------------------------------------------- */
- /* Buffer mapper */
- typedef struct ImagingBufferInstance {
- struct ImagingMemoryInstance im;
- PyObject *target;
- Py_buffer view;
- } ImagingBufferInstance;
- static void
- mapping_destroy_buffer(Imaging im) {
- ImagingBufferInstance *buffer = (ImagingBufferInstance *)im;
- PyBuffer_Release(&buffer->view);
- Py_XDECREF(buffer->target);
- }
- PyObject *
- PyImaging_MapBuffer(PyObject *self, PyObject *args) {
- Py_ssize_t y, size;
- Imaging im;
- PyObject *target;
- Py_buffer view;
- char *mode;
- char *codec;
- Py_ssize_t offset;
- int xsize, ysize;
- int stride;
- int ystep;
- if (!PyArg_ParseTuple(
- args,
- "O(ii)sn(sii)",
- &target,
- &xsize,
- &ysize,
- &codec,
- &offset,
- &mode,
- &stride,
- &ystep)) {
- return NULL;
- }
- if (!PyImaging_CheckBuffer(target)) {
- PyErr_SetString(PyExc_TypeError, "expected string or buffer");
- return NULL;
- }
- if (stride <= 0) {
- if (!strcmp(mode, "L") || !strcmp(mode, "P")) {
- stride = xsize;
- } else if (!strncmp(mode, "I;16", 4)) {
- stride = xsize * 2;
- } else {
- stride = xsize * 4;
- }
- }
- if (stride > 0 && ysize > PY_SSIZE_T_MAX / stride) {
- PyErr_SetString(PyExc_MemoryError, "Integer overflow in ysize");
- return NULL;
- }
- size = (Py_ssize_t)ysize * stride;
- if (offset > PY_SSIZE_T_MAX - size) {
- PyErr_SetString(PyExc_MemoryError, "Integer overflow in offset");
- return NULL;
- }
- /* check buffer size */
- if (PyImaging_GetBuffer(target, &view) < 0) {
- return NULL;
- }
- if (view.len < 0) {
- PyErr_SetString(PyExc_ValueError, "buffer has negative size");
- PyBuffer_Release(&view);
- return NULL;
- }
- if (offset + size > view.len) {
- PyErr_SetString(PyExc_ValueError, "buffer is not large enough");
- PyBuffer_Release(&view);
- return NULL;
- }
- im = ImagingNewPrologueSubtype(mode, xsize, ysize, sizeof(ImagingBufferInstance));
- if (!im) {
- PyBuffer_Release(&view);
- return NULL;
- }
- /* setup file pointers */
- if (ystep > 0) {
- for (y = 0; y < ysize; y++) {
- im->image[y] = (char *)view.buf + offset + y * stride;
- }
- } else {
- for (y = 0; y < ysize; y++) {
- im->image[ysize - y - 1] = (char *)view.buf + offset + y * stride;
- }
- }
- im->destroy = mapping_destroy_buffer;
- Py_INCREF(target);
- ((ImagingBufferInstance *)im)->target = target;
- ((ImagingBufferInstance *)im)->view = view;
- return PyImagingNew(im);
- }
|