use crate::io::IO;
use crate::validator;
use image::GenericImageView;
use rand::Rng;
fn build_brush<'a>(io: IO<'a>, proba: i32, min: i32, max: i32) -> Brush<'a> {
let brush = Brush {
min,
max,
proba,
io,
};
brush.validate_attributes();
brush
}
pub fn bottom_to_top(io: IO, proba: i32, min: i32, max: i32) {
let brush = build_brush(io, proba, min, max);
brush.bottom_to_top()
}
pub fn left_to_right(io: IO, proba: i32, min: i32, max: i32) {
let brush = build_brush(io, proba, min, max);
brush.left_to_right()
}
pub fn right_to_left(io: IO, proba: i32, min: i32, max: i32) {
let brush = build_brush(io, proba, min, max);
brush.right_to_left()
}
pub fn top_to_bottom(io: IO, proba: i32, min: i32, max: i32) {
let brush = build_brush(io, proba, min, max);
brush.top_to_bottom()
}
struct Brush<'a> {
min: i32,
max: i32,
proba: i32,
io: IO<'a>,
}
impl<'a> Brush<'a> {
fn validate_attributes(&self) {
validator::percent("probability", self.proba);
validator::min_max(self.min, self.max);
}
fn bottom_to_top(&self) {
let mut new_img = image::ImageBuffer::new(self.io.in_img.width(), self.io.in_img.height());
let mut rng = rand::thread_rng();
let mut pixel_to_glitch = rng.gen_range(self.min..self.max);
let mut color = self.io.in_img.get_pixel(1, 1);
for h in 0..(self.io.in_img.height() - 1) {
for w in 0..(self.io.in_img.width() - 1) {
new_img.put_pixel(w, h, self.io.in_img.get_pixel(w, h));
}
}
for w in 1..(self.io.in_img.width() - 1) {
for h in 1..(self.io.in_img.height() - 2) {
let inverted_w = self.io.in_img.width() - 1 - w;
let inverted_h = self.io.in_img.height() - 2 - h;
if pixel_to_glitch > 0 {
pixel_to_glitch = pixel_to_glitch - 1;
new_img.put_pixel(inverted_w, inverted_h, color);
} else {
if rng.gen_range(0..100) < self.proba {
pixel_to_glitch = rng.gen_range(self.min..self.max);
color = *new_img.get_pixel(inverted_w + 1, inverted_h);
new_img.put_pixel(w, h, color);
}
}
}
}
new_img.save(self.io.out_img).unwrap();
}
fn left_to_right(&self) {
let mut new_img = image::ImageBuffer::new(self.io.in_img.width(), self.io.in_img.height());
let mut rng = rand::thread_rng();
let mut pixel_to_glitch = rng.gen_range(self.min..self.max);
let mut color = self.io.in_img.get_pixel(1, 1);
for h in 0..(self.io.in_img.height() - 1) {
for w in 0..(self.io.in_img.width() - 1) {
new_img.put_pixel(w, h, self.io.in_img.get_pixel(w, h));
}
}
for h in 1..(self.io.in_img.height() - 1) {
for w in 2..(self.io.in_img.width() - 1) {
if pixel_to_glitch > 0 {
pixel_to_glitch = pixel_to_glitch - 1;
new_img.put_pixel(w, h, color);
} else {
if rng.gen_range(0..100) < self.proba {
pixel_to_glitch = rng.gen_range(self.min..self.max);
color = *new_img.get_pixel(w - 2, h - 1);
new_img.put_pixel(w, h, color);
}
}
}
}
new_img.save(self.io.out_img).unwrap();
}
fn right_to_left(&self) {
let mut new_img = image::ImageBuffer::new(self.io.in_img.width(), self.io.in_img.height());
let mut rng = rand::thread_rng();
let mut pixel_to_glitch = rng.gen_range(self.min..self.max);
let mut color = self.io.in_img.get_pixel(1, 1);
for h in 0..(self.io.in_img.height() - 1) {
for w in 0..(self.io.in_img.width() - 1) {
new_img.put_pixel(w, h, self.io.in_img.get_pixel(w, h));
}
}
for h in 1..(self.io.in_img.height() - 1) {
for w in 1..(self.io.in_img.width() - 2) {
let inverted_w = self.io.in_img.width() - 2 - w;
let inverted_h = self.io.in_img.height() - 1 - h;
if pixel_to_glitch > 0 {
pixel_to_glitch = pixel_to_glitch - 1;
new_img.put_pixel(inverted_w, inverted_h, color);
} else {
if rng.gen_range(0..100) < self.proba {
pixel_to_glitch = rng.gen_range(self.min..self.max);
color = *new_img.get_pixel(inverted_w, inverted_h + 1);
new_img.put_pixel(w, h, color);
}
}
}
}
new_img.save(self.io.out_img).unwrap();
}
fn top_to_bottom(&self) {
let mut new_img = image::ImageBuffer::new(self.io.in_img.width(), self.io.in_img.height());
let mut rng = rand::thread_rng();
let mut pixel_to_glitch = rng.gen_range(self.min..self.max);
let mut color = self.io.in_img.get_pixel(0, 0);
for h in 0..(self.io.in_img.height() - 1) {
for w in 0..(self.io.in_img.width() - 1) {
new_img.put_pixel(w, h, self.io.in_img.get_pixel(w, h));
}
}
for w in 1..(self.io.in_img.width() - 1) {
for h in 2..(self.io.in_img.height() - 1) {
if pixel_to_glitch > 0 {
pixel_to_glitch = pixel_to_glitch - 1;
new_img.put_pixel(w, h, color);
} else {
if rng.gen_range(0..100) < self.proba {
pixel_to_glitch = rng.gen_range(self.min..self.max);
color = *new_img.get_pixel(w - 1, h - 2);
new_img.put_pixel(w, h, color);
}
}
}
}
new_img.save(self.io.out_img).unwrap();
}
}