Skip to content

Commit 2593405

Browse files
committed
Remove LUT.
1 parent f1c0b3f commit 2593405

File tree

1 file changed

+60
-113
lines changed

1 file changed

+60
-113
lines changed

src/geometrify.rs

Lines changed: 60 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,11 @@ impl Triangle {
6262

6363
impl Primitive for Triangle {
6464
fn is_inside_primitive(&self, p: Point) -> bool {
65-
let span_a = Point {
66-
x: self.b.x - self.a.x,
67-
y: self.b.y - self.a.y,
68-
};
69-
let span_b = Point {
70-
x: self.c.x - self.a.x,
71-
y: self.c.y - self.a.y,
72-
};
73-
74-
let q = Point {
75-
x: p.x - self.a.x,
76-
y: p.y - self.a.y,
77-
};
78-
79-
let s = q.cross_product(span_b) as f32 * self.span_div();
80-
let t = span_a.cross_product(q) as f32 * self.span_div();
81-
82-
(s >= 0.0) && (t >= 0.0) && ((s + t) <= 1.0)
65+
return (self.a.x - self.b.x) * (p.y - self.a.y) -
66+
(self.a.y - self.b.y) * (p.x - self.a.x) > 0 &&
67+
(self.b.x - self.c.x) * (p.y - self.b.y) -
68+
(self.b.y - self.c.y) * (p.x - self.b.x) > 0 &&
69+
(self.c.x - self.a.x) * (p.y - self.c.y) - (self.c.y - self.a.y) * (p.x - self.c.x) > 0;
8370
}
8471

8572
fn bounding_box(&self) -> BoundingBox {
@@ -178,11 +165,10 @@ impl Geometrify {
178165
y: y as i32,
179166
};
180167
if primitive.is_inside_primitive(p) {
181-
*image.get_pixel_mut(x as u32, y as u32) =
182-
Geometrify::mix_color(
183-
primitive.get_color().expect("color of triangle not set"),
184-
*image.get_pixel(x as u32, y as u32),
185-
);
168+
*image.get_pixel_mut(x as u32, y as u32) = Geometrify::mix_color(
169+
primitive.get_color().expect("color of triangle not set"),
170+
*image.get_pixel(x as u32, y as u32),
171+
);
186172
}
187173
}
188174
}
@@ -203,93 +189,58 @@ impl Geometrify {
203189
fn difference(first: Rgba<u8>, second: Rgba<u8>) -> u32 {
204190
let (r1, g1, b1, a1) = first.channels4();
205191
let (r2, g2, b2, a2) = second.channels4();
206-
let mut d = 0i32;
192+
let mut d = 0;
207193

208-
d += i32::abs(r1 as i32 - r2 as i32);
209-
d += i32::abs(g1 as i32 - g2 as i32);
210-
d += i32::abs(b1 as i32 - b2 as i32);
211-
d += i32::abs(a1 as i32 - a2 as i32);
194+
d += i32::abs(r1 as i32 - r2 as i32) as u32;
195+
d += i32::abs(g1 as i32 - g2 as i32) as u32;
196+
d += i32::abs(b1 as i32 - b2 as i32) as u32;
197+
d += i32::abs(a1 as i32 - a2 as i32) as u32;
212198

213-
d as u32
199+
d
214200
}
215201

216-
fn calculate_difference(original: &RgbaImage,
217-
current: &RgbaImage,
218-
diff_lut: &[u64],
219-
primitive: &Primitive)
220-
-> u64 {
202+
fn calculate_difference(
203+
original: &RgbaImage,
204+
current: &RgbaImage,
205+
total_difference: u64,
206+
primitive: &Primitive,
207+
) -> u64 {
221208
let bb = primitive.bounding_box();
222-
223-
// Use LUT to calculate difference outside of the BB
224-
// TODO: Check whether indices are correct!
225-
let mut d = diff_lut[diff_lut.len() - 1];
226-
if bb.bottom_right.y > 0 && bb.bottom_right.x > 0 {
227-
d -= diff_lut[((bb.bottom_right.y - 1) as u32 * current.width() +
228-
bb.bottom_right.x as u32 - 1) as usize];
229-
}
230-
if bb.top_left.y > 0 && bb.bottom_right.x > 0 {
231-
d += diff_lut[((bb.top_left.y - 1) as u32 * current.width() +
232-
bb.bottom_right.x as u32 - 1) as usize];
233-
}
234-
if bb.bottom_right.y > 0 && bb.top_left.x > 0 {
235-
d += diff_lut[((bb.bottom_right.y - 1) as u32 * current.width() +
236-
bb.top_left.x as u32 - 1) as usize];
237-
}
238-
if bb.top_left.y > 0 && bb.top_left.x > 0 {
239-
d -= diff_lut[((bb.top_left.y - 1) as u32 * current.width() +
240-
bb.top_left.x as u32 - 1) as usize];
241-
}
209+
let mut d: u64 = total_difference;
242210

243211
for y in bb.top_left.y..bb.bottom_right.y {
244212
for x in bb.top_left.x..bb.bottom_right.x {
245-
let original_rgb = original.get_pixel(x as u32, y as u32);
246-
let result_rgb = if (bb.top_left.x as u32 <= x as u32) &&
247-
(x as u32 <= bb.bottom_right.x as u32) &&
248-
(bb.top_left.y as u32 <= y as u32) &&
249-
(y as u32 <= bb.bottom_right.y as u32) &&
250-
(primitive.is_inside_primitive(
251-
Point {
252-
x: x as i32,
253-
y: y as i32,
254-
}
255-
)) {
256-
Geometrify::mix_color(
257-
*current.get_pixel(x as u32, y as u32),
258-
primitive.get_color().expect("triangle color not "),
259-
)
260-
} else {
261-
*current.get_pixel(x as u32, y as u32)
262-
};
263-
264-
d += Geometrify::difference(*original_rgb, result_rgb) as u64;
213+
let source_color = original.get_pixel(x as u32, y as u32);
214+
let current_color = current.get_pixel(x as u32, y as u32);
215+
216+
if primitive.is_inside_primitive(Point { x: x, y: y }) {
217+
let old_difference = Geometrify::difference(*source_color, *current_color);
218+
d -= old_difference as u64;
219+
220+
let new_color = Geometrify::mix_color(
221+
*current_color,
222+
primitive.get_color().expect("triangle color not set."),
223+
);
224+
let new_difference = Geometrify::difference(*source_color, new_color);
225+
d += new_difference as u64;
226+
}
265227
}
266228
}
267229

268-
d
230+
d as u64
269231
}
270232

271-
fn calculate_difference_lut(a: &RgbaImage, b: &RgbaImage) -> Vec<u64> {
272-
let mut result = Vec::new();
233+
fn calculate_difference_image(a: &RgbaImage, b: &RgbaImage) -> u64 {
234+
let mut difference = 0u64;
273235

274236
for y in 0..a.height() {
275237
for x in 0..a.width() {
276-
let mut ldiff = Geometrify::difference(*a.get_pixel(x, y), *b.get_pixel(x, y)) as
277-
u64;
278-
if x > 0 {
279-
ldiff += result[(y * a.width() + x - 1) as usize];
280-
}
281-
if y > 0 {
282-
ldiff += result[((y - 1) * a.width() + x) as usize];
283-
}
284-
if x > 0 && y > 0 {
285-
ldiff -= result[((y - 1) * a.width() + x - 1) as usize];
286-
}
287-
288-
result.push(ldiff);
238+
let ldiff = Geometrify::difference(*a.get_pixel(x, y), *b.get_pixel(x, y)) as u64;
239+
difference += ldiff;
289240
}
290241
}
291242

292-
result
243+
difference
293244
}
294245
}
295246

@@ -298,40 +249,36 @@ impl Filter for Geometrify {
298249
progress.init(self.iterations as u64);
299250

300251
let mut destination = RgbaImage::new(image.width(), image.height());
252+
let mut total_difference = Geometrify::calculate_difference_image(&image, &destination);
301253

302254
for _ in 0..self.iterations {
303-
let difference_lut = Geometrify::calculate_difference_lut(&image, &destination);
304-
305255
let primitives = (0..self.samples)
306256
.map(|_| self.generate_primitive(image.width(), image.height()))
307-
.map(
308-
|mut p| {
309-
p.span_div_save();
310-
p
311-
}
312-
)
257+
.map(|mut p| {
258+
p.span_div_save();
259+
p
260+
})
313261
.collect::<Vec<Triangle>>();
314262
let min_primitive = primitives
315263
.par_iter()
316-
.map(
317-
|primitive| {
318-
let mut prim = *primitive;
319-
prim.color = Some(Geometrify::calculate_color(&image, &prim));
320-
(prim,
321-
Geometrify::calculate_difference(
264+
.map(|primitive| {
265+
let mut prim = *primitive;
266+
prim.color = Some(Geometrify::calculate_color(&image, &prim));
267+
(
268+
prim,
269+
Geometrify::calculate_difference(
322270
&image,
323271
&destination,
324-
&difference_lut,
272+
total_difference,
325273
&prim,
326-
))
327-
}
328-
)
274+
),
275+
)
276+
})
329277
.min_by_key(|tup| tup.1);
330278

331-
Geometrify::add_to_image(
332-
&mut destination,
333-
&min_primitive.expect("no fitting triangle found").0,
334-
);
279+
let (bestprimitive, bestscore) = min_primitive.expect("no fitting triangle found");
280+
Geometrify::add_to_image(&mut destination, &bestprimitive);
281+
total_difference = bestscore;
335282
progress.step();
336283
}
337284
progress.finish();

0 commit comments

Comments
 (0)