75 lines
2.5 KiB
Rust
75 lines
2.5 KiB
Rust
use async_zip;
|
|
use async_zip::base::read::seek::ZipFileReader;
|
|
use async_zip::base::write::ZipFileWriter;
|
|
use async_zip::{Compression, ZipEntryBuilder};
|
|
use infer;
|
|
use magick_rust::{self, MagickError};
|
|
use std::env;
|
|
use std::ffi::OsStr;
|
|
use std::path::Path;
|
|
use tokio::{fs::File, io::BufReader};
|
|
use tokio_util::compat::TokioAsyncReadCompatExt;
|
|
|
|
fn compress_image(input: Vec<u8>, extension: &str) -> Result<Vec<u8>, MagickError> {
|
|
let wand = magick_rust::MagickWand::new();
|
|
wand.read_image_blob(input)?;
|
|
wand.fit(1200, 1600);
|
|
wand.strip_image()?;
|
|
wand.write_image_blob(extension)
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> std::io::Result<()> {
|
|
let mut argv = env::args();
|
|
if argv.len() != 2 {
|
|
panic!("Not enough arguments");
|
|
}
|
|
let filename: String = argv.nth(1).unwrap();
|
|
let buf = File::open(&filename);
|
|
magick_rust::magick_wand_genesis();
|
|
|
|
let buf = BufReader::new(buf.await.expect("Failed to open input file")).compat();
|
|
let mut zip = ZipFileReader::new(buf)
|
|
.await
|
|
.expect("Failed to decompress input file.");
|
|
let tmp_filename = filename.to_string() + ".tmp";
|
|
let tmp_filepath = Path::new(&tmp_filename);
|
|
let tmp_file = File::create(tmp_filepath).await?;
|
|
let mut tmp_zip = ZipFileWriter::new(tmp_file.compat());
|
|
|
|
for i in 0..zip.file().entries().len() {
|
|
let file = zip.file().entries().get(i).unwrap().clone();
|
|
let filename = file.filename();
|
|
let entry = zip.reader_with_entry(i);
|
|
let mut buf = vec![];
|
|
|
|
let n = entry
|
|
.await
|
|
.expect("Failed to get zip individual file.")
|
|
.read_to_end_checked(&mut buf)
|
|
.await
|
|
.expect("Failed to read the zip individual file.");
|
|
let builder = ZipEntryBuilder::new(filename.clone(), Compression::Deflate);
|
|
let to_write = if infer::is_image(&buf[..n]) {
|
|
let extension = Path::new(filename.as_str().expect("Failed to read filename."))
|
|
.extension()
|
|
.and_then(OsStr::to_str)
|
|
.expect("String");
|
|
let to_write = compress_image(buf, extension).expect("Failed to compress image");
|
|
println!("{}", extension);
|
|
println!("data len: {}", to_write.len());
|
|
to_write
|
|
} else {
|
|
buf
|
|
};
|
|
tmp_zip
|
|
.write_entry_whole(builder, &to_write)
|
|
.await
|
|
.expect("Failed to write a compressed image.");
|
|
}
|
|
|
|
tmp_zip.close().await.expect("Failed to close the file");
|
|
|
|
Ok(())
|
|
}
|