Skip to content

Commit bac58a6

Browse files
committed
fix ImagingCore.tp_richcompare test for RGB and YCbCr
also, RGBX technically has 4 channels, so it shouldn't be masked. also, fix the mask for modes with three channels.
1 parent ae1f9e9 commit bac58a6

File tree

2 files changed

+16
-12
lines changed

2 files changed

+16
-12
lines changed

Tests/test_lib_image.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,17 @@ def test_not_equal(mode):
100100
assert img_a.im != img_b.im
101101

102102

103-
@pytest.mark.skip(reason="no way to directly set C bytes from Python")
104-
@pytest.mark.parametrize("mode", ("RGB", "RGBX", "YCbCr", "HSV", "LAB"))
105-
def test_equal_three_channels_four_bytes(mode):
106-
img_a = Image.frombytes("RGBA", (2, 2), b"ABC1DEF2GHI3JKL4")
107-
img_b = Image.frombytes("RGBA", (2, 2), b"ABC5DEF6GHI7JKL8")
108-
# this only sets the mode in Python, not C
109-
img_a.mode = mode
110-
img_b.mode = mode
103+
@pytest.mark.parametrize(
104+
("mode", "rawmode"),
105+
(("RGB", "RGBX"), ("YCbCr", "YCbCrX"), ("HSV", None), ("LAB", None)),
106+
)
107+
def test_equal_three_channels_four_bytes(mode, rawmode):
108+
if rawmode is None:
109+
pytest.skip("no 4-byte rawmode for " + mode)
110+
img_a = Image.frombytes(mode, (2, 2), b"ABC1DEF2GHI3JKL4", "raw", rawmode)
111+
img_b = Image.frombytes(mode, (2, 2), b"ABC5DEF6GHI7JKL8", "raw", rawmode)
111112
assert img_a.tobytes() == b"ABCDEFGHIJKL"
112113
assert img_b.tobytes() == b"ABCDEFGHIJKL"
113-
# this fails because the C code still thinks the mode is RGBA
114114
assert img_a.im == img_b.im
115115

116116

src/_imaging.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -3733,12 +3733,16 @@ _compare_pixels(
37333733
// Fortunately, all of the modes that have extra bytes in their pixels use four bytes for their pixels.
37343734
UINT32 mask = 0xffffffff;
37353735
if (
3736-
!strcmp(mode, "RGB") || !strcmp(mode, "RGBX") ||
3737-
!strcmp(mode, "YCbCr") || !strcmp(mode, "HSV") || !strcmp(mode, "LAB")
3736+
!strcmp(mode, "RGB") || !strcmp(mode, "YCbCr") ||
3737+
!strcmp(mode, "HSV") || !strcmp(mode, "LAB")
37383738
) {
37393739
// These modes have three channels in four bytes,
37403740
// so we have to ignore the last byte.
3741-
mask ^= 0xff;
3741+
#ifdef WORDS_BIGENDIAN
3742+
mask = 0xffffff00;
3743+
#else
3744+
mask = 0x00ffffff;
3745+
#endif
37423746
} else if (!strcmp(mode, "LA") || !strcmp(mode, "La") || !strcmp(mode, "PA")) {
37433747
// These modes have two channels in four bytes,
37443748
// so we have to ignore the middle two bytes.

0 commit comments

Comments
 (0)