use std::io::{Result, Write}; /// A 24-bit pixel represented by a red, green, and blue value. #[derive(Clone, Copy, Default, Debug)] pub struct Color { pub red: u8, pub green: u8, pub blue: u8, } impl Color { pub fn new(r: u8, g: u8, b: u8) -> Self { Color { red: r, green: g, blue: b, } } pub fn from_01_float(r: f64, g: f64, b: f64) -> Self { Color::new((r * 256.0) as u8, (g * 256.0) as u8, (b * 256.0) as u8) } } /// A representation of an image pub struct Image { /// Width in pixels pub(crate) width: usize, /// Height in pixels pub(crate) height: usize, /// Pixel data in row-major form. pub(crate) data: Vec, } impl Image { /// Write the image in PPM format to a file. pub fn write(&self, mut w: impl Write) -> Result<()> { // Header let header = format!("P3 {} {} 255\n", self.width, self.height); w.write_all(header.as_bytes())?; // Pixel data assert_eq!(self.data.len(), self.width * self.height); for pixel in self.data.iter() { let Color { red, green, blue } = pixel; let pixel = format!("{red} {green} {blue}\n"); w.write_all(pixel.as_bytes())?; } Ok(()) } }