Repository navigation
Add Jarvis-Judice-Ninke dithering - #10265
Open
hiyouwhatsapp wants to merge 14 commits into
Open
hiyouwhatsapp wants to merge 14 commits into
hiyouwhatsapp wants to merge 14 commits into
Conversation
for more information, see https://pre-commit.ci
Contributor
|
It would be nice to get #9829 merged first, as it refactors the palette quantization code into a separate module (and fixes bugs in it). |
akx
reviewed
Oct 25, 2026
| } | ||
|
|
||
| if (dither) { | ||
| if (dither == 4) { |
Contributor
There was a problem hiding this comment.
This probably shouldn't use the magic number 4. (Also see #10122, related)
Comment on lines
+9
to
+48
| # The JJN kernel has twelve forward neighbors and is normalized by 48. | ||
| TAPS = ( | ||
| (1, 0, 7), | ||
| (2, 0, 5), | ||
| (-2, 1, 3), | ||
| (-1, 1, 5), | ||
| (0, 1, 7), | ||
| (1, 1, 5), | ||
| (2, 1, 3), | ||
| (-2, 2, 1), | ||
| (-1, 2, 3), | ||
| (0, 2, 5), | ||
| (1, 2, 3), | ||
| (2, 2, 1), | ||
| ) | ||
|
|
||
|
|
||
| def _expected_bilevel(values: list[int], size: tuple[int, int]) -> list[int]: | ||
| width, height = size | ||
| errors = [[0] * width for _ in range(3)] | ||
| output: list[int] = [] | ||
|
|
||
| for y in range(height): | ||
| for x in range(width): | ||
| weighted_error = errors[y % 3][x] | ||
| correction = abs(weighted_error) // 48 | ||
| if weighted_error < 0: | ||
| correction = -correction | ||
| value = max(0, min(255, values[y * width + x] + correction)) | ||
| color = 255 if value > 128 else 0 | ||
| output.append(color) | ||
|
|
||
| for dx, dy, weight in TAPS: | ||
| xx, yy = x + dx, y + dy | ||
| if 0 <= xx < width and yy < height: | ||
| errors[yy % 3][xx] += (value - color) * weight | ||
|
|
||
| errors[y % 3] = [0] * width | ||
|
|
||
| return output |
Contributor
There was a problem hiding this comment.
Is this just a reimplementation of JJN in Python? I think house style would be to add a JJN-dithered Hopper test fixture image to compare against?
| } | ||
|
|
||
| /* Jarvis-Judice-Ninke error diffusion, with a 5x3 kernel (divisor 48). | ||
| * Keep three rows of weighted errors; every contribution stays in bounds. */ |
for more information, see https://pre-commit.ci
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds Jarvis-Judice-Ninke dithering for bilevel and palette images, keeping Floyd-Steinberg as the default.
Uses the shared ImagingDitherType enum for the C mode constant and documents the three-row error buffer and boundary handling.
The tests compare against the checked-in JJN-dithered Hopper fixture. The duplicate Python diffusion implementation has been removed; small solid-image cases retain edge-size coverage.
Merged current main and resolved the conversion-code conflicts. Fork Linux/macOS tests, Windows tests, MSYS2 tests, Docker tests and lint pass on commit 3b7346d. All 668 benchmark cases also passed. The benchmark workflow only failed when CodSpeed rejected the fork results upload with HTTP 401 (repository not configured or authorized). Upstream Actions is awaiting maintainer approval.
The requested prerequisite #9829 remains open.
Fixes #9619