File: test_file_webp.py

package info (click to toggle)
pillow 8.1.2%2Bdfsg-0.3
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye
  • size: 65,376 kB
  • sloc: python: 35,568; ansic: 31,004; makefile: 388; javascript: 114; sh: 77
file content (181 lines) | stat: -rw-r--r-- 5,749 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import io
import re

import pytest

from PIL import Image, WebPImagePlugin, features

from .helper import (
    assert_image_similar,
    assert_image_similar_tofile,
    hopper,
    skip_unless_feature,
)

import os

try:
    from PIL import _webp

    HAVE_WEBP = True
except ImportError:
    HAVE_WEBP = False


class TestUnsupportedWebp:
    def test_unsupported(self):
        if HAVE_WEBP:
            WebPImagePlugin.SUPPORTED = False

        file_path = "Tests/images/hopper.webp"
        pytest.warns(UserWarning, lambda: pytest.raises(OSError, Image.open, file_path))

        if HAVE_WEBP:
            WebPImagePlugin.SUPPORTED = True


@skip_unless_feature("webp")
class TestFileWebp:
    def setup_method(self):
        self.rgb_mode = "RGB"

    def test_version(self):
        _webp.WebPDecoderVersion()
        _webp.WebPDecoderBuggyAlpha()
        assert re.search(r"\d+\.\d+\.\d+$", features.version_module("webp"))

    def test_read_rgb(self):
        """
        Can we read a RGB mode WebP file without error?
        Does it have the bits we expect?
        """

        with Image.open("Tests/images/hopper.webp") as image:
            assert image.mode == self.rgb_mode
            assert image.size == (128, 128)
            assert image.format == "WEBP"
            image.load()
            image.getdata()

            # generated with:
            # dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
            if 'ADTTMP' in os.environ:
                target_file = os.path.join(os.environ['ADTTMP'], 'hopper_webp.ppm')
            else:
                target_file = 'Tests/images/hopper_webp_bits.ppm'
            assert_image_similar_tofile(image, target_file, 1.0)

    def _roundtrip(self, tmp_path, mode, epsilon, args={}):
        temp_file = str(tmp_path / "temp.webp")

        hopper(mode).save(temp_file, **args)
        with Image.open(temp_file) as image:
            assert image.mode == self.rgb_mode
            assert image.size == (128, 128)
            assert image.format == "WEBP"
            image.load()
            image.getdata()

            if mode == self.rgb_mode:
                # generated with: dwebp -ppm temp.webp -o hopper_webp_write.ppm
                assert_image_similar_tofile(
                    image, "Tests/images/hopper_webp_write.ppm", 12.0
                )

            # This test asserts that the images are similar. If the average pixel
            # difference between the two images is less than the epsilon value,
            # then we're going to accept that it's a reasonable lossy version of
            # the image.
            target = hopper(mode)
            if mode != self.rgb_mode:
                target = target.convert(self.rgb_mode)
            assert_image_similar(image, target, epsilon)

    def test_write_rgb(self, tmp_path):
        """
        Can we write a RGB mode file to webp without error?
        Does it have the bits we expect?
        """

        self._roundtrip(tmp_path, self.rgb_mode, 12.5)

    def test_write_method(self, tmp_path):
        self._roundtrip(tmp_path, self.rgb_mode, 12.0, {"method": 6})

        buffer_no_args = io.BytesIO()
        hopper().save(buffer_no_args, format="WEBP")

        buffer_method = io.BytesIO()
        hopper().save(buffer_method, format="WEBP", method=6)
        assert buffer_no_args.getbuffer() != buffer_method.getbuffer()

    def test_write_unsupported_mode_L(self, tmp_path):
        """
        Saving a black-and-white file to WebP format should work, and be
        similar to the original file.
        """

        self._roundtrip(tmp_path, "L", 10.0)

    def test_write_unsupported_mode_P(self, tmp_path):
        """
        Saving a palette-based file to WebP format should work, and be
        similar to the original file.
        """

        self._roundtrip(tmp_path, "P", 50.0)

    def test_WebPEncode_with_invalid_args(self):
        """
        Calling encoder functions with no arguments should result in an error.
        """

        if _webp.HAVE_WEBPANIM:
            with pytest.raises(TypeError):
                _webp.WebPAnimEncoder()
        with pytest.raises(TypeError):
            _webp.WebPEncode()

    def test_WebPDecode_with_invalid_args(self):
        """
        Calling decoder functions with no arguments should result in an error.
        """

        if _webp.HAVE_WEBPANIM:
            with pytest.raises(TypeError):
                _webp.WebPAnimDecoder()
        with pytest.raises(TypeError):
            _webp.WebPDecode()

    def test_no_resource_warning(self, tmp_path):
        file_path = "Tests/images/hopper.webp"
        with Image.open(file_path) as image:
            temp_file = str(tmp_path / "temp.webp")
            pytest.warns(None, image.save, temp_file)

    def test_file_pointer_could_be_reused(self):
        file_path = "Tests/images/hopper.webp"
        with open(file_path, "rb") as blob:
            Image.open(blob).load()
            Image.open(blob).load()

    @skip_unless_feature("webp")
    @skip_unless_feature("webp_anim")
    def test_background_from_gif(self, tmp_path):
        with Image.open("Tests/images/chi.gif") as im:
            original_value = im.convert("RGB").getpixel((1, 1))

            # Save as WEBP
            out_webp = str(tmp_path / "temp.webp")
            im.save(out_webp, save_all=True)

        # Save as GIF
        out_gif = str(tmp_path / "temp.gif")
        Image.open(out_webp).save(out_gif)

        with Image.open(out_gif) as reread:
            reread_value = reread.convert("RGB").getpixel((1, 1))
        difference = sum(
            [abs(original_value[i] - reread_value[i]) for i in range(0, 3)]
        )
        assert difference < 5