"""Utility functions for SpaceDebris Localizer.""" from __future__ import annotations import logging from typing import Any from PIL import Image logger = logging.getLogger(__name__) def validate_image(image: Any) -> tuple[bool, str]: """Validate that an input is a usable PIL image. Returns: Tuple of (is_valid, error_message). """ if image is None: return False, "No image provided. Please upload an image." if not isinstance(image, Image.Image): return False, "Invalid image format. Please upload a valid image file." if image.mode not in ("RGB", "RGBA", "L"): return False, f"Unsupported image mode: {image.mode}. Use RGB or grayscale." w, h = image.size if w < 32 or h < 32: return False, f"Image too small ({w}x{h}). Minimum 32x32 pixels." if w > 8192 or h > 8192: return False, f"Image too large ({w}x{h}). Maximum 8192x8192 pixels." return True, "" def ensure_rgb(image: Image.Image) -> Image.Image: """Convert image to RGB if needed.""" if image.mode == "RGBA": background = Image.new("RGB", image.size, (0, 0, 0)) background.paste(image, mask=image.split()[3]) return background if image.mode == "L": return image.convert("RGB") if image.mode != "RGB": return image.convert("RGB") return image def format_metadata(parse_result: Any) -> str: """Format parse result metadata as human-readable text.""" lines = [ f"Detected objects: {parse_result.num_detections}", f"Raw output length: {len(parse_result.raw_output)} chars", ] if parse_result.parse_errors: lines.append(f"Parse warnings: {len(parse_result.parse_errors)}") for err in parse_result.parse_errors[:5]: lines.append(f" - {err}") return "\n".join(lines) def format_json_output(parse_result: Any) -> dict[str, Any]: """Return JSON-serializable dict from parse result.""" return parse_result.to_dict()