| """ |
| Unified runner for classic digital forensics tools. |
| Wraps ELA, Spatial Gradient, Bit Plane, MinMax Deviation, and Wavelet Noise. |
| """ |
|
|
| import time |
| import numpy as np |
| from PIL import Image |
| from .ela import ELA |
| from .gradient import gradient_processing |
| from .bitplane import bit_plane_extractor |
| from .minmax import minmax_process |
| from .wavelet import noise_estimation |
| from xai_engine.viz import to_b64_png |
|
|
|
|
| def run_forensic_tool( |
| image: Image.Image, |
| tool_name: str, |
| quality: int = 75, |
| scale: int = 50, |
| contrast: int = 20, |
| gradient_intensity: int = 90, |
| blue_mode: str = "Abs", |
| channel: str = "Luminance", |
| bit: int = 0, |
| minmax_radius: int = 2, |
| ) -> dict: |
| """ |
| Execute selected forensic tool on input image. |
| |
| Returns dict: { |
| "tool": str, |
| "result_b64": str, |
| "info": str, |
| "compute_time_ms": float |
| } |
| """ |
| t0 = time.perf_counter() |
| img_np = np.array(image.convert("RGB")) |
| info_text = "" |
|
|
| if tool_name == "ela": |
| name = "Error Level Analysis (ELA)" |
| res_img = ELA(img_np, quality=quality, scale=scale, contrast=contrast) |
| info_text = f"JPEG Compression Quality: {quality}%, Scale: {scale}, Contrast: {contrast}%" |
|
|
| elif tool_name == "gradient": |
| name = "Spatial Gradient Analysis" |
| res_img = gradient_processing(image, intensity=gradient_intensity, blue_mode=blue_mode) |
| info_text = f"Gradient Intensity: {gradient_intensity}%, Blue Mode: {blue_mode}" |
|
|
| elif tool_name == "bitplane": |
| name = "Bit Plane Extractor" |
| res_img = bit_plane_extractor(image, channel=channel, bit=bit) |
| info_text = f"Channel: {channel}, Bit Plane: {bit} (0=LSB, 7=MSB)" |
|
|
| elif tool_name == "minmax": |
| name = "MinMax Local Deviation" |
| res_img = minmax_process(img_np, channel=4, radius=minmax_radius) |
| info_text = f"Local Block Radius: {minmax_radius} px" |
|
|
| elif tool_name == "wavelet": |
| name = "Wavelet Noise Estimation" |
| noise_var = noise_estimation(img_np) |
| info_text = f"Estimated High-Frequency Noise Variance: {noise_var:.4f}" |
| res_img = image.convert("RGB") |
|
|
| else: |
| raise ValueError(f"Unknown forensic tool: {tool_name}") |
|
|
| elapsed_ms = (time.perf_counter() - t0) * 1000 |
|
|
| return { |
| "tool": name, |
| "result_b64": to_b64_png(res_img), |
| "info": info_text, |
| "compute_time_ms": round(elapsed_ms, 1), |
| } |
|
|