From bcff58c0f43342575c9462885cca10b2b8d698e38405852f226fb8cc479d0ec6 Mon Sep 17 00:00:00 2001 From: Steve Kowalik Date: Thu, 6 Feb 2025 03:38:59 +0000 Subject: [PATCH] - Update to 0.7: * Drop Python 3.7 support. * Add Python 3.12 support. * Update support for newer versions of PIL/Pillow. - Drop patch pillow10.patch, included upstream. - Add patch use-pywavelets.patch: * Use PyWavelets rather scipy.signal for CWT. - Switch to pyproject macros. OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:numeric/python-pyssim?expand=0&rev=13 --- .gitattributes | 23 ++++++++++++ .gitignore | 1 + Pillow-imports.patch | 21 +++++++++++ pillow10.patch | 55 ++++++++++++++++++++++++++++ pyssim-0.6.tar.gz | 3 ++ pyssim-0.7.tar.gz | 3 ++ python-pyssim.changes | 49 +++++++++++++++++++++++++ python-pyssim.spec | 85 +++++++++++++++++++++++++++++++++++++++++++ use-pywavelets.patch | 52 ++++++++++++++++++++++++++ 9 files changed, 292 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 Pillow-imports.patch create mode 100644 pillow10.patch create mode 100644 pyssim-0.6.tar.gz create mode 100644 pyssim-0.7.tar.gz create mode 100644 python-pyssim.changes create mode 100644 python-pyssim.spec create mode 100644 use-pywavelets.patch diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/Pillow-imports.patch b/Pillow-imports.patch new file mode 100644 index 0000000..9f3eda9 --- /dev/null +++ b/Pillow-imports.patch @@ -0,0 +1,21 @@ +--- pyssim-0.4/ssim/compat.py.orig 2019-02-21 11:51:21.441139164 +0700 ++++ pyssim-0.4/ssim/compat.py 2019-02-21 11:51:49.633337140 +0700 +@@ -11,14 +11,14 @@ + # pylint: disable=unused-import + + try: +- import Image +-except ImportError: + from PIL import Image ++except ImportError: ++ import Image + + try: +- import ImageOps +-except ImportError: + from PIL import ImageOps ++except ImportError: ++ import ImageOps + + if sys.version_info[0] > 2: + basestring = (str, bytes) diff --git a/pillow10.patch b/pillow10.patch new file mode 100644 index 0000000..86dec6a --- /dev/null +++ b/pillow10.patch @@ -0,0 +1,55 @@ +From db4296c12ca9c027eb9cd61b52195a78dfcc6711 Mon Sep 17 00:00:00 2001 +From: Theodore Ni <3806110+tjni@users.noreply.github.com> +Date: Sun, 27 Aug 2023 11:36:25 -0700 +Subject: [PATCH] Replace Image.ANTIALIAS with Image.LANCZOS + +This adds compatibility with Pillow 10, when ANTIALIAS was removed. +Meanwhile, LANCZOS has been an alias since Pillow 2.7.0. + +Co-authored-by: emilylange +--- + SSIM_CW-SSIM_comparison.ipynb | 8 ++++---- + ssim/ssimlib.py | 2 +- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/SSIM_CW-SSIM_comparison.ipynb b/SSIM_CW-SSIM_comparison.ipynb +index e713ffd..68ea8ce 100644 +--- a/SSIM_CW-SSIM_comparison.ipynb ++++ b/SSIM_CW-SSIM_comparison.ipynb +@@ -34,19 +34,19 @@ + "size = (256,256)\n", + "\n", + "im = Image.open('test-images/test3-orig.jpg')\n", +- "im = im.resize(size, Image.ANTIALIAS)\n", ++ "im = im.resize(size, Image.LANCZOS)\n", + "\n", + "# slightly rotated image\n", + "im_rot = Image.open('test-images/test3-rot.jpg')\n", +- "im_rot = im_rot.resize(size, Image.ANTIALIAS)\n", ++ "im_rot = im_rot.resize(size, Image.LANCZOS)\n", + "\n", + "# slightly modified lighting conditions\n", + "im_lig = Image.open('test-images/test3-lig.jpg')\n", +- "im_lig = im_lig.resize(size, Image.ANTIALIAS)\n", ++ "im_lig = im_lig.resize(size, Image.LANCZOS)\n", + "\n", + "# image cropped\n", + "im_cro = Image.open('test-images/test3-cro.jpg')\n", +- "im_cro = im_cro.resize(size, Image.ANTIALIAS)" ++ "im_cro = im_cro.resize(size, Image.LANCZOS)" + ] + }, + { +diff --git a/ssim/ssimlib.py b/ssim/ssimlib.py +index 693f951..b40a8d4 100644 +--- a/ssim/ssimlib.py ++++ b/ssim/ssimlib.py +@@ -45,7 +45,7 @@ def __init__(self, img, gaussian_kernel_1d=None, size=None): + # Resize image if size is defined and different + # from original image + if size and size != self.img.size: +- self.img = self.img.resize(size, Image.ANTIALIAS) ++ self.img = self.img.resize(size, Image.LANCZOS) + + # Set the size of the image + self.size = self.img.size diff --git a/pyssim-0.6.tar.gz b/pyssim-0.6.tar.gz new file mode 100644 index 0000000..9164be8 --- /dev/null +++ b/pyssim-0.6.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:813dfddd42db72c24a450ebc996f726ea2609115ec642d440be5501d5a4bff01 +size 2263609 diff --git a/pyssim-0.7.tar.gz b/pyssim-0.7.tar.gz new file mode 100644 index 0000000..6117f65 --- /dev/null +++ b/pyssim-0.7.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ae82fd3579c504fa51e460c7a454b2902d00cb789c6bcc4388fb11bcf5cd2bb +size 2263748 diff --git a/python-pyssim.changes b/python-pyssim.changes new file mode 100644 index 0000000..c9c8872 --- /dev/null +++ b/python-pyssim.changes @@ -0,0 +1,49 @@ +------------------------------------------------------------------- +Thu Feb 6 03:38:31 UTC 2025 - Steve Kowalik + +- Update to 0.7: + * Drop Python 3.7 support. + * Add Python 3.12 support. + * Update support for newer versions of PIL/Pillow. +- Drop patch pillow10.patch, included upstream. +- Add patch use-pywavelets.patch: + * Use PyWavelets rather scipy.signal for CWT. +- Switch to pyproject macros. + +------------------------------------------------------------------- +Thu Oct 5 08:53:32 UTC 2023 - Markéta Machová + +- Update to 0.6 + * support numpy 1.20 +- Drop upstreamed numpy120.patch +- add upstream pillow10.patch + +------------------------------------------------------------------- +Mon Mar 6 11:17:51 UTC 2023 - Daniel Garcia + +- Add numpy120.patch to support numpy 1.20 gh#jterrace/pyssim#44 +- Update to 0.5 + * No release notes found + +------------------------------------------------------------------- +Sat Feb 13 07:49:33 UTC 2021 - Dirk Müller + +- skip python 36 build (scipy) + +------------------------------------------------------------------- +Wed May 20 07:26:43 UTC 2020 - Petr Gajdos + +- %python3_only -> %python_alternative + +------------------------------------------------------------------- +Thu Feb 21 12:40:03 UTC 2019 - Tomáš Chvátal + +- Switch to github tarball until upstream includes the license + and the tests, the master test refetching causes source validator + to fail + +------------------------------------------------------------------- +Thu Feb 21 04:28:04 AM UTC 2019 - John Vandenberg + +- Initial spec for v0.4, with Pillow-imports.patch to workaround + problems caused by top level Image.py diff --git a/python-pyssim.spec b/python-pyssim.spec new file mode 100644 index 0000000..a86422c --- /dev/null +++ b/python-pyssim.spec @@ -0,0 +1,85 @@ +# +# spec file for package python-pyssim +# +# Copyright (c) 2025 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +Name: python-pyssim +Version: 0.7 +Release: 0 +Summary: Structured Similarity Image Metric (SSIM) +License: MIT +URL: https://github.com/jterrace/pyssim +Source: https://files.pythonhosted.org/packages/source/p/pyssim/pyssim-%{version}.tar.gz +Patch0: Pillow-imports.patch +# PATCH-FIX-UPSTREAM Use PyWavelets rather than scipy.signal gh#jterrace/pyssim#49 +Patch1: use-pywavelets.patch +BuildRequires: %{python_module base >= 3.8} +BuildRequires: %{python_module pip} +BuildRequires: %{python_module setuptools} +BuildRequires: fdupes +BuildRequires: python-rpm-macros +Requires: python-Pillow +Requires: python-PyWavelets +Requires: python-numpy +Requires: python-scipy +Requires(post): update-alternatives +Requires(postun): update-alternatives +BuildArch: noarch +# SECTION test requirements +BuildRequires: %{python_module Pillow} +BuildRequires: %{python_module PyWavelets} +BuildRequires: %{python_module numpy} +BuildRequires: %{python_module scipy} +# /SECTION +%python_subpackages + +%description +Module for computing Structured Similarity Image Metric (SSIM) in Python. + +%prep +%autosetup -p1 -n pyssim-%{version} + +%build +%pyproject_wheel + +%install +%pyproject_install +%python_clone -a %{buildroot}%{_bindir}/pyssim +%python_expand %fdupes %{buildroot}%{$python_sitelib} + +%check +%{python_expand # Tests extracted from .travis.yml +$python -m ssim test-images/test1-1.png test-images/test1-1.png | grep 1 +$python -m ssim test-images/test1-1.png test-images/test1-2.png | grep 0.998 +$python -m ssim test-images/test1-1.png "test-images/*" | grep -E " 1| 0.998| 0.672| 0.648" | wc -l | grep 4 +$python -m ssim --cw --width 128 --height 128 test-images/test1-1.png test-images/test1-1.png | grep 1 +$python -m ssim --cw --width 128 --height 128 test-images/test3-orig.jpg test-images/test3-rot.jpg | grep 0.938 +} + +%post +%python_install_alternative pyssim + +%postun +%python_uninstall_alternative pyssim + +%files %{python_files} +%license LICENSE.md +%doc README.md +%python_alternative %{_bindir}/pyssim +%{python_sitelib}/ssim +%{python_sitelib}/pyssim-%{version}.dist-info + +%changelog diff --git a/use-pywavelets.patch b/use-pywavelets.patch new file mode 100644 index 0000000..cdbdc95 --- /dev/null +++ b/use-pywavelets.patch @@ -0,0 +1,52 @@ +From 64a58687f261eb397e9c22609b5d48497ef02762 Mon Sep 17 00:00:00 2001 +From: Steve Kowalik +Date: Thu, 6 Feb 2025 14:23:17 +1100 +Subject: [PATCH] Use PyWavelets for continuous wavelet transform + +scipy 1.15.0 has been released, and with it, signal.cwt has been +removed[1]. The suggested recommendation is to use PyWavelets. + +1: https://docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.signal.cwt.html +--- + requirements.txt | 1 + + setup.py | 2 +- + ssim/ssimlib.py | 6 +++--- + 3 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/setup.py b/setup.py +index bee0d6f..6ad4008 100644 +--- a/setup.py ++++ b/setup.py +@@ -12,7 +12,7 @@ + author_email='jterrace@gmail.com', + platforms=['any'], + license='MIT License', +- install_requires=['numpy', 'pillow', 'scipy'], ++ install_requires=['numpy', 'pillow', 'scipy', 'PyWavelets'], + url='https://github.com/jterrace/pyssim', + entry_points={ + 'console_scripts': [ +diff --git a/ssim/ssimlib.py b/ssim/ssimlib.py +index b40a8d4..46bde93 100644 +--- a/ssim/ssimlib.py ++++ b/ssim/ssimlib.py +@@ -7,7 +7,7 @@ + import sys + + import numpy as np +-from scipy import signal ++import pywt + + from ssim import compat + from ssim.compat import Image, ImageOps +@@ -168,8 +168,8 @@ def cw_ssim_value(self, target, width=30): + sig2 = np.asarray(target.img_gray.getdata()) + + # Convolution +- cwtmatr1 = signal.cwt(sig1, signal.ricker, widths) +- cwtmatr2 = signal.cwt(sig2, signal.ricker, widths) ++ cwtmatr1, freqs1 = pywt.cwt(sig1, widths, 'mexh') ++ cwtmatr2, freqs2 = pywt.cwt(sig2, widths, 'mexh') + + # Compute the first term + c1c2 = np.multiply(abs(cwtmatr1), abs(cwtmatr2))