walsh 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,70 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ The `## [x.y.z]` headings are load-bearing: the release workflow extracts the
9
+ section matching the version in `pyproject.toml` and uses it as the GitHub
10
+ Release notes.
11
+
12
+ ## [0.1.1]
13
+
14
+ ### Added
15
+
16
+ - `uv` support: a `uv.lock` committed to the repository, and a `dev`
17
+ [PEP 735](https://peps.python.org/pep-0735/) dependency group, so
18
+ `uv sync --group dev` reproduces the full development environment.
19
+ - Release automation. A version bump landing on `master` tags `v<version>`,
20
+ creates a GitHub Release with these notes attached, and publishes the sdist
21
+ and wheel to [PyPI](https://pypi.org/project/walsh/) via Trusted Publishing.
22
+ - CI on every pull request: ruff, `ruff format --check`, strict mypy, the test
23
+ suite on Python 3.10 through 3.14, and a packaging job that builds both
24
+ distributions and smoke-tests the wheel in a clean environment.
25
+ - Python 3.14 to the supported classifiers.
26
+ - `Issues` and `Changelog` project URLs.
27
+
28
+ ### Changed
29
+
30
+ - The `dev` extra became the `dev` dependency group. `pip install .[dev]` no
31
+ longer works; use `uv sync --group dev`, `pip install --group dev .`
32
+ (pip 25.1+), or `pip install -r requirements-dev.txt`.
33
+
34
+ ## [0.1.0]
35
+
36
+ ### Added
37
+
38
+ - `walsh` console script with `compress` and `extract` subcommands.
39
+ - Test suite covering the transform, colour models, both container formats, the
40
+ task pipelines and the CLI.
41
+ - Type annotations throughout, with a `py.typed` marker; clean under
42
+ `mypy --strict`.
43
+
44
+ ### Changed
45
+
46
+ - Ported from Python 2.7 to Python 3.10+ and restructured as an installable
47
+ package under `src/walsh`. The old `fal` package and root `transform.py` were
48
+ removed; the demo moved to `examples/roundtrip.py`.
49
+ - `numpy` is now the only runtime dependency. `matplotlib` and `Pillow` were
50
+ only ever used by the demo script and became the `demo` extra.
51
+ - Spectral coefficients are rounded with `np.rint` on write. Python 2 relied on
52
+ `struct.pack` implicitly truncating floats, so output differs from the
53
+ pre-port result by at most 2 per channel (mean 0.33).
54
+ - `np.matrix` replaced with `ndarray` and the `@` operator.
55
+ - Requirements files carry explicit version bounds.
56
+
57
+ ### Known issues
58
+
59
+ Both predate the port and are preserved deliberately, because changing either
60
+ alters every compressed output:
61
+
62
+ - `BMPImage` reads pixel triples in BMP's native B, G, R order while `Task`
63
+ treats them as R, G, B. Round trips are exact, but the YCbCr weights land on
64
+ swapped channels.
65
+ - The `coeff_removal` comparison is one-sided rather than on the magnitude, so
66
+ any non-`None` coefficient above `-1/sqrt(2)**n` zeroes essentially the whole
67
+ spectrum.
68
+
69
+ [0.1.1]: https://github.com/oskar-j/walsh-hadamard-transform/releases/tag/v0.1.1
70
+ [0.1.0]: https://github.com/oskar-j/walsh-hadamard-transform/releases/tag/v0.1.0
walsh-0.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Oskar Jarczyk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,14 @@
1
+ # Controls what lands in the sdist. The wheel is driven by
2
+ # [tool.setuptools.packages.find] in pyproject.toml instead.
3
+ #
4
+ # setuptools picks up tests/test_*.py on its own but not conftest.py, which
5
+ # would ship a test suite whose fixtures are all undefined.
6
+
7
+ include CHANGELOG.md
8
+ include requirements.txt requirements-demo.txt requirements-dev.txt
9
+ recursive-include tests *.py
10
+ recursive-include examples *.py
11
+
12
+ # data/image.bmp is 480 KB and only feeds one test, which skips when the file
13
+ # is absent. Keep it out of the distribution.
14
+ exclude data/*.bmp
walsh-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,176 @@
1
+ Metadata-Version: 2.4
2
+ Name: walsh
3
+ Version: 0.1.1
4
+ Summary: Image compression with the Walsh-Hadamard transform
5
+ Author-email: Oskar Jarczyk <oskar.jarczyk@gmail.com>
6
+ Maintainer-email: Oskar Jarczyk <oskar.jarczyk@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/oskar-j/walsh-hadamard-transform
9
+ Project-URL: Repository, https://github.com/oskar-j/walsh-hadamard-transform
10
+ Project-URL: Issues, https://github.com/oskar-j/walsh-hadamard-transform/issues
11
+ Project-URL: Changelog, https://github.com/oskar-j/walsh-hadamard-transform/blob/master/CHANGELOG.md
12
+ Keywords: walsh,hadamard,transform,image,compression,dsp
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Multimedia :: Graphics
23
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: numpy<3,>=1.24
28
+ Provides-Extra: demo
29
+ Requires-Dist: matplotlib<4,>=3.7; extra == "demo"
30
+ Requires-Dist: Pillow<13,>=10.0; extra == "demo"
31
+ Dynamic: license-file
32
+
33
+ # Walsh-hadamard transform
34
+
35
+ [![PyPI](https://img.shields.io/pypi/v/walsh.svg)](https://pypi.org/project/walsh/)
36
+ [![Python versions](https://img.shields.io/pypi/pyversions/walsh.svg)](https://pypi.org/project/walsh/)
37
+ [![CI](https://github.com/oskar-j/walsh-hadamard-transform/actions/workflows/ci.yml/badge.svg)](https://github.com/oskar-j/walsh-hadamard-transform/actions/workflows/ci.yml)
38
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
39
+
40
+ Compressing images with a Hadamard transform
41
+
42
+ ## Description
43
+
44
+ **From Wikipedia:** The Hadamard transform (also known as the *Walsh–Hadamard transform*,
45
+ *Hadamard–Rademacher–Walsh transform*, *Walsh transform*, or *Walsh–Fourier transform*) is an example
46
+ of a generalized class of Fourier transforms. It performs an orthogonal, symmetric,
47
+ involutive, linear operation on 2m real numbers (or complex numbers, although the
48
+ Hadamard matrices themselves are purely real).
49
+
50
+ The Hadamard transform can be regarded as being built out of *size-2
51
+ discrete Fourier transforms* (DFTs), and is in fact equivalent to a
52
+ multidimensional DFT of size `2 × 2 × ⋯ × 2 × 2`. It decomposes an
53
+ arbitrary input vector into a superposition of *Walsh functions*.
54
+
55
+ The transform is named for the French mathematician Jacques Hadamard,
56
+ the German-American mathematician Hans Rademacher, and the
57
+ American mathematician Joseph L. Walsh.
58
+
59
+ The Hadamard transform is also used in data encryption, as well as many signal processing
60
+ and data compression algorithms, such as `JPEG XR` and `MPEG-4 AVC`. In video compression
61
+ applications, it is usually used in the form of the sum of absolute transformed differences.
62
+ It is also a crucial part of *Grover's algorithm* and *Shor's algorithm* in quantum computing.
63
+
64
+ ## Acknowledgement
65
+
66
+ This code is partially based on the solution from [ktisha/python2012](https://github.com/ktisha/python2012/tree/dee4beda8e22f3a66a3e31384d4b72ab66102e88/avereshchagin)
67
+
68
+ ## Installation
69
+
70
+ Requires Python 3.10 or newer.
71
+
72
+ ```
73
+ pip install walsh
74
+ ```
75
+
76
+ or, with [uv](https://docs.astral.sh/uv/):
77
+
78
+ ```
79
+ uv add walsh # into a project
80
+ uv tool install walsh # just the command line tool
81
+ ```
82
+
83
+ The example script additionally needs matplotlib and Pillow, which are the
84
+ `demo` extra: `pip install "walsh[demo]"`.
85
+
86
+ ### Development
87
+
88
+ `uv.lock` is committed, so a checkout reproduces exactly the environment CI
89
+ uses:
90
+
91
+ ```
92
+ uv sync --group dev --all-extras
93
+ ```
94
+
95
+ `--group dev` brings in pytest, ruff and mypy; `--all-extras` adds the `demo`
96
+ extra so `examples/roundtrip.py` runs too. Without uv:
97
+
98
+ ```
99
+ pip install -e ".[demo]" -r requirements-dev.txt
100
+ ```
101
+
102
+ ## How to run
103
+
104
+ ### Command line
105
+
106
+ ```
107
+ walsh compress data/image.bmp data/transformed.cim
108
+ walsh extract data/transformed.cim data/recreated.bmp
109
+ ```
110
+
111
+ `compress` accepts `--packed-block-size` (how many low-frequency coefficients
112
+ per axis to keep -- lower is smaller and lossier), `--y-block-size`,
113
+ `--chroma-block-size` and `--coeff-removal`. Add `-v`/`-vv` for progress
114
+ logging, and see `walsh --help` for the full list.
115
+
116
+ ### As a library
117
+
118
+ ```python
119
+ from walsh import Task
120
+
121
+ Task().with_action("compress").with_input("data/image.bmp").with_output("out.cim").run()
122
+ Task().with_action("extract").with_input("out.cim").with_output("back.bmp").run()
123
+ ```
124
+
125
+ ### Example
126
+
127
+ `examples/roundtrip.py` compresses the sample image, restores it, and plots
128
+ both images with their histograms side by side (needs the `demo` extra):
129
+
130
+ ```
131
+ python examples/roundtrip.py
132
+ ```
133
+
134
+ ## Requirements
135
+
136
+ The package itself needs only `numpy` -- BMP parsing is done by hand with
137
+ `struct`. `matplotlib` and `Pillow` are needed only by the example script, and
138
+ are declared as the `demo` extra. Versions are pinned in `pyproject.toml`;
139
+ `requirements.txt`, `requirements-demo.txt` and `requirements-dev.txt` mirror
140
+ them for plain `pip install -r` workflows.
141
+
142
+ ## Development commands
143
+
144
+ ```
145
+ uv run pytest # test suite
146
+ uv run ruff check . # lint
147
+ uv run ruff format . # format
148
+ uv run mypy # strict type check
149
+ uv build # sdist + wheel into dist/
150
+ ```
151
+
152
+ CI runs exactly these on every pull request, plus the test suite against
153
+ Python 3.10 through 3.14.
154
+
155
+ ## Releasing
156
+
157
+ The version in `pyproject.toml` is the single source of truth. To cut a
158
+ release, bump it, add the matching `## [x.y.z]` section to `CHANGELOG.md`, and
159
+ merge to `master`. The release workflow then tags `v<version>`, creates a
160
+ GitHub Release with those notes, and publishes the sdist and wheel to
161
+ [PyPI](https://pypi.org/project/walsh/) using Trusted Publishing — no API token
162
+ is stored in this repository.
163
+
164
+ Merges that do not change the version are a no-op, since PyPI permanently
165
+ refuses to accept the same version twice.
166
+
167
+ ## File format
168
+
169
+ `compress` writes a `.cim` file: an atypical, project-specific container, so
170
+ most commercial tools will not be able to read it. It stores the image
171
+ dimensions, three block-layout descriptions (Y, Cb, Cr), and the retained
172
+ Walsh-Hadamard coefficients as little-endian `int16`.
173
+
174
+ ## Effects
175
+
176
+ ![https://raw.githubusercontent.com/oskar-j/walsh-hadamard-transform/master/doc/sample_usage.jpg](https://raw.githubusercontent.com/oskar-j/walsh-hadamard-transform/master/doc/sample_usage.jpg)
walsh-0.1.1/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # Walsh-hadamard transform
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/walsh.svg)](https://pypi.org/project/walsh/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/walsh.svg)](https://pypi.org/project/walsh/)
5
+ [![CI](https://github.com/oskar-j/walsh-hadamard-transform/actions/workflows/ci.yml/badge.svg)](https://github.com/oskar-j/walsh-hadamard-transform/actions/workflows/ci.yml)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+
8
+ Compressing images with a Hadamard transform
9
+
10
+ ## Description
11
+
12
+ **From Wikipedia:** The Hadamard transform (also known as the *Walsh–Hadamard transform*,
13
+ *Hadamard–Rademacher–Walsh transform*, *Walsh transform*, or *Walsh–Fourier transform*) is an example
14
+ of a generalized class of Fourier transforms. It performs an orthogonal, symmetric,
15
+ involutive, linear operation on 2m real numbers (or complex numbers, although the
16
+ Hadamard matrices themselves are purely real).
17
+
18
+ The Hadamard transform can be regarded as being built out of *size-2
19
+ discrete Fourier transforms* (DFTs), and is in fact equivalent to a
20
+ multidimensional DFT of size `2 × 2 × ⋯ × 2 × 2`. It decomposes an
21
+ arbitrary input vector into a superposition of *Walsh functions*.
22
+
23
+ The transform is named for the French mathematician Jacques Hadamard,
24
+ the German-American mathematician Hans Rademacher, and the
25
+ American mathematician Joseph L. Walsh.
26
+
27
+ The Hadamard transform is also used in data encryption, as well as many signal processing
28
+ and data compression algorithms, such as `JPEG XR` and `MPEG-4 AVC`. In video compression
29
+ applications, it is usually used in the form of the sum of absolute transformed differences.
30
+ It is also a crucial part of *Grover's algorithm* and *Shor's algorithm* in quantum computing.
31
+
32
+ ## Acknowledgement
33
+
34
+ This code is partially based on the solution from [ktisha/python2012](https://github.com/ktisha/python2012/tree/dee4beda8e22f3a66a3e31384d4b72ab66102e88/avereshchagin)
35
+
36
+ ## Installation
37
+
38
+ Requires Python 3.10 or newer.
39
+
40
+ ```
41
+ pip install walsh
42
+ ```
43
+
44
+ or, with [uv](https://docs.astral.sh/uv/):
45
+
46
+ ```
47
+ uv add walsh # into a project
48
+ uv tool install walsh # just the command line tool
49
+ ```
50
+
51
+ The example script additionally needs matplotlib and Pillow, which are the
52
+ `demo` extra: `pip install "walsh[demo]"`.
53
+
54
+ ### Development
55
+
56
+ `uv.lock` is committed, so a checkout reproduces exactly the environment CI
57
+ uses:
58
+
59
+ ```
60
+ uv sync --group dev --all-extras
61
+ ```
62
+
63
+ `--group dev` brings in pytest, ruff and mypy; `--all-extras` adds the `demo`
64
+ extra so `examples/roundtrip.py` runs too. Without uv:
65
+
66
+ ```
67
+ pip install -e ".[demo]" -r requirements-dev.txt
68
+ ```
69
+
70
+ ## How to run
71
+
72
+ ### Command line
73
+
74
+ ```
75
+ walsh compress data/image.bmp data/transformed.cim
76
+ walsh extract data/transformed.cim data/recreated.bmp
77
+ ```
78
+
79
+ `compress` accepts `--packed-block-size` (how many low-frequency coefficients
80
+ per axis to keep -- lower is smaller and lossier), `--y-block-size`,
81
+ `--chroma-block-size` and `--coeff-removal`. Add `-v`/`-vv` for progress
82
+ logging, and see `walsh --help` for the full list.
83
+
84
+ ### As a library
85
+
86
+ ```python
87
+ from walsh import Task
88
+
89
+ Task().with_action("compress").with_input("data/image.bmp").with_output("out.cim").run()
90
+ Task().with_action("extract").with_input("out.cim").with_output("back.bmp").run()
91
+ ```
92
+
93
+ ### Example
94
+
95
+ `examples/roundtrip.py` compresses the sample image, restores it, and plots
96
+ both images with their histograms side by side (needs the `demo` extra):
97
+
98
+ ```
99
+ python examples/roundtrip.py
100
+ ```
101
+
102
+ ## Requirements
103
+
104
+ The package itself needs only `numpy` -- BMP parsing is done by hand with
105
+ `struct`. `matplotlib` and `Pillow` are needed only by the example script, and
106
+ are declared as the `demo` extra. Versions are pinned in `pyproject.toml`;
107
+ `requirements.txt`, `requirements-demo.txt` and `requirements-dev.txt` mirror
108
+ them for plain `pip install -r` workflows.
109
+
110
+ ## Development commands
111
+
112
+ ```
113
+ uv run pytest # test suite
114
+ uv run ruff check . # lint
115
+ uv run ruff format . # format
116
+ uv run mypy # strict type check
117
+ uv build # sdist + wheel into dist/
118
+ ```
119
+
120
+ CI runs exactly these on every pull request, plus the test suite against
121
+ Python 3.10 through 3.14.
122
+
123
+ ## Releasing
124
+
125
+ The version in `pyproject.toml` is the single source of truth. To cut a
126
+ release, bump it, add the matching `## [x.y.z]` section to `CHANGELOG.md`, and
127
+ merge to `master`. The release workflow then tags `v<version>`, creates a
128
+ GitHub Release with those notes, and publishes the sdist and wheel to
129
+ [PyPI](https://pypi.org/project/walsh/) using Trusted Publishing — no API token
130
+ is stored in this repository.
131
+
132
+ Merges that do not change the version are a no-op, since PyPI permanently
133
+ refuses to accept the same version twice.
134
+
135
+ ## File format
136
+
137
+ `compress` writes a `.cim` file: an atypical, project-specific container, so
138
+ most commercial tools will not be able to read it. It stores the image
139
+ dimensions, three block-layout descriptions (Y, Cb, Cr), and the retained
140
+ Walsh-Hadamard coefficients as little-endian `int16`.
141
+
142
+ ## Effects
143
+
144
+ ![https://raw.githubusercontent.com/oskar-j/walsh-hadamard-transform/master/doc/sample_usage.jpg](https://raw.githubusercontent.com/oskar-j/walsh-hadamard-transform/master/doc/sample_usage.jpg)
@@ -0,0 +1,57 @@
1
+ """Compress an image and restore it, showing both plus their histograms.
2
+
3
+ Run from the repository root after ``pip install -e .[demo]``::
4
+
5
+ python examples/roundtrip.py
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import logging
11
+ from pathlib import Path
12
+
13
+ import matplotlib.pyplot as plt
14
+ import numpy as np
15
+ from PIL import Image
16
+
17
+ from walsh import Task
18
+
19
+ DATA = Path(__file__).resolve().parent.parent / "data"
20
+ SOURCE = DATA / "image.bmp"
21
+ COMPRESSED = DATA / "transformed.cim" # raw post-transform data, not a standard format
22
+ RESTORED = DATA / "recreated.bmp"
23
+
24
+
25
+ def main() -> None:
26
+ logging.basicConfig(level=logging.INFO, format="%(levelname)s %(name)s: %(message)s")
27
+
28
+ Task().with_action("compress").with_input(str(SOURCE)).with_output(str(COMPRESSED)).run()
29
+
30
+ Task().with_action("extract").with_input(str(COMPRESSED)).with_output(str(RESTORED)).run()
31
+
32
+ original_bytes = SOURCE.stat().st_size
33
+ compressed_bytes = COMPRESSED.stat().st_size
34
+ print(
35
+ f"{original_bytes:,} B -> {compressed_bytes:,} B "
36
+ f"({compressed_bytes / original_bytes:.1%} of the original)"
37
+ )
38
+
39
+ # The image after transformation shows a visible loss of quality, and its
40
+ # colour profile (the per-pixel-value histogram) has shifted as well.
41
+ before = Image.open(SOURCE)
42
+ after = Image.open(RESTORED)
43
+
44
+ figure, axes = plt.subplots(2, 2, figsize=(14, 10))
45
+ for column, (title, image) in enumerate((("original", before), ("restored", after))):
46
+ axes[0][column].imshow(np.asarray(image))
47
+ axes[0][column].set_title(title)
48
+ axes[0][column].axis("off")
49
+ axes[1][column].hist(image.histogram(), bins=40)
50
+ axes[1][column].set_title(f"{title} histogram")
51
+
52
+ figure.tight_layout()
53
+ plt.show()
54
+
55
+
56
+ if __name__ == "__main__":
57
+ main()
@@ -0,0 +1,78 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "walsh"
7
+ version = "0.1.1"
8
+ description = "Image compression with the Walsh-Hadamard transform"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Oskar Jarczyk", email = "oskar.jarczyk@gmail.com" }]
14
+ maintainers = [{ name = "Oskar Jarczyk", email = "oskar.jarczyk@gmail.com" }]
15
+ keywords = ["walsh", "hadamard", "transform", "image", "compression", "dsp"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Science/Research",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
26
+ "Topic :: Multimedia :: Graphics",
27
+ "Topic :: Scientific/Engineering :: Image Processing",
28
+ ]
29
+ dependencies = ["numpy>=1.24,<3"]
30
+
31
+ [project.optional-dependencies]
32
+ # A real extra, because `pip install walsh[demo]` is something a user may want:
33
+ # it is what examples/roundtrip.py needs. The package itself parses BMP by hand.
34
+ demo = ["matplotlib>=3.7,<4", "Pillow>=10.0,<13"]
35
+
36
+ [project.scripts]
37
+ walsh = "walsh.cli:main"
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/oskar-j/walsh-hadamard-transform"
41
+ Repository = "https://github.com/oskar-j/walsh-hadamard-transform"
42
+ Issues = "https://github.com/oskar-j/walsh-hadamard-transform/issues"
43
+ Changelog = "https://github.com/oskar-j/walsh-hadamard-transform/blob/master/CHANGELOG.md"
44
+
45
+ # PEP 735 groups rather than extras: these are for working on the project, not
46
+ # for installing it. `uv sync --group dev` pulls them in; pip 25.1+ can too,
47
+ # with `pip install --group dev`.
48
+ [dependency-groups]
49
+ dev = [
50
+ "pytest>=8.0,<10",
51
+ "ruff>=0.6,<1",
52
+ "mypy>=1.10,<2",
53
+ "build>=1.2,<2",
54
+ ]
55
+
56
+ [tool.setuptools.packages.find]
57
+ where = ["src"]
58
+
59
+ [tool.setuptools.package-data]
60
+ walsh = ["py.typed"]
61
+
62
+ [tool.pytest.ini_options]
63
+ testpaths = ["tests"]
64
+ addopts = "-ra"
65
+
66
+ [tool.ruff]
67
+ line-length = 100
68
+ src = ["src", "tests"]
69
+ target-version = "py310"
70
+
71
+ [tool.ruff.lint]
72
+ select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
73
+
74
+ [tool.mypy]
75
+ # No python_version pin: numpy's bundled stubs require mypy to target 3.12+.
76
+ # Minimum-version compatibility is enforced by ruff's target-version instead.
77
+ packages = ["walsh"]
78
+ strict = true
@@ -0,0 +1,7 @@
1
+ # Extra packages needed only by examples/roundtrip.py, which displays the
2
+ # before/after images and their histograms. Equivalent to `pip install .[demo]`.
3
+
4
+ -r requirements.txt
5
+
6
+ matplotlib>=3.7,<4
7
+ Pillow>=10.0,<13
@@ -0,0 +1,7 @@
1
+ # Test and lint tooling. Equivalent to `pip install -e .[demo,dev]`.
2
+
3
+ -r requirements-demo.txt
4
+
5
+ pytest>=8.0,<10
6
+ ruff>=0.6,<1
7
+ mypy>=1.10,<2
@@ -0,0 +1,8 @@
1
+ # Runtime dependency of the `walsh` package itself.
2
+ # Authoritative versions live in pyproject.toml; this file mirrors them so the
3
+ # project can also be set up with a plain `pip install -r requirements.txt`.
4
+ #
5
+ # For the example script (examples/roundtrip.py) also install requirements-demo.txt.
6
+ # For tests and linting, install requirements-dev.txt.
7
+
8
+ numpy>=1.24,<3
walsh-0.1.1/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,43 @@
1
+ """Image compression with the Walsh-Hadamard transform.
2
+
3
+ Typical use::
4
+
5
+ from walsh import Task
6
+
7
+ Task().with_action("compress").with_input("image.bmp").with_output("out.cim").run()
8
+ Task().with_action("extract").with_input("out.cim").with_output("back.bmp").run()
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from importlib.metadata import PackageNotFoundError, version
14
+
15
+ from walsh.colors import ColorModel, RgbColorModel, YCbCrColorModel
16
+ from walsh.image import (
17
+ BlockDescription,
18
+ BMPImage,
19
+ CustomizableImage,
20
+ UnsupportedFileFormatError,
21
+ )
22
+ from walsh.task import Action, Task
23
+ from walsh.transforms import Transform, WalshHadamardTransform
24
+
25
+ try:
26
+ __version__ = version("walsh")
27
+ except PackageNotFoundError: # pragma: no cover - source checkout without install
28
+ __version__ = "0.0.0.dev0"
29
+
30
+ __all__ = [
31
+ "Action",
32
+ "BMPImage",
33
+ "BlockDescription",
34
+ "ColorModel",
35
+ "CustomizableImage",
36
+ "RgbColorModel",
37
+ "Task",
38
+ "Transform",
39
+ "UnsupportedFileFormatError",
40
+ "WalshHadamardTransform",
41
+ "YCbCrColorModel",
42
+ "__version__",
43
+ ]