Fix ICO save producing an empty file for images smaller than 16x16#9745
Open
gaoflow wants to merge 1 commit into
Open
Fix ICO save producing an empty file for images smaller than 16x16#9745gaoflow wants to merge 1 commit into
gaoflow wants to merge 1 commit into
Conversation
Saving an image smaller than the smallest default size (16x16) as ICO, without an explicit sizes argument, wrote a header-only 6-byte file with zero icon entries. Reopening it raised UnidentifiedImageError and the image was lost silently. The default sizes start at 16x16 and the save loop skips every candidate larger than the source image, so for a sub-16 image all candidates are skipped and no frame is written. Filter the requested sizes up front and, if none fit, fall back to the image's own size (capped at the 256x256 ICO maximum) so a valid, readable icon is always written. This also covers the case where every explicitly requested size is larger than the image.
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.
Saving an image smaller than the smallest default ICO size (16×16) as ICO, without an explicit
sizesargument, silently produces an empty, unreadable file:The 8×8 image is representable as an ICO (
save(buf, "ICO", sizes=[(8, 8)])works fine), but the default-sizespath drops it entirely with no error or warning.Cause
The default
sizesstart at(16, 16), and_saveskips every candidate size larger than the source image. For an image smaller than 16×16 every default candidate is skipped, soframesstays empty ando16(len(frames))writesidCount=0— a 6-byte header-only file.Fix
Filter the requested sizes up front, and if none fit, fall back to the image's own size (capped at the 256×256 ICO maximum) so a valid, readable icon is always written. This also fixes the related case where every explicitly requested size is larger than the image (previously also an empty file) — consistent with the documented behaviour that oversized requested sizes are ignored.
Tests
test_save_smaller_than_default_sizesparametrizes(1, 1),(8, 8),(15, 15)and the non-square(8, 12), asserting each round-trips to a valid ICO of the right size withinfo["sizes"]and a corner pixel preserved.test_save_all_sizes_larger_than_imagepins the explicit-sizesfallback. All fail onmainwithUnidentifiedImageErrorand pass with the fix; the fullTests/test_file_ico.pysuite stays green (27 passed);ruff format,ruff checkandmypyare clean.