Skip to content

Commit

Permalink
Merge pull request #1009 from wiredfool/putdata-1008
Browse files Browse the repository at this point in the history
Fix for Image.putdata segfault
  • Loading branch information
hugovk committed Nov 14, 2014
2 parents ccba6af + f75c556 commit b5b0b88
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 5 deletions.
20 changes: 20 additions & 0 deletions Tests/test_image_putdata.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from helper import unittest, PillowTestCase, hopper
from array import array

import sys

Expand Down Expand Up @@ -63,6 +64,25 @@ def test_mode_F(self):
target = [2.0 * float(elt) + 256.0 for elt in data]
self.assertEqual(list(im.getdata()), target)

def test_array_B(self):
# shouldn't segfault
# see https://github.com/python-pillow/Pillow/issues/1008

arr = array('B', [0])*15000
im = Image.new('L', (150, 100))
im.putdata(arr)

self.assertEqual(len(im.getdata()),len(arr))

def test_array_F(self):
# shouldn't segfault
# see https://github.com/python-pillow/Pillow/issues/1008

im = Image.new('F', (150, 100))
arr = array('f', [0.0])*15000
im.putdata(arr)

self.assertEqual(len(im.getdata()),len(arr))

if __name__ == '__main__':
unittest.main()
Expand Down
10 changes: 10 additions & 0 deletions Tests/test_numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ def test_point_lut(self):

im.point(lut)

def test_putdata(self):
# shouldn't segfault
# see https://github.com/python-pillow/Pillow/issues/1008

im = Image.new('F', (150, 100))
arr = numpy.zeros((15000,), numpy.float32)
im.putdata(arr)

self.assertEqual(len(im.getdata()),len(arr))


if __name__ == '__main__':
unittest.main()
Expand Down
10 changes: 5 additions & 5 deletions _imaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@ _putdata(ImagingObject* self, PyObject* args)
if (scale == 1.0 && offset == 0.0) {
/* Clipped data */
for (i = x = y = 0; i < n; i++) {
op = PySequence_Fast_GET_ITEM(data, i);
op = PySequence_Fast_GET_ITEM(seq, i);
image->image8[y][x] = (UINT8) CLIP(PyInt_AsLong(op));
if (++x >= (int) image->xsize){
x = 0, y++;
Expand All @@ -1279,7 +1279,7 @@ _putdata(ImagingObject* self, PyObject* args)
} else {
/* Scaled and clipped data */
for (i = x = y = 0; i < n; i++) {
PyObject *op = PySequence_Fast_GET_ITEM(data, i);
PyObject *op = PySequence_Fast_GET_ITEM(seq, i);
image->image8[y][x] = CLIP(
(int) (PyFloat_AsDouble(op) * scale + offset));
if (++x >= (int) image->xsize){
Expand All @@ -1299,7 +1299,7 @@ _putdata(ImagingObject* self, PyObject* args)
switch (image->type) {
case IMAGING_TYPE_INT32:
for (i = x = y = 0; i < n; i++) {
op = PySequence_Fast_GET_ITEM(data, i);
op = PySequence_Fast_GET_ITEM(seq, i);
IMAGING_PIXEL_INT32(image, x, y) =
(INT32) (PyFloat_AsDouble(op) * scale + offset);
if (++x >= (int) image->xsize){
Expand All @@ -1310,7 +1310,7 @@ _putdata(ImagingObject* self, PyObject* args)
break;
case IMAGING_TYPE_FLOAT32:
for (i = x = y = 0; i < n; i++) {
op = PySequence_Fast_GET_ITEM(data, i);
op = PySequence_Fast_GET_ITEM(seq, i);
IMAGING_PIXEL_FLOAT32(image, x, y) =
(FLOAT32) (PyFloat_AsDouble(op) * scale + offset);
if (++x >= (int) image->xsize){
Expand All @@ -1326,7 +1326,7 @@ _putdata(ImagingObject* self, PyObject* args)
INT32 inkint;
} u;

op = PySequence_Fast_GET_ITEM(data, i);
op = PySequence_Fast_GET_ITEM(seq, i);
if (!op || !getink(op, image, u.ink)) {
return NULL;
}
Expand Down

0 comments on commit b5b0b88

Please sign in to comment.