first commit

This commit is contained in:
Auric Vente
2024-07-31 23:53:55 -06:00
commit 7c6318bcf1
11 changed files with 2052 additions and 0 deletions

2
rust/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/target
**/*.rs.bk

396
rust/Cargo.lock generated Normal file
View File

@@ -0,0 +1,396 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "adler32"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bytemuck"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431"
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "color_quant"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
[[package]]
name = "crc32fast"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-deque"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
"maybe-uninit",
]
[[package]]
name = "crossbeam-epoch"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"lazy_static",
"maybe-uninit",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if",
"lazy_static",
]
[[package]]
name = "deflate"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7e5d2a2273fed52a7f947ee55b092c4057025d7a3e04e5ecdbd25d6c3fb1bd7"
dependencies = [
"adler32",
"byteorder",
]
[[package]]
name = "either"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "gif"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af"
dependencies = [
"color_quant",
"lzw",
]
[[package]]
name = "hermit-abi"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a0d737e0f947a1864e93d33fdef4af8445a00d1ed8dc0c8ddb73139ea6abf15"
dependencies = [
"libc",
]
[[package]]
name = "image"
version = "0.23.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfc5483f8d5afd3653b38a196c52294dcb239c3e1a5bade1990353ea13bcf387"
dependencies = [
"bytemuck",
"byteorder",
"gif",
"jpeg-decoder",
"num-iter",
"num-rational",
"num-traits",
"png",
"scoped_threadpool",
"tiff",
]
[[package]]
name = "inflate"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
dependencies = [
"adler32",
]
[[package]]
name = "jpeg-decoder"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0256f0aec7352539102a9efbcb75543227b7ab1117e0f95450023af730128451"
dependencies = [
"byteorder",
"rayon",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
[[package]]
name = "lzw"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
[[package]]
name = "maybe-uninit"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "memoffset"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8"
dependencies = [
"autocfg",
]
[[package]]
name = "miniz_oxide"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
dependencies = [
"adler32",
]
[[package]]
name = "mutant"
version = "0.1.0"
dependencies = [
"gif",
"image",
"rand",
]
[[package]]
name = "num-integer"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "png"
version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "910f09135b1ed14bb16be445a8c23ddf0777eca485fbfc7cee00d81fecab158a"
dependencies = [
"bitflags",
"crc32fast",
"deflate",
"inflate",
]
[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[package]]
name = "rayon"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
dependencies = [
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
dependencies = [
"crossbeam-deque",
"crossbeam-queue",
"crossbeam-utils",
"lazy_static",
"num_cpus",
]
[[package]]
name = "scoped_threadpool"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "tiff"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "002351e428db1eb1d8656d4ca61947c3519ac3191e1c804d4600cd32093b77ad"
dependencies = [
"byteorder",
"lzw",
"miniz_oxide",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"

12
rust/Cargo.toml Normal file
View File

@@ -0,0 +1,12 @@
[package]
name = "mutant"
version = "0.1.0"
authors = ["madprops"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
image = "0.23.3"
rand = "0.7.3"
gif = "0.10.3"

564
rust/src/main.rs Normal file
View File

@@ -0,0 +1,564 @@
use rand::{Rng, seq::SliceRandom};
use std::time::{SystemTime, UNIX_EPOCH};
use std::process::exit;
use std::env;
use image::GenericImageView;
use std::fs::File;
use gif::{Frame, Encoder, Repeat, SetParameter};
// Usage Examples
// mutant 2 250 image.jpg (use mode number 2)
// mutant 1,3,5 100 image.jpg image2.png (use modes 1, 3, and 5, a delay of 100ms, with 2 images)
fn main() {
let num_modes = 8;
let args: Vec<String> = env::args().collect();
let mut modes: Vec<u32> = args[1].split(",").map(|x| x.parse::<u32>().unwrap()).collect();
if modes.len() == 0 {
exit(0);
}
for mode in modes.iter() {
if *mode == 0 || *mode > num_modes {
println!("Invalid mode: {}", mode);
exit(0);
}
}
let delay_ms = args[2].parse::<u16>().unwrap_or_else(|_| {
println!("Wrong delay.");
exit(0);
});
let delay = (delay_ms as f64 / 10.0) as u16;
if delay == 0 {
println!("Delay is too short.");
exit(0);
} else if delay > 1000 {
println!("Delay is too long.");
exit(0);
}
let paths = args
.iter()
.skip(3)
.map(|s| s.clone())
.collect::<Vec<String>>();
if paths.len() == 0 || paths.len() > 4 {
exit(0)
}
let mut img = match image::open(&paths[0]) {
Ok(im) => im,
Err(_) => {
println!("Invalid file path.");
exit(0);
}
};
let mut dims = img.dimensions();
let ratio: f64 = dims.1 as f64 / dims.0 as f64;
let width;
let height;
if dims.0 >= dims.1 {
width = if dims.0 < 800 {
dims.0
} else {800};
height = (width as f64 * ratio) as u32;
} else {
height = if dims.0 < 800 {
dims.0
} else {800};
width = (height as f64 / ratio) as u32;
}
img = img.thumbnail(width, height);
dims = img.dimensions();
let mut bytes: Vec<Vec<u8>> = vec![img.to_rgb().to_vec()];
if paths.len() > 1 {
for i in 1..paths.len()
{
let im = match image::open(&paths[i]) {
Ok(im) => im,
Err(_) => {
println!("Invalid file path.");
exit(0);
}
};
let imbuff = image::imageops::resize(&im, dims.0, dims.1, image::imageops::FilterType::Nearest);
let mut byts: Vec<u8> = vec![];
for pixel in imbuff.pixels() {
byts.push(pixel[0]);
byts.push(pixel[1]);
byts.push(pixel[2]);
}
bytes.push(byts);
}
}
let mut res_paths: Vec<String> = vec![];
loop {
let mut n = 1;
let mut frames: Vec<Frame> = vec![];
let mode = modes[modes.len() - 1];
let mut bn = 0;
let double_first = if mode == 3 {
true
} else { false };
loop {
let mut byts = bytes[bn].clone();
let mut exit_early = false;
match mode {
// Glitch
1 => {
match n {
1 => {
remove_first_byte(&mut byts);
},
2 => {
for _ in 0..get_num_mutations() {
remove_random_byte(&mut byts);
}
},
3 => {
remove_first_byte(&mut byts);
remove_first_byte(&mut byts);
},
4 => {
for _ in 0..get_num_mutations() {
remove_random_byte(&mut byts);
}
},
_ => {}
}
},
// Wave
2 => {
modify_bytes(&mut byts, dims.0, dims.1, false);
modify_bytes(&mut byts, dims.0, dims.1, true);
modify_bytes(&mut byts, dims.0, dims.1, false);
modify_bytes(&mut byts, dims.0, dims.1, false);
modify_bytes(&mut byts, dims.0, dims.1, false);
modify_bytes(&mut byts, dims.0, dims.1, false);
modify_bytes(&mut byts, dims.0, dims.1, false);
},
// Mirror
3 => {
match n {
2 => {
byts = line_reverse(byts, dims.0, "left");
},
3 => {
byts = line_reverse(byts, dims.0, "full");
},
4 => {
byts = line_reverse(byts, dims.0, "right");
}
_ => {}
}
},
// Static
4 => {
make_static(&mut byts);
if n >= 2 {
if n >= paths.len() {
exit_early = true;
}
}
},
// Glow
5 => {
if n == 2 {
byts = reverse_group(byts, false);
} else if n == 4 {
byts = reverse_group(byts, true);
}
},
// Glass
6 => {
match n {
1 => {
byts = swap_group(byts, 1, dims.0);
},
2 => {
byts = swap_group(byts, 2, dims.0);
},
3 => {
byts = swap_group(byts, 3, dims.0);
},
4 => {
byts = swap_group(byts, 2, dims.0);
},
_ => {}
}
},
// Color
7 => {
if n % 2 == 0 {
colorize(&mut byts);
}
},
// Chalk
8 => {
if n % 2 == 0 {
decolorize(&mut byts);
if n >= paths.len() {
exit_early = true;
}
}
}
_ => {}
}
let d = if n == 1 && double_first {
delay * 2
} else { delay };
let mut frame = gif::Frame::from_rgb_speed(dims.0 as u16, dims.1 as u16, &mut byts, 30);
frame.delay = d;
frames.push(frame);
n += 1;
if exit_early || n > 4 {break}
bn += 1;
if bn >= bytes.len() {
bn = 0;
}
}
let color_map = &[0xFF, 0xFF, 0xFF, 0, 0, 0];
let new_path = format!("mutated/{}_{}.gif", random_word(), now());
let mut image = File::create(&new_path).unwrap();
let mut encoder = Encoder::new(&mut image, dims.0 as u16, dims.1 as u16, color_map).unwrap();
encoder.set(Repeat::Infinite).unwrap();
for frame in frames {
encoder.write_frame(&frame).unwrap();
}
res_paths.push(new_path);
modes.pop();
if modes.len() == 0 {
break;
}
}
let mut s = "".to_string();
// There is no join in rust yet
// without an external crate
for path in res_paths.iter().rev() {
s = format!("{} {}", s, path);
}
println!("{}", s.trim());
}
fn now() -> u128 {
let start = SystemTime::now();
let since_the_epoch = start.duration_since(UNIX_EPOCH).unwrap();
since_the_epoch.as_millis()
}
fn get_num_mutations() -> u8 {
let mut rng = rand::thread_rng();
rng.gen_range(1, 20)
}
fn remove_random_byte(bytes: &mut Vec<u8>) {
let mut rng = rand::thread_rng();
let index = rng.gen_range(0, bytes.len() - 1);
let og = bytes[index];
bytes.remove(index);
bytes.push(og)
}
fn remove_first_byte(bytes: &mut Vec<u8>) {
let og = bytes[0];
bytes.remove(0);
bytes.push(og)
}
fn modify_bytes(bytes: &mut Vec<u8>, width: u32, height: u32, start: bool) {
let mut rng = rand::thread_rng();
let row = if start {0} else {rng.gen_range(0, height)};
let range = rng.gen_range((height as f64 * 0.1).round() as u32,
(height as f64 * 0.6).round() as u32);
let mut i = if row == 0 {0} else {
((row * width * 3) - 1) as usize
};
let mode = rng.gen_range(1, 4);
for _ in 0..range {
for _ in 0..width {
let r = bytes[i];
let g = bytes[i + 1];
let b = bytes[i + 2];
match mode {
1 => {
bytes[i + 1] = 255 - r;
bytes[i + 2] = 255 - g;
bytes[i + 3] = 255 - b;
},
2 => {
bytes[i + 1] = 255 - b;
bytes[i + 2] = 255 - r;
bytes[i + 3] = 255 - g;
},
3 => {
bytes[i + 1] = 255 - g;
bytes[i + 2] = 255 - b;
bytes[i + 3] = 255 - r;
},
_ => {}
}
i += 3;
}
if i >= bytes.len() - 1 {
break;
}
}
}
fn line_reverse(bytes: Vec<u8>, width: u32, mode: &str) -> Vec<u8> {
if mode == "full" {
return bytes.into_iter().rev().collect();
} else {
let mut n = 0;
let mut nbytes: Vec<u8> =vec![];
let mut line: Vec<u8> = vec![];
for byte in bytes.iter() {
line.push(*byte);
n += 1;
if n >= width {
for b in line.into_iter().rev() {
nbytes.push(b)
}
n = 0;
line = vec![];
}
}
if mode == "right" {
return nbytes.into_iter().rev().collect();
} else {
return nbytes;
}
}
}
fn make_static(bytes: &mut Vec<u8>) {
let amount = (bytes.len() as f64 * 0.25).round() as u32;
let mut rng = rand::thread_rng();
for _ in 0..amount {
let index = rng.gen_range(0, bytes.len() - 1);
bytes[index] = rng.gen_range(0, 255);
}
}
fn reverse_group(bytes: Vec<u8>, alt: bool) -> Vec<u8> {
let mut nbytes: Vec<u8> = vec![];
let mut temp: Vec<u8> = vec![];
let mut n = 0;
for byte in bytes.iter() {
temp.push(*byte);
n += 1;
if n == 3 {
if alt {
nbytes.push(temp[1]);
nbytes.push(temp[2]);
nbytes.push(temp[0]);
} else {
nbytes.push(temp[2]);
nbytes.push(temp[1]);
nbytes.push(temp[0]);
}
temp = vec![];
n = 0
}
}
for b in temp.iter().rev() {
nbytes.push(*b);
}
return nbytes;
}
fn swap_group(bytes: Vec<u8>, level: u32, width: u32) -> Vec<u8> {
let mut nbytes: Vec<u8> = vec![];
let mut temp: Vec<u8> = vec![];
let mut temp2: Vec<u8> = vec![];
let mut n = 0;
let mut limit = ((width as f64) * (level as f64 * 0.008)) as u32;
while limit > 0 && limit % 3 != 0 {
limit -= 1;
}
if limit < 3 * level {
limit = 3 * level;
}
for byte in bytes.iter() {
n += 1;
if n <= limit {
temp.push(*byte);
} else if n <= limit * 2 {
temp2.push(*byte);
}
if n == limit * 2 {
for b in temp2.iter() {
nbytes.push(*b);
}
for b in temp.iter() {
nbytes.push(*b);
}
temp = vec![];
temp2 = vec![];
n = 0;
}
}
if temp2.len() > 0 {
for b in temp2.iter() {
nbytes.push(*b)
}
}
if temp.len() > 0 {
for b in temp.iter() {
nbytes.push(*b)
}
}
return nbytes;
}
fn colorize(bytes: &mut Vec<u8>) {
let mut n = 0;
let mut rng = rand::thread_rng();
let w1 = rng.gen_range(128, 255);
let w2 = rng.gen_range(128, 255);
let w3 = rng.gen_range(128, 255);
let b1 = rng.gen_range(0, 128);
let b2 = rng.gen_range(0, 128);
let b3 = rng.gen_range(0, 128);
let mut line: Vec<u8> = vec![];
for i in 0..bytes.len() {
n += 1;
line.push(bytes[i]);
if n == 3 {
let d1 = (line[0] as i32 - line[1] as i32).abs();
let d2 = (line[0] as i32 - line[2] as i32).abs();
let d3 = (line[1] as i32 - line[2] as i32).abs();
if d1 < 20 && d2 < 20 && d3 < 20 {
if line[0] >= 128 {
bytes[i - 2] = w1;
bytes[i - 1] = w2;
bytes[i - 0] = w3;
} else {
bytes[i - 2] = b1;
bytes[i - 1] = b2;
bytes[i - 0] = b3;
}
}
line = vec![];
n = 0;
}
}
}
fn decolorize(bytes: &mut Vec<u8>) {
let mut n = 0;
let mut line: Vec<u8> = vec![];
for i in 0..bytes.len() {
n += 1;
line.push(bytes[i]);
if n == 3 {
let d1 = (line[0] as i32 - line[1] as i32).abs();
let d2 = (line[0] as i32 - line[2] as i32).abs();
let d3 = (line[1] as i32 - line[2] as i32).abs();
if d1 > 20 || d2 > 20 || d3 > 20 {
if line[0] >= 128 {
bytes[i - 2] = 255;
bytes[i - 1] = 255;
bytes[i - 0] = 255;
} else {
bytes[i - 2] = 0;
bytes[i - 1] = 0;
bytes[i - 0] = 0;
}
}
line = vec![];
n = 0;
}
}
}
fn random_word() -> String {
let a = vec!["a","e","i","o","u"];
let b = vec!["b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "r", "s", "t", "v", "w", "x", "y", "z"];
let mut word = "".to_string();
for i in 1..=6 {
let letter = if i % 2 == 0 {
b.choose(&mut rand::thread_rng())
} else {
a.choose(&mut rand::thread_rng())
};
word.push_str(letter.unwrap());
}
return word;
}