From 807b66746f8719d0b35405889ad737f2b95b384d Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sun, 31 May 2026 23:45:17 +1000 Subject: [PATCH] Apply XOR mask to 1 and L mode images --- src/PIL/CurImagePlugin.py | 34 +++++++++++++++++++++++++++++++--- src/libImaging/Convert.c | 1 + 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/PIL/CurImagePlugin.py b/src/PIL/CurImagePlugin.py index 9c188e08446..b20425040f4 100644 --- a/src/PIL/CurImagePlugin.py +++ b/src/PIL/CurImagePlugin.py @@ -17,7 +17,7 @@ # from __future__ import annotations -from . import BmpImagePlugin, Image +from . import BmpImagePlugin, Image, ImageOps from ._binary import i16le as i16 from ._binary import i32le as i32 @@ -61,10 +61,38 @@ def _open(self) -> None: # load as bitmap self._bitmap(i32(m, 12) + offset) + self._masked = self.mode in ("1", "L") + if self._masked: + self._rawmode = self.mode + self._mode = "LA" # patch up the bitmap height - self._size = self.size[0], self.size[1] // 2 - self.tile = [self.tile[0]._replace(extents=(0, 0) + self.size)] + self._size = self.width, self.height // 2 + if not self._masked: + self.tile = [self.tile[0]._replace(extents=(0, 0) + self.size)] + + def load_prepare(self) -> None: + if self._masked: + self._mode = self._rawmode + self._size = self.width, self.height * 2 + super().load_prepare() + + def load_end(self) -> None: + if not self._masked: + return + self._mode = "LA" + new_height = self.height // 2 + + and_mask = self.im.crop((0, 0, self.width, new_height)) + xor_mask = self.im.crop((0, new_height, self.width, self.height)) + + self._size = self.width, new_height + self._im = Image.core.fill(self.mode, self.size) + self._im.paste( + xor_mask.convert(self.mode), + (0, 0) + self.size, + ImageOps.invert(Image.Image()._new(and_mask)).im, + ) # diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c index 2c62528c892..1fd14a944ef 100644 --- a/src/libImaging/Convert.c +++ b/src/libImaging/Convert.c @@ -1450,6 +1450,7 @@ static struct { {IMAGING_MODE_1, IMAGING_MODE_L, bit2l}, {IMAGING_MODE_1, IMAGING_MODE_I, bit2i}, {IMAGING_MODE_1, IMAGING_MODE_F, bit2f}, + {IMAGING_MODE_1, IMAGING_MODE_LA, bit2rgb}, {IMAGING_MODE_1, IMAGING_MODE_RGB, bit2rgb}, {IMAGING_MODE_1, IMAGING_MODE_RGBA, bit2rgb}, {IMAGING_MODE_1, IMAGING_MODE_RGBX, bit2rgb},