Pillow

Форк
0
/
test_file_pcx.py 
168 строк · 4.4 Кб
1
from __future__ import annotations
2

3
from pathlib import Path
4

5
import pytest
6

7
from PIL import Image, ImageFile, PcxImagePlugin
8

9
from .helper import assert_image_equal, hopper
10

11

12
def _roundtrip(tmp_path: Path, im: Image.Image) -> None:
13
    f = str(tmp_path / "temp.pcx")
14
    im.save(f)
15
    with Image.open(f) as im2:
16
        assert im2.mode == im.mode
17
        assert im2.size == im.size
18
        assert im2.format == "PCX"
19
        assert im2.get_format_mimetype() == "image/x-pcx"
20
        assert_image_equal(im2, im)
21

22

23
def test_sanity(tmp_path: Path) -> None:
24
    for mode in ("1", "L", "P", "RGB"):
25
        _roundtrip(tmp_path, hopper(mode))
26

27
    # Test a palette with less than 256 colors
28
    im = Image.new("P", (1, 1))
29
    im.putpalette((255, 0, 0))
30
    _roundtrip(tmp_path, im)
31

32
    # Test an unsupported mode
33
    f = str(tmp_path / "temp.pcx")
34
    im = hopper("RGBA")
35
    with pytest.raises(ValueError):
36
        im.save(f)
37

38

39
def test_invalid_file() -> None:
40
    invalid_file = "Tests/images/flower.jpg"
41

42
    with pytest.raises(SyntaxError):
43
        PcxImagePlugin.PcxImageFile(invalid_file)
44

45

46
@pytest.mark.parametrize("mode", ("1", "L", "P", "RGB"))
47
def test_odd(tmp_path: Path, mode: str) -> None:
48
    # See issue #523, odd sized images should have a stride that's even.
49
    # Not that ImageMagick or GIMP write PCX that way.
50
    # We were not handling properly.
51
    # larger, odd sized images are better here to ensure that
52
    # we handle interrupted scan lines properly.
53
    _roundtrip(tmp_path, hopper(mode).resize((511, 511)))
54

55

56
def test_odd_read() -> None:
57
    # Reading an image with an odd stride, making it malformed
58
    with Image.open("Tests/images/odd_stride.pcx") as im:
59
        im.load()
60

61
        assert im.size == (371, 150)
62

63

64
def test_pil184() -> None:
65
    # Check reading of files where xmin/xmax is not zero.
66

67
    test_file = "Tests/images/pil184.pcx"
68
    with Image.open(test_file) as im:
69
        assert im.size == (447, 144)
70
        assert im.tile[0][1] == (0, 0, 447, 144)
71

72
        # Make sure all pixels are either 0 or 255.
73
        assert im.histogram()[0] + im.histogram()[255] == 447 * 144
74

75

76
def test_1px_width(tmp_path: Path) -> None:
77
    im = Image.new("L", (1, 256))
78
    px = im.load()
79
    assert px is not None
80
    for y in range(256):
81
        px[0, y] = y
82
    _roundtrip(tmp_path, im)
83

84

85
def test_large_count(tmp_path: Path) -> None:
86
    im = Image.new("L", (256, 1))
87
    px = im.load()
88
    assert px is not None
89
    for x in range(256):
90
        px[x, 0] = x // 67 * 67
91
    _roundtrip(tmp_path, im)
92

93

94
def _test_buffer_overflow(tmp_path: Path, im: Image.Image, size: int = 1024) -> None:
95
    _last = ImageFile.MAXBLOCK
96
    ImageFile.MAXBLOCK = size
97
    try:
98
        _roundtrip(tmp_path, im)
99
    finally:
100
        ImageFile.MAXBLOCK = _last
101

102

103
def test_break_in_count_overflow(tmp_path: Path) -> None:
104
    im = Image.new("L", (256, 5))
105
    px = im.load()
106
    assert px is not None
107
    for y in range(4):
108
        for x in range(256):
109
            px[x, y] = x % 128
110
    _test_buffer_overflow(tmp_path, im)
111

112

113
def test_break_one_in_loop(tmp_path: Path) -> None:
114
    im = Image.new("L", (256, 5))
115
    px = im.load()
116
    assert px is not None
117
    for y in range(5):
118
        for x in range(256):
119
            px[x, y] = x % 128
120
    _test_buffer_overflow(tmp_path, im)
121

122

123
def test_break_many_in_loop(tmp_path: Path) -> None:
124
    im = Image.new("L", (256, 5))
125
    px = im.load()
126
    assert px is not None
127
    for y in range(4):
128
        for x in range(256):
129
            px[x, y] = x % 128
130
    for x in range(8):
131
        px[x, 4] = 16
132
    _test_buffer_overflow(tmp_path, im)
133

134

135
def test_break_one_at_end(tmp_path: Path) -> None:
136
    im = Image.new("L", (256, 5))
137
    px = im.load()
138
    assert px is not None
139
    for y in range(5):
140
        for x in range(256):
141
            px[x, y] = x % 128
142
    px[0, 3] = 128 + 64
143
    _test_buffer_overflow(tmp_path, im)
144

145

146
def test_break_many_at_end(tmp_path: Path) -> None:
147
    im = Image.new("L", (256, 5))
148
    px = im.load()
149
    assert px is not None
150
    for y in range(5):
151
        for x in range(256):
152
            px[x, y] = x % 128
153
    for x in range(4):
154
        px[x * 2, 3] = 128 + 64
155
        px[x + 256 - 4, 3] = 0
156
    _test_buffer_overflow(tmp_path, im)
157

158

159
def test_break_padding(tmp_path: Path) -> None:
160
    im = Image.new("L", (257, 5))
161
    px = im.load()
162
    assert px is not None
163
    for y in range(5):
164
        for x in range(257):
165
            px[x, y] = x % 128
166
    for x in range(5):
167
        px[x, 3] = 0
168
    _test_buffer_overflow(tmp_path, im)
169

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.