Skip to content

Commit 8c1dc0d

Browse files
authored
Merge branch 'main' into emf_records
2 parents ce40591 + 29cdbce commit 8c1dc0d

File tree

4 files changed

+78
-54
lines changed

4 files changed

+78
-54
lines changed

CHANGES.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ Changelog (Pillow)
55
11.1.0 (unreleased)
66
-------------------
77

8+
- Corrected EMF DPI #8485
9+
[radarhere]
10+
811
- Fix IFDRational with a zero denominator #8474
912
[radarhere]
1013

Tests/test_file_jpeg2k.py

Lines changed: 68 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import os
44
import re
5+
from collections.abc import Generator
56
from io import BytesIO
67
from pathlib import Path
78
from typing import Any
@@ -29,8 +30,16 @@
2930

3031
pytestmark = skip_unless_feature("jpg_2000")
3132

32-
test_card = Image.open("Tests/images/test-card.png")
33-
test_card.load()
33+
34+
@pytest.fixture
35+
def card() -> Generator[ImageFile.ImageFile, None, None]:
36+
with Image.open("Tests/images/test-card.png") as im:
37+
im.load()
38+
try:
39+
yield im
40+
finally:
41+
im.close()
42+
3443

3544
# OpenJPEG 2.0.0 outputs this debugging message sometimes; we should
3645
# ignore it---it doesn't represent a test failure.
@@ -74,76 +83,76 @@ def test_invalid_file() -> None:
7483
Jpeg2KImagePlugin.Jpeg2KImageFile(invalid_file)
7584

7685

77-
def test_bytesio() -> None:
86+
def test_bytesio(card: ImageFile.ImageFile) -> None:
7887
with open("Tests/images/test-card-lossless.jp2", "rb") as f:
7988
data = BytesIO(f.read())
8089
with Image.open(data) as im:
8190
im.load()
82-
assert_image_similar(im, test_card, 1.0e-3)
91+
assert_image_similar(im, card, 1.0e-3)
8392

8493

8594
# These two test pre-written JPEG 2000 files that were not written with
8695
# PIL (they were made using Adobe Photoshop)
8796

8897

89-
def test_lossless(tmp_path: Path) -> None:
98+
def test_lossless(card: ImageFile.ImageFile, tmp_path: Path) -> None:
9099
with Image.open("Tests/images/test-card-lossless.jp2") as im:
91100
im.load()
92101
outfile = str(tmp_path / "temp_test-card.png")
93102
im.save(outfile)
94-
assert_image_similar(im, test_card, 1.0e-3)
103+
assert_image_similar(im, card, 1.0e-3)
95104

96105

97-
def test_lossy_tiled() -> None:
98-
assert_image_similar_tofile(
99-
test_card, "Tests/images/test-card-lossy-tiled.jp2", 2.0
100-
)
106+
def test_lossy_tiled(card: ImageFile.ImageFile) -> None:
107+
assert_image_similar_tofile(card, "Tests/images/test-card-lossy-tiled.jp2", 2.0)
101108

102109

103-
def test_lossless_rt() -> None:
104-
im = roundtrip(test_card)
105-
assert_image_equal(im, test_card)
110+
def test_lossless_rt(card: ImageFile.ImageFile) -> None:
111+
im = roundtrip(card)
112+
assert_image_equal(im, card)
106113

107114

108-
def test_lossy_rt() -> None:
109-
im = roundtrip(test_card, quality_layers=[20])
110-
assert_image_similar(im, test_card, 2.0)
115+
def test_lossy_rt(card: ImageFile.ImageFile) -> None:
116+
im = roundtrip(card, quality_layers=[20])
117+
assert_image_similar(im, card, 2.0)
111118

112119

113-
def test_tiled_rt() -> None:
114-
im = roundtrip(test_card, tile_size=(128, 128))
115-
assert_image_equal(im, test_card)
120+
def test_tiled_rt(card: ImageFile.ImageFile) -> None:
121+
im = roundtrip(card, tile_size=(128, 128))
122+
assert_image_equal(im, card)
116123

117124

