Skip to content

Commit

Permalink
Support BGR;15, BGR;16 and BGR;24 in putdata
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Jul 26, 2023
1 parent 5fa0562 commit 9bd5740
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 12 deletions.
9 changes: 9 additions & 0 deletions Tests/test_image_putdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ def test_mode_F():
assert list(im.getdata()) == target


@pytest.mark.parametrize("mode", ("BGR;15", "BGR;16", "BGR;24"))
def test_mode_BGR(mode):
data = [(16, 32, 49), (32, 32, 98)]
im = Image.new(mode, (1, 2))
im.putdata(data)

assert list(im.getdata()) == data


def test_array_B():
# shouldn't segfault
# see https://github.com/python-pillow/Pillow/issues/1008
Expand Down
49 changes: 37 additions & 12 deletions src/_imaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -1573,21 +1573,46 @@ if (PySequence_Check(op)) { \
PyErr_SetString(PyExc_TypeError, must_be_sequence);
return NULL;
}
int endian = strncmp(image->mode, "I;16", 4) == 0 ? (strcmp(image->mode, "I;16B") == 0 ? 2 : 1) : 0;
double value;
for (i = x = y = 0; i < n; i++) {
set_value_to_item(seq, i);
if (scale != 1.0 || offset != 0.0) {
value = value * scale + offset;
if (image->bands == 1) {
int bigendian;
if (image->type == IMAGING_TYPE_SPECIAL) {
// I;16*
bigendian = strcmp(image->mode, "I;16B") == 0;
}
if (endian == 0) {
image->image8[y][x] = (UINT8)CLIP8(value);
} else {
image->image8[y][x * 2 + (endian == 2 ? 1 : 0)] = CLIP8((int)value % 256);
image->image8[y][x * 2 + (endian == 2 ? 0 : 1)] = CLIP8((int)value >> 8);
for (i = x = y = 0; i < n; i++) {
set_value_to_item(seq, i);
if (scale != 1.0 || offset != 0.0) {
value = value * scale + offset;
}
if (image->type == IMAGING_TYPE_SPECIAL) {
image->image8[y][x * 2 + (bigendian ? 1 : 0)] = CLIP8((int)value % 256);
image->image8[y][x * 2 + (bigendian ? 0 : 1)] = CLIP8((int)value >> 8);
} else {
image->image8[y][x] = (UINT8)CLIP8(value);
}
if (++x >= (int)image->xsize) {
x = 0, y++;
}
}
if (++x >= (int)image->xsize) {
x = 0, y++;
} else {
// BGR;*
int b;
for (i = x = y = 0; i < n; i++) {
char ink[4];

op = PySequence_Fast_GET_ITEM(seq, i);
if (!op || !getink(op, image, ink)) {
Py_DECREF(seq);
return NULL;

Check warning on line 1607 in src/_imaging.c

View check run for this annotation

Codecov / codecov/patch

src/_imaging.c#L1606-L1607

Added lines #L1606 - L1607 were not covered by tests
}
/* FIXME: what about scale and offset? */
for (b = 0; b < image->pixelsize; b++) {
image->image8[y][x * image->pixelsize + b] = ink[b];
}
if (++x >= (int)image->xsize) {
x = 0, y++;
}
}
}
PyErr_Clear(); /* Avoid weird exceptions */
Expand Down

0 comments on commit 9bd5740

Please sign in to comment.