Support BGR;15, BGR;16 and BGR;24 in putdata

This commit is contained in:
Andrew Murray 2023-07-26 19:13:56 +10:00
parent 5fa05623ff
commit 9bd574058e
2 changed files with 46 additions and 12 deletions

View File

@ -76,6 +76,15 @@ def test_mode_F():
assert list(im.getdata()) == target 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(): def test_array_B():
# shouldn't segfault # shouldn't segfault
# see https://github.com/python-pillow/Pillow/issues/1008 # see https://github.com/python-pillow/Pillow/issues/1008

View File

@ -1573,21 +1573,46 @@ if (PySequence_Check(op)) { \
PyErr_SetString(PyExc_TypeError, must_be_sequence); PyErr_SetString(PyExc_TypeError, must_be_sequence);
return NULL; return NULL;
} }
int endian = strncmp(image->mode, "I;16", 4) == 0 ? (strcmp(image->mode, "I;16B") == 0 ? 2 : 1) : 0;
double value; double value;
for (i = x = y = 0; i < n; i++) { if (image->bands == 1) {
set_value_to_item(seq, i); int bigendian;
if (scale != 1.0 || offset != 0.0) { if (image->type == IMAGING_TYPE_SPECIAL) {
value = value * scale + offset; // I;16*
bigendian = strcmp(image->mode, "I;16B") == 0;
} }
if (endian == 0) { for (i = x = y = 0; i < n; i++) {
image->image8[y][x] = (UINT8)CLIP8(value); set_value_to_item(seq, i);
} else { if (scale != 1.0 || offset != 0.0) {
image->image8[y][x * 2 + (endian == 2 ? 1 : 0)] = CLIP8((int)value % 256); value = value * scale + offset;
image->image8[y][x * 2 + (endian == 2 ? 0 : 1)] = CLIP8((int)value >> 8); }
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) { } else {
x = 0, y++; // 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;
}
/* 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 */ PyErr_Clear(); /* Avoid weird exceptions */