69 lines
1.8 KiB
Rust
69 lines
1.8 KiB
Rust
use regex::Regex;
|
|
use std::{borrow::Cow, env::args, process::exit};
|
|
|
|
fn main() {
|
|
let path = args().nth(1).expect("usage: file [--nosize]");
|
|
let nosize = match args().nth(2) {
|
|
None => false,
|
|
Some(t) => {
|
|
if t == "--nosize" {
|
|
true
|
|
} else {
|
|
eprint!("usage: file [--nosize]");
|
|
exit(1)
|
|
}
|
|
}
|
|
};
|
|
let (data, name, width, height) = path_to_img(path.as_str());
|
|
println!("{name}:");
|
|
if !nosize {
|
|
println!(" D {width}");
|
|
println!(" D {height}");
|
|
}
|
|
for d in data {
|
|
println!(" D 0x{d:08x}");
|
|
}
|
|
}
|
|
fn remove_non_alphanumeric(input: &str) -> Cow<'_, str> {
|
|
let re = Regex::new(r"[^a-zA-Z0-9_]+").unwrap();
|
|
re.replace_all(input, "")
|
|
}
|
|
|
|
fn path_to_img(path: &str) -> (Vec<u32>, String, u32, u32) {
|
|
let img = match image::open(path) {
|
|
Ok(img) => img.to_luma8(),
|
|
Err(e) => panic!("failed to open image {path}: {e}"),
|
|
};
|
|
|
|
let width = img.width();
|
|
let height = img.height();
|
|
|
|
let mut bytes = Vec::new();
|
|
let mut bit = 0;
|
|
let mut byte = 0;
|
|
for y in 0..height {
|
|
for x in 0..width {
|
|
let pix = img.get_pixel(x, y)[0];
|
|
if pix >= 127 {
|
|
byte |= 1 << bit
|
|
}
|
|
bit += 1;
|
|
if bit == 32 {
|
|
bytes.push(byte);
|
|
byte = 0;
|
|
bit = 0;
|
|
}
|
|
}
|
|
}
|
|
if bit != 0 {
|
|
bytes.push(byte);
|
|
}
|
|
let path = path.split('/').next_back().unwrap();
|
|
let split: Vec<_> = path.split('.').collect();
|
|
let name = format!(
|
|
"picture_{}",
|
|
remove_non_alphanumeric(&split[0..split.len() - 1].join("_")).to_lowercase()
|
|
);
|
|
(bytes, name, width, height)
|
|
}
|