feat(tui): image rendering — sixel backend via img2sixel #57

Merged
charles merged 1 commit from tui/sixel-13 into main 2026-04-11 20:42:10 +00:00
Owner

Summary

Third of four image backends. Shells out to img2sixel (from libsixel) rather than taking a Rust build-time sixel dep. Stacks on #56. Closes charles/loom#13.

What's in

  • image::sixel::SixelRenderer implementing ImageRenderer
  • SixelRenderer::detect() returns Err(SixelNotFound) when img2sixel isn't on $PATH
  • Clamps output to rect.width * 10 × rect.height * 20 pixels (default monospace cell ratio); caches payloads under the same (source, w, h) key semantics as Kitty
  • Cursor-position then bytes-dump onto stdout

Tests (2 new, 55 total)

  • detect() returns Err when $PATH is cleared
  • Cache keyed on size: different cell dimensions store different entries

Notes

  • The crate deliberately does not take a cargo dep on sixel/libsixel-sys — keeps build portable and avoids C headers. Terminals that speak sixel invariably have libsixel's img2sixel command available
  • chafa::which_bin_public exposes the $PATH walker so this module and future detect code don't duplicate the traversal
## Summary Third of four image backends. Shells out to `img2sixel` (from libsixel) rather than taking a Rust build-time sixel dep. Stacks on #56. Closes charles/loom#13. ## What's in - **`image::sixel::SixelRenderer`** implementing `ImageRenderer` - **`SixelRenderer::detect()`** returns `Err(SixelNotFound)` when `img2sixel` isn't on `$PATH` - Clamps output to `rect.width * 10 × rect.height * 20` pixels (default monospace cell ratio); caches payloads under the same `(source, w, h)` key semantics as Kitty - Cursor-position then bytes-dump onto stdout ## Tests (2 new, 55 total) - `detect()` returns `Err` when `$PATH` is cleared - Cache keyed on size: different cell dimensions store different entries ## Notes - The crate deliberately does not take a cargo dep on `sixel`/`libsixel-sys` — keeps build portable and avoids C headers. Terminals that speak sixel invariably have libsixel's `img2sixel` command available - `chafa::which_bin_public` exposes the `$PATH` walker so this module and future detect code don't duplicate the traversal
Shells out to img2sixel (libsixel) rather than taking a build-time
dependency on a Rust sixel crate, keeping the core binary lean and
avoiding C header requirements. Clamps output to cell dimensions
using a default 10×20 pixel-per-cell ratio and caches the encoded
payload under the same (source, w, h) key semantics as the Kitty
backend.

Shares the which_bin $PATH lookup with the chafa backend via a
public alias so the detect() flows stay symmetric.

Closes charles/loom#13

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
charles changed target branch from tui/chafa-14 to main 2026-04-11 20:42:09 +00:00
charles deleted branch tui/sixel-13 2026-04-11 20:42:11 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/loom!57
No description provided.