-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Image -> Arrow support #8330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Image -> Arrow support #8330
Changes from 8 commits
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
5890e40
WIP - Initial Pillow->Arrow support
wiredfool d44212d
WIP - Non working struct encoding
wiredfool bdd4b3a
Export as fixed width pixels, or just pixel values for single channel.
wiredfool 56780ce
Tests, lifetime changes
wiredfool 6ec855e
Lifetime check
wiredfool e1ef083
fix macoxisim
wiredfool 97eb7c0
WIP -- First light of round trip of image -> arrow -> image
wiredfool f1349e9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 9d584a1
Lint
wiredfool 2b88b1c
Typing Lint
wiredfool af64250
Lint
wiredfool 244dded
Typing Lint
wiredfool dbe0304
Tests for destructors of the PyCapsules
wiredfool 388da5c
Test rejection of incorrect modes
wiredfool 55f5351
Test for size, add offset support
wiredfool ad492ee
Pull readonly in from the C level
wiredfool d02417e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 6fad11a
added mutex around refcount, renamed arrow_borrow to refcount
wiredfool 4fc8328
remove unused code
wiredfool e7bd152
Error handling:
wiredfool 9f94d4f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 13e3301
Fix handling of capsule destruct sequencing
wiredfool 2401757
Add a way to force the use of the old block allocator
wiredfool be3b0fd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 159ffe3
Fix mutex for Free-tread pythons
wiredfool 91e2759
split pyarrow tests out from plain loopback arrow tests
wiredfool 05ae6e9
install pyarrow for those test platforms where it's available
wiredfool 9ff0465
merge from upstream/main
wiredfool dd18fac
fix yml
wiredfool b2210d1
mac/linux: install binary only pyarrow, and don't fail if there's no …
wiredfool a0927be
merge from main
wiredfool 9021829
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 038f62c
fix macos pyarrow test install
wiredfool 01998fc
Added docs
wiredfool 4ea8ac8
Fix the windows test matrix?
wiredfool e81b669
Lint
wiredfool 7ac90fa
PyCapsules aren't actually importable in python.
wiredfool 2418a23
Yaml
wiredfool a129efd
Workflow yaml
wiredfool afc16e5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] bba1b13
docs tweaks
wiredfool 19eb3e4
environment reference in test-windows.yml
wiredfool cba8e09
Fix pre-commit.ci lint.
wiredfool 7e59428
Take 4: not environment variables
wiredfool a8d819c
Mypy error -- can't have a bare tuple
wiredfool 7d498c3
Mypy error -- doesn't like the none return
wiredfool e4ad2c0
doc indent
wiredfool cb14672
le-sigh
wiredfool bafb968
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] cca80e2
make mypy happy
wiredfool ae187ca
Apply suggestions from code review
wiredfool 42d0682
re-add include item
wiredfool 48bbc64
Test Typing, consistency/style issues
wiredfool 088f80d
Fix mypy
wiredfool b729f64
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 3e28e05
Types and typos
hugovk 1678641
Apply suggestions from code review
hugovk e56e01c
Merge branch 'main' into arrow
radarhere File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from typing import Any # undone | ||
|
|
||
| import pytest | ||
|
|
||
| from PIL import Image | ||
|
|
||
| from .helper import ( | ||
| assert_deep_equal, | ||
| assert_image_equal, | ||
| hopper, | ||
| ) | ||
|
|
||
| pyarrow = pytest.importorskip("pyarrow", reason="PyArrow not installed") | ||
|
|
||
| TEST_IMAGE_SIZE = (10, 10) | ||
|
|
||
|
|
||
| def _test_img_equals_pyarray(img: Image.Image, arr: Any, mask) -> None: | ||
| assert img.height * img.width == len(arr) | ||
| px = img.load() | ||
| assert px is not None | ||
| for x in range(0, img.size[0], int(img.size[0] / 10)): | ||
| for y in range(0, img.size[1], int(img.size[1] / 10)): | ||
| if mask: | ||
| for ix, elt in enumerate(mask): | ||
| assert px[x, y][ix] == arr[y * img.width + x].as_py()[elt] | ||
| else: | ||
| assert_deep_equal(px[x, y], arr[y * img.width + x].as_py()) | ||
|
|
||
|
|
||
| # really hard to get a non-nullable list type | ||
| fl_uint8_4_type = pyarrow.field( | ||
| "_", pyarrow.list_(pyarrow.field("_", pyarrow.uint8()).with_nullable(False), 4) | ||
| ).type | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "mode, dtype, mask", | ||
| ( | ||
| ("L", pyarrow.uint8(), None), | ||
| ("I", pyarrow.int32(), None), | ||
| ("F", pyarrow.float32(), None), | ||
| ("LA", fl_uint8_4_type, [0, 3]), | ||
| ("RGB", fl_uint8_4_type, [0, 1, 2]), | ||
| ("RGBA", fl_uint8_4_type, None), | ||
| ("RGBX", fl_uint8_4_type, None), | ||
| ("CMYK", fl_uint8_4_type, None), | ||
| ("YCbCr", fl_uint8_4_type, [0, 1, 2]), | ||
| ("HSV", fl_uint8_4_type, [0, 1, 2]), | ||
| ), | ||
| ) | ||
| def test_to_array(mode: str, dtype: Any, mask: Any) -> None: | ||
| img = hopper(mode) | ||
|
|
||
| # Resize to non-square | ||
| img = img.crop((3, 0, 124, 127)) | ||
| assert img.size == (121, 127) | ||
|
|
||
| arr = pyarrow.array(img) | ||
| _test_img_equals_pyarray(img, arr, mask) | ||
| assert arr.type == dtype | ||
|
|
||
| reloaded = Image.fromarrow(arr, mode, img.size) | ||
|
|
||
| assert reloaded | ||
|
|
||
| assert_image_equal(img, reloaded) | ||
|
|
||
|
|
||
| def test_lifetime(): | ||
| # valgrind shouldn't error out here. | ||
| # arrays should be accessible after the image is deleted. | ||
|
|
||
| img = hopper("L") | ||
|
|
||
| arr_1 = pyarrow.array(img) | ||
| arr_2 = pyarrow.array(img) | ||
|
|
||
| del img | ||
|
|
||
| assert arr_1.sum().as_py() > 0 | ||
| del arr_1 | ||
|
|
||
| assert arr_2.sum().as_py() > 0 | ||
| del arr_2 | ||
|
|
||
|
|
||
| def test_lifetime2(): | ||
| # valgrind shouldn't error out here. | ||
| # img should remain after the arrays are collected. | ||
|
|
||
| img = hopper("L") | ||
|
|
||
| arr_1 = pyarrow.array(img) | ||
| arr_2 = pyarrow.array(img) | ||
|
|
||
| assert arr_1.sum().as_py() > 0 | ||
| del arr_1 | ||
|
|
||
| assert arr_2.sum().as_py() > 0 | ||
| del arr_2 | ||
|
|
||
| img2 = img.copy() | ||
| px = img2.load() | ||
| assert isinstance(px[0, 0], int) | ||
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
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.