Skip to content

fix(app): report the decode allocation limit instead of "Allowed formats" - #2417

Open
Sanjays2402 wants to merge 2 commits into
wkentaro:mainfrom
Sanjays2402:fix/image-too-large-error-message
Open

fix(app): report the decode allocation limit instead of "Allowed formats"#2417
Sanjays2402 wants to merge 2 commits into
wkentaro:mainfrom
Sanjays2402:fix/image-too-large-error-message

Conversation

@Sanjays2402

Copy link
Copy Markdown

Closes #2388

A supported image whose decode exceeds QImageReader.allocationLimit() (256 MB by default) makes QImage.fromData() return a null image, which fell through to the generic "Allowed formats" dialog and wrongly implied the file format was unsupported.

_image_too_large_message() re-reads the header with QImageReader (no decode) to get the pixel dimensions, compares the required allocation against the limit, and returns a message naming both. The generic message is still used when the data is unreadable or fits within the limit.

…ats"

When a supported image decodes to more than QImageReader's allocation
limit (256 MB by default), QImage.fromData returns a null image and the
image-load path fell through to the generic "Allowed formats" dialog,
which wrongly implies the file format is unsupported.

Add _image_too_large_message(), which re-reads the header with
QImageReader to get the pixel dimensions without decoding, compares the
required allocation against QImageReader.allocationLimit(), and returns
a message naming the dimensions and the limit. The generic
unsupported-format message is still used when the data is not readable
at all or fits within the limit.

Adds regression tests covering the over-limit, undecodable, and
within-limit cases.

Closes wkentaro#2388
@github-actions

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@wkentaro

Copy link
Copy Markdown
Owner

This was generated by AI during PR processing.

Thanks for taking this on. I ran a two-axis review (repo standards + fidelity to #2388) plus the test suite and lint locally. The core approach is right, and I verified the mechanism actually works for the reported case. A few things to address before this can be recommended for merge.

Verified working

I traced the concern that would have sunk this: read_image_file() re-encodes to PNG/JPEG in memory before _app ever sees the bytes, so I checked whether QImageReader(buffer).size() on the re-encoded blob still reports the true dimensions. It does. Reproduced with a 20000x20000 RGBA PNG under a lowered allocation limit: QImage.fromData() returns null while QImageReader(...).size() reports (20000, 20000), because PNG/JPEG headers carry the dimensions and Qt's size probe does not allocate the decode buffer. For the reported 37296x49319 GeoTIFF the new function fires and reports accurate numbers (~7016 MB against a 256 MB limit).

Locally: 739 passed on tests/unit, ruff check and ruff format --check both clean.

Blocking

1. The CLA is unsigned. The cla check is the only red one, and it is the reason the test workflow has not run. Please post the comment the bot asked for:

I have read the CLA Document and I hereby sign the CLA

2. No CHANGELOG entry. Per CLAUDE.md, user-facing changes go in CHANGELOG.md under ## [Unreleased] in the right subsection with the PR number linked. This changes a user-facing error dialog, so it needs a ### Fixed entry ending with ([#2417](https://github.com/wkentaro/labelme/pull/2417)).

Spec gap worth closing

3. The ~32767 px per-side raster limit is unhandled. #2388 explicitly calls this out:

Raising the limit is not a fix: a 7.4 GB QImage is not usable, and the Qt raster engine has a ~32767 px per-side limit while this image is 37296 px wide.

_image_too_large_message() only compares width * height * 4 against allocationLimit(). An image with one side over ~32767 px whose allocation math still fits under the limit produces a null QImage, required_mb <= limit_mb returns None, and the user lands back on the misleading "Allowed formats" message. That is the exact failure this PR exists to fix, just via the other door. It also means the current message can quote an MB limit that, if raised, would still not let the image open, which is the false hope #2388 warns against.

Suggest adding a per-side check alongside the allocation check, with a message that names whichever ceiling was actually hit.

4. The message drops gdal_retile.py. #2388 asked for it by name:

The error message should state that the image is too large, show the image dimensions and the limit, and suggest tiles (gdal_retile.py) or a smaller copy.

The current text says "split the image into tiles" without naming a tool. Naming it is the difference between advice and an actionable next step.

Minor

5. Redundant local annotations. limit_mb: int = ...allocationLimit() and required_mb: float = ... / 1024 / 1024 are both fully inferable. The repo convention is to annotate signatures, not locals.

6. The docstring's first line restates the function name. Sibling module-level functions in _app.py (_format_window_title, _resolve_label_path, _shape_to_dict) carry none. The second sentence explaining why None means "fall back to the generic message" is genuinely useful; the first is not.

Not an issue: QtCore.QCoreApplication.translate("MainWindow", ...) is the correct call here. self.tr() is unavailable in a module-level function, and MainWindow.tr() resolves to the same "MainWindow" context, so the translation context is preserved exactly.

Follow-up filed, not blocking this PR: #2418 covers the ~36s / ~7.4 GB eager decode-and-re-encode in read_image_file() that happens before this error path is ever reached.

@wkentaro wkentaro added the needs-info issue/pr: Waiting on reporter for more information label Jul 25, 2026
The too-large message only compared width*height*4 against the decode
allocation limit, so an image whose one side exceeds the raster engine
limit but whose allocation math fits fell back to the misleading
"Allowed formats" text. Check the per-side ceiling first and say which
limit was hit, since raising the allocation limit cannot lift it.

Also name gdal_retile.py in both messages, drop the inferable local
annotations and the docstring line that restated the function name, and
add the CHANGELOG entry.
@Sanjays2402

Copy link
Copy Markdown
Author

Pushed 1dc918a covering points 2-6.

The per-side gap was real and you're right that it's the same failure through the other door. _image_too_large_message now checks max(width, height) > 32767 before the allocation math and returns a message that says the raster engine's per-side limit was hit and that raising the decode limit won't help, so it can't quote an MB number that would be false hope. The allocation branch is unchanged apart from wording. Both messages now name gdal_retile.py. Added a test that stubs QImageReader to report 37296x49319 (the dimensions from #2388) and asserts the per-side message, since materializing an image that size isn't practical in the suite.

Also: CHANGELOG entry under ## [Unreleased] / ### Fixed with the PR link, dropped the limit_mb: int / required_mb: float locals, and cut the first docstring line.

tests/unit is 740 passed, ruff check and ruff format --check clean on both touched files.

On the CLA: that's tied to my identity as a legal agreement, so I'd rather sign it deliberately than have it happen as part of an automated pass. I'll post the signature comment myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-info issue/pr: Waiting on reporter for more information

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Misleading "Allowed formats" error when the decoded image exceeds Qt's allocation limit

2 participants