map.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * The Python Imaging Library.
  3. *
  4. * standard memory mapping interface for the Imaging library
  5. *
  6. * history:
  7. * 1998-03-05 fl added Win32 read mapping
  8. * 1999-02-06 fl added "I;16" support
  9. * 2003-04-21 fl added PyImaging_MapBuffer primitive
  10. *
  11. * Copyright (c) 1998-2003 by Secret Labs AB.
  12. * Copyright (c) 2003 by Fredrik Lundh.
  13. *
  14. * See the README file for information on usage and redistribution.
  15. */
  16. /*
  17. * FIXME: should move the memory mapping primitives into libImaging!
  18. */
  19. #include "Python.h"
  20. #include "libImaging/Imaging.h"
  21. /* compatibility wrappers (defined in _imaging.c) */
  22. extern int
  23. PyImaging_CheckBuffer(PyObject *buffer);
  24. extern int
  25. PyImaging_GetBuffer(PyObject *buffer, Py_buffer *view);
  26. extern PyObject *
  27. PyImagingNew(Imaging im);
  28. /* -------------------------------------------------------------------- */
  29. /* Buffer mapper */
  30. typedef struct ImagingBufferInstance {
  31. struct ImagingMemoryInstance im;
  32. PyObject *target;
  33. Py_buffer view;
  34. } ImagingBufferInstance;
  35. static void
  36. mapping_destroy_buffer(Imaging im) {
  37. ImagingBufferInstance *buffer = (ImagingBufferInstance *)im;
  38. PyBuffer_Release(&buffer->view);
  39. Py_XDECREF(buffer->target);
  40. }
  41. PyObject *
  42. PyImaging_MapBuffer(PyObject *self, PyObject *args) {
  43. Py_ssize_t y, size;
  44. Imaging im;
  45. PyObject *target;
  46. Py_buffer view;
  47. char *mode;
  48. char *codec;
  49. Py_ssize_t offset;
  50. int xsize, ysize;
  51. int stride;
  52. int ystep;
  53. if (!PyArg_ParseTuple(
  54. args,
  55. "O(ii)sn(sii)",
  56. &target,
  57. &xsize,
  58. &ysize,
  59. &codec,
  60. &offset,
  61. &mode,
  62. &stride,
  63. &ystep)) {
  64. return NULL;
  65. }
  66. if (!PyImaging_CheckBuffer(target)) {
  67. PyErr_SetString(PyExc_TypeError, "expected string or buffer");
  68. return NULL;
  69. }
  70. if (stride <= 0) {
  71. if (!strcmp(mode, "L") || !strcmp(mode, "P")) {
  72. stride = xsize;
  73. } else if (!strncmp(mode, "I;16", 4)) {
  74. stride = xsize * 2;
  75. } else {
  76. stride = xsize * 4;
  77. }
  78. }
  79. if (stride > 0 && ysize > PY_SSIZE_T_MAX / stride) {
  80. PyErr_SetString(PyExc_MemoryError, "Integer overflow in ysize");
  81. return NULL;
  82. }
  83. size = (Py_ssize_t)ysize * stride;
  84. if (offset > PY_SSIZE_T_MAX - size) {
  85. PyErr_SetString(PyExc_MemoryError, "Integer overflow in offset");
  86. return NULL;
  87. }
  88. /* check buffer size */
  89. if (PyImaging_GetBuffer(target, &view) < 0) {
  90. return NULL;
  91. }
  92. if (view.len < 0) {
  93. PyErr_SetString(PyExc_ValueError, "buffer has negative size");
  94. PyBuffer_Release(&view);
  95. return NULL;
  96. }
  97. if (offset + size > view.len) {
  98. PyErr_SetString(PyExc_ValueError, "buffer is not large enough");
  99. PyBuffer_Release(&view);
  100. return NULL;
  101. }
  102. im = ImagingNewPrologueSubtype(mode, xsize, ysize, sizeof(ImagingBufferInstance));
  103. if (!im) {
  104. PyBuffer_Release(&view);
  105. return NULL;
  106. }
  107. /* setup file pointers */
  108. if (ystep > 0) {
  109. for (y = 0; y < ysize; y++) {
  110. im->image[y] = (char *)view.buf + offset + y * stride;
  111. }
  112. } else {
  113. for (y = 0; y < ysize; y++) {
  114. im->image[ysize - y - 1] = (char *)view.buf + offset + y * stride;
  115. }
  116. }
  117. im->destroy = mapping_destroy_buffer;
  118. Py_INCREF(target);
  119. ((ImagingBufferInstance *)im)->target = target;
  120. ((ImagingBufferInstance *)im)->view = view;
  121. return PyImagingNew(im);
  122. }