mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-22 21:24:46 +03:00
Merge branch 'master' into anchor
This commit is contained in:
commit
bbcb9483ed
|
@ -5,6 +5,12 @@ Changelog (Pillow)
|
||||||
7.2.0 (unreleased)
|
7.2.0 (unreleased)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
- Deprecate Image.show(command="...") #4646
|
||||||
|
[nulano, hugovk, radarhere]
|
||||||
|
|
||||||
|
- Updated JPEG magic number #4707
|
||||||
|
[Cykooz, radarhere]
|
||||||
|
|
||||||
- Change STRIPBYTECOUNTS to LONG if necessary when saving #4626
|
- Change STRIPBYTECOUNTS to LONG if necessary when saving #4626
|
||||||
[radarhere, hugovk]
|
[radarhere, hugovk]
|
||||||
|
|
||||||
|
|
BIN
Tests/images/imagedraw_wide_line_larger_than_int.png
Normal file
BIN
Tests/images/imagedraw_wide_line_larger_than_int.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 557 B |
|
@ -3,7 +3,14 @@ import re
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from PIL import ExifTags, Image, ImageFile, JpegImagePlugin, features
|
from PIL import (
|
||||||
|
ExifTags,
|
||||||
|
Image,
|
||||||
|
ImageFile,
|
||||||
|
JpegImagePlugin,
|
||||||
|
UnidentifiedImageError,
|
||||||
|
features,
|
||||||
|
)
|
||||||
|
|
||||||
from .helper import (
|
from .helper import (
|
||||||
assert_image,
|
assert_image,
|
||||||
|
@ -709,6 +716,24 @@ class TestFileJpeg:
|
||||||
with Image.open("Tests/images/icc-after-SOF.jpg") as im:
|
with Image.open("Tests/images/icc-after-SOF.jpg") as im:
|
||||||
assert im.info["icc_profile"] == b"profile"
|
assert im.info["icc_profile"] == b"profile"
|
||||||
|
|
||||||
|
def test_jpeg_magic_number(self):
|
||||||
|
size = 4097
|
||||||
|
buffer = BytesIO(b"\xFF" * size) # Many xFF bytes
|
||||||
|
buffer.max_pos = 0
|
||||||
|
orig_read = buffer.read
|
||||||
|
|
||||||
|
def read(n=-1):
|
||||||
|
res = orig_read(n)
|
||||||
|
buffer.max_pos = max(buffer.max_pos, buffer.tell())
|
||||||
|
return res
|
||||||
|
|
||||||
|
buffer.read = read
|
||||||
|
with pytest.raises(UnidentifiedImageError):
|
||||||
|
Image.open(buffer)
|
||||||
|
|
||||||
|
# Assert the entire file has not been read
|
||||||
|
assert 0 < buffer.max_pos < size
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not is_win32(), reason="Windows only")
|
@pytest.mark.skipif(not is_win32(), reason="Windows only")
|
||||||
@skip_unless_feature("jpg")
|
@skip_unless_feature("jpg")
|
||||||
|
|
|
@ -664,6 +664,18 @@ class TestImage:
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
assert str(e) == "buffer overrun when reading image file"
|
assert str(e) == "buffer overrun when reading image file"
|
||||||
|
|
||||||
|
def test_show_deprecation(self, monkeypatch):
|
||||||
|
monkeypatch.setattr(Image, "_show", lambda *args, **kwargs: None)
|
||||||
|
|
||||||
|
im = Image.new("RGB", (50, 50), "white")
|
||||||
|
|
||||||
|
with pytest.warns(None) as raised:
|
||||||
|
im.show()
|
||||||
|
assert not raised
|
||||||
|
|
||||||
|
with pytest.warns(DeprecationWarning):
|
||||||
|
im.show(command="mock")
|
||||||
|
|
||||||
|
|
||||||
class MockEncoder:
|
class MockEncoder:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -5,7 +5,7 @@ from PIL import Image, ImageColor, ImageDraw, ImageFont
|
||||||
|
|
||||||
from .helper import (
|
from .helper import (
|
||||||
assert_image_equal,
|
assert_image_equal,
|
||||||
assert_image_similar,
|
assert_image_similar_tofile,
|
||||||
hopper,
|
hopper,
|
||||||
skip_unless_feature,
|
skip_unless_feature,
|
||||||
)
|
)
|
||||||
|
@ -71,7 +71,7 @@ def helper_arc(bbox, start, end):
|
||||||
draw.arc(bbox, start, end)
|
draw.arc(bbox, start, end)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open("Tests/images/imagedraw_arc.png"), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_arc.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_arc1():
|
def test_arc1():
|
||||||
|
@ -110,20 +110,19 @@ def test_arc_no_loops():
|
||||||
draw.arc(BBOX1, start=start, end=end)
|
draw.arc(BBOX1, start=start, end=end)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open("Tests/images/imagedraw_arc_no_loops.png"), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_arc_no_loops.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_arc_width():
|
def test_arc_width():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_arc_width.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.arc(BBOX1, 10, 260, width=5)
|
draw.arc(BBOX1, 10, 260, width=5)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_arc_width.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_arc_width_pieslice_large():
|
def test_arc_width_pieslice_large():
|
||||||
|
@ -131,26 +130,24 @@ def test_arc_width_pieslice_large():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_arc_width_pieslice.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.arc(BBOX1, 10, 260, fill="yellow", width=100)
|
draw.arc(BBOX1, 10, 260, fill="yellow", width=100)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_arc_width_pieslice.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_arc_width_fill():
|
def test_arc_width_fill():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_arc_width_fill.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.arc(BBOX1, 10, 260, fill="yellow", width=5)
|
draw.arc(BBOX1, 10, 260, fill="yellow", width=5)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_arc_width_fill.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_arc_width_non_whole_angle():
|
def test_arc_width_non_whole_angle():
|
||||||
|
@ -163,7 +160,7 @@ def test_arc_width_non_whole_angle():
|
||||||
draw.arc(BBOX1, 10, 259.5, width=5)
|
draw.arc(BBOX1, 10, 259.5, width=5)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, expected, 1)
|
||||||
|
|
||||||
|
|
||||||
def test_bitmap():
|
def test_bitmap():
|
||||||
|
@ -190,7 +187,7 @@ def helper_chord(mode, bbox, start, end):
|
||||||
draw.chord(bbox, start, end, fill="red", outline="yellow")
|
draw.chord(bbox, start, end, fill="red", outline="yellow")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, expected, 1)
|
||||||
|
|
||||||
|
|
||||||
def test_chord1():
|
def test_chord1():
|
||||||
|
@ -209,26 +206,24 @@ def test_chord_width():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_chord_width.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.chord(BBOX1, 10, 260, outline="yellow", width=5)
|
draw.chord(BBOX1, 10, 260, outline="yellow", width=5)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_chord_width.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_chord_width_fill():
|
def test_chord_width_fill():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_chord_width_fill.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.chord(BBOX1, 10, 260, fill="red", outline="yellow", width=5)
|
draw.chord(BBOX1, 10, 260, fill="red", outline="yellow", width=5)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_chord_width_fill.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_chord_zero_width():
|
def test_chord_zero_width():
|
||||||
|
@ -254,7 +249,7 @@ def helper_ellipse(mode, bbox):
|
||||||
draw.ellipse(bbox, fill="green", outline="blue")
|
draw.ellipse(bbox, fill="green", outline="blue")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, expected, 1)
|
||||||
|
|
||||||
|
|
||||||
def test_ellipse1():
|
def test_ellipse1():
|
||||||
|
@ -276,8 +271,8 @@ def test_ellipse_translucent():
|
||||||
draw.ellipse(BBOX1, fill=(0, 255, 0, 127))
|
draw.ellipse(BBOX1, fill=(0, 255, 0, 127))
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
expected = Image.open("Tests/images/imagedraw_ellipse_translucent.png")
|
expected = "Tests/images/imagedraw_ellipse_translucent.png"
|
||||||
assert_image_similar(im, expected, 1)
|
assert_image_similar_tofile(im, expected, 1)
|
||||||
|
|
||||||
|
|
||||||
def test_ellipse_edge():
|
def test_ellipse_edge():
|
||||||
|
@ -289,7 +284,7 @@ def test_ellipse_edge():
|
||||||
draw.ellipse(((0, 0), (W - 1, H)), fill="white")
|
draw.ellipse(((0, 0), (W - 1, H)), fill="white")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_ellipse_edge.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_ellipse_symmetric():
|
def test_ellipse_symmetric():
|
||||||
|
@ -304,39 +299,36 @@ def test_ellipse_width():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_ellipse_width.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.ellipse(BBOX1, outline="blue", width=5)
|
draw.ellipse(BBOX1, outline="blue", width=5)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_ellipse_width.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_ellipse_width_large():
|
def test_ellipse_width_large():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (500, 500))
|
im = Image.new("RGB", (500, 500))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_ellipse_width_large.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.ellipse((25, 25, 475, 475), outline="blue", width=75)
|
draw.ellipse((25, 25, 475, 475), outline="blue", width=75)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_ellipse_width_large.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_ellipse_width_fill():
|
def test_ellipse_width_fill():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_ellipse_width_fill.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.ellipse(BBOX1, fill="green", outline="blue", width=5)
|
draw.ellipse(BBOX1, fill="green", outline="blue", width=5)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_ellipse_width_fill.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_ellipse_zero_width():
|
def test_ellipse_zero_width():
|
||||||
|
@ -423,7 +415,7 @@ def helper_pieslice(bbox, start, end):
|
||||||
draw.pieslice(bbox, start, end, fill="white", outline="blue")
|
draw.pieslice(bbox, start, end, fill="white", outline="blue")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open("Tests/images/imagedraw_pieslice.png"), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_pieslice.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_pieslice1():
|
def test_pieslice1():
|
||||||
|
@ -440,13 +432,12 @@ def test_pieslice_width():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_pieslice_width.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.pieslice(BBOX1, 10, 260, outline="blue", width=5)
|
draw.pieslice(BBOX1, 10, 260, outline="blue", width=5)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_pieslice_width.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_pieslice_width_fill():
|
def test_pieslice_width_fill():
|
||||||
|
@ -459,7 +450,7 @@ def test_pieslice_width_fill():
|
||||||
draw.pieslice(BBOX1, 10, 260, fill="white", outline="blue", width=5)
|
draw.pieslice(BBOX1, 10, 260, fill="white", outline="blue", width=5)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, expected, 1)
|
||||||
|
|
||||||
|
|
||||||
def test_pieslice_zero_width():
|
def test_pieslice_zero_width():
|
||||||
|
@ -571,13 +562,12 @@ def test_big_rectangle():
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
bbox = [(-1, -1), (W + 1, H + 1)]
|
bbox = [(-1, -1), (W + 1, H + 1)]
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_big_rectangle.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.rectangle(bbox, fill="orange")
|
draw.rectangle(bbox, fill="orange")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_big_rectangle.png", 1)
|
||||||
|
|
||||||
|
|
||||||
def test_rectangle_width():
|
def test_rectangle_width():
|
||||||
|
@ -878,13 +868,25 @@ def test_wide_line_dot():
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_wide_line_dot.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.line([(50, 50), (50, 50)], width=3)
|
draw.line([(50, 50), (50, 50)], width=3)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_wide_line_dot.png", 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_wide_line_larger_than_int():
|
||||||
|
# Arrange
|
||||||
|
im = Image.new("RGB", (W, H))
|
||||||
|
draw = ImageDraw.Draw(im)
|
||||||
|
expected = "Tests/images/imagedraw_wide_line_larger_than_int.png"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
draw.line([(0, 0), (32768, 32768)], width=3)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
assert_image_similar_tofile(im, expected, 1)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
@ -971,13 +973,12 @@ def test_wide_line_dot():
|
||||||
def test_line_joint(xy):
|
def test_line_joint(xy):
|
||||||
im = Image.new("RGB", (500, 325))
|
im = Image.new("RGB", (500, 325))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_line_joint_curve.png"
|
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.line(xy, GRAY, 50, "curve")
|
draw.line(xy, GRAY, 50, "curve")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(im, Image.open(expected), 3)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_line_joint_curve.png", 3)
|
||||||
|
|
||||||
|
|
||||||
def test_textsize_empty_string():
|
def test_textsize_empty_string():
|
||||||
|
@ -1018,8 +1019,8 @@ def test_stroke():
|
||||||
draw.text((12, 12), "A", "#f00", font, stroke_width=2, stroke_fill=stroke_fill)
|
draw.text((12, 12), "A", "#f00", font, stroke_width=2, stroke_fill=stroke_fill)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(
|
assert_image_similar_tofile(
|
||||||
im, Image.open("Tests/images/imagedraw_stroke_" + suffix + ".png"), 3.1
|
im, "Tests/images/imagedraw_stroke_" + suffix + ".png", 3.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1034,9 +1035,7 @@ def test_stroke_descender():
|
||||||
draw.text((12, 2), "y", "#f00", font, stroke_width=2, stroke_fill="#0f0")
|
draw.text((12, 2), "y", "#f00", font, stroke_width=2, stroke_fill="#0f0")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_stroke_descender.png", 6.78)
|
||||||
im, Image.open("Tests/images/imagedraw_stroke_descender.png"), 6.78
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@skip_unless_feature("freetype2")
|
@skip_unless_feature("freetype2")
|
||||||
|
@ -1052,9 +1051,7 @@ def test_stroke_multiline():
|
||||||
)
|
)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar(
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_stroke_multiline.png", 3.3)
|
||||||
im, Image.open("Tests/images/imagedraw_stroke_multiline.png"), 3.3
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_same_color_outline():
|
def test_same_color_outline():
|
||||||
|
@ -1093,4 +1090,4 @@ def test_same_color_outline():
|
||||||
expected = "Tests/images/imagedraw_outline_{}_{}.png".format(
|
expected = "Tests/images/imagedraw_outline_{}_{}.png".format(
|
||||||
operation, mode
|
operation, mode
|
||||||
)
|
)
|
||||||
assert_image_similar(im, Image.open(expected), 1)
|
assert_image_similar_tofile(im, expected, 1)
|
||||||
|
|
|
@ -12,6 +12,14 @@ Deprecated features
|
||||||
Below are features which are considered deprecated. Where appropriate,
|
Below are features which are considered deprecated. Where appropriate,
|
||||||
a ``DeprecationWarning`` is issued.
|
a ``DeprecationWarning`` is issued.
|
||||||
|
|
||||||
|
Image.show command parameter
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. deprecated:: 7.2.0
|
||||||
|
|
||||||
|
The ``command`` parameter was deprecated and will be removed in a future release.
|
||||||
|
Use a subclass of ``ImageShow.Viewer`` instead.
|
||||||
|
|
||||||
ImageFile.raise_ioerror
|
ImageFile.raise_ioerror
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,12 @@ are now read as just a single bytestring.
|
||||||
Deprecations
|
Deprecations
|
||||||
^^^^^^^^^^^^
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Image.show command parameter
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The ``command`` parameter was deprecated and will be removed in a future release.
|
||||||
|
Use a subclass of :py:class:`PIL.ImageShow.Viewer` instead.
|
||||||
|
|
||||||
ImageFile.raise_ioerror
|
ImageFile.raise_ioerror
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ class BmpImageFile(ImageFile.ImageFile):
|
||||||
# read 14 bytes: magic number, filesize, reserved, header final offset
|
# read 14 bytes: magic number, filesize, reserved, header final offset
|
||||||
head_data = self.fp.read(14)
|
head_data = self.fp.read(14)
|
||||||
# choke if the file does not have the required magic bytes
|
# choke if the file does not have the required magic bytes
|
||||||
if head_data[0:2] != b"BM":
|
if not _accept(head_data):
|
||||||
raise SyntaxError("Not a BMP file")
|
raise SyntaxError("Not a BMP file")
|
||||||
# read the start position of the BMP image data (u32)
|
# read the start position of the BMP image data (u32)
|
||||||
offset = i32(head_data[10:14])
|
offset = i32(head_data[10:14])
|
||||||
|
|
|
@ -46,7 +46,7 @@ class DcxImageFile(PcxImageFile):
|
||||||
|
|
||||||
# Header
|
# Header
|
||||||
s = self.fp.read(4)
|
s = self.fp.read(4)
|
||||||
if i32(s) != MAGIC:
|
if not _accept(s):
|
||||||
raise SyntaxError("not a DCX file")
|
raise SyntaxError("not a DCX file")
|
||||||
|
|
||||||
# Component directory
|
# Component directory
|
||||||
|
|
|
@ -42,9 +42,8 @@ class FliImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
# HEAD
|
# HEAD
|
||||||
s = self.fp.read(128)
|
s = self.fp.read(128)
|
||||||
magic = i16(s[4:6])
|
|
||||||
if not (
|
if not (
|
||||||
magic in [0xAF11, 0xAF12]
|
_accept(s)
|
||||||
and i16(s[14:16]) in [0, 3] # flags
|
and i16(s[14:16]) in [0, 3] # flags
|
||||||
and s[20:22] == b"\x00\x00" # reserved
|
and s[20:22] == b"\x00\x00" # reserved
|
||||||
):
|
):
|
||||||
|
@ -60,6 +59,7 @@ class FliImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
# animation speed
|
# animation speed
|
||||||
duration = i32(s[16:20])
|
duration = i32(s[16:20])
|
||||||
|
magic = i16(s[4:6])
|
||||||
if magic == 0xAF11:
|
if magic == 0xAF11:
|
||||||
duration = (duration * 1000) // 70
|
duration = (duration * 1000) // 70
|
||||||
self.info["duration"] = duration
|
self.info["duration"] = duration
|
||||||
|
|
|
@ -63,7 +63,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
# Screen
|
# Screen
|
||||||
s = self.fp.read(13)
|
s = self.fp.read(13)
|
||||||
if s[:6] not in [b"GIF87a", b"GIF89a"]:
|
if not _accept(s):
|
||||||
raise SyntaxError("not a GIF file")
|
raise SyntaxError("not a GIF file")
|
||||||
|
|
||||||
self.info["version"] = s[:6]
|
self.info["version"] = s[:6]
|
||||||
|
|
|
@ -2181,8 +2181,10 @@ class Image:
|
||||||
|
|
||||||
def show(self, title=None, command=None):
|
def show(self, title=None, command=None):
|
||||||
"""
|
"""
|
||||||
Displays this image. This method is mainly intended for
|
Displays this image. This method is mainly intended for debugging purposes.
|
||||||
debugging purposes.
|
|
||||||
|
This method calls :py:func:`PIL.ImageShow.show` internally. You can use
|
||||||
|
:py:func:`PIL.ImageShow.register` to override its default behaviour.
|
||||||
|
|
||||||
The image is first saved to a temporary file. By default, it will be in
|
The image is first saved to a temporary file. By default, it will be in
|
||||||
PNG format.
|
PNG format.
|
||||||
|
@ -2194,11 +2196,16 @@ class Image:
|
||||||
|
|
||||||
On Windows, the image is opened with the standard PNG display utility.
|
On Windows, the image is opened with the standard PNG display utility.
|
||||||
|
|
||||||
:param title: Optional title to use for the image window,
|
:param title: Optional title to use for the image window, where possible.
|
||||||
where possible.
|
|
||||||
:param command: command used to show the image
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if command is not None:
|
||||||
|
warnings.warn(
|
||||||
|
"The command parameter is deprecated and will be removed in a future "
|
||||||
|
"release. Use a subclass of ImageShow.Viewer instead.",
|
||||||
|
DeprecationWarning,
|
||||||
|
)
|
||||||
|
|
||||||
_show(self, title=title, command=command)
|
_show(self, title=title, command=command)
|
||||||
|
|
||||||
def split(self):
|
def split(self):
|
||||||
|
|
|
@ -323,7 +323,8 @@ MARKER = {
|
||||||
|
|
||||||
|
|
||||||
def _accept(prefix):
|
def _accept(prefix):
|
||||||
return prefix[0:1] == b"\377"
|
# Magic number was taken from https://en.wikipedia.org/wiki/JPEG
|
||||||
|
return prefix[0:3] == b"\xFF\xD8\xFF"
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -337,10 +338,11 @@ class JpegImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
def _open(self):
|
def _open(self):
|
||||||
|
|
||||||
s = self.fp.read(1)
|
s = self.fp.read(3)
|
||||||
|
|
||||||
if i8(s) != 255:
|
if not _accept(s):
|
||||||
raise SyntaxError("not a JPEG file")
|
raise SyntaxError("not a JPEG file")
|
||||||
|
s = b"\xFF"
|
||||||
|
|
||||||
# Create attributes
|
# Create attributes
|
||||||
self.bits = self.layers = 0
|
self.bits = self.layers = 0
|
||||||
|
|
|
@ -51,7 +51,7 @@ class MspImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
# Header
|
# Header
|
||||||
s = self.fp.read(32)
|
s = self.fp.read(32)
|
||||||
if s[:4] not in [b"DanM", b"LinS"]:
|
if not _accept(s):
|
||||||
raise SyntaxError("not an MSP file")
|
raise SyntaxError("not an MSP file")
|
||||||
|
|
||||||
# Header checksum
|
# Header checksum
|
||||||
|
|
|
@ -43,7 +43,7 @@ class PixarImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
# assuming a 4-byte magic label
|
# assuming a 4-byte magic label
|
||||||
s = self.fp.read(4)
|
s = self.fp.read(4)
|
||||||
if s != b"\200\350\000\000":
|
if not _accept(s):
|
||||||
raise SyntaxError("not a PIXAR file")
|
raise SyntaxError("not a PIXAR file")
|
||||||
|
|
||||||
# read rest of header
|
# read rest of header
|
||||||
|
|
|
@ -633,7 +633,7 @@ class PngImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
def _open(self):
|
def _open(self):
|
||||||
|
|
||||||
if self.fp.read(8) != _MAGIC:
|
if not _accept(self.fp.read(8)):
|
||||||
raise SyntaxError("not a PNG file")
|
raise SyntaxError("not a PNG file")
|
||||||
self.__fp = self.fp
|
self.__fp = self.fp
|
||||||
self.__frame = 0
|
self.__frame = 0
|
||||||
|
|
|
@ -61,7 +61,7 @@ class PsdImageFile(ImageFile.ImageFile):
|
||||||
# header
|
# header
|
||||||
|
|
||||||
s = read(26)
|
s = read(26)
|
||||||
if s[:4] != b"8BPS" or i16(s[4:]) != 1:
|
if not _accept(s) or i16(s[4:]) != 1:
|
||||||
raise SyntaxError("not a PSD file")
|
raise SyntaxError("not a PSD file")
|
||||||
|
|
||||||
psd_bits = i16(s[22:])
|
psd_bits = i16(s[22:])
|
||||||
|
|
|
@ -58,8 +58,7 @@ class SgiImageFile(ImageFile.ImageFile):
|
||||||
headlen = 512
|
headlen = 512
|
||||||
s = self.fp.read(headlen)
|
s = self.fp.read(headlen)
|
||||||
|
|
||||||
# magic number : 474
|
if not _accept(s):
|
||||||
if i16(s) != 474:
|
|
||||||
raise ValueError("Not an SGI image file")
|
raise ValueError("Not an SGI image file")
|
||||||
|
|
||||||
# compression : verbatim or RLE
|
# compression : verbatim or RLE
|
||||||
|
|
|
@ -53,7 +53,7 @@ class SunImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
# HEAD
|
# HEAD
|
||||||
s = self.fp.read(32)
|
s = self.fp.read(32)
|
||||||
if i32(s) != 0x59A66A95:
|
if not _accept(s):
|
||||||
raise SyntaxError("not an SUN raster file")
|
raise SyntaxError("not an SUN raster file")
|
||||||
|
|
||||||
offset = 32
|
offset = 32
|
||||||
|
|
|
@ -683,7 +683,7 @@ ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
big_hypotenuse = sqrt((double) (dx*dx + dy*dy));
|
big_hypotenuse = hypot(dx, dy);
|
||||||
small_hypotenuse = (width - 1) / 2.0;
|
small_hypotenuse = (width - 1) / 2.0;
|
||||||
ratio_max = ROUND_UP(small_hypotenuse) / big_hypotenuse;
|
ratio_max = ROUND_UP(small_hypotenuse) / big_hypotenuse;
|
||||||
ratio_min = ROUND_DOWN(small_hypotenuse) / big_hypotenuse;
|
ratio_min = ROUND_DOWN(small_hypotenuse) / big_hypotenuse;
|
||||||
|
|
|
@ -251,9 +251,9 @@ deps = {
|
||||||
"libs": [r"*.lib"],
|
"libs": [r"*.lib"],
|
||||||
},
|
},
|
||||||
"harfbuzz": {
|
"harfbuzz": {
|
||||||
"url": "https://github.com/harfbuzz/harfbuzz/archive/2.6.7.zip",
|
"url": "https://github.com/harfbuzz/harfbuzz/archive/2.6.8.zip",
|
||||||
"filename": "harfbuzz-2.6.7.zip",
|
"filename": "harfbuzz-2.6.8.zip",
|
||||||
"dir": "harfbuzz-2.6.7",
|
"dir": "harfbuzz-2.6.8",
|
||||||
"build": [
|
"build": [
|
||||||
cmd_cmake("-DHB_HAVE_FREETYPE:BOOL=TRUE"),
|
cmd_cmake("-DHB_HAVE_FREETYPE:BOOL=TRUE"),
|
||||||
cmd_nmake(target="clean"),
|
cmd_nmake(target="clean"),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user