diff options
Diffstat (limited to 'vendor/image/src/codecs/pnm/mod.rs')
-rw-r--r-- | vendor/image/src/codecs/pnm/mod.rs | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/vendor/image/src/codecs/pnm/mod.rs b/vendor/image/src/codecs/pnm/mod.rs new file mode 100644 index 0000000..de8612d --- /dev/null +++ b/vendor/image/src/codecs/pnm/mod.rs @@ -0,0 +1,184 @@ +//! Decoding of netpbm image formats (pbm, pgm, ppm and pam). +//! +//! The formats pbm, pgm and ppm are fully supported. The pam decoder recognizes the tuple types +//! `BLACKANDWHITE`, `GRAYSCALE` and `RGB` and explicitly recognizes but rejects their `_ALPHA` +//! variants for now as alpha color types are unsupported. +use self::autobreak::AutoBreak; +pub use self::decoder::PnmDecoder; +pub use self::encoder::PnmEncoder; +use self::header::HeaderRecord; +pub use self::header::{ + ArbitraryHeader, ArbitraryTuplType, BitmapHeader, GraymapHeader, PixmapHeader, +}; +pub use self::header::{PnmHeader, PnmSubtype, SampleEncoding}; + +mod autobreak; +mod decoder; +mod encoder; +mod header; + +#[cfg(test)] +mod tests { + use super::*; + use crate::color::ColorType; + use crate::image::ImageDecoder; + use byteorder::{ByteOrder, NativeEndian}; + + fn execute_roundtrip_default(buffer: &[u8], width: u32, height: u32, color: ColorType) { + let mut encoded_buffer = Vec::new(); + + { + let mut encoder = PnmEncoder::new(&mut encoded_buffer); + encoder + .encode(buffer, width, height, color) + .expect("Failed to encode the image buffer"); + } + + let (header, loaded_color, loaded_image) = { + let decoder = PnmDecoder::new(&encoded_buffer[..]).unwrap(); + let color_type = decoder.color_type(); + let mut image = vec![0; decoder.total_bytes() as usize]; + decoder + .read_image(&mut image) + .expect("Failed to decode the image"); + let (_, header) = PnmDecoder::new(&encoded_buffer[..]).unwrap().into_inner(); + (header, color_type, image) + }; + + assert_eq!(header.width(), width); + assert_eq!(header.height(), height); + assert_eq!(loaded_color, color); + assert_eq!(loaded_image.as_slice(), buffer); + } + + fn execute_roundtrip_with_subtype( + buffer: &[u8], + width: u32, + height: u32, + color: ColorType, + subtype: PnmSubtype, + ) { + let mut encoded_buffer = Vec::new(); + + { + let mut encoder = PnmEncoder::new(&mut encoded_buffer).with_subtype(subtype); + encoder + .encode(buffer, width, height, color) + .expect("Failed to encode the image buffer"); + } + + let (header, loaded_color, loaded_image) = { + let decoder = PnmDecoder::new(&encoded_buffer[..]).unwrap(); + let color_type = decoder.color_type(); + let mut image = vec![0; decoder.total_bytes() as usize]; + decoder + .read_image(&mut image) + .expect("Failed to decode the image"); + let (_, header) = PnmDecoder::new(&encoded_buffer[..]).unwrap().into_inner(); + (header, color_type, image) + }; + + assert_eq!(header.width(), width); + assert_eq!(header.height(), height); + assert_eq!(header.subtype(), subtype); + assert_eq!(loaded_color, color); + assert_eq!(loaded_image.as_slice(), buffer); + } + + fn execute_roundtrip_u16(buffer: &[u16], width: u32, height: u32, color: ColorType) { + let mut encoded_buffer = Vec::new(); + + { + let mut encoder = PnmEncoder::new(&mut encoded_buffer); + encoder + .encode(buffer, width, height, color) + .expect("Failed to encode the image buffer"); + } + + let (header, loaded_color, loaded_image) = { + let decoder = PnmDecoder::new(&encoded_buffer[..]).unwrap(); + let color_type = decoder.color_type(); + let mut image = vec![0; decoder.total_bytes() as usize]; + decoder + .read_image(&mut image) + .expect("Failed to decode the image"); + let (_, header) = PnmDecoder::new(&encoded_buffer[..]).unwrap().into_inner(); + (header, color_type, image) + }; + + let mut buffer_u8 = vec![0; buffer.len() * 2]; + NativeEndian::write_u16_into(buffer, &mut buffer_u8[..]); + + assert_eq!(header.width(), width); + assert_eq!(header.height(), height); + assert_eq!(loaded_color, color); + assert_eq!(loaded_image, buffer_u8); + } + + #[test] + fn roundtrip_gray() { + #[rustfmt::skip] + let buf: [u8; 16] = [ + 0, 0, 0, 255, + 255, 255, 255, 255, + 255, 0, 255, 0, + 255, 0, 0, 0, + ]; + + execute_roundtrip_default(&buf, 4, 4, ColorType::L8); + execute_roundtrip_with_subtype(&buf, 4, 4, ColorType::L8, PnmSubtype::ArbitraryMap); + execute_roundtrip_with_subtype( + &buf, + 4, + 4, + ColorType::L8, + PnmSubtype::Graymap(SampleEncoding::Ascii), + ); + execute_roundtrip_with_subtype( + &buf, + 4, + 4, + ColorType::L8, + PnmSubtype::Graymap(SampleEncoding::Binary), + ); + } + + #[test] + fn roundtrip_rgb() { + #[rustfmt::skip] + let buf: [u8; 27] = [ + 0, 0, 0, + 0, 0, 255, + 0, 255, 0, + 0, 255, 255, + 255, 0, 0, + 255, 0, 255, + 255, 255, 0, + 255, 255, 255, + 255, 255, 255, + ]; + execute_roundtrip_default(&buf, 3, 3, ColorType::Rgb8); + execute_roundtrip_with_subtype(&buf, 3, 3, ColorType::Rgb8, PnmSubtype::ArbitraryMap); + execute_roundtrip_with_subtype( + &buf, + 3, + 3, + ColorType::Rgb8, + PnmSubtype::Pixmap(SampleEncoding::Binary), + ); + execute_roundtrip_with_subtype( + &buf, + 3, + 3, + ColorType::Rgb8, + PnmSubtype::Pixmap(SampleEncoding::Ascii), + ); + } + + #[test] + fn roundtrip_u16() { + let buf: [u16; 6] = [0, 1, 0xFFFF, 0x1234, 0x3412, 0xBEAF]; + + execute_roundtrip_u16(&buf, 6, 1, ColorType::L16); + } +} |