-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Initial VTF support #6487
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
Open
REDxEYE
wants to merge
45
commits into
python-pillow:main
Choose a base branch
from
REDxEYE:vtf-support
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Initial VTF support #6487
Changes from all commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
df3c025
Initial VTF read support
REDxEYE 9223c06
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 59c2d19
Adjusted formatting regions
REDxEYE 719a3ba
Initial implementation of Bcn encoder
REDxEYE b883b64
Update copyright
REDxEYE 0d9ac2a
Update copyright
REDxEYE 43592dd
Add Bcn BC1 encoder
REDxEYE 8e11a61
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 1c3a1df
Add back accidentally removed static from decode_565
REDxEYE 1ce95d1
Fix variable type
REDxEYE affaa62
Made loops compatible with old C standart
REDxEYE a9364f3
Fix flake errors
REDxEYE 2cc5893
Restored black formatting
radarhere a05be82
Minor changes
radarhere c6c0749
Remove pointer casts as they may lead to UB and refactor code to not …
REDxEYE 7285b74
Add support for other common pixel formats
REDxEYE afc0e8e
Fix mipmap calculation
REDxEYE 59a4375
Refactor vtf saving
REDxEYE b7a5894
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] ed70519
Add better check for DXT1 with alpha
REDxEYE 3e78437
Add support for few more formats
REDxEYE f368f30
Add basic read tests for VTF
REDxEYE 53e1831
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 6b781a6
Add raw encoders/decoders for 2 channel RG format
REDxEYE 9ff852f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] a634a44
Add missing images
REDxEYE c3457f1
Add switch to DXT1 encoder to select block mode (With alpha/Without a…
REDxEYE 906890b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] a2729c0
Merge branch 'main' into vtf-support
radarhere d5e330e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] f73325f
mode is read-only
radarhere 0ed7d5c
Assign exception string to variable first
radarhere 1b567c5
Merge branch 'main' into vtf-support
radarhere 44d70b8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 72c3420
Merge branch 'main' into vtf-support
radarhere f41910c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 753964c
Fixed type hints
radarhere 1c7b3e4
Merge branch 'main' into vtf-support
radarhere e29c0a5
Removed support for saving DXT1_ONEBITALPHA
radarhere 64f992e
Corrected comment
radarhere 2ec01c9
Added type hints
radarhere 2f16077
Use ImageFile._Tile
radarhere f594d20
Removed unneeded converts
radarhere 1eb30cf
Update src/PIL/VtfImagePlugin.py
REDxEYE 487c7b2
Restored use of bytes
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
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,124 @@ | ||
from __future__ import annotations | ||
|
||
import pytest | ||
|
||
from PIL import Image | ||
from PIL.VtfImagePlugin import ( | ||
VtfPF, | ||
_closest_power, | ||
_get_mipmap_count, | ||
_get_texture_size, | ||
) | ||
|
||
from .helper import assert_image_equal, assert_image_similar | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"size, expected_size", | ||
[ | ||
(8, 8), | ||
(7, 8), | ||
(9, 8), | ||
(192, 256), | ||
(1, 1), | ||
(2000, 2048), | ||
], | ||
) | ||
def test_closest_power(size: int, expected_size: int) -> None: | ||
assert _closest_power(size) == expected_size | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"size, expected_count", | ||
[ | ||
((1, 1), 1), | ||
((2, 2), 2), | ||
((4, 4), 3), | ||
((8, 8), 4), | ||
((128, 128), 8), | ||
((256, 256), 9), | ||
((512, 512), 10), | ||
((1024, 1024), 11), | ||
((1024, 1), 11), | ||
], | ||
) | ||
def test_get_mipmap_count(size: tuple[int, int], expected_count: int) -> None: | ||
assert _get_mipmap_count(*size) == expected_count | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"pixel_format, size, expected_size", | ||
[ | ||
(VtfPF.DXT1, (16, 16), (16 * 16) // 2), | ||
(VtfPF.DXT1_ONEBITALPHA, (16, 16), (16 * 16) // 2), | ||
(VtfPF.DXT3, (16, 16), 16 * 16), | ||
(VtfPF.DXT5, (16, 16), 16 * 16), | ||
(VtfPF.BGR888, (16, 16), 16 * 16 * 3), | ||
(VtfPF.RGB888, (16, 16), 16 * 16 * 3), | ||
(VtfPF.RGBA8888, (16, 16), 16 * 16 * 4), | ||
(VtfPF.UV88, (16, 16), 16 * 16 * 2), | ||
(VtfPF.A8, (16, 16), 16 * 16), | ||
(VtfPF.I8, (16, 16), 16 * 16), | ||
(VtfPF.IA88, (16, 16), 16 * 16 * 2), | ||
], | ||
) | ||
def test_get_texture_size( | ||
pixel_format: VtfPF, size: tuple[int, int], expected_size: int | ||
) -> None: | ||
assert _get_texture_size(pixel_format, *size) == expected_size | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"etalon_path, file_path, expected_mode, epsilon", | ||
[ | ||
("Tests/images/vtf_i8.png", "Tests/images/vtf_i8.vtf", "L", 0.0), | ||
("Tests/images/vtf_a8.png", "Tests/images/vtf_a8.vtf", "RGBA", 0.0), | ||
("Tests/images/vtf_ia88.png", "Tests/images/vtf_ia88.vtf", "LA", 0.0), | ||
("Tests/images/vtf_uv88.png", "Tests/images/vtf_uv88.vtf", "RGB", 0.0), | ||
("Tests/images/vtf_rgb888.png", "Tests/images/vtf_rgb888.vtf", "RGB", 0.0), | ||
("Tests/images/vtf_bgr888.png", "Tests/images/vtf_bgr888.vtf", "RGB", 0.0), | ||
("Tests/images/vtf_dxt1.png", "Tests/images/vtf_dxt1.vtf", "RGBA", 3.0), | ||
("Tests/images/vtf_dxt1A.png", "Tests/images/vtf_dxt1A.vtf", "RGBA", 8.0), | ||
("Tests/images/vtf_rgba8888.png", "Tests/images/vtf_rgba8888.vtf", "RGBA", 0), | ||
], | ||
) | ||
def test_vtf_read( | ||
etalon_path: str, file_path: str, expected_mode: str, epsilon: float | ||
) -> None: | ||
with Image.open(file_path) as f: | ||
assert f.mode == expected_mode | ||
with Image.open(etalon_path) as e: | ||
converted_e = e.convert(expected_mode) | ||
if epsilon == 0: | ||
assert_image_equal(converted_e, f) | ||
else: | ||
assert_image_similar(converted_e, f, epsilon) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"pixel_format, file_path, expected_mode, epsilon", | ||
[ | ||
(VtfPF.I8, "Tests/images/vtf_i8.png", "L", 0.0), | ||
(VtfPF.A8, "Tests/images/vtf_a8.png", "RGBA", 0.0), | ||
(VtfPF.IA88, "Tests/images/vtf_ia88.png", "LA", 0.0), | ||
(VtfPF.UV88, "Tests/images/vtf_uv88.png", "RGB", 0.0), | ||
(VtfPF.RGB888, "Tests/images/vtf_rgb888.png", "RGB", 0.0), | ||
(VtfPF.BGR888, "Tests/images/vtf_bgr888.png", "RGB", 0.0), | ||
(VtfPF.DXT1, "Tests/images/vtf_dxt1.png", "RGBA", 3.0), | ||
(VtfPF.RGBA8888, "Tests/images/vtf_rgba8888.png", "RGBA", 0), | ||
], | ||
) | ||
def test_vtf_save( | ||
pixel_format: VtfPF, file_path: str, expected_mode: str, epsilon: float, tmp_path | ||
) -> None: | ||
f: Image.Image = Image.open(file_path) | ||
out = (tmp_path / "tmp.vtf").as_posix() | ||
f.save(out, pixel_format=pixel_format) | ||
if pixel_format == VtfPF.DXT1: | ||
f = f.convert("RGBA") | ||
e = Image.open(out) | ||
assert e.mode == expected_mode | ||
if epsilon == 0: | ||
assert_image_equal(e, f) | ||
else: | ||
assert_image_similar(e, f, epsilon) |
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does 'etalon' refer to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
supposed to be like reference image or something :)