118-
def test_tiled_offset_rt() -> None:
119-
im = roundtrip(test_card, tile_size=(128, 128), tile_offset=(0, 0), offset=(32, 32))
120-
assert_image_equal(im, test_card)
125+
def test_tiled_offset_rt(card: ImageFile.ImageFile) -> None:
126+
im = roundtrip(card, tile_size=(128, 128), tile_offset=(0, 0), offset=(32, 32))
127+
assert_image_equal(im, card)
121128

122129

123-
def test_tiled_offset_too_small() -> None:
130+
def test_tiled_offset_too_small(card: ImageFile.ImageFile) -> None:
124131
with pytest.raises(ValueError):
125-
roundtrip(test_card, tile_size=(128, 128), tile_offset=(0, 0), offset=(128, 32))
132+
roundtrip(card, tile_size=(128, 128), tile_offset=(0, 0), offset=(128, 32))
126133

127134

128-
def test_irreversible_rt() -> None:
129-
im = roundtrip(test_card, irreversible=True, quality_layers=[20])
130-
assert_image_similar(im, test_card, 2.0)
135+
def test_irreversible_rt(card: ImageFile.ImageFile) -> None:
136+
im = roundtrip(card, irreversible=True, quality_layers=[20])
137+
assert_image_similar(im, card, 2.0)
131138

132139

133-
def test_prog_qual_rt() -> None:
134-
im = roundtrip(test_card, quality_layers=[60, 40, 20], progression="LRCP")
135-
assert_image_similar(im, test_card, 2.0)
140+
def test_prog_qual_rt(card: ImageFile.ImageFile) -> None:
141+
im = roundtrip(card, quality_layers=[60, 40, 20], progression="LRCP")
142+
assert_image_similar(im, card, 2.0)
136143

137144

138-
def test_prog_res_rt() -> None:
139-
im = roundtrip(test_card, num_resolutions=8, progression="RLCP")
140-
assert_image_equal(im, test_card)
145+
def test_prog_res_rt(card: ImageFile.ImageFile) -> None:
146+
im = roundtrip(card, num_resolutions=8, progression="RLCP")
147+
assert_image_equal(im, card)
141148

142149

143150
@pytest.mark.parametrize("num_resolutions", range(2, 6))
144-
def test_default_num_resolutions(num_resolutions: int) -> None:
151+
def test_default_num_resolutions(
152+
card: ImageFile.ImageFile, num_resolutions: int
153+
) -> None:
145154
d = 1 << (num_resolutions - 1)
146-
im = test_card.resize((d - 1, d - 1))
155+
im = card.resize((d - 1, d - 1))
147156
with pytest.raises(OSError):
148157
roundtrip(im, num_resolutions=num_resolutions)
149158
reloaded = roundtrip(im)
@@ -205,31 +214,31 @@ def test_header_errors() -> None:
205214
pass
206215

207216

208-
def test_layers_type(tmp_path: Path) -> None:
217+
def test_layers_type(card: ImageFile.ImageFile, tmp_path: Path) -> None:
209218
outfile = str(tmp_path / "temp_layers.jp2")
210219
for quality_layers in [[100, 50, 10], (100, 50, 10), None]:
211-
test_card.save(outfile, quality_layers=quality_layers)
220+
card.save(outfile, quality_layers=quality_layers)
212221

213222
for quality_layers_str in ["quality_layers", ("100", "50", "10")]:
214223
with pytest.raises(ValueError):
215-
test_card.save(outfile, quality_layers=quality_layers_str)
224+
card.save(outfile, quality_layers=quality_layers_str)
216225

217226

218-
def test_layers() -> None:
227+
def test_layers(card: ImageFile.ImageFile) -> None:
219228
out = BytesIO()
220-
test_card.save(out, "JPEG2000", quality_layers=[100, 50, 10], progression="LRCP")
229+
card.save(out, "JPEG2000", quality_layers=[100, 50, 10], progression="LRCP")
221230
out.seek(0)
222231

223232
with Image.open(out) as im:
224233
im.layers = 1
225234
im.load()
226-
assert_image_similar(im, test_card, 13)
235+
assert_image_similar(im, card, 13)
227236

228237
out.seek(0)
229238
with Image.open(out) as im:
230239
im.layers = 3
231240
im.load()
232-
assert_image_similar(im, test_card, 0.4)
241+
assert_image_similar(im, card, 0.4)
233242

234243

