diff --git a/.github/workflows/test-cygwin.yml b/.github/workflows/test-cygwin.yml index 7b8070d34..1dfb36f44 100644 --- a/.github/workflows/test-cygwin.yml +++ b/.github/workflows/test-cygwin.yml @@ -34,18 +34,34 @@ jobs: with: platform: x86_64 packages: > - ImageMagick gcc-g++ ghostscript jpeg libfreetype-devel - libimagequant-devel libjpeg-devel liblapack-devel - liblcms2-devel libopenjp2-devel libraqm-devel - libtiff-devel libwebp-devel libxcb-devel libxcb-xinerama0 - make netpbm perl + gcc-g++ + ghostscript + ImageMagick + jpeg + libfreetype-devel + libimagequant-devel + libjpeg-devel + liblapack-devel + liblcms2-devel + libopenjp2-devel + libraqm-devel + libtiff-devel + libwebp-devel + libxcb-devel + libxcb-xinerama0 + make + netpbm + perl python3${{ matrix.python-minor-version }}-cffi python3${{ matrix.python-minor-version }}-cython python3${{ matrix.python-minor-version }}-devel python3${{ matrix.python-minor-version }}-numpy python3${{ matrix.python-minor-version }}-sip python3${{ matrix.python-minor-version }}-tkinter - qt5-devel-tools subversion xorg-server-extra zlib-devel + qt5-devel-tools + subversion + xorg-server-extra + zlib-devel - name: Add Lapack to PATH uses: egor-tensin/cleanup-path@v3 diff --git a/.github/workflows/test-mingw.yml b/.github/workflows/test-mingw.yml index 6a60bc7f0..24575f6c7 100644 --- a/.github/workflows/test-mingw.yml +++ b/.github/workflows/test-mingw.yml @@ -45,11 +45,6 @@ jobs: - name: Install dependencies run: | pacman -S --noconfirm \ - ${{ matrix.package }}-python3-cffi \ - ${{ matrix.package }}-python3-numpy \ - ${{ matrix.package }}-python3-olefile \ - ${{ matrix.package }}-python3-pip \ - ${{ matrix.package }}-python3-setuptools \ ${{ matrix.package }}-freetype \ ${{ matrix.package }}-gcc \ ${{ matrix.package }}-ghostscript \ @@ -60,6 +55,11 @@ jobs: ${{ matrix.package }}-libtiff \ ${{ matrix.package }}-libwebp \ ${{ matrix.package }}-openjpeg2 \ + ${{ matrix.package }}-python3-cffi \ + ${{ matrix.package }}-python3-numpy \ + ${{ matrix.package }}-python3-olefile \ + ${{ matrix.package }}-python3-pip \ + ${{ matrix.package }}-python3-setuptools \ subversion if [ ${{ matrix.package }} == "mingw-w64-x86_64" ]; then diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d790e7850..45c1f3c5f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/psf/black - rev: 22.12.0 + rev: 23.1.0 hooks: - id: black args: [--target-version=py37] @@ -9,7 +9,7 @@ repos: types: [] - repo: https://github.com/PyCQA/isort - rev: 5.11.4 + rev: 5.12.0 hooks: - id: isort @@ -26,7 +26,7 @@ repos: - id: yesqa - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.3.1 + rev: v1.4.2 hooks: - id: remove-tabs exclude: (Makefile$|\.bat$|\.cmake$|\.eps$|\.fits$|\.opt$) @@ -39,7 +39,7 @@ repos: [flake8-2020, flake8-errmsg, flake8-implicit-str-concat] - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.9.0 + rev: v1.10.0 hooks: - id: python-check-blanket-noqa - id: rst-backticks @@ -57,7 +57,7 @@ repos: - id: sphinx-lint - repo: https://github.com/tox-dev/tox-ini-fmt - rev: 0.5.2 + rev: 0.6.1 hooks: - id: tox-ini-fmt diff --git a/CHANGES.rst b/CHANGES.rst index bf3017ca9..e35a55965 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,24 @@ Changelog (Pillow) 9.5.0 (unreleased) ------------------ +- Handle more than one directory returned by pkg-config #6896 + [sebastic, radarhere] + +- Do not retry past formats when loading all formats for the first time #6902 + [radarhere] + +- Do not retry specified formats if they failed when opening #6893 + [radarhere] + +- Do not unintentionally load TIFF format at first #6892 + [radarhere] + +- Stop reading when EPS line becomes too long #6897 + [radarhere] + +- Allow writing IFDRational to BYTE tag #6890 + [radarhere] + - Raise ValueError for BoxBlur filter with negative radius #6874 [hugovk, radarhere] diff --git a/LICENSE b/LICENSE index 616808a48..125bdcc44 100644 --- a/LICENSE +++ b/LICENSE @@ -5,7 +5,7 @@ The Python Imaging Library (PIL) is Pillow is the friendly PIL fork. It is - Copyright © 2010-2023 by Alex Clark and contributors + Copyright © 2010-2023 by Jeffrey A. Clark (Alex) and contributors. Like PIL, Pillow is licensed under the open source HPND License: diff --git a/README.md b/README.md index 489d3db54..af1ca57c2 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ ## Python Imaging Library (Fork) -Pillow is the friendly PIL fork by [Alex Clark and -Contributors](https://github.com/python-pillow/Pillow/graphs/contributors). +Pillow is the friendly PIL fork by [Jeffrey A. Clark (Alex) and +contributors](https://github.com/python-pillow/Pillow/graphs/contributors). PIL is the Python Imaging Library by Fredrik Lundh and Contributors. As of 2019, Pillow development is [supported by Tidelift](https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=readme&utm_campaign=enterprise). diff --git a/Tests/check_fli_overflow.py b/Tests/check_fli_overflow.py index 08a55d349..c600c45ed 100644 --- a/Tests/check_fli_overflow.py +++ b/Tests/check_fli_overflow.py @@ -4,7 +4,6 @@ TEST_FILE = "Tests/images/fli_overflow.fli" def test_fli_overflow(): - # this should not crash with a malloc error or access violation with Image.open(TEST_FILE) as im: im.load() diff --git a/Tests/check_png_dos.py b/Tests/check_png_dos.py index d8d645189..f4a129f50 100644 --- a/Tests/check_png_dos.py +++ b/Tests/check_png_dos.py @@ -23,7 +23,6 @@ def test_ignore_dos_text(): def test_dos_text(): - try: im = Image.open(TEST_FILE) im.load() diff --git a/Tests/test_bmp_reference.py b/Tests/test_bmp_reference.py index ed9aff9cc..002a44a4f 100644 --- a/Tests/test_bmp_reference.py +++ b/Tests/test_bmp_reference.py @@ -18,7 +18,6 @@ def test_bad(): """These shouldn't crash/dos, but they shouldn't return anything either""" for f in get_files("b"): - # Assert that there is no unclosed file warning with warnings.catch_warnings(): try: diff --git a/Tests/test_deprecate.py b/Tests/test_deprecate.py index 30ed4a808..3375eb6b2 100644 --- a/Tests/test_deprecate.py +++ b/Tests/test_deprecate.py @@ -11,6 +11,11 @@ from PIL import _deprecate "Old thing is deprecated and will be removed in Pillow 10 " r"\(2023-07-01\)\. Use new thing instead\.", ), + ( + 11, + "Old thing is deprecated and will be removed in Pillow 11 " + r"\(2024-10-15\)\. Use new thing instead\.", + ), ( None, r"Old thing is deprecated and will be removed in a future version\. " diff --git a/Tests/test_file_bmp.py b/Tests/test_file_bmp.py index 5f6d52355..9e79937e9 100644 --- a/Tests/test_file_bmp.py +++ b/Tests/test_file_bmp.py @@ -141,7 +141,6 @@ def test_rgba_bitfields(): # This test image has been manually hexedited # to change the bitfield compression in the header from XBGR to RGBA with Image.open("Tests/images/rgb32bf-rgba.bmp") as im: - # So before the comparing the image, swap the channels b, g, r = im.split()[1:] im = Image.merge("RGB", (r, g, b)) diff --git a/Tests/test_file_bufrstub.py b/Tests/test_file_bufrstub.py index e330404d6..76f185b9a 100644 --- a/Tests/test_file_bufrstub.py +++ b/Tests/test_file_bufrstub.py @@ -10,7 +10,6 @@ TEST_FILE = "Tests/images/gfs.t06z.rassda.tm00.bufr_d" def test_open(): # Act with Image.open(TEST_FILE) as im: - # Assert assert im.format == "BUFR" @@ -31,7 +30,6 @@ def test_invalid_file(): def test_load(): # Arrange with Image.open(TEST_FILE) as im: - # Act / Assert: stub cannot load without an implemented handler with pytest.raises(OSError): im.load() diff --git a/Tests/test_file_dcx.py b/Tests/test_file_dcx.py index 0f09c4b99..ef378b24a 100644 --- a/Tests/test_file_dcx.py +++ b/Tests/test_file_dcx.py @@ -15,7 +15,6 @@ def test_sanity(): # Act with Image.open(TEST_FILE) as im: - # Assert assert im.size == (128, 128) assert isinstance(im, DcxImagePlugin.DcxImageFile) @@ -54,7 +53,6 @@ def test_invalid_file(): def test_tell(): # Arrange with Image.open(TEST_FILE) as im: - # Act frame = im.tell() diff --git a/Tests/test_file_fits.py b/Tests/test_file_fits.py index 447888acd..d2f5a6d17 100644 --- a/Tests/test_file_fits.py +++ b/Tests/test_file_fits.py @@ -12,7 +12,6 @@ TEST_FILE = "Tests/images/hopper.fits" def test_open(): # Act with Image.open(TEST_FILE) as im: - # Assert assert im.format == "FITS" assert im.size == (128, 128) diff --git a/Tests/test_file_fli.py b/Tests/test_file_fli.py index b8b999d70..70d4d76db 100644 --- a/Tests/test_file_fli.py +++ b/Tests/test_file_fli.py @@ -64,7 +64,6 @@ def test_context_manager(): def test_tell(): # Arrange with Image.open(static_test_file) as im: - # Act frame = im.tell() @@ -110,7 +109,6 @@ def test_eoferror(): def test_seek_tell(): with Image.open(animated_test_file) as im: - layer_number = im.tell() assert layer_number == 0 diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index 6fbc0ee30..bce72d192 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -209,7 +209,7 @@ def test_optimize_if_palette_can_be_reduced_by_half(): im = im.resize((591, 443)) im_rgb = im.convert("RGB") - for (optimize, colors) in ((False, 256), (True, 8)): + for optimize, colors in ((False, 256), (True, 8)): out = BytesIO() im_rgb.save(out, "GIF", optimize=optimize) with Image.open(out) as reloaded: @@ -221,7 +221,6 @@ def test_roundtrip(tmp_path): im = hopper() im.save(out) with Image.open(out) as reread: - assert_image_similar(reread.convert("RGB"), im, 50) @@ -232,7 +231,6 @@ def test_roundtrip2(tmp_path): im2 = im.copy() im2.save(out) with Image.open(out) as reread: - assert_image_similar(reread.convert("RGB"), hopper(), 50) @@ -242,7 +240,6 @@ def test_roundtrip_save_all(tmp_path): im = hopper() im.save(out, save_all=True) with Image.open(out) as reread: - assert_image_similar(reread.convert("RGB"), im, 50) # Multiframe image @@ -284,13 +281,11 @@ def test_headers_saving_for_animated_gifs(tmp_path): important_headers = ["background", "version", "duration", "loop"] # Multiframe image with Image.open("Tests/images/dispose_bgnd.gif") as im: - info = im.info.copy() out = str(tmp_path / "temp.gif") im.save(out, save_all=True) with Image.open(out) as reread: - for header in important_headers: assert info[header] == reread.info[header] @@ -308,7 +303,6 @@ def test_palette_handling(tmp_path): im2.save(f, optimize=True) with Image.open(f) as reloaded: - assert_image_similar(im, reloaded.convert("RGB"), 10) @@ -324,7 +318,6 @@ def test_palette_434(tmp_path): orig = "Tests/images/test.colors.gif" with Image.open(orig) as im: - with roundtrip(im) as reloaded: assert_image_similar(im, reloaded, 1) with roundtrip(im, optimize=True) as reloaded: @@ -575,7 +568,6 @@ def test_save_dispose(tmp_path): ) with Image.open(out) as img: - for i in range(2): img.seek(img.tell() + 1) assert img.disposal_method == i + 1 @@ -773,7 +765,6 @@ def test_multiple_duration(tmp_path): out, save_all=True, append_images=im_list[1:], duration=duration_list ) with Image.open(out) as reread: - for duration in duration_list: assert reread.info["duration"] == duration try: @@ -786,7 +777,6 @@ def test_multiple_duration(tmp_path): out, save_all=True, append_images=im_list[1:], duration=tuple(duration_list) ) with Image.open(out) as reread: - for duration in duration_list: assert reread.info["duration"] == duration try: @@ -844,7 +834,6 @@ def test_identical_frames(tmp_path): out, save_all=True, append_images=im_list[1:], duration=duration_list ) with Image.open(out) as reread: - # Assert that the first three frames were combined assert reread.n_frames == 2 diff --git a/Tests/test_file_gribstub.py b/Tests/test_file_gribstub.py index fd427746e..768ac12bd 100644 --- a/Tests/test_file_gribstub.py +++ b/Tests/test_file_gribstub.py @@ -10,7 +10,6 @@ TEST_FILE = "Tests/images/WAlaska.wind.7days.grb" def test_open(): # Act with Image.open(TEST_FILE) as im: - # Assert assert im.format == "GRIB" @@ -31,7 +30,6 @@ def test_invalid_file(): def test_load(): # Arrange with Image.open(TEST_FILE) as im: - # Act / Assert: stub cannot load without an implemented handler with pytest.raises(OSError): im.load() diff --git a/Tests/test_file_hdf5stub.py b/Tests/test_file_hdf5stub.py index 20b4b9619..98dc5443c 100644 --- a/Tests/test_file_hdf5stub.py +++ b/Tests/test_file_hdf5stub.py @@ -8,7 +8,6 @@ TEST_FILE = "Tests/images/hdf5.h5" def test_open(): # Act with Image.open(TEST_FILE) as im: - # Assert assert im.format == "HDF5" @@ -29,7 +28,6 @@ def test_invalid_file(): def test_load(): # Arrange with Image.open(TEST_FILE) as im: - # Act / Assert: stub cannot load without an implemented handler with pytest.raises(OSError): im.load() diff --git a/Tests/test_file_icns.py b/Tests/test_file_icns.py index 55632909c..42275424d 100644 --- a/Tests/test_file_icns.py +++ b/Tests/test_file_icns.py @@ -16,7 +16,6 @@ def test_sanity(): # Loading this icon by default should result in the largest size # (512x512@2x) being loaded with Image.open(TEST_FILE) as im: - # Assert that there is no unclosed file warning with warnings.catch_warnings(): im.load() diff --git a/Tests/test_file_ico.py b/Tests/test_file_ico.py index afb17b1af..9c1c3cf17 100644 --- a/Tests/test_file_ico.py +++ b/Tests/test_file_ico.py @@ -175,7 +175,6 @@ def test_save_256x256(tmp_path): # Act im.save(outfile) with Image.open(outfile) as im_saved: - # Assert assert im_saved.size == (256, 256) diff --git a/Tests/test_file_im.py b/Tests/test_file_im.py index 5cf93713b..425e690d6 100644 --- a/Tests/test_file_im.py +++ b/Tests/test_file_im.py @@ -51,7 +51,6 @@ def test_context_manager(): def test_tell(): # Arrange with Image.open(TEST_IM) as im: - # Act frame = im.tell() diff --git a/Tests/test_file_iptc.py b/Tests/test_file_iptc.py index 2d0e6977a..2d99528d3 100644 --- a/Tests/test_file_iptc.py +++ b/Tests/test_file_iptc.py @@ -11,7 +11,6 @@ TEST_FILE = "Tests/images/iptc.jpg" def test_getiptcinfo_jpg_none(): # Arrange with hopper() as im: - # Act iptc = IptcImagePlugin.getiptcinfo(im) @@ -22,7 +21,6 @@ def test_getiptcinfo_jpg_none(): def test_getiptcinfo_jpg_found(): # Arrange with Image.open(TEST_FILE) as im: - # Act iptc = IptcImagePlugin.getiptcinfo(im) @@ -35,7 +33,6 @@ def test_getiptcinfo_jpg_found(): def test_getiptcinfo_tiff_none(): # Arrange with Image.open("Tests/images/hopper.tif") as im: - # Act iptc = IptcImagePlugin.getiptcinfo(im) diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index eabc6bf75..e3c5abcbd 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -57,7 +57,6 @@ class TestFileJpeg: return Image.frombytes(mode, size, os.urandom(size[0] * size[1] * len(mode))) def test_sanity(self): - # internal version number assert re.search(r"\d+\.\d+$", features.version_codec("jpg")) @@ -368,7 +367,6 @@ class TestFileJpeg: def test_exif_gps_typeerror(self): with Image.open("Tests/images/exif_gps_typeerror.jpg") as im: - # Should not raise a TypeError im._getexif() @@ -682,7 +680,6 @@ class TestFileJpeg: # Shouldn't raise error fn = "Tests/images/sugarshack_bad_mpo_header.jpg" with pytest.warns(UserWarning, Image.open, fn) as im: - # Assert assert im.format == "JPEG" @@ -704,7 +701,6 @@ class TestFileJpeg: # Arrange outfile = str(tmp_path / "temp.tif") with Image.open("Tests/images/hopper.tif") as im: - # Act im.save(outfile, "JPEG", dpi=im.info["dpi"]) @@ -731,7 +727,6 @@ class TestFileJpeg: # This Photoshop CC 2017 image has DPI in EXIF not metadata # EXIF XResolution is (2000000, 10000) with Image.open("Tests/images/photoshop-200dpi.jpg") as im: - # Act / Assert assert im.info.get("dpi") == (200, 200) @@ -740,7 +735,6 @@ class TestFileJpeg: # This image has DPI in EXIF not metadata # EXIF XResolution is 72 with Image.open("Tests/images/exif-72dpi-int.jpg") as im: - # Act / Assert assert im.info.get("dpi") == (72, 72) @@ -749,7 +743,6 @@ class TestFileJpeg: # This is photoshop-200dpi.jpg with EXIF resolution unit set to cm: # exiftool -exif:ResolutionUnit=cm photoshop-200dpi.jpg with Image.open("Tests/images/exif-200dpcm.jpg") as im: - # Act / Assert assert im.info.get("dpi") == (508, 508) @@ -758,7 +751,6 @@ class TestFileJpeg: # This is photoshop-200dpi.jpg with EXIF resolution set to 0/0: # exiftool -XResolution=0/0 -YResolution=0/0 photoshop-200dpi.jpg with Image.open("Tests/images/exif-dpi-zerodivision.jpg") as im: - # Act / Assert # This should return the default, and not raise a ZeroDivisionError assert im.info.get("dpi") == (72, 72) @@ -767,7 +759,6 @@ class TestFileJpeg: # Arrange # 0x011A tag in this exif contains string '300300\x02' with Image.open("Tests/images/broken_exif_dpi.jpg") as im: - # Act / Assert # This should return the default assert im.info.get("dpi") == (72, 72) @@ -777,7 +768,6 @@ class TestFileJpeg: # This is photoshop-200dpi.jpg with resolution removed from EXIF: # exiftool "-*resolution*"= photoshop-200dpi.jpg with Image.open("Tests/images/no-dpi-in-exif.jpg") as im: - # Act / Assert # "When the image resolution is unknown, 72 [dpi] is designated." # https://exiv2.org/tags.html @@ -787,7 +777,6 @@ class TestFileJpeg: # This is no-dpi-in-exif with the tiff header of the exif block # hexedited from MM * to FF FF FF FF with Image.open("Tests/images/invalid-exif.jpg") as im: - # This should return the default, and not a SyntaxError or # OSError for unidentified image. assert im.info.get("dpi") == (72, 72) @@ -810,7 +799,6 @@ class TestFileJpeg: def test_invalid_exif_x_resolution(self): # When no x or y resolution is defined in EXIF with Image.open("Tests/images/invalid-exif-without-x-resolution.jpg") as im: - # This should return the default, and not a ValueError or # OSError for an unidentified image. assert im.info.get("dpi") == (72, 72) @@ -820,7 +808,6 @@ class TestFileJpeg: # This image has been manually hexedited to have an IFD offset of 10, # in contrast to normal 8 with Image.open("Tests/images/exif-ifd-offset.jpg") as im: - # Act / Assert assert im._getexif()[306] == "2017:03:13 23:03:09" diff --git a/Tests/test_file_jpeg2k.py b/Tests/test_file_jpeg2k.py index 0229b2243..de622c478 100644 --- a/Tests/test_file_jpeg2k.py +++ b/Tests/test_file_jpeg2k.py @@ -270,7 +270,6 @@ def test_rgba(): # Arrange with Image.open("Tests/images/rgb_trns_ycbc.j2k") as j2k: with Image.open("Tests/images/rgb_trns_ycbc.jp2") as jp2: - # Act j2k.load() jp2.load() diff --git a/Tests/test_file_libtiff.py b/Tests/test_file_libtiff.py index 1109cd15e..f886d3aae 100644 --- a/Tests/test_file_libtiff.py +++ b/Tests/test_file_libtiff.py @@ -645,7 +645,6 @@ class TestFileLibTiff(LibTiffTestCase): pilim = hopper() def save_bytesio(compression=None): - buffer_io = io.BytesIO() pilim.save(buffer_io, format="tiff", compression=compression) buffer_io.seek(0) @@ -740,7 +739,6 @@ class TestFileLibTiff(LibTiffTestCase): def test_multipage_compression(self): with Image.open("Tests/images/compression.tif") as im: - im.seek(0) assert im._compression == "tiff_ccitt" assert im.size == (10, 10) diff --git a/Tests/test_file_msp.py b/Tests/test_file_msp.py index 50d7c590b..497052b05 100644 --- a/Tests/test_file_msp.py +++ b/Tests/test_file_msp.py @@ -44,7 +44,6 @@ def test_open_windows_v1(): # Arrange # Act with Image.open(TEST_FILE) as im: - # Assert assert_image_equal(im, hopper("1")) assert isinstance(im, MspImagePlugin.MspImageFile) @@ -59,7 +58,6 @@ def _assert_file_image_equal(source_path, target_path): not os.path.exists(EXTRA_DIR), reason="Extra image files not installed" ) def test_open_windows_v2(): - files = ( os.path.join(EXTRA_DIR, f) for f in os.listdir(EXTRA_DIR) diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py index 5299febe9..216b93ca9 100644 --- a/Tests/test_file_pdf.py +++ b/Tests/test_file_pdf.py @@ -89,7 +89,6 @@ def test_save_all(tmp_path): # Multiframe image with Image.open("Tests/images/dispose_bgnd.gif") as im: - outfile = str(tmp_path / "temp.pdf") im.save(outfile, save_all=True) @@ -123,7 +122,6 @@ def test_save_all(tmp_path): def test_multiframe_normal_save(tmp_path): # Test saving a multiframe image without save_all with Image.open("Tests/images/dispose_bgnd.gif") as im: - outfile = str(tmp_path / "temp.pdf") im.save(outfile) diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py index 133f3e47e..c4db97905 100644 --- a/Tests/test_file_png.py +++ b/Tests/test_file_png.py @@ -78,7 +78,6 @@ class TestFilePng: return chunks def test_sanity(self, tmp_path): - # internal version number assert re.search(r"\d+\.\d+\.\d+(\.\d+)?$", features.version_codec("zlib")) @@ -156,7 +155,6 @@ class TestFilePng: assert im.info == {"spam": "egg"} def test_bad_itxt(self): - im = load(HEAD + chunk(b"iTXt") + TAIL) assert im.info == {} @@ -201,7 +199,6 @@ class TestFilePng: assert im.info["spam"].tkey == "Spam" def test_interlace(self): - test_file = "Tests/images/pil123p.png" with Image.open(test_file) as im: assert_image(im, "P", (162, 150)) @@ -495,7 +492,6 @@ class TestFilePng: # Check reading images with null tRNS value, issue #1239 test_file = "Tests/images/tRNS_null_1x1.png" with Image.open(test_file) as im: - assert im.info["transparency"] == 0 def test_save_icc_profile(self): diff --git a/Tests/test_file_psd.py b/Tests/test_file_psd.py index 4f934375c..036cb9d4b 100644 --- a/Tests/test_file_psd.py +++ b/Tests/test_file_psd.py @@ -77,7 +77,6 @@ def test_eoferror(): def test_seek_tell(): with Image.open(test_file) as im: - layer_number = im.tell() assert layer_number == 1 @@ -95,7 +94,6 @@ def test_seek_tell(): def test_seek_eoferror(): with Image.open(test_file) as im: - with pytest.raises(EOFError): im.seek(-1) diff --git a/Tests/test_file_spider.py b/Tests/test_file_spider.py index 0e3b705a2..011e208d8 100644 --- a/Tests/test_file_spider.py +++ b/Tests/test_file_spider.py @@ -79,7 +79,6 @@ def test_is_spider_image(): def test_tell(): # Arrange with Image.open(TEST_FILE) as im: - # Act index = im.tell() diff --git a/Tests/test_file_sun.py b/Tests/test_file_sun.py index 05c78c316..edb320603 100644 --- a/Tests/test_file_sun.py +++ b/Tests/test_file_sun.py @@ -16,7 +16,6 @@ def test_sanity(): # Act with Image.open(test_file) as im: - # Assert assert im.size == (128, 128) diff --git a/Tests/test_file_tar.py b/Tests/test_file_tar.py index 5daab47fc..799c243d6 100644 --- a/Tests/test_file_tar.py +++ b/Tests/test_file_tar.py @@ -10,18 +10,21 @@ from .helper import is_pypy TEST_TAR_FILE = "Tests/images/hopper.tar" -def test_sanity(): - for codec, test_path, format in [ - ["zlib", "hopper.png", "PNG"], - ["jpg", "hopper.jpg", "JPEG"], - ]: - if features.check(codec): - with TarIO.TarIO(TEST_TAR_FILE, test_path) as tar: - with Image.open(tar) as im: - im.load() - assert im.mode == "RGB" - assert im.size == (128, 128) - assert im.format == format +@pytest.mark.parametrize( + "codec, test_path, format", + ( + ("zlib", "hopper.png", "PNG"), + ("jpg", "hopper.jpg", "JPEG"), + ), +) +def test_sanity(codec, test_path, format): + if features.check(codec): + with TarIO.TarIO(TEST_TAR_FILE, test_path) as tar: + with Image.open(tar) as im: + im.load() + assert im.mode == "RGB" + assert im.size == (128, 128) + assert im.format == format @pytest.mark.skipif(is_pypy(), reason="Requires CPython") diff --git a/Tests/test_file_tga.py b/Tests/test_file_tga.py index 7d8b5139a..bac00e855 100644 --- a/Tests/test_file_tga.py +++ b/Tests/test_file_tga.py @@ -78,7 +78,6 @@ def test_id_field(): # Act with Image.open(test_file) as im: - # Assert assert im.size == (100, 100) @@ -89,7 +88,6 @@ def test_id_field_rle(): # Act with Image.open(test_file) as im: - # Assert assert im.size == (199, 199) @@ -171,7 +169,6 @@ def test_save_id_section(tmp_path): test_file = "Tests/images/tga_id_field.tga" with Image.open(test_file) as im: - # Save with no id section im.save(out, id_section="") with Image.open(out) as test_im: diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index 4f3c8e390..70142747c 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -25,7 +25,6 @@ except ImportError: class TestFileTiff: def test_sanity(self, tmp_path): - filename = str(tmp_path / "temp.tif") hopper("RGB").save(filename) @@ -157,7 +156,6 @@ class TestFileTiff: def test_xyres_tiff(self): filename = "Tests/images/pil168.tif" with Image.open(filename) as im: - # legacy api assert isinstance(im.tag[X_RESOLUTION][0], tuple) assert isinstance(im.tag[Y_RESOLUTION][0], tuple) @@ -171,7 +169,6 @@ class TestFileTiff: def test_xyres_fallback_tiff(self): filename = "Tests/images/compression.tif" with Image.open(filename) as im: - # v2 api assert isinstance(im.tag_v2[X_RESOLUTION], TiffImagePlugin.IFDRational) assert isinstance(im.tag_v2[Y_RESOLUTION], TiffImagePlugin.IFDRational) @@ -186,7 +183,6 @@ class TestFileTiff: def test_int_resolution(self): filename = "Tests/images/pil168.tif" with Image.open(filename) as im: - # Try to read a file where X,Y_RESOLUTION are ints im.tag_v2[X_RESOLUTION] = 71 im.tag_v2[Y_RESOLUTION] = 71 @@ -381,7 +377,6 @@ class TestFileTiff: def test___str__(self): filename = "Tests/images/pil136.tiff" with Image.open(filename) as im: - # Act ret = str(im.ifd) @@ -392,7 +387,6 @@ class TestFileTiff: # Arrange filename = "Tests/images/pil136.tiff" with Image.open(filename) as im: - # v2 interface v2_tags = { 256: 55, @@ -630,7 +624,6 @@ class TestFileTiff: filename = str(tmp_path / "temp.tif") hopper("RGB").save(filename, **kwargs) with Image.open(filename) as im: - # legacy interface assert im.tag[X_RESOLUTION][0][0] == 72 assert im.tag[Y_RESOLUTION][0][0] == 36 diff --git a/Tests/test_file_tiff_metadata.py b/Tests/test_file_tiff_metadata.py index 48797ea08..a4481d85f 100644 --- a/Tests/test_file_tiff_metadata.py +++ b/Tests/test_file_tiff_metadata.py @@ -54,7 +54,6 @@ def test_rt_metadata(tmp_path): img.save(f, tiffinfo=info) with Image.open(f) as loaded: - assert loaded.tag[ImageJMetaDataByteCounts] == (len(bin_data),) assert loaded.tag_v2[ImageJMetaDataByteCounts] == (len(bin_data),) @@ -74,14 +73,12 @@ def test_rt_metadata(tmp_path): info[ImageJMetaDataByteCounts] = (8, len(bin_data) - 8) img.save(f, tiffinfo=info) with Image.open(f) as loaded: - assert loaded.tag[ImageJMetaDataByteCounts] == (8, len(bin_data) - 8) assert loaded.tag_v2[ImageJMetaDataByteCounts] == (8, len(bin_data) - 8) def test_read_metadata(): with Image.open("Tests/images/hopper_g4.tif") as img: - assert { "YResolution": IFDRational(4294967295, 113653537), "PlanarConfiguration": 1, @@ -202,14 +199,15 @@ def test_writing_other_types_to_ascii(value, expected, tmp_path): assert reloaded.tag_v2[271] == expected -def test_writing_int_to_bytes(tmp_path): +@pytest.mark.parametrize("value", (1, IFDRational(1))) +def test_writing_other_types_to_bytes(value, tmp_path): im = hopper() info = TiffImagePlugin.ImageFileDirectory_v2() tag = TiffTags.TAGS_V2[700] assert tag.type == TiffTags.BYTE - info[700] = 1 + info[700] = value out = str(tmp_path / "temp.tiff") im.save(out, tiffinfo=info) diff --git a/Tests/test_file_webp_metadata.py b/Tests/test_file_webp_metadata.py index 4f513d82b..037479f9f 100644 --- a/Tests/test_file_webp_metadata.py +++ b/Tests/test_file_webp_metadata.py @@ -18,10 +18,8 @@ except ImportError: def test_read_exif_metadata(): - file_path = "Tests/images/flower.webp" with Image.open(file_path) as image: - assert image.format == "WEBP" exif_data = image.info.get("exif", None) assert exif_data @@ -64,10 +62,8 @@ def test_write_exif_metadata(): def test_read_icc_profile(): - file_path = "Tests/images/flower2.webp" with Image.open(file_path) as image: - assert image.format == "WEBP" assert image.info.get("icc_profile", None) diff --git a/Tests/test_file_wmf.py b/Tests/test_file_wmf.py index 439cb15bc..7c8b54fd1 100644 --- a/Tests/test_file_wmf.py +++ b/Tests/test_file_wmf.py @@ -6,7 +6,6 @@ from .helper import assert_image_similar_tofile, hopper def test_load_raw(): - # Test basic EMF open and rendering with Image.open("Tests/images/drawing.emf") as im: if hasattr(Image.core, "drawwmf"): diff --git a/Tests/test_file_xbm.py b/Tests/test_file_xbm.py index 9c54c6755..d2c05b78a 100644 --- a/Tests/test_file_xbm.py +++ b/Tests/test_file_xbm.py @@ -44,7 +44,6 @@ def test_open(): # Act with Image.open(filename) as im: - # Assert assert im.mode == "1" assert im.size == (128, 128) @@ -57,7 +56,6 @@ def test_open_filename_with_underscore(): # Act with Image.open(filename) as im: - # Assert assert im.mode == "1" assert im.size == (128, 128) diff --git a/Tests/test_file_xvthumb.py b/Tests/test_file_xvthumb.py index ae53d2b63..9efe7ec14 100644 --- a/Tests/test_file_xvthumb.py +++ b/Tests/test_file_xvthumb.py @@ -10,7 +10,6 @@ TEST_FILE = "Tests/images/hopper.p7" def test_open(): # Act with Image.open(TEST_FILE) as im: - # Assert assert im.format == "XVThumb" diff --git a/Tests/test_image.py b/Tests/test_image.py index d261638f9..85e3ff55b 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -69,7 +69,6 @@ class TestImage: assert issubclass(UnidentifiedImageError, OSError) def test_sanity(self): - im = Image.new("L", (100, 100)) assert repr(im)[:45] == ">> im.save('Tests/images/hopper_45.png') with Image.open("Tests/images/hopper_45.png") as target: - for (resample, epsilon) in ( + for resample, epsilon in ( (Image.Resampling.NEAREST, 10), (Image.Resampling.BILINEAR, 5), (Image.Resampling.BICUBIC, 0), diff --git a/Tests/test_image_tobitmap.py b/Tests/test_image_tobitmap.py index 178cfcef3..a12ce329f 100644 --- a/Tests/test_image_tobitmap.py +++ b/Tests/test_image_tobitmap.py @@ -4,7 +4,6 @@ from .helper import assert_image_equal, fromstring, hopper def test_sanity(): - with pytest.raises(ValueError): hopper().tobitmap() diff --git a/Tests/test_imagechops.py b/Tests/test_imagechops.py index b839a7b14..d0fea3854 100644 --- a/Tests/test_imagechops.py +++ b/Tests/test_imagechops.py @@ -50,7 +50,6 @@ def test_add(): # Arrange with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: - # Act new = ImageChops.add(im1, im2) @@ -63,7 +62,6 @@ def test_add_scale_offset(): # Arrange with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: - # Act new = ImageChops.add(im1, im2, scale=2.5, offset=100) @@ -87,7 +85,6 @@ def test_add_modulo(): # Arrange with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: - # Act new = ImageChops.add_modulo(im1, im2) @@ -111,7 +108,6 @@ def test_blend(): # Arrange with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: - # Act new = ImageChops.blend(im1, im2, 0.5) @@ -137,7 +133,6 @@ def test_darker_image(): # Arrange with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: - # Act new = ImageChops.darker(im1, im2) @@ -149,7 +144,6 @@ def test_darker_pixel(): # Arrange im1 = hopper() with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: - # Act new = ImageChops.darker(im1, im2) @@ -161,7 +155,6 @@ def test_difference(): # Arrange with Image.open("Tests/images/imagedraw_arc_end_le_start.png") as im1: with Image.open("Tests/images/imagedraw_arc_no_loops.png") as im2: - # Act new = ImageChops.difference(im1, im2) @@ -173,7 +166,6 @@ def test_difference_pixel(): # Arrange im1 = hopper() with Image.open("Tests/images/imagedraw_polygon_kite_RGB.png") as im2: - # Act new = ImageChops.difference(im1, im2) @@ -195,7 +187,6 @@ def test_duplicate(): def test_invert(): # Arrange with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im: - # Act new = ImageChops.invert(im) @@ -209,7 +200,6 @@ def test_lighter_image(): # Arrange with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: - # Act new = ImageChops.lighter(im1, im2) @@ -221,7 +211,6 @@ def test_lighter_pixel(): # Arrange im1 = hopper() with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: - # Act new = ImageChops.lighter(im1, im2) @@ -275,7 +264,6 @@ def test_offset(): xoffset = 45 yoffset = 20 with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im: - # Act new = ImageChops.offset(im, xoffset, yoffset) @@ -292,7 +280,6 @@ def test_screen(): # Arrange with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1: with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2: - # Act new = ImageChops.screen(im1, im2) @@ -305,7 +292,6 @@ def test_subtract(): # Arrange with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: - # Act new = ImageChops.subtract(im1, im2) @@ -319,7 +305,6 @@ def test_subtract_scale_offset(): # Arrange with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: - # Act new = ImageChops.subtract(im1, im2, scale=2.5, offset=100) @@ -332,7 +317,6 @@ def test_subtract_clip(): # Arrange im1 = hopper() with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: - # Act new = ImageChops.subtract(im1, im2) @@ -344,7 +328,6 @@ def test_subtract_modulo(): # Arrange with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1: with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2: - # Act new = ImageChops.subtract_modulo(im1, im2) @@ -358,7 +341,6 @@ def test_subtract_modulo_no_clip(): # Arrange im1 = hopper() with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2: - # Act new = ImageChops.subtract_modulo(im1, im2) @@ -370,7 +352,6 @@ def test_soft_light(): # Arrange with Image.open("Tests/images/hopper.png") as im1: with Image.open("Tests/images/hopper-XYZ.png") as im2: - # Act new = ImageChops.soft_light(im1, im2) @@ -383,7 +364,6 @@ def test_hard_light(): # Arrange with Image.open("Tests/images/hopper.png") as im1: with Image.open("Tests/images/hopper-XYZ.png") as im2: - # Act new = ImageChops.hard_light(im1, im2) @@ -396,7 +376,6 @@ def test_overlay(): # Arrange with Image.open("Tests/images/hopper.png") as im1: with Image.open("Tests/images/hopper-XYZ.png") as im2: - # Act new = ImageChops.overlay(im1, im2) diff --git a/Tests/test_imagedraw.py b/Tests/test_imagedraw.py index 4c4c41b7b..d4723c924 100644 --- a/Tests/test_imagedraw.py +++ b/Tests/test_imagedraw.py @@ -52,7 +52,6 @@ def test_sanity(): def test_valueerror(): with Image.open("Tests/images/chi.gif") as im: - draw = ImageDraw.Draw(im) draw.line((0, 0), fill=(0, 0, 0)) diff --git a/Tests/test_imagefile.py b/Tests/test_imagefile.py index fc0fbfb9b..412bc10d9 100644 --- a/Tests/test_imagefile.py +++ b/Tests/test_imagefile.py @@ -30,7 +30,6 @@ SAFEBLOCK = ImageFile.SAFEBLOCK class TestImageFile: def test_parser(self): def roundtrip(format): - im = hopper("L").resize((1000, 1000), Image.Resampling.NEAREST) if format in ("MSP", "XBM"): im = im.convert("1") diff --git a/Tests/test_imageops.py b/Tests/test_imageops.py index c9b2fd865..d390f3c1e 100644 --- a/Tests/test_imageops.py +++ b/Tests/test_imageops.py @@ -21,7 +21,6 @@ deformer = Deformer() def test_sanity(): - ImageOps.autocontrast(hopper("L")) ImageOps.autocontrast(hopper("RGB")) @@ -419,7 +418,6 @@ def test_autocontrast_cutoff(): def test_autocontrast_mask_toy_input(): # Test the mask argument of autocontrast with Image.open("Tests/images/bw_gradient.png") as img: - rect_mask = Image.new("L", img.size, 0) draw = ImageDraw.Draw(rect_mask) x0 = img.size[0] // 4 @@ -439,7 +437,6 @@ def test_autocontrast_mask_toy_input(): def test_autocontrast_mask_real_input(): # Test the autocontrast with a rectangular mask with Image.open("Tests/images/iptc.jpg") as img: - rect_mask = Image.new("L", img.size, 0) draw = ImageDraw.Draw(rect_mask) x0, y0 = img.size[0] // 2, img.size[1] // 2 diff --git a/Tests/test_imagepalette.py b/Tests/test_imagepalette.py index 5bda28117..ac99ef381 100644 --- a/Tests/test_imagepalette.py +++ b/Tests/test_imagepalette.py @@ -6,7 +6,6 @@ from .helper import assert_image_equal, assert_image_equal_tofile def test_sanity(): - palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3) assert len(palette.colors) == 256 @@ -23,7 +22,6 @@ def test_reload(): def test_getcolor(): - palette = ImagePalette.ImagePalette() assert len(palette.palette) == 0 assert len(palette.colors) == 0 @@ -84,7 +82,6 @@ def test_getcolor_not_special(index, palette): def test_file(tmp_path): - palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3) f = str(tmp_path / "temp.lut") diff --git a/Tests/test_imagepath.py b/Tests/test_imagepath.py index 861fb64f0..8f8a9f449 100644 --- a/Tests/test_imagepath.py +++ b/Tests/test_imagepath.py @@ -8,7 +8,6 @@ from PIL import Image, ImagePath def test_path(): - p = ImagePath.Path(list(range(10))) # sequence interface diff --git a/Tests/test_imagesequence.py b/Tests/test_imagesequence.py index 6af7e7602..62f528332 100644 --- a/Tests/test_imagesequence.py +++ b/Tests/test_imagesequence.py @@ -6,7 +6,6 @@ from .helper import assert_image_equal, hopper, skip_unless_feature def test_sanity(tmp_path): - test_file = str(tmp_path / "temp.im") im = hopper("RGB") diff --git a/Tests/test_imagestat.py b/Tests/test_imagestat.py index 5717fe150..b3b5db13f 100644 --- a/Tests/test_imagestat.py +++ b/Tests/test_imagestat.py @@ -6,7 +6,6 @@ from .helper import hopper def test_sanity(): - im = hopper() st = ImageStat.Stat(im) @@ -31,7 +30,6 @@ def test_sanity(): def test_hopper(): - im = hopper() st = ImageStat.Stat(im) @@ -45,7 +43,6 @@ def test_hopper(): def test_constant(): - im = Image.new("L", (128, 128), 128) st = ImageStat.Stat(im) diff --git a/Tests/test_lib_image.py b/Tests/test_lib_image.py index 37ed3659d..f6818be46 100644 --- a/Tests/test_lib_image.py +++ b/Tests/test_lib_image.py @@ -4,7 +4,6 @@ from PIL import Image def test_setmode(): - im = Image.new("L", (1, 1), 255) im.im.setmode("1") assert im.im.getpixel((0, 0)) == 255 diff --git a/Tests/test_mode_i16.py b/Tests/test_mode_i16.py index efcdab9ec..dcdee3d41 100644 --- a/Tests/test_mode_i16.py +++ b/Tests/test_mode_i16.py @@ -42,7 +42,6 @@ def test_basic(tmp_path, mode): im_in.save(filename) with Image.open(filename) as im_out: - verify(im_in) verify(im_out) @@ -87,7 +86,6 @@ def test_tobytes(): def test_convert(): - im = original.copy() verify(im.convert("I;16")) diff --git a/Tests/test_numpy.py b/Tests/test_numpy.py index 3de7ec30f..a8bbcbdb8 100644 --- a/Tests/test_numpy.py +++ b/Tests/test_numpy.py @@ -235,7 +235,6 @@ def test_no_resource_warning_for_numpy_array(): test_file = "Tests/images/hopper.png" with Image.open(test_file) as im: - # Act/Assert with warnings.catch_warnings(): array(im) diff --git a/Tests/test_pickle.py b/Tests/test_pickle.py index 23eb9e39f..2f6d05888 100644 --- a/Tests/test_pickle.py +++ b/Tests/test_pickle.py @@ -89,7 +89,6 @@ def test_pickle_la_mode_with_palette(tmp_path): def test_pickle_tell(): # Arrange with Image.open("Tests/images/hopper.webp") as image: - # Act: roundtrip unpickled_image = pickle.loads(pickle.dumps(image)) diff --git a/Tests/test_qt_image_qapplication.py b/Tests/test_qt_image_qapplication.py index 1fc816146..34609314c 100644 --- a/Tests/test_qt_image_qapplication.py +++ b/Tests/test_qt_image_qapplication.py @@ -6,7 +6,7 @@ with warnings.catch_warnings(): warnings.simplefilter("ignore", category=DeprecationWarning) from PIL import ImageQt -from .helper import assert_image_equal, assert_image_equal_tofile, hopper +from .helper import assert_image_equal_tofile, assert_image_similar, hopper if ImageQt.qt_is_installed: from PIL.ImageQt import QPixmap @@ -48,7 +48,7 @@ if ImageQt.qt_is_installed: def roundtrip(expected): result = ImageQt.fromqpixmap(ImageQt.toqpixmap(expected)) # Qt saves all pixmaps as rgb - assert_image_equal(result, expected.convert("RGB")) + assert_image_similar(result, expected.convert("RGB"), 0.3) @pytest.mark.skipif(not ImageQt.qt_is_installed, reason="Qt bindings are not installed") diff --git a/Tests/test_tiff_ifdrational.py b/Tests/test_tiff_ifdrational.py index 12f475df0..6e3fcec90 100644 --- a/Tests/test_tiff_ifdrational.py +++ b/Tests/test_tiff_ifdrational.py @@ -7,7 +7,6 @@ from .helper import hopper def _test_equal(num, denom, target): - t = IFDRational(num, denom) assert target == t @@ -15,7 +14,6 @@ def _test_equal(num, denom, target): def test_sanity(): - _test_equal(1, 1, 1) _test_equal(1, 1, Fraction(1, 1)) diff --git a/Tests/test_webp_leaks.py b/Tests/test_webp_leaks.py index 34197c14f..5bd9bacdb 100644 --- a/Tests/test_webp_leaks.py +++ b/Tests/test_webp_leaks.py @@ -9,7 +9,6 @@ test_file = "Tests/images/hopper.webp" @skip_unless_feature("webp") class TestWebPLeaks(PillowLeakTestCase): - mem_limit = 3 * 1024 # kb iterations = 100 diff --git a/depends/install_imagequant.sh b/depends/install_imagequant.sh index 64dd024bd..8b847b894 100755 --- a/depends/install_imagequant.sh +++ b/depends/install_imagequant.sh @@ -1,7 +1,7 @@ #!/bin/bash # install libimagequant -archive=libimagequant-4.0.4 +archive=libimagequant-4.1.0 ./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/main/$archive.tar.gz diff --git a/depends/install_webp.sh b/depends/install_webp.sh index 05867b7d4..f8b985a7a 100755 --- a/depends/install_webp.sh +++ b/depends/install_webp.sh @@ -1,7 +1,7 @@ #!/bin/bash # install webp -archive=libwebp-1.2.4 +archive=libwebp-1.3.0 ./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/main/$archive.tar.gz diff --git a/docs/COPYING b/docs/COPYING index b400381d3..bc44ba388 100644 --- a/docs/COPYING +++ b/docs/COPYING @@ -5,7 +5,7 @@ The Python Imaging Library (PIL) is Pillow is the friendly PIL fork. It is - Copyright © 2010-2023 by Alex Clark and contributors + Copyright © 2010-2023 by Jeffrey A. Clark (Alex) and contributors Like PIL, Pillow is licensed under the open source PIL Software License: diff --git a/docs/conf.py b/docs/conf.py index fb58d25ed..e1ffa49b8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,8 +52,10 @@ master_doc = "index" # General information about the project. project = "Pillow (PIL Fork)" -copyright = "1995-2011 Fredrik Lundh, 2010-2023 Alex Clark and Contributors" -author = "Fredrik Lundh, Alex Clark and Contributors" +copyright = ( + "1995-2011 Fredrik Lundh, 2010-2023 Jeffrey A. Clark (Alex) and contributors" +) +author = "Fredrik Lundh, Jeffrey A. Clark (Alex), contributors" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -243,7 +245,7 @@ latex_documents = [ master_doc, "PillowPILFork.tex", "Pillow (PIL Fork) Documentation", - "Alex Clark", + "Jeffrey A. Clark (Alex)", "manual", ) ] @@ -293,7 +295,7 @@ texinfo_documents = [ "Pillow (PIL Fork) Documentation", author, "PillowPILFork", - "Pillow is the friendly PIL fork by Alex Clark and Contributors.", + "Pillow is the friendly PIL fork by Jeffrey A. Clark (Alex) and contributors.", "Miscellaneous", ) ] diff --git a/docs/handbook/concepts.rst b/docs/handbook/concepts.rst index 45c662bd6..0aa2f1119 100644 --- a/docs/handbook/concepts.rst +++ b/docs/handbook/concepts.rst @@ -31,7 +31,7 @@ INT32 and a 32-bit floating point pixel has the range of FLOAT32. The current re supports the following standard modes: * ``1`` (1-bit pixels, black and white, stored with one pixel per byte) - * ``L`` (8-bit pixels, black and white) + * ``L`` (8-bit pixels, grayscale) * ``P`` (8-bit pixels, mapped to any other mode using a color palette) * ``RGB`` (3x8-bit pixels, true color) * ``RGBA`` (4x8-bit pixels, true color with transparency mask) diff --git a/docs/index.rst b/docs/index.rst index a4663bac8..418844ba7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,7 +1,7 @@ Pillow ====== -Pillow is the friendly PIL fork by `Alex Clark and Contributors `_. PIL is the Python Imaging Library by Fredrik Lundh and Contributors. +Pillow is the friendly PIL fork by `Jeffrey A. Clark (Alex) and contributors `_. PIL is the Python Imaging Library by Fredrik Lundh and contributors. Pillow for enterprise is available via the Tidelift Subscription. `Learn more `_. diff --git a/docs/installation.rst b/docs/installation.rst index cc7d0258b..ea8722c56 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -169,7 +169,7 @@ Many of Pillow's features require external libraries: * **libimagequant** provides improved color quantization - * Pillow has been tested with libimagequant **2.6-4.0.4** + * Pillow has been tested with libimagequant **2.6-4.1** * Libimagequant is licensed GPLv3, which is more restrictive than the Pillow license, therefore we will not be distributing binaries with libimagequant support enabled. diff --git a/setup.cfg b/setup.cfg index 2dc552a2c..824cae088 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,8 +4,8 @@ description = Python Imaging Library (Fork) long_description = file: README.md long_description_content_type = text/markdown url = https://python-pillow.org -author = Alex Clark (PIL Fork Author) -author_email = aclark@python-pillow.org +author = Jeffrey A. Clark (Alex) +author_email = aclark@aclark.net license = HPND classifiers = Development Status :: 6 - Mature diff --git a/setup.py b/setup.py index 243365681..8f7f223f8 100755 --- a/setup.py +++ b/setup.py @@ -263,18 +263,18 @@ def _pkg_config(name): if not DEBUG: command_libs.append("--silence-errors") command_cflags.append("--silence-errors") - libs = ( + libs = re.split( + r"(^|\s+)-L", subprocess.check_output(command_libs, stderr=stderr) .decode("utf8") - .strip() - .replace("-L", "") - ) - cflags = ( - subprocess.check_output(command_cflags) + .strip(), + )[::2][1:] + cflags = re.split( + r"(^|\s+)-I", + subprocess.check_output(command_cflags, stderr=stderr) .decode("utf8") - .strip() - .replace("-I", "") - ) + .strip(), + )[::2][1:] return libs, cflags except Exception: pass @@ -430,7 +430,6 @@ class pil_build_ext(build_ext): return sdk_path def build_extensions(self): - library_dirs = [] include_dirs = [] @@ -473,8 +472,12 @@ class pil_build_ext(build_ext): else: lib_root = include_root = root - _add_directory(library_dirs, lib_root) - _add_directory(include_dirs, include_root) + if lib_root is not None: + for lib_dir in lib_root: + _add_directory(library_dirs, lib_dir) + if include_root is not None: + for include_dir in include_root: + _add_directory(include_dirs, include_dir) # respect CFLAGS/CPPFLAGS/LDFLAGS for k in ("CFLAGS", "CPPFLAGS", "LDFLAGS"): @@ -913,7 +916,6 @@ class pil_build_ext(build_ext): self.summary_report(feature) def summary_report(self, feature): - print("-" * 68) print("PIL SETUP SUMMARY") print("-" * 68) diff --git a/src/PIL/BmpImagePlugin.py b/src/PIL/BmpImagePlugin.py index e13b18f27..5bda0a5b0 100644 --- a/src/PIL/BmpImagePlugin.py +++ b/src/PIL/BmpImagePlugin.py @@ -223,7 +223,6 @@ class BmpImageFile(ImageFile.ImageFile): # --------------- Once the header is processed, process the palette/LUT if self.mode == "P": # Paletted for 1, 4 and 8 bit images - # ---------------------------------------------------- 1-bit images if not (0 < file_info["colors"] <= 65536): msg = f"Unsupported BMP Palette size ({file_info['colors']})" @@ -360,7 +359,6 @@ class BmpRleDecoder(ImageFile.PyDecoder): # Image plugin for the DIB format (BMP alias) # ============================================================================= class DibImageFile(BmpImageFile): - format = "DIB" format_description = "Windows Bitmap" diff --git a/src/PIL/BufrStubImagePlugin.py b/src/PIL/BufrStubImagePlugin.py index a0da1b786..0425bbd75 100644 --- a/src/PIL/BufrStubImagePlugin.py +++ b/src/PIL/BufrStubImagePlugin.py @@ -33,12 +33,10 @@ def _accept(prefix): class BufrStubImageFile(ImageFile.StubImageFile): - format = "BUFR" format_description = "BUFR" def _open(self): - offset = self.fp.tell() if not _accept(self.fp.read(4)): diff --git a/src/PIL/CurImagePlugin.py b/src/PIL/CurImagePlugin.py index aedc6ce7f..94efff341 100644 --- a/src/PIL/CurImagePlugin.py +++ b/src/PIL/CurImagePlugin.py @@ -32,12 +32,10 @@ def _accept(prefix): class CurImageFile(BmpImagePlugin.BmpImageFile): - format = "CUR" format_description = "Windows Cursor" def _open(self): - offset = self.fp.tell() # check magic diff --git a/src/PIL/DcxImagePlugin.py b/src/PIL/DcxImagePlugin.py index 81c0314f0..cde9d42f0 100644 --- a/src/PIL/DcxImagePlugin.py +++ b/src/PIL/DcxImagePlugin.py @@ -37,13 +37,11 @@ def _accept(prefix): class DcxImageFile(PcxImageFile): - format = "DCX" format_description = "Intel DCX" _close_exclusive_fp_after_loading = False def _open(self): - # Header s = self.fp.read(4) if not _accept(s): diff --git a/src/PIL/FitsImagePlugin.py b/src/PIL/FitsImagePlugin.py index 536bc1fe6..1185ef2d3 100644 --- a/src/PIL/FitsImagePlugin.py +++ b/src/PIL/FitsImagePlugin.py @@ -19,7 +19,6 @@ def _accept(prefix): class FitsImageFile(ImageFile.ImageFile): - format = "FITS" format_description = "FITS" diff --git a/src/PIL/FitsStubImagePlugin.py b/src/PIL/FitsStubImagePlugin.py index 86eb2d5a2..50948ec42 100644 --- a/src/PIL/FitsStubImagePlugin.py +++ b/src/PIL/FitsStubImagePlugin.py @@ -44,7 +44,6 @@ def register_handler(handler): class FITSStubImageFile(ImageFile.StubImageFile): - format = FitsImagePlugin.FitsImageFile.format format_description = FitsImagePlugin.FitsImageFile.format_description diff --git a/src/PIL/FliImagePlugin.py b/src/PIL/FliImagePlugin.py index 66681939d..f4e89a03e 100644 --- a/src/PIL/FliImagePlugin.py +++ b/src/PIL/FliImagePlugin.py @@ -40,13 +40,11 @@ def _accept(prefix): class FliImageFile(ImageFile.ImageFile): - format = "FLI" format_description = "Autodesk FLI/FLC Animation" _close_exclusive_fp_after_loading = False def _open(self): - # HEAD s = self.fp.read(128) if not (_accept(s) and s[20:22] == b"\x00\x00"): diff --git a/src/PIL/FontFile.py b/src/PIL/FontFile.py index c5fc80b37..5ec0a6632 100644 --- a/src/PIL/FontFile.py +++ b/src/PIL/FontFile.py @@ -36,7 +36,6 @@ class FontFile: bitmap = None def __init__(self): - self.info = {} self.glyph = [None] * 256 diff --git a/src/PIL/FpxImagePlugin.py b/src/PIL/FpxImagePlugin.py index 8ddc6b40b..d145d01f7 100644 --- a/src/PIL/FpxImagePlugin.py +++ b/src/PIL/FpxImagePlugin.py @@ -48,7 +48,6 @@ def _accept(prefix): class FpxImageFile(ImageFile.ImageFile): - format = "FPX" format_description = "FlashPix" @@ -157,7 +156,6 @@ class FpxImageFile(ImageFile.ImageFile): self.tile = [] for i in range(0, len(s), length): - x1 = min(xsize, x + xtile) y1 = min(ysize, y + ytile) @@ -174,7 +172,6 @@ class FpxImageFile(ImageFile.ImageFile): ) elif compression == 1: - # FIXME: the fill decoder is not implemented self.tile.append( ( @@ -186,7 +183,6 @@ class FpxImageFile(ImageFile.ImageFile): ) elif compression == 2: - internal_color_conversion = s[14] jpeg_tables = s[15] rawmode = self.rawmode @@ -234,7 +230,6 @@ class FpxImageFile(ImageFile.ImageFile): self.fp = None def load(self): - if not self.fp: self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"]) diff --git a/src/PIL/GbrImagePlugin.py b/src/PIL/GbrImagePlugin.py index 828a45ced..994a6e8eb 100644 --- a/src/PIL/GbrImagePlugin.py +++ b/src/PIL/GbrImagePlugin.py @@ -37,7 +37,6 @@ def _accept(prefix): class GbrImageFile(ImageFile.ImageFile): - format = "GBR" format_description = "GIMP brush file" diff --git a/src/PIL/GdImageFile.py b/src/PIL/GdImageFile.py index 3875dc866..7dda4f143 100644 --- a/src/PIL/GdImageFile.py +++ b/src/PIL/GdImageFile.py @@ -44,7 +44,6 @@ class GdImageFile(ImageFile.ImageFile): format_description = "GD uncompressed images" def _open(self): - # Header s = self.fp.read(1037) diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index 6ee1bd3d8..eadee1560 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -61,7 +61,6 @@ def _accept(prefix): class GifImageFile(ImageFile.ImageFile): - format = "GIF" format_description = "Compuserve GIF" _close_exclusive_fp_after_loading = False @@ -81,7 +80,6 @@ class GifImageFile(ImageFile.ImageFile): return False def _open(self): - # Screen s = self.fp.read(13) if not _accept(s): @@ -157,7 +155,6 @@ class GifImageFile(ImageFile.ImageFile): raise EOFError(msg) from e def _seek(self, frame, update_image=True): - if frame == 0: # rewind self.__offset = 0 @@ -195,7 +192,6 @@ class GifImageFile(ImageFile.ImageFile): interlace = None frame_dispose_extent = None while True: - if not s: s = self.fp.read(1) if not s or s == b";": @@ -579,7 +575,6 @@ def _getbbox(base_im, im_frame): def _write_multiple_frames(im, fp, palette): - duration = im.encoderinfo.get("duration") disposal = im.encoderinfo.get("disposal", im.info.get("disposal")) @@ -752,7 +747,6 @@ def _write_local_header(fp, im, offset, flags): def _save_netpbm(im, fp, filename): - # Unused by default. # To use, uncomment the register_save call at the end of the file. # diff --git a/src/PIL/GimpGradientFile.py b/src/PIL/GimpGradientFile.py index b5c5e3ca4..8e801be0b 100644 --- a/src/PIL/GimpGradientFile.py +++ b/src/PIL/GimpGradientFile.py @@ -64,18 +64,15 @@ SEGMENTS = [linear, curved, sine, sphere_increasing, sphere_decreasing] class GradientFile: - gradient = None def getpalette(self, entries=256): - palette = [] ix = 0 x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] for i in range(entries): - x = i / (entries - 1) while x1 < x: @@ -105,7 +102,6 @@ class GimpGradientFile(GradientFile): """File handler for GIMP's gradient format.""" def __init__(self, fp): - if fp.readline()[:13] != b"GIMP Gradient": msg = "not a GIMP gradient file" raise SyntaxError(msg) @@ -121,7 +117,6 @@ class GimpGradientFile(GradientFile): gradient = [] for i in range(count): - s = fp.readline().split() w = [float(x) for x in s[:11]] diff --git a/src/PIL/GimpPaletteFile.py b/src/PIL/GimpPaletteFile.py index 2e9cbe58d..d38892894 100644 --- a/src/PIL/GimpPaletteFile.py +++ b/src/PIL/GimpPaletteFile.py @@ -25,7 +25,6 @@ class GimpPaletteFile: rawmode = "RGB" def __init__(self, fp): - self.palette = [o8(i) * 3 for i in range(256)] if fp.readline()[:12] != b"GIMP Palette": @@ -33,7 +32,6 @@ class GimpPaletteFile: raise SyntaxError(msg) for i in range(256): - s = fp.readline() if not s: break @@ -55,5 +53,4 @@ class GimpPaletteFile: self.palette = b"".join(self.palette) def getpalette(self): - return self.palette, self.rawmode diff --git a/src/PIL/GribStubImagePlugin.py b/src/PIL/GribStubImagePlugin.py index 2088eb7b0..8a799f19c 100644 --- a/src/PIL/GribStubImagePlugin.py +++ b/src/PIL/GribStubImagePlugin.py @@ -33,12 +33,10 @@ def _accept(prefix): class GribStubImageFile(ImageFile.StubImageFile): - format = "GRIB" format_description = "GRIB" def _open(self): - offset = self.fp.tell() if not _accept(self.fp.read(8)): diff --git a/src/PIL/Hdf5StubImagePlugin.py b/src/PIL/Hdf5StubImagePlugin.py index d6f283739..bba05ed65 100644 --- a/src/PIL/Hdf5StubImagePlugin.py +++ b/src/PIL/Hdf5StubImagePlugin.py @@ -33,12 +33,10 @@ def _accept(prefix): class HDF5StubImageFile(ImageFile.StubImageFile): - format = "HDF5" format_description = "HDF5" def _open(self): - offset = self.fp.tell() if not _accept(self.fp.read(8)): diff --git a/src/PIL/IcnsImagePlugin.py b/src/PIL/IcnsImagePlugin.py index e76d0c35a..c2f050edd 100644 --- a/src/PIL/IcnsImagePlugin.py +++ b/src/PIL/IcnsImagePlugin.py @@ -135,7 +135,6 @@ def read_png_or_jpeg2000(fobj, start_length, size): class IcnsFile: - SIZES = { (512, 512, 2): [(b"ic10", read_png_or_jpeg2000)], (512, 512, 1): [(b"ic09", read_png_or_jpeg2000)], @@ -189,7 +188,7 @@ class IcnsFile: def itersizes(self): sizes = [] for size, fmts in self.SIZES.items(): - for (fmt, reader) in fmts: + for fmt, reader in fmts: if fmt in self.dct: sizes.append(size) break diff --git a/src/PIL/IcoImagePlugin.py b/src/PIL/IcoImagePlugin.py index 568e6d38d..a188f8fdc 100644 --- a/src/PIL/IcoImagePlugin.py +++ b/src/PIL/IcoImagePlugin.py @@ -185,7 +185,7 @@ class IcoFile: return {(h["width"], h["height"]) for h in self.entry} def getentryindex(self, size, bpp=False): - for (i, h) in enumerate(self.entry): + for i, h in enumerate(self.entry): if size == h["dim"] and (bpp is False or bpp == h["color_depth"]): return i return 0 diff --git a/src/PIL/ImImagePlugin.py b/src/PIL/ImImagePlugin.py index 875a20326..746743f65 100644 --- a/src/PIL/ImImagePlugin.py +++ b/src/PIL/ImImagePlugin.py @@ -115,13 +115,11 @@ def number(s): class ImImageFile(ImageFile.ImageFile): - format = "IM" format_description = "IFUNC Image Memory" _close_exclusive_fp_after_loading = False def _open(self): - # Quick rejection: if there's not an LF among the first # 100 bytes, this is (probably) not a text header. @@ -140,7 +138,6 @@ class ImImageFile(ImageFile.ImageFile): self.rawmode = "L" while True: - s = self.fp.read(1) # Some versions of IFUNC uses \n\r instead of \r\n... @@ -169,7 +166,6 @@ class ImImageFile(ImageFile.ImageFile): raise SyntaxError(msg) from e if m: - k, v = m.group(1, 2) # Don't know if this is the correct encoding, @@ -200,7 +196,6 @@ class ImImageFile(ImageFile.ImageFile): n += 1 else: - msg = "Syntax error in IM header: " + s.decode("ascii", "replace") raise SyntaxError(msg) @@ -252,7 +247,6 @@ class ImImageFile(ImageFile.ImageFile): self._fp = self.fp # FIXME: hack if self.rawmode[:2] == "F;": - # ifunc95 formats try: # use bit decoder (if necessary) @@ -332,7 +326,6 @@ SAVE = { def _save(im, fp, filename): - try: image_type, rawmode = SAVE[im.mode] except KeyError as e: diff --git a/src/PIL/Image.py b/src/PIL/Image.py index b0ff5173c..81123d070 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -153,6 +153,7 @@ def isImageType(t): # # Constants + # transpose class Transpose(IntEnum): FLIP_LEFT_RIGHT = 0 @@ -391,7 +392,6 @@ def init(): def _getdecoder(mode, decoder_name, args, extra=()): - # tweak arguments if args is None: args = () @@ -415,7 +415,6 @@ def _getdecoder(mode, decoder_name, args, extra=()): def _getencoder(mode, encoder_name, args, extra=()): - # tweak arguments if args is None: args = () @@ -3267,9 +3266,15 @@ def open(fp, mode="r", formats=None): im = _open_core(fp, filename, prefix, formats) - if im is None: + if im is None and formats is ID: + checked_formats = formats.copy() if init(): - im = _open_core(fp, filename, prefix, formats) + im = _open_core( + fp, + filename, + prefix, + tuple(format for format in formats if format not in checked_formats), + ) if im: im._exclusive_fp = exclusive_fp @@ -3400,7 +3405,8 @@ def register_open(id, factory, accept=None): reject images having another format. """ id = id.upper() - ID.append(id) + if id not in ID: + ID.append(id) OPEN[id] = factory, accept diff --git a/src/PIL/ImageDraw.py b/src/PIL/ImageDraw.py index ce29a163b..163828d31 100644 --- a/src/PIL/ImageDraw.py +++ b/src/PIL/ImageDraw.py @@ -928,8 +928,8 @@ def floodfill(image, xy, value, border=None, thresh=0): full_edge = set() while edge: new_edge = set() - for (x, y) in edge: # 4 adjacent method - for (s, t) in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)): + for x, y in edge: # 4 adjacent method + for s, t in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)): # If already processed, or if a coordinate is negative, skip if (s, t) in full_edge or s < 0 or t < 0: continue diff --git a/src/PIL/ImageFile.py b/src/PIL/ImageFile.py index 12391955f..132490a8e 100644 --- a/src/PIL/ImageFile.py +++ b/src/PIL/ImageFile.py @@ -395,7 +395,6 @@ class Parser: # parse what we have if self.decoder: - if self.offset > 0: # skip header skip = min(len(self.data), self.offset) @@ -420,14 +419,12 @@ class Parser: self.data = self.data[n:] elif self.image: - # if we end up here with no decoder, this file cannot # be incrementally parsed. wait until we've gotten all # available data pass else: - # attempt to open this file try: with io.BytesIO(self.data) as fp: diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index b144c3dd2..bd13c391e 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -90,7 +90,6 @@ class ImageFont: """PIL font wrapper""" def _load_pilfont(self, filename): - with open(filename, "rb") as fp: image = None for ext in (".png", ".gif", ".pbm"): @@ -116,7 +115,6 @@ class ImageFont: image.close() def _load_pilfont_data(self, file, image): - # read PILfont header if file.readline() != b"PILfont\n": msg = "Not a PILfont file" diff --git a/src/PIL/ImageOps.py b/src/PIL/ImageOps.py index 16c83f4e4..301c593c7 100644 --- a/src/PIL/ImageOps.py +++ b/src/PIL/ImageOps.py @@ -205,7 +205,6 @@ def colorize(image, black, white, mid=None, blackpoint=0, whitepoint=255, midpoi # Create the mapping (2-color) if mid is None: - range_map = range(0, whitepoint - blackpoint) for i in range_map: @@ -215,7 +214,6 @@ def colorize(image, black, white, mid=None, blackpoint=0, whitepoint=255, midpoi # Create the mapping (3-color) else: - range_map1 = range(0, midpoint - blackpoint) range_map2 = range(0, whitepoint - midpoint) diff --git a/src/PIL/ImagePalette.py b/src/PIL/ImagePalette.py index fe0d32155..e455c0459 100644 --- a/src/PIL/ImagePalette.py +++ b/src/PIL/ImagePalette.py @@ -248,11 +248,9 @@ def wedge(mode="RGB"): def load(filename): - # FIXME: supports GIMP gradients only with open(filename, "rb") as fp: - for paletteHandler in [ GimpPaletteFile.GimpPaletteFile, GimpGradientFile.GimpGradientFile, diff --git a/src/PIL/ImageShow.py b/src/PIL/ImageShow.py index 29d900bef..f0e73fb90 100644 --- a/src/PIL/ImageShow.py +++ b/src/PIL/ImageShow.py @@ -390,7 +390,6 @@ else: if __name__ == "__main__": - if len(sys.argv) < 2: print("Syntax: python3 ImageShow.py imagefile [title]") sys.exit() diff --git a/src/PIL/ImageTk.py b/src/PIL/ImageTk.py index 09a6356fa..ef569ed2e 100644 --- a/src/PIL/ImageTk.py +++ b/src/PIL/ImageTk.py @@ -97,7 +97,6 @@ class PhotoImage: """ def __init__(self, image=None, size=None, **kw): - # Tk compatibility: file or data if image is None: image = _get_image_from_kw(kw) @@ -209,7 +208,6 @@ class BitmapImage: """ def __init__(self, image=None, **kw): - # Tk compatibility: file or data if image is None: image = _get_image_from_kw(kw) diff --git a/src/PIL/ImtImagePlugin.py b/src/PIL/ImtImagePlugin.py index cfeadd53c..ac267457b 100644 --- a/src/PIL/ImtImagePlugin.py +++ b/src/PIL/ImtImagePlugin.py @@ -30,12 +30,10 @@ field = re.compile(rb"([a-z]*) ([^ \r\n]*)") class ImtImageFile(ImageFile.ImageFile): - format = "IMT" format_description = "IM Tools" def _open(self): - # Quick rejection: if there's not a LF among the first # 100 bytes, this is (probably) not a text header. @@ -47,7 +45,6 @@ class ImtImageFile(ImageFile.ImageFile): xsize = ysize = 0 while True: - if buffer: s = buffer[:1] buffer = buffer[1:] @@ -57,7 +54,6 @@ class ImtImageFile(ImageFile.ImageFile): break if s == b"\x0C": - # image data begins self.tile = [ ( @@ -71,7 +67,6 @@ class ImtImageFile(ImageFile.ImageFile): break else: - # read key/value pair if b"\n" not in buffer: buffer += self.fp.read(100) diff --git a/src/PIL/IptcImagePlugin.py b/src/PIL/IptcImagePlugin.py index 774817569..4c47b55c1 100644 --- a/src/PIL/IptcImagePlugin.py +++ b/src/PIL/IptcImagePlugin.py @@ -48,7 +48,6 @@ def dump(c): class IptcImageFile(ImageFile.ImageFile): - format = "IPTC" format_description = "IPTC/NAA" @@ -84,7 +83,6 @@ class IptcImageFile(ImageFile.ImageFile): return tag, size def _open(self): - # load descriptive fields while True: offset = self.fp.tell() @@ -134,7 +132,6 @@ class IptcImageFile(ImageFile.ImageFile): ] def load(self): - if len(self.tile) != 1 or self.tile[0][0] != "iptc": return ImageFile.ImageFile.load(self) diff --git a/src/PIL/JpegImagePlugin.py b/src/PIL/JpegImagePlugin.py index 9657ae9d0..d7ddbe0d9 100644 --- a/src/PIL/JpegImagePlugin.py +++ b/src/PIL/JpegImagePlugin.py @@ -41,7 +41,7 @@ import sys import tempfile import warnings -from . import Image, ImageFile, TiffImagePlugin +from . import Image, ImageFile from ._binary import i16be as i16 from ._binary import i32be as i32 from ._binary import o8 @@ -344,12 +344,10 @@ def _accept(prefix): class JpegImageFile(ImageFile.ImageFile): - format = "JPEG" format_description = "JPEG (ISO 10918)" def _open(self): - s = self.fp.read(3) if not _accept(s): @@ -370,7 +368,6 @@ class JpegImageFile(ImageFile.ImageFile): self.icclist = [] while True: - i = s[0] if i == 0xFF: s = s + self.fp.read(1) @@ -418,7 +415,6 @@ class JpegImageFile(ImageFile.ImageFile): return s def draft(self, mode, size): - if len(self.tile) != 1: return @@ -455,7 +451,6 @@ class JpegImageFile(ImageFile.ImageFile): return self.mode, box def load_djpeg(self): - # ALTERNATIVE: handle JPEGs via the IJG command line utilities f, path = tempfile.mkstemp() @@ -524,6 +519,8 @@ def _getmp(self): head = file_contents.read(8) endianness = ">" if head[:4] == b"\x4d\x4d\x00\x2a" else "<" # process dictionary + from . import TiffImagePlugin + try: info = TiffImagePlugin.ImageFileDirectory_v2(head) file_contents.seek(info.next) diff --git a/src/PIL/McIdasImagePlugin.py b/src/PIL/McIdasImagePlugin.py index 8d4d826aa..17c008b9a 100644 --- a/src/PIL/McIdasImagePlugin.py +++ b/src/PIL/McIdasImagePlugin.py @@ -30,12 +30,10 @@ def _accept(s): class McIdasImageFile(ImageFile.ImageFile): - format = "MCIDAS" format_description = "McIdas area file" def _open(self): - # parse area file directory s = self.fp.read(256) if not _accept(s) or len(s) != 256: diff --git a/src/PIL/MicImagePlugin.py b/src/PIL/MicImagePlugin.py index e7e1054a3..8dd9f2909 100644 --- a/src/PIL/MicImagePlugin.py +++ b/src/PIL/MicImagePlugin.py @@ -34,13 +34,11 @@ def _accept(prefix): class MicImageFile(TiffImagePlugin.TiffImageFile): - format = "MIC" format_description = "Microsoft Image Composer" _close_exclusive_fp_after_loading = False def _open(self): - # read the OLE directory and see if this is a likely # to be a Microsoft Image Composer file diff --git a/src/PIL/MpegImagePlugin.py b/src/PIL/MpegImagePlugin.py index 2d799d6d8..d96d3a11c 100644 --- a/src/PIL/MpegImagePlugin.py +++ b/src/PIL/MpegImagePlugin.py @@ -58,12 +58,10 @@ class BitStream: class MpegImageFile(ImageFile.ImageFile): - format = "MPEG" format_description = "MPEG" def _open(self): - s = BitStream(self.fp) if s.read(32) != 0x1B3: diff --git a/src/PIL/MpoImagePlugin.py b/src/PIL/MpoImagePlugin.py index b1ec2c7bc..f9261c77d 100644 --- a/src/PIL/MpoImagePlugin.py +++ b/src/PIL/MpoImagePlugin.py @@ -101,7 +101,6 @@ def _save_all(im, fp, filename): class MpoImageFile(JpegImagePlugin.JpegImageFile): - format = "MPO" format_description = "MPO (CIPA DC-007)" _close_exclusive_fp_after_loading = False diff --git a/src/PIL/MspImagePlugin.py b/src/PIL/MspImagePlugin.py index 5420894dc..c6567b2ae 100644 --- a/src/PIL/MspImagePlugin.py +++ b/src/PIL/MspImagePlugin.py @@ -44,12 +44,10 @@ def _accept(prefix): class MspImageFile(ImageFile.ImageFile): - format = "MSP" format_description = "Windows Paint" def _open(self): - # Header s = self.fp.read(32) if not _accept(s): @@ -111,7 +109,6 @@ class MspDecoder(ImageFile.PyDecoder): _pulls_fd = True def decode(self, buffer): - img = io.BytesIO() blank_line = bytearray((0xFF,) * ((self.state.xsize + 7) // 8)) try: @@ -162,7 +159,6 @@ Image.register_decoder("MSP", MspDecoder) def _save(im, fp, filename): - if im.mode != "1": msg = f"cannot write mode {im.mode} as MSP" raise OSError(msg) diff --git a/src/PIL/PaletteFile.py b/src/PIL/PaletteFile.py index 07acd5580..4a2c497fc 100644 --- a/src/PIL/PaletteFile.py +++ b/src/PIL/PaletteFile.py @@ -22,11 +22,9 @@ class PaletteFile: rawmode = "RGB" def __init__(self, fp): - self.palette = [(i, i, i) for i in range(256)] while True: - s = fp.readline() if not s: @@ -50,5 +48,4 @@ class PaletteFile: self.palette = b"".join(self.palette) def getpalette(self): - return self.palette, self.rawmode diff --git a/src/PIL/PalmImagePlugin.py b/src/PIL/PalmImagePlugin.py index 109aad9ab..a88a90791 100644 --- a/src/PIL/PalmImagePlugin.py +++ b/src/PIL/PalmImagePlugin.py @@ -112,9 +112,7 @@ _COMPRESSION_TYPES = {"none": 0xFF, "rle": 0x01, "scanline": 0x00} def _save(im, fp, filename): - if im.mode == "P": - # we assume this is a color Palm image with the standard colormap, # unless the "info" dict has a "custom-colormap" field @@ -147,14 +145,12 @@ def _save(im, fp, filename): version = 1 elif im.mode == "1": - # monochrome -- write it inverted, as is the Palm standard rawmode = "1;I" bpp = 1 version = 0 else: - msg = f"cannot write mode {im.mode} as Palm" raise OSError(msg) diff --git a/src/PIL/PcdImagePlugin.py b/src/PIL/PcdImagePlugin.py index 5802d386a..e390f3fe5 100644 --- a/src/PIL/PcdImagePlugin.py +++ b/src/PIL/PcdImagePlugin.py @@ -24,12 +24,10 @@ from . import Image, ImageFile class PcdImageFile(ImageFile.ImageFile): - format = "PCD" format_description = "Kodak PhotoCD" def _open(self): - # rough self.fp.seek(2048) s = self.fp.read(2048) diff --git a/src/PIL/PcfFontFile.py b/src/PIL/PcfFontFile.py index ecce1b097..d5f510f03 100644 --- a/src/PIL/PcfFontFile.py +++ b/src/PIL/PcfFontFile.py @@ -58,7 +58,6 @@ class PcfFontFile(FontFile.FontFile): name = "name" def __init__(self, fp, charset_encoding="iso8859-1"): - self.charset_encoding = charset_encoding magic = l32(fp.read(4)) @@ -92,7 +91,6 @@ class PcfFontFile(FontFile.FontFile): self.glyph[ch] = glyph def _getformat(self, tag): - format, size, offset = self.toc[tag] fp = self.fp @@ -108,7 +106,6 @@ class PcfFontFile(FontFile.FontFile): return fp, format, i16, i32 def _load_properties(self): - # # font properties @@ -136,7 +133,6 @@ class PcfFontFile(FontFile.FontFile): return properties def _load_metrics(self): - # # font metrics @@ -147,7 +143,6 @@ class PcfFontFile(FontFile.FontFile): append = metrics.append if (format & 0xFF00) == 0x100: - # "compressed" metrics for i in range(i16(fp.read(2))): left = i8(fp.read(1)) - 128 @@ -160,7 +155,6 @@ class PcfFontFile(FontFile.FontFile): append((xsize, ysize, left, right, width, ascent, descent, 0)) else: - # "jumbo" metrics for i in range(i32(fp.read(4))): left = i16(fp.read(2)) @@ -176,7 +170,6 @@ class PcfFontFile(FontFile.FontFile): return metrics def _load_bitmaps(self, metrics): - # # bitmap data diff --git a/src/PIL/PcxImagePlugin.py b/src/PIL/PcxImagePlugin.py index 3202475dc..f42c2456b 100644 --- a/src/PIL/PcxImagePlugin.py +++ b/src/PIL/PcxImagePlugin.py @@ -45,12 +45,10 @@ def _accept(prefix): class PcxImageFile(ImageFile.ImageFile): - format = "PCX" format_description = "Paintbrush" def _open(self): - # header s = self.fp.read(128) if not _accept(s): @@ -143,7 +141,6 @@ SAVE = { def _save(im, fp, filename): - try: version, bits, planes, rawmode = SAVE[im.mode] except KeyError as e: diff --git a/src/PIL/PixarImagePlugin.py b/src/PIL/PixarImagePlugin.py index 8d0a34dba..7eb82228a 100644 --- a/src/PIL/PixarImagePlugin.py +++ b/src/PIL/PixarImagePlugin.py @@ -35,12 +35,10 @@ def _accept(prefix): class PixarImageFile(ImageFile.ImageFile): - format = "PIXAR" format_description = "PIXAR raster image" def _open(self): - # assuming a 4-byte magic label s = self.fp.read(4) if not _accept(s): diff --git a/src/PIL/PngImagePlugin.py b/src/PIL/PngImagePlugin.py index b6626bbc5..9078957dc 100644 --- a/src/PIL/PngImagePlugin.py +++ b/src/PIL/PngImagePlugin.py @@ -161,7 +161,6 @@ def _crc32(data, seed=0): class ChunkStream: def __init__(self, fp): - self.fp = fp self.queue = [] @@ -195,7 +194,6 @@ class ChunkStream: self.queue = self.fp = None def push(self, cid, pos, length): - self.queue.append((cid, pos, length)) def call(self, cid, pos, length): @@ -230,7 +228,6 @@ class ChunkStream: self.fp.read(4) def verify(self, endchunk=b"IEND"): - # Simple approach; just calculate checksum for all remaining # blocks. Must be called directly after open. @@ -397,7 +394,6 @@ class PngStream(ChunkStream): self._seq_num = self.rewind_state["seq_num"] def chunk_iCCP(self, pos, length): - # ICC profile s = ImageFile._safe_read(self.fp, length) # according to PNG spec, the iCCP chunk contains: @@ -425,7 +421,6 @@ class PngStream(ChunkStream): return s def chunk_IHDR(self, pos, length): - # image header s = ImageFile._safe_read(self.fp, length) if length < 13: @@ -446,7 +441,6 @@ class PngStream(ChunkStream): return s def chunk_IDAT(self, pos, length): - # image data if "bbox" in self.im_info: tile = [("zip", self.im_info["bbox"], pos, self.im_rawmode)] @@ -459,12 +453,10 @@ class PngStream(ChunkStream): raise EOFError def chunk_IEND(self, pos, length): - # end of PNG image raise EOFError def chunk_PLTE(self, pos, length): - # palette s = ImageFile._safe_read(self.fp, length) if self.im_mode == "P": @@ -472,7 +464,6 @@ class PngStream(ChunkStream): return s def chunk_tRNS(self, pos, length): - # transparency s = ImageFile._safe_read(self.fp, length) if self.im_mode == "P": @@ -524,7 +515,6 @@ class PngStream(ChunkStream): return s def chunk_pHYs(self, pos, length): - # pixels per unit s = ImageFile._safe_read(self.fp, length) if length < 9: @@ -542,7 +532,6 @@ class PngStream(ChunkStream): return s def chunk_tEXt(self, pos, length): - # text s = ImageFile._safe_read(self.fp, length) try: @@ -562,7 +551,6 @@ class PngStream(ChunkStream): return s def chunk_zTXt(self, pos, length): - # compressed text s = ImageFile._safe_read(self.fp, length) try: @@ -597,7 +585,6 @@ class PngStream(ChunkStream): return s def chunk_iTXt(self, pos, length): - # international text r = s = ImageFile._safe_read(self.fp, length) try: @@ -721,12 +708,10 @@ def _accept(prefix): class PngImageFile(ImageFile.ImageFile): - format = "PNG" format_description = "Portable network graphics" def _open(self): - if not _accept(self.fp.read(8)): msg = "not a PNG file" raise SyntaxError(msg) @@ -740,7 +725,6 @@ class PngImageFile(ImageFile.ImageFile): self.png = PngStream(self.fp) while True: - # # get next chunk @@ -1264,7 +1248,6 @@ def _save(im, fp, filename, chunk=putchunk, save_all=False): mode = im.mode if mode == "P": - # # attempt to minimize storage requirements for palette images if "bits" in im.encoderinfo: diff --git a/src/PIL/PpmImagePlugin.py b/src/PIL/PpmImagePlugin.py index dee2f1e15..5aa418044 100644 --- a/src/PIL/PpmImagePlugin.py +++ b/src/PIL/PpmImagePlugin.py @@ -51,7 +51,6 @@ def _accept(prefix): class PpmImageFile(ImageFile.ImageFile): - format = "PPM" format_description = "Pbmplus image" diff --git a/src/PIL/PsdImagePlugin.py b/src/PIL/PsdImagePlugin.py index 7e8d12759..5a5d60d56 100644 --- a/src/PIL/PsdImagePlugin.py +++ b/src/PIL/PsdImagePlugin.py @@ -51,13 +51,11 @@ def _accept(prefix): class PsdImageFile(ImageFile.ImageFile): - format = "PSD" format_description = "Adobe Photoshop" _close_exclusive_fp_after_loading = False def _open(self): - read = self.fp.read # @@ -177,7 +175,6 @@ def _layerinfo(fp, ct_bytes): raise SyntaxError(msg) for _ in range(abs(ct)): - # bounding box y0 = i32(read(4)) x0 = i32(read(4)) @@ -250,7 +247,6 @@ def _layerinfo(fp, ct_bytes): def _maketile(file, mode, bbox, channels): - tile = None read = file.read diff --git a/src/PIL/SgiImagePlugin.py b/src/PIL/SgiImagePlugin.py index d533c55e5..3662ffd15 100644 --- a/src/PIL/SgiImagePlugin.py +++ b/src/PIL/SgiImagePlugin.py @@ -49,12 +49,10 @@ MODES = { ## # Image plugin for SGI images. class SgiImageFile(ImageFile.ImageFile): - format = "SGI" format_description = "SGI Image File Format" def _open(self): - # HEAD headlen = 512 s = self.fp.read(headlen) diff --git a/src/PIL/SpiderImagePlugin.py b/src/PIL/SpiderImagePlugin.py index 1192c2d73..eac27e679 100644 --- a/src/PIL/SpiderImagePlugin.py +++ b/src/PIL/SpiderImagePlugin.py @@ -91,7 +91,6 @@ def isSpiderImage(filename): class SpiderImageFile(ImageFile.ImageFile): - format = "SPIDER" format_description = "Spider 2D image" _close_exclusive_fp_after_loading = False @@ -200,6 +199,7 @@ class SpiderImageFile(ImageFile.ImageFile): # -------------------------------------------------------------------- # Image series + # given a list of filenames, return a list of images def loadImageSeries(filelist=None): """create a list of :py:class:`~PIL.Image.Image` objects for use in a montage""" @@ -289,7 +289,6 @@ Image.register_open(SpiderImageFile.format, SpiderImageFile) Image.register_save(SpiderImageFile.format, _save_spider) if __name__ == "__main__": - if len(sys.argv) < 2: print("Syntax: python3 SpiderImagePlugin.py [infile] [outfile]") sys.exit() diff --git a/src/PIL/SunImagePlugin.py b/src/PIL/SunImagePlugin.py index c64de4444..6712583d7 100644 --- a/src/PIL/SunImagePlugin.py +++ b/src/PIL/SunImagePlugin.py @@ -30,12 +30,10 @@ def _accept(prefix): class SunImageFile(ImageFile.ImageFile): - format = "SUN" format_description = "Sun Raster File" def _open(self): - # The Sun Raster file header is 32 bytes in length # and has the following format: diff --git a/src/PIL/TarIO.py b/src/PIL/TarIO.py index 20e8a083f..32928f6af 100644 --- a/src/PIL/TarIO.py +++ b/src/PIL/TarIO.py @@ -32,7 +32,6 @@ class TarIO(ContainerIO.ContainerIO): self.fh = open(tarfile, "rb") while True: - s = self.fh.read(512) if len(s) != 512: msg = "unexpected end of tar file" diff --git a/src/PIL/TgaImagePlugin.py b/src/PIL/TgaImagePlugin.py index 53fe6ef5c..67dfc3d3c 100644 --- a/src/PIL/TgaImagePlugin.py +++ b/src/PIL/TgaImagePlugin.py @@ -46,12 +46,10 @@ MODES = { class TgaImageFile(ImageFile.ImageFile): - format = "TGA" format_description = "Targa" def _open(self): - # process header s = self.fp.read(18) @@ -174,7 +172,6 @@ SAVE = { def _save(im, fp, filename): - try: rawmode, bits, colormaptype, imagetype = SAVE[im.mode] except KeyError as e: diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index 431a95701..2cf5b173f 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -722,6 +722,8 @@ class ImageFileDirectory_v2(MutableMapping): @_register_writer(1) # Basic type, except for the legacy API. def write_byte(self, data): + if isinstance(data, IFDRational): + data = int(data) if isinstance(data, int): data = bytes((data,)) return data @@ -791,7 +793,6 @@ class ImageFileDirectory_v2(MutableMapping): return ret def load(self, fp): - self.reset() self._offset = fp.tell() @@ -936,7 +937,6 @@ class ImageFileDirectory_v2(MutableMapping): return result def save(self, fp): - if fp.tell() == 0: # skip TIFF header on subsequent pages # tiff header -- PIL always starts the first IFD at offset 8 fp.write(self._prefix + self._pack("HL", 42, 8)) @@ -1057,7 +1057,6 @@ ImageFileDirectory = ImageFileDirectory_v1 class TiffImageFile(ImageFile.ImageFile): - format = "TIFF" format_description = "Adobe TIFF" _close_exclusive_fp_after_loading = False @@ -1580,7 +1579,6 @@ SAVE_INFO = { def _save(im, fp, filename): - try: rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode] except KeyError as e: diff --git a/src/PIL/WalImageFile.py b/src/PIL/WalImageFile.py index 0dc695a88..e4f47aa04 100644 --- a/src/PIL/WalImageFile.py +++ b/src/PIL/WalImageFile.py @@ -28,7 +28,6 @@ from ._binary import i32le as i32 class WalImageFile(ImageFile.ImageFile): - format = "WAL" format_description = "Quake2 Texture" diff --git a/src/PIL/WebPImagePlugin.py b/src/PIL/WebPImagePlugin.py index 1d074f78c..d060dd4b8 100644 --- a/src/PIL/WebPImagePlugin.py +++ b/src/PIL/WebPImagePlugin.py @@ -35,7 +35,6 @@ def _accept(prefix): class WebPImageFile(ImageFile.ImageFile): - format = "WEBP" format_description = "WebP image" __loaded = 0 diff --git a/src/PIL/WmfImagePlugin.py b/src/PIL/WmfImagePlugin.py index 639730b8e..0ecab56a8 100644 --- a/src/PIL/WmfImagePlugin.py +++ b/src/PIL/WmfImagePlugin.py @@ -75,7 +75,6 @@ def _accept(prefix): class WmfStubImageFile(ImageFile.StubImageFile): - format = "WMF" format_description = "Windows Metafile" @@ -86,7 +85,6 @@ class WmfStubImageFile(ImageFile.StubImageFile): s = self.fp.read(80) if s[:6] == b"\xd7\xcd\xc6\x9a\x00\x00": - # placeable windows metafile # get units per inch diff --git a/src/PIL/XVThumbImagePlugin.py b/src/PIL/XVThumbImagePlugin.py index f0e05e867..aa4a01f4e 100644 --- a/src/PIL/XVThumbImagePlugin.py +++ b/src/PIL/XVThumbImagePlugin.py @@ -41,12 +41,10 @@ def _accept(prefix): class XVThumbImageFile(ImageFile.ImageFile): - format = "XVThumb" format_description = "XV thumbnail image" def _open(self): - # check magic if not _accept(self.fp.read(6)): msg = "not an XV thumbnail file" diff --git a/src/PIL/XbmImagePlugin.py b/src/PIL/XbmImagePlugin.py index ad18e0031..3c12564c9 100644 --- a/src/PIL/XbmImagePlugin.py +++ b/src/PIL/XbmImagePlugin.py @@ -44,12 +44,10 @@ def _accept(prefix): class XbmImageFile(ImageFile.ImageFile): - format = "XBM" format_description = "X11 Bitmap" def _open(self): - m = xbm_head.match(self.fp.read(512)) if not m: @@ -69,7 +67,6 @@ class XbmImageFile(ImageFile.ImageFile): def _save(im, fp, filename): - if im.mode != "1": msg = f"cannot write mode {im.mode} as XBM" raise OSError(msg) diff --git a/src/PIL/XpmImagePlugin.py b/src/PIL/XpmImagePlugin.py index 5fae4cd68..5d5bdc3ed 100644 --- a/src/PIL/XpmImagePlugin.py +++ b/src/PIL/XpmImagePlugin.py @@ -33,12 +33,10 @@ def _accept(prefix): class XpmImageFile(ImageFile.ImageFile): - format = "XPM" format_description = "X11 Pixel Map" def _open(self): - if not _accept(self.fp.read(9)): msg = "not an XPM file" raise SyntaxError(msg) @@ -68,7 +66,6 @@ class XpmImageFile(ImageFile.ImageFile): palette = [b"\0\0\0"] * 256 for _ in range(pal): - s = self.fp.readline() if s[-2:] == b"\r\n": s = s[:-2] @@ -79,9 +76,7 @@ class XpmImageFile(ImageFile.ImageFile): s = s[2:-2].split() for i in range(0, len(s), 2): - if s[i] == b"c": - # process colour key rgb = s[i + 1] if rgb == b"None": @@ -99,7 +94,6 @@ class XpmImageFile(ImageFile.ImageFile): break else: - # missing colour key msg = "cannot read this XPM file" raise ValueError(msg) @@ -110,7 +104,6 @@ class XpmImageFile(ImageFile.ImageFile): self.tile = [("raw", (0, 0) + self.size, self.fp.tell(), ("P", 0, 1))] def load_read(self, bytes): - # # load all image data in one chunk diff --git a/src/PIL/__init__.py b/src/PIL/__init__.py index 4b76e893f..0e6f82092 100644 --- a/src/PIL/__init__.py +++ b/src/PIL/__init__.py @@ -1,11 +1,11 @@ """Pillow (Fork of the Python Imaging Library) -Pillow is the friendly PIL fork by Alex Clark and Contributors. +Pillow is the friendly PIL fork by Jeffrey A. Clark (Alex) and contributors. https://github.com/python-pillow/Pillow/ Pillow is forked from PIL 1.1.7. -PIL is the Python Imaging Library by Fredrik Lundh and Contributors. +PIL is the Python Imaging Library by Fredrik Lundh and contributors. Copyright (c) 1999 by Secret Labs AB. Use PIL.__version__ for this Pillow version. diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index a34e8b342..89903c621 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -109,9 +109,9 @@ header = [ deps = { "libjpeg": { "url": SF_PROJECTS - + "/libjpeg-turbo/files/2.1.4/libjpeg-turbo-2.1.4.tar.gz/download", - "filename": "libjpeg-turbo-2.1.4.tar.gz", - "dir": "libjpeg-turbo-2.1.4", + + "/libjpeg-turbo/files/2.1.5/libjpeg-turbo-2.1.5.tar.gz/download", + "filename": "libjpeg-turbo-2.1.5.tar.gz", + "dir": "libjpeg-turbo-2.1.5", "license": ["README.ijg", "LICENSE.md"], "license_pattern": ( "(LEGAL ISSUES\n============\n\n.+?)\n\nREFERENCES\n==========" @@ -177,9 +177,9 @@ deps = { "libs": [r"windows\vs2019\Release\{msbuild_arch}\liblzma\liblzma.lib"], }, "libwebp": { - "url": "http://downloads.webmproject.org/releases/webp/libwebp-1.2.4.tar.gz", - "filename": "libwebp-1.2.4.tar.gz", - "dir": "libwebp-1.2.4", + "url": "http://downloads.webmproject.org/releases/webp/libwebp-1.3.0.tar.gz", + "filename": "libwebp-1.3.0.tar.gz", + "dir": "libwebp-1.3.0", "license": "COPYING", "build": [ cmd_rmdir(r"output\release-static"), # clean