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

1.8 KiB
Raw Permalink Blame History

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