1mod sixel_serializer;
27mod sixel_deserializer;
28
29pub use sixel_serializer::SixelSerializer;
30pub use sixel_deserializer::SixelDeserializer;
31
32use std::fmt;
33use std::collections::BTreeMap;
34use sixel_tokenizer::{ColorCoordinateSystem, Parser};
35
36#[derive(Debug, Clone)]
37pub struct SixelImage {
38 color_registers: BTreeMap<u16, SixelColor>,
39 pixels: Vec<Vec<Pixel>>,
40}
41
42impl SixelImage {
43 pub fn new(bytes: &[u8]) -> Result<Self, &'static str> {
45 let mut parser = Parser::new();
46 let mut sixel_deserializer = SixelDeserializer::new();
47 for byte in bytes {
48 let mut handle_result = Ok(());
49 parser.advance(&byte, |sixel_event| {
50 handle_result = sixel_deserializer.handle_event(sixel_event);
51 });
52 handle_result?
53 }
54 let sixel_image = sixel_deserializer.create_image();
55 sixel_image
56 }
57 pub fn pixel_size(&self) -> (usize, usize) { let width = self.pixels.first().map(|first_line| first_line.len()).unwrap_or(0);
60 let height = self.pixels.len();
61 (height, width)
62 }
63 pub fn serialize(&self) -> String {
65 let sixel_serializer = SixelSerializer::new(&self.color_registers, &self.pixels);
66 let serialized_image = sixel_serializer.serialize();
67 serialized_image
68 }
69 pub fn serialize_range(&self, start_x_index: usize, start_y_index: usize, width: usize, height: usize) -> String {
72 let sixel_serializer = SixelSerializer::new(&self.color_registers, &self.pixels);
73 let serialized_image = sixel_serializer.serialize_range(start_x_index, start_y_index, width, height);
74 serialized_image
75 }
76 pub fn cut_out(&mut self, start_x_index: usize, start_y_index: usize, width: usize, height: usize) {
80 for row in self.pixels.iter_mut().skip(start_y_index).take(height) {
81 for pixel in row.iter_mut().skip(start_x_index).take(width) {
82 pixel.on = false;
83 }
84 }
85 }
86}
87
88#[derive(Clone, Copy)]
89pub struct Pixel {
90 on: bool,
91 color: u16,
92}
93
94impl fmt::Debug for Pixel {
95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96 if self.on {
97 write!(f, "{}", self.color)
98 } else {
99 write!(f, "x")
100 }
101 }
102}
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
105pub enum SixelColor {
106 Rgb(u8, u8, u8), Hsl(u16, u8, u8), }
109
110impl From<ColorCoordinateSystem> for SixelColor {
111 fn from(item: ColorCoordinateSystem) -> Self {
112 match item {
113 ColorCoordinateSystem::HLS(x, y, z) => SixelColor::Hsl(x as u16, y as u8, z as u8),
114 ColorCoordinateSystem::RGB(x, y, z) => SixelColor::Rgb(x as u8, y as u8, z as u8),
115 }
116 }
117}
118
119#[cfg(test)]
120mod tests;