ICFP 2007 Contest: https://web.archive.org/web/20090301164728/https://save-endo.cs.uu.nl/
1pub const SIZE: usize = 600;
2
3pub type Point = (usize, usize);
4pub type Pixel = (u8, u8, u8, u8);
5// A bitmap is large enough that it will stack overflow. The Box isn't
6// strictly necessary if I can just be careful everywhere, but it's nice
7// to have.
8pub struct Bitmap {
9 data: Box<[[Pixel; SIZE]; SIZE]>,
10}
11
12impl Bitmap {
13 pub fn new() -> Bitmap {
14 Bitmap {
15 data: Box::new([[(0, 0, 0, 0); SIZE]; SIZE]),
16 }
17 }
18
19 pub fn pixel_mut(&mut self, p: Point) -> &mut Pixel {
20 let (x, y) = p;
21 &mut self.data[x][y]
22 }
23
24 pub fn pixel(&self, p: Point) -> &Pixel {
25 let (x, y) = p;
26 &self.data[x][y]
27 }
28
29 pub fn to_data(&self) -> Vec<u8> {
30 let mut writer = Writer::new();
31 let row_padding = (4 - (3 * SIZE) % 4) % 4;
32 let pix_size: u32 = (SIZE * (3 * SIZE + row_padding)) as u32;
33 writer.output_u16(0x4d42); // BM
34 writer.output_u32(0x36 + pix_size); // Size
35 writer.output_u16(0x0); // Reserved
36 writer.output_u16(0x0); // Reserved
37 writer.output_u32(0x36); // Offset of pixel array
38 writer.output_u32(0x28); // Length of DIB header
39 writer.output_u32(SIZE as u32); // Width
40 writer.output_u32(SIZE as u32); // Height
41 writer.output_u16(0x1); // Color planes
42 writer.output_u16(0x18); // Bits per pixel
43 writer.output_u32(0x0); // No pixel array compression
44 writer.output_u32(pix_size); // Pixel data size
45 writer.output_u32(0x0); // Horizontal resolution
46 writer.output_u32(0x0); // Vertical resolution
47 writer.output_u32(0x0); // Colors in the palette
48 writer.output_u32(0x0); // All colors are important
49
50 for y in (0..SIZE).rev() {
51 for x in 0..SIZE {
52 let (r, g, b, _) = self.data[x][y];
53 writer.output_u8(b);
54 writer.output_u8(g);
55 writer.output_u8(r);
56 }
57
58 for _ in 0..row_padding {
59 writer.output_u8(0);
60 }
61 }
62
63 return writer.output();
64 }
65}
66
67struct Writer {
68 output: Vec<u8>,
69}
70
71impl Writer {
72 fn new() -> Writer {
73 Writer { output: Vec::new() }
74 }
75
76 fn output_u8(&mut self, n: u8) {
77 self.output.push(n);
78 }
79
80 fn output_u16(&mut self, n: u16) {
81 self.output.push(n as u8);
82 self.output.push((n >> 8) as u8);
83 }
84
85 fn output_u32(&mut self, n: u32) {
86 self.output.push(n as u8);
87 self.output.push((n >> 8) as u8);
88 self.output.push((n >> 16) as u8);
89 self.output.push((n >> 24) as u8);
90 }
91
92 fn output(self) -> Vec<u8> {
93 self.output
94 }
95}