Skip to content

disable PIL DecompressionBombError for large rasters in predict_tile#1326

Merged
bw4sz merged 1 commit intoweecology:mainfrom
musaqlain:fix/1324-large-images-bombissue
Mar 12, 2026
Merged

disable PIL DecompressionBombError for large rasters in predict_tile#1326
bw4sz merged 1 commit intoweecology:mainfrom
musaqlain:fix/1324-large-images-bombissue

Conversation

@musaqlain
Copy link
Copy Markdown
Contributor

When processing large orthomosaics via predict_tile, DeepForest triggers a PIL.Image.DecompressionBombError (or warning). This occurs because Pillow hardcodes a safety limit of ~89.5 million pixels to prevent DoS attacks, which standard drone imagery effortlessly exceeds.

Technical Implementation

  • Added Image.MAX_IMAGE_PIXELS = None to the module initialization block in src/deepforest/main.py.

AI usage acknowledgement

@musaqlain
Copy link
Copy Markdown
Contributor Author

To ensure responsibility as a developer, I wrote a reproduction script to isolate and verify this issue before implementing a fix.

Here is the behavior I observed regarding Pillow's two-tiered safety mechanism:

  1. When setting dimensions to width = 10000, height = 9000 (90M pixels), I received a warning: DecompressionBombWarning.
  2. When increasing the area to width = 15000, height = 15000 (225M pixels), I successfully reproduced the hard crash reported in the issue: DecompressionBombError.
warning Screenshot 2026-02-26 192050

The Solution and Architectural Rationale
The proposed solution involves a single-line configuration change (Image.MAX_IMAGE_PIXELS = None) placed at the module level in src/deepforest/main.py.

Background Knowledge & Justification:
If DeepForest were used as a backend for a public-facing web API that accepted arbitrary image uploads, disabling this limit would expose the server to DoS attacks. However, DeepForest is primarily a scientific compute tool running on trusted data (researcher-provided geospatial rasters) on local machines or HPC clusters. Therefore, the risk of a malicious Decompression Bomb is statistically negligible compared to the absolute necessity of processing huge orthomosaics.

@musaqlain
Copy link
Copy Markdown
Contributor Author

can u trigger GitHub Actions CI workflows? cc @henrykironde

@vickysharma-prog
Copy link
Copy Markdown
Contributor

vickysharma-prog commented Feb 26, 2026

Nice work on the reproduction test!
One consideration: setting MAX_IMAGE_PIXELS = None at module level disables the check globally for all image operations. A scoped approach (applying it only within predict_tile) or a configurable flag might give users more control over the security trade-off.
Just a suggestion happy to help test whichever approach maintainers prefer.

@musaqlain
Copy link
Copy Markdown
Contributor Author

thank you @vickysharma-prog for you feedback. I went with the module-level override to preserve the current API. Since Image.open() is called deep within the SingleImage dataloader, plumbing a new flag through predict_tile or managing scope across PyTorch Lightning's distributed loaders adds significant boilerplate.
--Given DeepForest is mostly used in trusted, isolated environments (HPC/Notebooks) rather than public web APIs, this felt like an acceptable trade-off to keep the codebase clean. (I completely agree it's a trade-off...) with that being said, @henrykironde /, I defer to you—let me know if you’d prefer a scoped approach or config flag, and I’ll gladly update the PR. 🙌

@musaqlain
Copy link
Copy Markdown
Contributor Author

musaqlain commented Feb 27, 2026

Thanks again for the feedback, @vickysharma-prog! I want to elaborate on the architectural reasoning behind the module-level approach for the maintainers' consideration.

After evaluating a scoped approach (like a context manager or a per-function toggle), I found a few architectural realities that strongly reinforce the global module-level implementation:

  1. Existing Codebase Precedent: download.py already sets Image.MAX_IMAGE_PIXELS = None at the module level (line 22). Applying this change in main.py follows the established pattern, keeping the codebase consistent.
  2. The Blast Radius of Image.open(): This function is called across 7+ modules, not just within predict_tile. A scoped approach would require injecting boilerplate into:

Touching every call site introduces a massive maintenance burden.

  1. Zero-Config UX: Forcing users to toggle a security flag just to process standard 100M+ pixel orthomosaics degrades the API's out-of-the-box usability.
  2. Threat Model: Pillow protects web servers against malicious uploads,,, a threat model completely irrelevant to DeepForest executing trusted data in local/HPC environments.

Ultimately, this is a one-line, backward-compatible fix that aligns with the existing approach in download.py .

@henrykironde @bw4sz , I am happy to make any adjustments if you'd prefer a different direction!

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.97%. Comparing base (3146b96) to head (e8d21b4).
⚠️ Report is 38 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1326      +/-   ##
==========================================
- Coverage   87.89%   86.97%   -0.92%     
==========================================
  Files          20       24       +4     
  Lines        2776     3010     +234     
==========================================
+ Hits         2440     2618     +178     
- Misses        336      392      +56     
Flag Coverage Δ
unittests 86.97% <100.00%> (-0.92%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bw4sz bw4sz self-requested a review March 12, 2026 16:36
Copy link
Copy Markdown
Collaborator

@bw4sz bw4sz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bw4sz bw4sz merged commit 455c80f into weecology:main Mar 12, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PIL DecompressionBombError when processing large images

3 participants