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
use std::fs::File;
use std::io;
use std::ptr;
use mask::Mask;
use palette::Rgba;
use palette::Blend;
use png;
use png::HasParameters;
pub struct Raster {
pub width : u32,
pub height : u32,
pixels : Vec<u8>,
}
impl Raster {
pub fn new(width: u32, height: u32) -> Raster {
let n = width as usize * height as usize * 4 as usize;
let pixels = vec![0u8; n];
Raster { width: width, height: height, pixels: pixels }
}
pub fn clear(&mut self) {
let len = self.pixels.len();
unsafe {
let pix = self.pixels.as_mut_ptr().offset(0 as isize);
ptr::write_bytes(pix, 0u8, len);
}
}
pub fn composite(&mut self, mask: &Mask, clr: [u8; 3]) {
for (mut p, m) in self.pixels.chunks_mut(4).zip(mask.iter()) {
let src = Rgba::<f32>::new_u8(clr[0], clr[1], clr[2], *m);
let dst = Rgba::<f32>::new_u8(p[0], p[1], p[2], p[3]);
let c = src.over(dst);
let d = c.to_pixel::<[u8; 4]>();
p[0] = d[0];
p[1] = d[1];
p[2] = d[2];
p[3] = d[3];
}
}
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::RGBA).set(png::BitDepth::Eight);
let mut writer = enc.write_header()?;
writer.write_image_data(&self.pixels[..])?;
Ok(())
}
}