Files
CheapRetouch/specs/03-inpaint-engine.md
jared 1049057d7d Add Ralph Wiggum agent setup and project specifications
- Add project constitution with vision, principles, and autonomy settings
- Add 15 feature specifications covering full app scope
- Configure agent entry points (AGENTS.md, CLAUDE.md)
- Add build prompt and speckit command for spec creation
- Include comprehensive .gitignore for iOS development

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 23:19:41 -05:00

44 lines
1.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Inpainting Engine (Metal)
## Description
Implement exemplar-based inpainting (Criminisi-style) using Metal for content-aware fill of masked regions.
## Acceptance Criteria
- [ ] `InpaintEngine` class with public interface:
- `func inpaint(image: CGImage, mask: CGImage) async throws -> CGImage`
- `func inpaintPreview(image: CGImage, mask: CGImage) async throws -> CGImage`
- [ ] Metal shaders in `Shaders.metal` for:
- Mask dilation (2-4px configurable)
- Mask feathering (gaussian blur on alpha)
- Patch matching (find best match from known region)
- Patch copying (fill unknown region)
- Edge-aware blending (reduce seams)
- [ ] `PatchMatch.swift` implementing the algorithm:
- Build image pyramid for preview vs export
- Priority-based boundary pixel processing
- Best-matching patch search
- Boundary update after each patch copy
- [ ] Performance targets met:
- Preview (2048px): < 300ms on A14
- Export (12MP): < 4 seconds on A14
- Export (48MP): < 12 seconds on A17 Pro
- [ ] Memory management:
- Tile-based processing for images > 12MP
- Peak memory < 1.5GB
- Intermediate textures released aggressively
- [ ] Accelerate/vImage fallback when Metal unavailable
- [ ] Snapshot tests with reference images verifying output quality
## Technical Notes
- Criminisi algorithm paper: "Region Filling and Object Removal by Exemplar-Based Inpainting"
- Patch size typically 9x9 or 11x11 pixels
- Priority = confidence × data term (edge strength)
- Search region can be limited for performance
- Use MTLHeap for efficient texture allocation
## Edge Cases
- Metal unavailable: fall back to Accelerate with warning toast
- Memory pressure during export: throw error with "Image too large" message
- Very large mask (>50% of image): may produce poor results, warn user
- Mask touches image edge: handle boundary conditions in patch search