Skip to content

Commit 9bd5740

Browse files
committed
Support BGR;15, BGR;16 and BGR;24 in putdata
1 parent 5fa0562 commit 9bd5740

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

Tests/test_image_putdata.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,15 @@ def test_mode_F():
7676
assert list(im.getdata()) == target
7777

7878

79+
@pytest.mark.parametrize("mode", ("BGR;15", "BGR;16", "BGR;24"))
80+
def test_mode_BGR(mode):
81+
data = [(16, 32, 49), (32, 32, 98)]
82+
im = Image.new(mode, (1, 2))
83+
im.putdata(data)
84+
85+
assert list(im.getdata()) == data
86+
87+
7988
def test_array_B():
8089
# shouldn't segfault
8190
# see https://github.com/python-pillow/Pillow/issues/1008

src/_imaging.c

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,21 +1573,46 @@ if (PySequence_Check(op)) { \
15731573
PyErr_SetString(PyExc_TypeError, must_be_sequence);
15741574
return NULL;
15751575
}
1576-
int endian = strncmp(image->mode, "I;16", 4) == 0 ? (strcmp(image->mode, "I;16B") == 0 ? 2 : 1) : 0;
15771576
double value;
1578-
for (i = x = y = 0; i < n; i++) {
1579-
set_value_to_item(seq, i);
1580-
if (scale != 1.0 || offset != 0.0) {
1581-
value = value * scale + offset;
1577+
if (image->bands == 1) {
1578+
int bigendian;
1579+
if (image->type == IMAGING_TYPE_SPECIAL) {
1580+
// I;16*
1581+
bigendian = strcmp(image->mode, "I;16B") == 0;
15821582
}
1583-
if (endian == 0) {
1584-
image->image8[y][x] = (UINT8)CLIP8(value);
1585-
} else {
1586-
image->image8[y][x * 2 + (endian == 2 ? 1 : 0)] = CLIP8((int)value % 256);
1587-
image->image8[y][x * 2 + (endian == 2 ? 0 : 1)] = CLIP8((int)value >> 8);
1583+
for (i = x = y = 0; i < n; i++) {
1584+
set_value_to_item(seq, i);
1585+
if (scale != 1.0 || offset != 0.0) {
1586+
value = value * scale + offset;
1587+
}
1588+
if (image->type == IMAGING_TYPE_SPECIAL) {
1589+
image->image8[y][x * 2 + (bigendian ? 1 : 0)] = CLIP8((int)value % 256);
1590+
image->image8[y][x * 2 + (bigendian ? 0 : 1)] = CLIP8((int)value >> 8);
1591+
} else {
1592+
image->image8[y][x] = (UINT8)CLIP8(value);
1593+
}
1594+
if (++x >= (int)image->xsize) {
1595+
x = 0, y++;
1596+
}
15881597
}
1589-
if (++x >= (int)image->xsize) {
1590-
x = 0, y++;
1598+
} else {
1599+
// BGR;*
1600+
int b;
1601+
for (i = x = y = 0; i < n; i++) {
1602+
char ink[4];
1603+
1604+
op = PySequence_Fast_GET_ITEM(seq, i);
1605+
if (!op || !getink(op, image, ink)) {
1606+
Py_DECREF(seq);
1607+
return NULL;
1608+
}
1609+
/* FIXME: what about scale and offset? */
1610+
for (b = 0; b < image->pixelsize; b++) {
1611+
image->image8[y][x * image->pixelsize + b] = ink[b];
1612+
}
1613+
if (++x >= (int)image->xsize) {
1614+
x = 0, y++;
1615+
}
15911616
}
15921617
}
15931618
PyErr_Clear(); /* Avoid weird exceptions */

0 commit comments

Comments
 (0)