first commit
This commit is contained in:
2
rust/.gitignore
vendored
Normal file
2
rust/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/target
|
||||
**/*.rs.bk
|
396
rust/Cargo.lock
generated
Normal file
396
rust/Cargo.lock
generated
Normal 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
12
rust/Cargo.toml
Normal 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
564
rust/src/main.rs
Normal 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;
|
||||
}
|
Reference in New Issue
Block a user