use super::osc::simple_base64_encode;
use std::io::{self, Write};
#[derive(Clone, Debug, Default)]
pub struct ImageOptions {
pub x: Option<u32>,
pub y: Option<u32>,
pub z_index: i32,
pub placement_id: Option<u32>,
pub columns: Option<u32>,
pub rows: Option<u32>,
}
pub struct ImageProtocol;
impl ImageProtocol {
pub fn transmit_rgba<W: Write>(
writer: &mut W,
data: &[u8],
width: u32,
height: u32,
id: u32,
) -> io::Result<()> {
let encoded = simple_base64_encode(data);
let chunks = encoded.as_bytes().chunks(4096);
let total_chunks = chunks.len();
for (i, chunk) in chunks.enumerate() {
write!(writer, "\x1b_G")?;
if i == 0 {
write!(writer, "a=t,f=32,s={},v={},i={},q=2", width, height, id)?;
}
let more = if i < total_chunks - 1 { 1 } else { 0 };
write!(writer, ",m={};", more)?;
writer.write_all(chunk)?;
write!(writer, "\x1b\\")?;
}
Ok(())
}
pub fn put_image<W: Write>(writer: &mut W, id: u32, options: ImageOptions) -> io::Result<()> {
write!(writer, "\x1b_Ga=p,i={}", id)?;
write!(writer, ",z={}", options.z_index)?;
if let Some(pid) = options.placement_id {
write!(writer, ",p={}", pid)?;
}
if let Some(c) = options.columns {
write!(writer, ",c={}", c)?;
}
if let Some(r) = options.rows {
write!(writer, ",r={}", r)?;
}
if let Some(x) = options.x {
write!(writer, ",x={}", x)?;
}
if let Some(y) = options.y {
write!(writer, ",y={}", y)?;
}
write!(writer, "\x1b\\")
}
pub fn display_rgba<W: Write>(
writer: &mut W,
data: &[u8],
width: u32,
height: u32,
id: u32,
options: ImageOptions,
) -> io::Result<()> {
let encoded = simple_base64_encode(data);
let chunks = encoded.as_bytes().chunks(4096);
let total_chunks = chunks.len();
for (i, chunk) in chunks.enumerate() {
write!(writer, "\x1b_G")?;
if i == 0 {
write!(writer, "a=T,f=32,s={},v={},i={},q=2", width, height, id)?;
write!(writer, ",z={}", options.z_index)?;
if let Some(pid) = options.placement_id {
write!(writer, ",p={}", pid)?;
}
if let Some(x) = options.x {
write!(writer, ",x={}", x)?;
}
if let Some(y) = options.y {
write!(writer, ",y={}", y)?;
}
if let Some(c) = options.columns {
write!(writer, ",c={}", c)?;
}
if let Some(r) = options.rows {
write!(writer, ",r={}", r)?;
}
}
let more = if i < total_chunks - 1 { 1 } else { 0 };
write!(writer, ",m={};", more)?;
writer.write_all(chunk)?;
write!(writer, "\x1b\\")?;
}
Ok(())
}
pub fn delete_id<W: Write>(writer: &mut W, id: u32) -> io::Result<()> {
write!(writer, "\x1b_Ga=d,d=i,i={}\x1b\\", id)
}
pub fn delete_all<W: Write>(writer: &mut W) -> io::Result<()> {
write!(writer, "\x1b_Ga=d,d=a\x1b\\")
}
}