diff --git a/src/cli/defines.rs b/src/cli/defines.rs index 4d07f20..6e2213a 100644 --- a/src/cli/defines.rs +++ b/src/cli/defines.rs @@ -7,6 +7,7 @@ use pigment64::{ImageSize, ImageType}; pub enum BinaryFormat { Ci4, Ci8, + I1, I4, I8, Ia4, @@ -22,6 +23,7 @@ impl BinaryFormat { match self { BinaryFormat::Ci4 => CArrayWidth::U8, BinaryFormat::Ci8 => CArrayWidth::U8, + BinaryFormat::I1 => CArrayWidth::U8, BinaryFormat::I4 => CArrayWidth::U8, BinaryFormat::I8 => CArrayWidth::U8, BinaryFormat::Ia4 => CArrayWidth::U8, @@ -37,6 +39,7 @@ impl BinaryFormat { match self { BinaryFormat::Ci4 => ImageType::Ci4, BinaryFormat::Ci8 => ImageType::Ci8, + BinaryFormat::I1 => ImageType::I1, BinaryFormat::I4 => ImageType::I4, BinaryFormat::I8 => ImageType::I8, BinaryFormat::Ia4 => ImageType::Ia4, @@ -52,6 +55,7 @@ impl BinaryFormat { match self { BinaryFormat::Ci4 => Bits4, BinaryFormat::Ci8 => ImageSize::Bits8, + BinaryFormat::I1 => ImageSize::Bits1, BinaryFormat::I4 => ImageSize::Bits4, BinaryFormat::I8 => ImageSize::Bits8, BinaryFormat::Ia4 => ImageSize::Bits4, diff --git a/src/image/native_image.rs b/src/image/native_image.rs index ae16342..3abd741 100644 --- a/src/image/native_image.rs +++ b/src/image/native_image.rs @@ -34,6 +34,19 @@ impl NativeImage { let mut cursor = Cursor::new(&self.data); match self.format { + ImageType::I1 => { + for _y in 0..self.height { + for _x in (0..self.width).step_by(8) { + let byte = cursor.read_u8()?; + + for i in 0..8 { + let mask = 0b00000001 << (7 - i); + let intensity = if byte & mask == 0 { 0 } else { 255 }; + writer.write_all(&[intensity, intensity, intensity, 0xFF])?; + } + } + } + } ImageType::I4 => { for _y in 0..self.height { for _x in (0..self.width).step_by(2) { @@ -149,19 +162,12 @@ impl NativeImage { let mut encoder = png::Encoder::new(writer, self.width, self.height); match self.format { - ImageType::I4 => { - self.decode(&mut data, None)?; - } - ImageType::I8 => { - self.decode(&mut data, None)?; - } - ImageType::Ia4 => { - self.decode(&mut data, None)?; - } - ImageType::Ia8 => { - self.decode(&mut data, None)?; - } - ImageType::Ia16 => { + ImageType::I1 + | ImageType::I4 + | ImageType::I8 + | ImageType::Ia4 + | ImageType::Ia8 + | ImageType::Ia16 => { self.decode(&mut data, None)?; } ImageType::Ci4 => { diff --git a/src/image/png_image.rs b/src/image/png_image.rs index 7eab89e..e049899 100644 --- a/src/image/png_image.rs +++ b/src/image/png_image.rs @@ -107,6 +107,7 @@ impl PNGImage { pub fn as_native(&self, writer: &mut W, image_type: ImageType) -> Result<()> { match image_type { + ImageType::I1 => self.as_i1(writer), ImageType::I4 => self.as_i4(writer), ImageType::I8 => self.as_i8(writer), ImageType::Ia4 => self.as_ia4(writer), @@ -142,6 +143,25 @@ impl PNGImage { Ok(()) } + pub fn as_i1(&self, writer: &mut W) -> Result<()> { + if let (ColorType::Grayscale, BitDepth::One) = (self.color_type, self.bit_depth) { + writer.write_all(&self.data).map_err(Into::into) + } else { + let mut i8_data = vec![0; self.data.len() * 8]; + self.as_i8(&mut i8_data.as_mut_slice())?; + + for chunk in i8_data.chunks_exact(8) { + let mut byte = 0; + for (i, pixel) in chunk.iter().copied().enumerate() { + byte |= ((pixel > 127) as u8) << (7 - i); + } + writer.write_u8(byte)?; + } + + Ok(()) + } + } + pub fn as_i4(&self, writer: &mut W) -> Result<()> { match (self.color_type, self.bit_depth) { (ColorType::Grayscale, BitDepth::Four) => writer.write_all(&self.data)?, diff --git a/src/lib.rs b/src/lib.rs index c79d290..2a80896 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,12 +16,14 @@ pub enum ImageSize { Bits8 = 1, Bits16 = 2, Bits32 = 3, + Bits1 = 4, DD = 5, } impl ImageSize { pub fn get_tlut_size(&self) -> usize { match self { + ImageSize::Bits1 => 0b10, ImageSize::Bits4 => 0x10, ImageSize::Bits8 => 0x100, ImageSize::Bits16 => 0x1000, @@ -44,6 +46,7 @@ pub enum ImageFormat { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TryFromPrimitive)] #[repr(u8)] pub enum ImageType { + I1, I4, I8, Ia4, @@ -60,6 +63,7 @@ impl ImageType { match self { ImageType::Ci4 => ImageSize::Bits4, ImageType::Ci8 => ImageSize::Bits8, + ImageType::I1 => ImageSize::Bits1, ImageType::I4 => ImageSize::Bits4, ImageType::I8 => ImageSize::Bits8, ImageType::Ia4 => ImageSize::Bits4, @@ -74,6 +78,7 @@ impl ImageType { match self { ImageType::Ci4 => ImageFormat::Ci, ImageType::Ci8 => ImageFormat::Ci, + ImageType::I1 => ImageFormat::I, ImageType::I4 => ImageFormat::I, ImageType::I8 => ImageFormat::I, ImageType::Ia4 => ImageFormat::Ia,