235244
@pytest.mark.parametrize(
@@ -245,24 +254,30 @@ def test_layers() -> None:
245254
(None, {"no_jp2": False}, 4, b"jP"),
246255
),
247256
)
248-
def test_no_jp2(name: str, args: dict[str, bool], offset: int, data: bytes) -> None:
257+
def test_no_jp2(
258+
card: ImageFile.ImageFile,
259+
name: str,
260+
args: dict[str, bool],
261+
offset: int,
262+
data: bytes,
263+
) -> None:
249264
out = BytesIO()
250265
if name:
251266
out.name = name
252-
test_card.save(out, "JPEG2000", **args)
267+
card.save(out, "JPEG2000", **args)
253268
out.seek(offset)
254269
assert out.read(2) == data
255270

256271

257-
def test_mct() -> None:
272+
def test_mct(card: ImageFile.ImageFile) -> None:
258273
# Three component
259274
for val in (0, 1):
260275
out = BytesIO()
261-
test_card.save(out, "JPEG2000", mct=val, no_jp2=True)
276+
card.save(out, "JPEG2000", mct=val, no_jp2=True)
262277

263278
assert out.getvalue()[59] == val
264279
with Image.open(out) as im:
265-
assert_image_similar(im, test_card, 1.0e-3)
280+
assert_image_similar(im, card, 1.0e-3)
266281

267282
# Single component should have MCT disabled
268283
for val in (0, 1):
@@ -419,22 +434,22 @@ def test_comment() -> None:
419434
pass
420435

421436

422-
def test_save_comment() -> None:
437+
def test_save_comment(card: ImageFile.ImageFile) -> None:
423438
for comment in ("Created by Pillow", b"Created by Pillow"):
424439
out = BytesIO()
425-
test_card.save(out, "JPEG2000", comment=comment)
440+
card.save(out, "JPEG2000", comment=comment)
426441

427442
with Image.open(out) as im:
428443
assert im.info["comment"] == b"Created by Pillow"
429444

430445
out = BytesIO()
431446
long_comment = b" " * 65531
432-
test_card.save(out, "JPEG2000", comment=long_comment)
447+
card.save(out, "JPEG2000", comment=long_comment)
433448
with Image.open(out) as im:
434449
assert im.info["comment"] == long_comment
435450

436451
with pytest.raises(ValueError):
437-
test_card.save(out, "JPEG2000", comment=long_comment + b" ")
452+
card.save(out, "JPEG2000", comment=long_comment + b" ")
438453

439454

440455
@pytest.mark.parametrize(
@@ -457,10 +472,10 @@ def test_crashes(test_file: str) -> None:
457472

458473

459474
@skip_unless_feature_version("jpg_2000", "2.4.0")
460-
def test_plt_marker() -> None:
475+
def test_plt_marker(card: ImageFile.ImageFile) -> None:
461476
# Search the start of the codesteam for PLT
462477
out = BytesIO()
463-
test_card.save(out, "JPEG2000", no_jp2=True, plt=True)
478+
card.save(out, "JPEG2000", no_jp2=True, plt=True)
464479
out.seek(0)
465480
while True:
466481
marker = out.read(2)

Tests/test_file_wmf.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ def test_load_float_dpi() -> None:
7171
with Image.open("Tests/images/drawing.emf") as im:
7272
assert im.info["dpi"] == 1423.7668161434979
7373

74+
with open("Tests/images/drawing.emf", "rb") as fp:
75+
data = fp.read()
76+
b = BytesIO(data[:8] + b"\x06\xFA" + data[10:])
77+
with Image.open(b) as im:
78+
assert im.info["dpi"][0] == 2540
79+
7480

7581
def test_load_set_dpi() -> None:
7682
with Image.open("Tests/images/drawing.wmf") as im:

src/PIL/WmfImagePlugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def _open(self) -> None:
128128
size = x1 - x0, y1 - y0
129129

130130
# calculate dots per inch from bbox and frame
131-
xdpi = 2540.0 * (x1 - y0) / (frame[2] - frame[0])
131+
xdpi = 2540.0 * (x1 - x0) / (frame[2] - frame[0])
132132
ydpi = 2540.0 * (y1 - y0) / (frame[3] - frame[1])
133133

134134
self.info["wmf_bbox"] = x0, y0, x1, y1

0 commit comments

Comments
 (0)