pub const SIZE: usize = 600; pub type Point = (usize, usize); pub type Pixel = (u8, u8, u8, u8); // A bitmap is large enough that it will stack overflow. The Box isn't // strictly necessary if I can just be careful everywhere, but it's nice // to have. pub struct Bitmap { data: Box<[[Pixel; SIZE]; SIZE]>, } impl Bitmap { pub fn new() -> Bitmap { Bitmap { data: Box::new([[(0, 0, 0, 0); SIZE]; SIZE]), } } pub fn pixel_mut(&mut self, p: Point) -> &mut Pixel { let (x, y) = p; &mut self.data[x][y] } pub fn pixel(&self, p: Point) -> &Pixel { let (x, y) = p; &self.data[x][y] } pub fn to_data(&self) -> Vec { let mut writer = Writer::new(); let row_padding = (4 - (3 * SIZE) % 4) % 4; let pix_size: u32 = (SIZE * (3 * SIZE + row_padding)) as u32; writer.output_u16(0x4d42); // BM writer.output_u32(0x36 + pix_size); // Size writer.output_u16(0x0); // Reserved writer.output_u16(0x0); // Reserved writer.output_u32(0x36); // Offset of pixel array writer.output_u32(0x28); // Length of DIB header writer.output_u32(SIZE as u32); // Width writer.output_u32(SIZE as u32); // Height writer.output_u16(0x1); // Color planes writer.output_u16(0x18); // Bits per pixel writer.output_u32(0x0); // No pixel array compression writer.output_u32(pix_size); // Pixel data size writer.output_u32(0x0); // Horizontal resolution writer.output_u32(0x0); // Vertical resolution writer.output_u32(0x0); // Colors in the palette writer.output_u32(0x0); // All colors are important for y in (0..SIZE).rev() { for x in 0..SIZE { let (r, g, b, _) = self.data[x][y]; writer.output_u8(b); writer.output_u8(g); writer.output_u8(r); } for _ in 0..row_padding { writer.output_u8(0); } } return writer.output(); } } struct Writer { output: Vec, } impl Writer { fn new() -> Writer { Writer { output: Vec::new() } } fn output_u8(&mut self, n: u8) { self.output.push(n); } fn output_u16(&mut self, n: u16) { self.output.push(n as u8); self.output.push((n >> 8) as u8); } fn output_u32(&mut self, n: u32) { self.output.push(n as u8); self.output.push((n >> 8) as u8); self.output.push((n >> 16) as u8); self.output.push((n >> 24) as u8); } fn output(self) -> Vec { self.output } }