Skip to content

Commit 5833866

Browse files
committed
Simplify code
1 parent e5f4aa3 commit 5833866

3 files changed

Lines changed: 19 additions & 39 deletions

File tree

Tests/test_file_png.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -766,12 +766,10 @@ def test_specify_bits_fewer_palette_entries(self, tmp_path: Path) -> None:
766766
im.save(out, bits=4)
767767

768768
with Image.open(out) as reloaded:
769-
assert isinstance(reloaded, PngImagePlugin.PngImageFile)
770-
assert reloaded.png is not None
771-
assert reloaded.png.im_palette is not None
772-
# Only the 5 actual palette entries are written, rather than
773-
# padding the PLTE chunk out to 2 ** 4 == 16 entries.
774-
assert len(reloaded.png.im_palette[1]) == 15
769+
# Only the 5 actual palette entries are written,
770+
# rather than padding the PLTE chunk out to 16 entries (1 << 4).
771+
assert reloaded.palette is not None
772+
assert len(reloaded.palette.palette) == 5 * 3
775773

776774
assert_image_equal(im.convert("RGB"), reloaded.convert("RGB"))
777775

docs/releasenotes/13.0.0.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ Other changes
135135
=============
136136

137137
PNG palettes are no longer padded when saving with the ``bits`` argument
138-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
138+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
139139

140140
When saving a ``P`` mode image as a PNG with the ``bits`` argument, Pillow used to pad
141141
the ``PLTE`` chunk with zeroes up to ``2 ** bits`` entries. The ``PLTE`` chunk now only

src/PIL/PngImagePlugin.py

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,25 +1397,17 @@ def _save(
13971397
palette_frame_with_alpha = im if im.palette.mode == "RGBA" else None
13981398

13991399
outmode = mode
1400-
palette_colors = None
14011400
if mode == "P":
1402-
#
1403-
# attempt to minimize storage requirements for palette images
1404-
if "bits" in im.encoderinfo:
1405-
# number of bits specified by user
1406-
colors = min(1 << im.encoderinfo["bits"], 256)
1407-
1408-
if palette:
1409-
# write only as many PLTE entries as the palette actually
1410-
# contains, rather than padding out to the full 2**bits
1411-
palette_colors = max(min(len(palette) // 3, colors), 1)
1412-
else:
1413-
# check palette contents
1414-
if palette:
1415-
colors = max(min(len(palette) // 3, 256), 1)
1416-
else:
1417-
colors = 256
1418-
1401+
colors = max(
1402+
1,
1403+
min(
1404+
# number of bits specified by user
1405+
1 << im.encoderinfo.get("bits", 8),
1406+
# write only as many PLTE entries as the palette actually contains
1407+
len(palette) // 3 if palette else 0,
1408+
256,
1409+
),
1410+
)
14191411
if colors <= 16:
14201412
if colors <= 2:
14211413
bits = 1
@@ -1425,12 +1417,6 @@ def _save(
14251417
bits = 4
14261418
outmode += f";{bits}"
14271419

1428-
if palette_colors is None:
1429-
# no palette was available above to trim the PLTE/tRNS chunks to
1430-
# actual content, so fall back to the number of colors used to
1431-
# determine the bit depth
1432-
palette_colors = colors if mode == "P" else None
1433-
14341420
# get the corresponding PNG mode
14351421
try:
14361422
rawmode, bit_depth, color_type = _OUTMODES[outmode]
@@ -1487,20 +1473,16 @@ def _save(
14871473
if not after_idat:
14881474
chunk(fp, cid, data)
14891475

1490-
if mode == "P" and palette is not None:
1491-
assert palette_colors is not None
1492-
palette_byte_number = palette_colors * 3
1493-
palette_bytes = bytes(palette[:palette_byte_number])
1494-
while len(palette_bytes) < palette_byte_number:
1495-
palette_bytes += b"\0"
1476+
if mode == "P":
1477+
palette_bytes = (palette and bytes(palette[: colors * 3])) or b"\x00\x00\x00"
14961478
chunk(fp, b"PLTE", palette_bytes)
14971479

14981480
transparency = im.encoderinfo.get("transparency", im.info.get("transparency"))
14991481

15001482
if transparency is not None:
15011483
if mode == "P":
15021484
# limit to actual palette size
1503-
alpha_bytes = palette_colors
1485+
alpha_bytes = colors
15041486
if isinstance(transparency, bytes):
15051487
chunk(fp, b"tRNS", transparency[:alpha_bytes])
15061488
elif isinstance(transparency, int):
@@ -1534,7 +1516,7 @@ def _save(
15341516
raise OSError(msg)
15351517
elif mode == "P" and palette_frame_with_alpha:
15361518
alpha = palette_frame_with_alpha.im.getpalette("RGBA", "A")
1537-
alpha_bytes = palette_colors
1519+
alpha_bytes = colors
15381520
chunk(fp, b"tRNS", alpha[:alpha_bytes])
15391521

15401522
if dpi := im.encoderinfo.get("dpi"):

0 commit comments

Comments
 (0)