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 bff6dcd (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.
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 bff6dcd (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.