1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::fs::File;
use std::io;
use std::io::Write;
use std::ptr;
use png;
use png::HasParameters;
pub struct Mask {
pub width : u32,
pub height : u32,
pixels : Vec<u8>,
}
impl Mask {
pub fn new(width: u32, height: u32) -> Mask {
let pixels = vec![0; (width * height) as usize];
Mask { width: width, height: height, pixels: pixels }
}
pub(crate) fn iter(&self) -> ::std::slice::Iter<u8> {
self.pixels.iter()
}
pub(crate) fn clear(&mut self) {
let len = self.pixels.len();
self.fill(0, len, 0);
}
pub(crate) fn fill(&mut self, x: usize, len: usize, v: u8) {
assert!(x + len <= self.pixels.len());
unsafe {
let pix = self.pixels.as_mut_ptr().offset(x as isize);
ptr::write_bytes(pix, v, len);
}
}
pub(crate) fn set(&mut self, x: i32, v: i32) {
assert!(x >= 0 && (x as u32) < self.width);
self.pixels[x as usize] = v as u8;
}
pub(crate) fn accumulate(&mut self, scan_buf: &Mask, row: u32) {
assert!(scan_buf.height == 1);
assert!(self.width == scan_buf.width);
let w = self.width as usize;
let mut pix = &mut self.scan_line(row)[..w];
let buf = &scan_buf.pixels[..w];
for i in 0..w {
pix[i] = pix[i].saturating_add(buf[i]);
}
}
fn scan_line(&mut self, row: u32) -> &mut [u8] {
let s = (row * self.width) as usize;
let t = s + self.width as usize;
&mut self.pixels[s..t]
}
pub fn write_pgm(&self, filename: &str) -> io::Result<()> {
let fl = File::create(filename)?;
let mut bw = io::BufWriter::new(fl);
let mut w = bw.get_mut();
w.write_all(format!("P5\n{} {}\n255\n", self.width, self.height)
.as_bytes())?;
w.write_all(&self.pixels[..])?;
w.flush()?;
Ok(())
}
pub fn write_png(&self, filename: &str) -> io::Result<()> {
let fl = File::create(filename)?;
let ref mut bw = io::BufWriter::new(fl);
let mut enc = png::Encoder::new(bw, self.width, self.height);
enc.set(png::ColorType::Grayscale).set(png::BitDepth::Eight);
let mut writer = enc.write_header()?;
writer.write_image_data(&self.pixels[..])?;
Ok(())
}
}
#[test]
fn test_mask() {
let mut m = Mask::new(10, 10);
m.clear();
assert!(m.width == 10);
assert!(m.height == 10);
assert!(m.pixels.len() == 100);
m.fill(40, 20, 255u8);
assert!(m.pixels[0] == 0u8);
assert!(m.pixels[39] == 0u8);
assert!(m.pixels[40] == 255u8);
assert!(m.pixels[59] == 255u8);
assert!(m.pixels[60] == 0u8);
assert!(m.pixels[99] == 0u8);
}