From 33bd401e2a52891d77723e692bfe09f1d145dbd4 Mon Sep 17 00:00:00 2001 From: Victor Kuznetsov Date: Sun, 31 May 2026 14:00:52 -0700 Subject: [PATCH] fix(visible): guard remove_watermark_reverse_alpha on tiny images too The previous commit guarded extract_mask, but the 2048x1 crash was actually in _fixed_alpha_map's cv2.resize to a ~1-px-tall target (Windows: "Unknown C++ exception" / access violation). Return image.copy() up front when h < 32 or w < 64 (no real watermarked image is that small), before any cv2 call. Same guard in both Doubao and Jimeng. Co-Authored-By: Claude Opus 4.8 --- src/remove_ai_watermarks/doubao_engine.py | 7 +++++++ src/remove_ai_watermarks/jimeng_engine.py | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/remove_ai_watermarks/doubao_engine.py b/src/remove_ai_watermarks/doubao_engine.py index fb67b83..b79b0ea 100644 --- a/src/remove_ai_watermarks/doubao_engine.py +++ b/src/remove_ai_watermarks/doubao_engine.py @@ -383,6 +383,13 @@ class DoubaoEngine: image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) elif image.shape[2] == 4: image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR) + # An image too small to hold the mark would make the geometry boxes + # degenerate and feed cv2.resize a ~1-px-tall target / GaussianBlur a sliver + # ROI, which faults natively on Windows (access violation / "Unknown C++ + # exception"). No real watermarked image is this small; skip cv2 entirely. + h, w = image.shape[:2] + if h < 32 or w < 64: + return image.copy() maps = [c for c in (self._fixed_alpha_map(image), self._aligned_alpha_map(image)) if c is not None] if not maps: return image.copy() diff --git a/src/remove_ai_watermarks/jimeng_engine.py b/src/remove_ai_watermarks/jimeng_engine.py index 0f69478..871f580 100644 --- a/src/remove_ai_watermarks/jimeng_engine.py +++ b/src/remove_ai_watermarks/jimeng_engine.py @@ -371,6 +371,13 @@ class JimengEngine: image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) elif image.shape[2] == 4: image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR) + # An image too small to hold the mark would make the geometry boxes + # degenerate and feed cv2.resize a ~1-px-tall target / GaussianBlur a sliver + # ROI, which faults natively on Windows (access violation / "Unknown C++ + # exception"). No real watermarked image is this small; skip cv2 entirely. + h, w = image.shape[:2] + if h < 32 or w < 64: + return image.copy() # Always try fixed geometry AND the NCC-aligned placement and keep # whichever leaves the least residual mark (re-detect confidence on the # bare reverse-alpha). Unlike Doubao's deterministic overlay, Jimeng jitters