1extern crate rayon;
2use self::rayon::prelude::*;
3
4#[derive(Debug, Clone, PartialEq)]
5pub struct OpBuffer {
6 pub width: usize,
7 pub height: usize,
8 pub colors: usize,
9 pub monochrome: bool,
10 pub data: Vec<f32>,
11}
12
13impl OpBuffer {
14 pub fn default() -> OpBuffer {
15 OpBuffer {
16 width: 0,
17 height: 0,
18 colors: 0,
19 monochrome: false,
20 data: Vec::new(),
21 }
22 }
23
24 pub fn new(width: usize, height: usize, colors: usize, monochrome: bool) -> OpBuffer {
25 OpBuffer {
26 width: width,
27 height: height,
28 colors: colors,
29 monochrome,
30 data: vec![0.0; width*height*(colors as usize)],
31 }
32 }
33
34 pub fn mutate_lines<F>(&mut self, closure: &F)
35 where F : Fn(&mut [f32], usize)+Sync {
36
37 self.data.par_chunks_mut(self.width*self.colors).enumerate().for_each(|(row, line)| {
38 closure(line, row);
39 });
40 }
41
42 pub fn mutate_lines_copying<F>(&self, closure: &F) -> OpBuffer
43 where F : Fn(&mut [f32], usize)+Sync {
44
45 let mut buf = self.clone();
46 buf.data.par_chunks_mut(self.width*self.colors).enumerate().for_each(|(row, line)| {
47 closure(line, row);
48 });
49 buf
50 }
51
52 pub fn process_into_new<F>(&self, colors: usize, closure: &F) -> OpBuffer
53 where F : Fn(&mut [f32], &[f32])+Sync {
54
55 let mut out = OpBuffer::new(self.width, self.height, colors, self.monochrome);
56 out.data.par_chunks_mut(out.width*out.colors).enumerate().for_each(|(row, line)| {
57 closure(line, &self.data[self.width*self.colors*row..]);
58 });
59 out
60 }
61
62 pub fn transform(&self,
63 topleft: (isize, isize),
64 topright: (isize, isize),
65 bottomleft: (isize, isize),
66 width: usize,
67 height: usize) -> OpBuffer {
68
69 let newdata = crate::scaling::transform_buffer(&self.data, self.width, self.height,
70 topleft, topright, bottomleft, width, height, self.colors, None);
71
72 Self {
73 width,
74 height,
75 colors: self.colors,
76 monochrome: self.monochrome,
77 data: newdata,
78 }
79 }
80
81 pub fn from_rgb_str_vec(data: Vec<&str>) -> OpBuffer {
83 let width = data.first().expect("Invalid data for rgb helper function").len();
84 let height = data.len();
85 let colors = 3;
86
87 let mut pixel_data: Vec<f32> = Vec::with_capacity(width * height * colors);
88 for row in data {
89 for col in row.chars() {
90 let (r, g, b) = match col {
91 'R' => (1.0, 0.0, 0.0),
92 'G' => (0.0, 1.0, 0.0),
93 'B' => (0.0, 0.0, 1.0),
94 'O' => (1.0, 1.0, 1.0),
95 ' ' => (0.0, 0.0, 0.0),
96 c @ _ => panic!(
97 "Invalid color '{}' sent to rgb expected any of 'RGBO '", c),
98 };
99
100 pixel_data.push(r);
101 pixel_data.push(g);
102 pixel_data.push(b);
103 }
104 }
105
106 OpBuffer {
107 width: width,
108 height: height,
109 colors: colors,
110 monochrome: false,
111 data: pixel_data,
112 }
113 }
114}