fast image operations
Diffstat (limited to 'src/term/sixel.rs')
-rw-r--r--src/term/sixel.rs35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/term/sixel.rs b/src/term/sixel.rs
index 7091968..2304f51 100644
--- a/src/term/sixel.rs
+++ b/src/term/sixel.rs
@@ -40,6 +40,34 @@ impl<T: AsRef<[u8]>, const N: usize> Sixel<T, N> {
where
[(); N]: Basic,
{
+ #[cfg(unix)]
+ let q = {
+ extern crate libc;
+ // SAFETY: is stdout a tty
+ (unsafe { libc::isatty(0) } == 1)
+ };
+ #[cfg(not(unix))]
+ let q = true;
+ let colors = q
+ .then_some(super::query("[?1;1;0S").and_then(|x| {
+ // [?1;0;65536S
+ if let [b'?', b'1', b';', b'0', b';', n @ ..] = x.as_bytes() {
+ Some(
+ n.iter()
+ .copied()
+ .take_while(u8::is_ascii_digit)
+ .fold(0u16, |acc, x| {
+ acc.saturating_mul(10).saturating_add((x - b'0') as u16)
+ })
+ .max(64)
+ .min(0xfff),
+ )
+ } else {
+ None
+ }
+ }))
+ .flatten()
+ .unwrap_or(255);
to.write_str("Pq")?;
write!(to, r#""1;1;{};{}"#, self.width(), self.height())?;
let buf;
@@ -63,14 +91,15 @@ impl<T: AsRef<[u8]>, const N: usize> Sixel<T, N> {
&*buf
};
- let q = qwant::NeuQuant::new(15, 255, rgba);
+ let q = qwant::NeuQuant::new(15, colors as _, rgba);
+
// TODO: don't colllect
- let pixels: Vec<u8> = rgba.iter().map(|&pix| q.index_of(pix) as u8).collect();
+ let pixels: Vec<u16> = rgba.iter().map(|&pix| q.index_of(pix) as _).collect();
for ([r, g, b], i) in q
.color_map_rgb()
.map(|x| x.map(|x| (x as f32 * (100. / 255.)) as u32))
- .zip(0u8..)
+ .zip(0u64..)
{
write!(to, "#{i};2;{r};{g};{b}")?;
}