|
9 | 9 | from .helper import ( |
10 | 10 | assert_deep_equal, |
11 | 11 | assert_image_equal, |
| 12 | + is_big_endian, |
12 | 13 | hopper, |
13 | 14 | ) |
14 | 15 |
|
@@ -41,6 +42,34 @@ def _test_img_equals_pyarray( |
41 | 42 | assert_deep_equal(px[x, y], arr[y * img.width + x].as_py()) |
42 | 43 |
|
43 | 44 |
|
| 45 | +def _test_img_equals_int32_pyarray( |
| 46 | + img: Image.Image, arr: Any, mask: list[int] | None, elts_per_pixel: int = 1 |
| 47 | +) -> None: |
| 48 | + assert img.height * img.width * elts_per_pixel == len(arr) |
| 49 | + px = img.load() |
| 50 | + assert px is not None |
| 51 | + if mask is None: |
| 52 | + # have to do element wise comparison when we're comparing |
| 53 | + # flattened rgba in an uint32 to a pixel. |
| 54 | + mask = list(range(elts_per_pixel)) |
| 55 | + for x in range(0, img.size[0], int(img.size[0] / 10)): |
| 56 | + for y in range(0, img.size[1], int(img.size[1] / 10)): |
| 57 | + pixel = px[x, y] |
| 58 | + assert isinstance(pixel, tuple) |
| 59 | + arr_pixel_int = arr[y * img.width + x].as_py() |
| 60 | + arr_pixel_tuple = ( |
| 61 | + arr_pixel_int % 256, |
| 62 | + (arr_pixel_int // 256) % 256, |
| 63 | + (arr_pixel_int // 256**2) % 256, |
| 64 | + (arr_pixel_int // 256**3), |
| 65 | + ) |
| 66 | + if is_big_endian(): |
| 67 | + arr_pixel_tuple = arr_pixel_tuple[::-1] |
| 68 | + |
| 69 | + for ix, elt in enumerate(mask): |
| 70 | + assert pixel[ix] == arr_pixel_tuple[elt] |
| 71 | + |
| 72 | + |
44 | 73 | # really hard to get a non-nullable list type |
45 | 74 | fl_uint8_4_type = pyarrow.field( |
46 | 75 | "_", pyarrow.list_(pyarrow.field("_", pyarrow.uint8()).with_nullable(False), 4) |
@@ -129,7 +158,11 @@ def test_lifetime2() -> None: |
129 | 158 | 3, |
130 | 159 | 4 |
131 | 160 | ) |
132 | | - |
| 161 | +INT32 = ( |
| 162 | + pyarrow.uint32(), |
| 163 | + 0xabcdef45, |
| 164 | + 1 |
| 165 | +) |
133 | 166 |
|
134 | 167 |
|
135 | 168 | @pytest.mark.parametrize( |
@@ -166,3 +199,29 @@ def test_fromarray(mode: str, |
166 | 199 | img = Image.fromarrow(arr, mode, TEST_IMAGE_SIZE) |
167 | 200 |
|
168 | 201 | _test_img_equals_pyarray(img, arr, mask, elts_per_pixel) |
| 202 | + |
| 203 | + |
| 204 | +@pytest.mark.parametrize( |
| 205 | + "mode, data_tp, mask", |
| 206 | + ( |
| 207 | + ("LA", INT32, [0, 3]), |
| 208 | + ("RGB", INT32, [0, 1, 2]), |
| 209 | + ("RGBA", INT32, None), |
| 210 | + ("RGBA", INT32, None), |
| 211 | + ("CMYK", INT32, None), |
| 212 | + ("YCbCr", INT32, [0, 1, 2]), |
| 213 | + ("HSV", INT32, [0, 1, 2]), |
| 214 | + ), |
| 215 | +) |
| 216 | +def test_from_int32array(mode: str, |
| 217 | + data_tp: tuple, |
| 218 | + mask:list[int] | None) -> None: |
| 219 | + (dtype, |
| 220 | + elt, |
| 221 | + elts_per_pixel) = data_tp |
| 222 | + |
| 223 | + ct_pixels = TEST_IMAGE_SIZE[0] * TEST_IMAGE_SIZE[1] |
| 224 | + arr = pyarrow.array([elt]*(ct_pixels*elts_per_pixel), type=dtype) |
| 225 | + img = Image.fromarrow(arr, mode, TEST_IMAGE_SIZE) |
| 226 | + |
| 227 | + _test_img_equals_int32_pyarray(img, arr, mask, elts_per_pixel) |
0 commit comments