Rust decoder loses watermarks: decode-path resize uses non-antialiased ResizeAlg::Interpolation
- Dominant language
- JavaScript
- Stars
- 141
- Forks
- 34
- PR merge metrics
- No merged PRs in 30d
Description
Hi, I found that the TrustMark Python library was detecting watermarks that the Rust library was not, so I dug a bit deeper. My fix on my end is pinning the Rust library back to an earlier commit.
Worth noting the failure is silent: ECC returns 61 bits but flags them not-detected, so the CLI prints Corrupt or missing watermark and exits 0 — indistinguishable from an unwatermarked image.
**Root cause:** rust/src/image_processing.rs:69-73. fast_image_resize distinguishes ResizeAlg::Convolution (scaled support, antialiased) from ResizeAlg::Interpolation (documented as "like Convolution but with fixed kernel size" / "similar to OpenCV except INTER_AREA") a fixed 2x2 kernel means no antialiasing however large the ratio. The decoder uses the latter; PIL's Image.BILINEAR on the Python side is antialiased. Decoding a multi-megapixel image at 256x256 is a 4-7x downscale, so this drops most of the pixels. The same TryFrom conversion is used by encode (lib.rs:130, :141), so the residual is computed from an aliased downscale too, decode is where I looked.
**Regression:** 3b3aabe ("perf: switch from image-rs to fast_image_resize…") replaced .resize_exact(size, size, FilterType::Triangle), which is antialiased in image, so the change reads as unintended — a like-for-like swap of "bilinear" for "bilinear". Parent bff6dcdd (2025-04-15) uses the antialiased path. Only five commits have ever touched the file; 9234078 ("fix: integer truncation bug") is in remove_boundary_artifact, off the decode path.
Repro, without patching anything: take an image the binary reports as undetected and hand it the same content pre-resized to exactly 256x256 with an antialiased filter, so the internal resize becomes an identity op. The unmodified binary then detects it, while the full-size original still doesn't — same binary, same models, same pixels, only the resize does or doesn't do work. I couldn't build a patched CLI in my environment to confirm the fix directly.
Suggested fix: ResizeAlg::Convolution(FilterType::Bilinear) still SIMD-accelerated, so most of 3b3aabe's win is retained.
Contributor guide
Research direction
Start with rust/src/image_processing.rs:69-73 and inspect the TryFrom conversion referenced in lib.rs:130 and :141. Reproduce the issue by comparing a full-size image with the same content pre-resized to 256x256 using an antialiased filter, then verify that the decoder detects the watermark after the resize path is corrected and add a regression check if the project’s existing test structure supports it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- computer-vision
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100