jp2a ripoff
-rw-r--r--Cargo.lock125
-rw-r--r--Cargo.toml9
-rw-r--r--src/main.rs7
-rw-r--r--src/picture.rs42
4 files changed, 28 insertions, 155 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 046753a..3daf247 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -77,9 +77,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytemuck"
-version = "1.13.1"
+version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea"
+checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
[[package]]
name = "byteorder"
@@ -163,55 +163,6 @@ dependencies = [
]
[[package]]
-name = "crossbeam-channel"
-version = "0.5.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
-dependencies = [
- "cfg-if",
- "crossbeam-epoch",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.9.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
-dependencies = [
- "autocfg",
- "cfg-if",
- "crossbeam-utils",
- "memoffset",
- "scopeguard",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "either"
-version = "1.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
-
-[[package]]
name = "errno"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -259,24 +210,15 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]]
name = "image"
-version = "0.24.6"
+version = "0.24.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a"
+checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711"
dependencies = [
"bytemuck",
"byteorder",
@@ -293,7 +235,7 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
- "hermit-abi 0.3.1",
+ "hermit-abi",
"libc",
"windows-sys",
]
@@ -304,7 +246,7 @@ version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
dependencies = [
- "hermit-abi 0.3.1",
+ "hermit-abi",
"io-lifetimes",
"rustix",
"windows-sys",
@@ -315,9 +257,6 @@ name = "jpeg-decoder"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
-dependencies = [
- "rayon",
-]
[[package]]
name = "libc"
@@ -332,15 +271,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
-name = "memoffset"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
name = "miniz_oxide"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -373,24 +303,14 @@ dependencies = [
[[package]]
name = "num-traits"
-version = "0.2.15"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
dependencies = [
"autocfg",
]
[[package]]
-name = "num_cpus"
-version = "1.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
-dependencies = [
- "hermit-abi 0.2.6",
- "libc",
-]
-
-[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -403,7 +323,6 @@ dependencies = [
"anyhow",
"clap",
"image",
- "rayon",
"rgb2ansi256",
]
@@ -439,28 +358,6 @@ dependencies = [
]
[[package]]
-name = "rayon"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
-dependencies = [
- "either",
- "rayon-core",
-]
-
-[[package]]
-name = "rayon-core"
-version = "1.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
-dependencies = [
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-utils",
- "num_cpus",
-]
-
-[[package]]
name = "rgb2ansi256"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -481,12 +378,6 @@ dependencies = [
]
[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
name = "simd-adler32"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 36582e6..c39a5cf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,17 +9,12 @@ edition = "2021"
anyhow = "1.0.71"
clap = { version = "4.3.3", features = ["derive"] }
image = { version = "0.24.6", features = [
- "png",
- "jpeg_rayon",
+ "png",
+ "jpeg",
], default-features = false }
-rayon = { version = "1.7.0", optional = true }
rgb2ansi256 = "0.1.1"
[profile.release]
lto = true
opt-level = 3
strip = true
-
-[features]
-rayon = ["dep:rayon"]
-default = []
diff --git a/src/main.rs b/src/main.rs
index 58c844e..e4185f9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,6 @@
use clap::Parser;
-use picture::*;
-use std::path::PathBuf;
+use picture::ToText;
+use std::{io::BufWriter, path::PathBuf};
mod picture;
#[derive(Parser)]
@@ -14,6 +14,7 @@ struct Args {
fn main() -> anyhow::Result<()> {
let args = Args::parse();
let p = image::open(args.from)?;
- println!("{}", p.text(" ...,:clodxkO0KXM".as_bytes()));
+ let mut s = BufWriter::new(std::io::stdout().lock());
+ p.text(b" ...,:clodxkO0KXM", &mut s)?;
Ok(())
}
diff --git a/src/picture.rs b/src/picture.rs
index 8fa1af8..04de046 100644
--- a/src/picture.rs
+++ b/src/picture.rs
@@ -1,7 +1,6 @@
use image::{DynamicImage, GenericImageView, Pixel, Rgb};
-#[cfg(rayon)]
-use rayon::prelude::*;
use rgb2ansi256::rgb_to_ansi256;
+use std::io::{self, Write};
macro_rules! fg {
($color:expr,$c:expr) => {
@@ -10,19 +9,13 @@ macro_rules! fg {
}
pub trait ToText {
- fn text(&self, palette: &[u8]) -> String;
+ fn text(&self, palette: &[u8], w: &mut impl Write) -> io::Result<()>;
}
impl ToText for DynamicImage {
- fn text(&self, palette: &[u8]) -> String {
+ fn text(&self, palette: &[u8], w: &mut impl Write) -> io::Result<()> {
let p_len = (palette.len() - 1) as f32;
- let mut output: Vec<String> = vec![];
let height = (self.height() / 2) as usize;
- output.resize(height, String::new());
- #[cfg(not(rayon))]
- let iter = output.iter_mut();
- #[cfg(rayon)]
- let iter = output.par_iter_mut();
- iter.enumerate().for_each(|(mut y, output)| {
+ for mut y in 0..height {
y <<= 1;
let mut last_p: Option<u8> = None;
for x in 0..self.width() {
@@ -32,19 +25,25 @@ impl ToText for DynamicImage {
let pos = (p_len * y).round();
let i: usize = (pos * a).round() as usize;
let ch = palette[i] as char;
+ if y <= 0.01 {
+ write!(w, "{ch}")?;
+ continue;
+ }
// must round it into ansi256 or we will get duplicates
let color = p.to_rgb().ansi_256();
if let Some(last) = last_p {
if last == color {
- output.push(ch);
+ write!(w, "{ch}")?;
continue;
}
}
+
last_p = Some(color);
- output.push_str(&fg!(color, ch));
+ write!(w, "{}", fg!(color, ch))?;
}
- });
- output.join("\n")
+ writeln!(w)?;
+ }
+ Ok(())
}
}
@@ -61,16 +60,3 @@ impl Ansi256 for Rgb<u8> {
fn i2range(i: u8) -> f32 {
(i as f32 / u8::MAX as f32).clamp(0.0, 1.0)
}
-
-#[test]
-fn ansi_color() {
- macro_rules! test {
- ($c:expr, $expect:expr) => {{
- let args: [u8; 3] = $c;
- assert_eq!(Rgb::from(args).ansi_256(), $expect)
- }};
- }
- test!([0, 0, 255], 21);
- test!([0, 255, 0], 46);
- test!([255, 0, 0], 196);
-}