use std::env;
use std::fs::File;
use std::io::Write;
use tx2_iff::{Encoder, EncoderConfig};
fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
let args: Vec<String> = env::args().collect();
if args.len() < 3 {
eprintln!("Usage: {} <input.png|jpg> <output.iff> [options]", args[0]);
eprintln!();
eprintln!("Options:");
eprintln!(" --levels <n> Wavelet decomposition levels (default: 5)");
eprintln!(" --quality <n> Base quantization (default: 10, lower = better)");
eprintln!(" --texture-size <n> Minimum texture region size (default: 32)");
eprintln!(" --no-texture Disable Layer 2 (texture synthesis)");
eprintln!(" --no-warp Disable Layer 3 (warp fields)");
eprintln!(" --residual-threshold <f> Residual RMSE threshold (default: 5.0)");
std::process::exit(1);
}
let input_path = &args[1];
let output_path = &args[2];
let mut config = EncoderConfig::default();
let mut i = 3;
while i < args.len() {
match args[i].as_str() {
"--levels" => {
i += 1;
if i < args.len() {
config.wavelet_levels = args[i].parse()?;
}
}
"--quality" => {
i += 1;
if i < args.len() {
config.base_quantization = args[i].parse()?;
}
}
"--texture-size" => {
i += 1;
if i < args.len() {
config.texture_min_size = args[i].parse()?;
}
}
"--no-texture" => {
config.enable_layer2 = false;
}
"--no-warp" => {
config.enable_layer3 = false;
}
"--residual-threshold" => {
i += 1;
if i < args.len() {
config.residual_threshold = args[i].parse()?;
}
}
_ => {
eprintln!("Warning: Unknown option: {}", args[i]);
}
}
i += 1;
}
println!("Loading image: {}", input_path);
let image = image::open(input_path)?;
let width = image.width();
let height = image.height();
println!("Image size: {}x{}", width, height);
println!();
println!("Encoder configuration:");
println!(" Wavelet levels: {}", config.wavelet_levels);
println!(" Base quantization: {}", config.base_quantization);
println!(" Layer 2 (texture): {}", config.enable_layer2);
println!(" Layer 3 (warp): {}", config.enable_layer3);
println!(" Texture min size: {}", config.texture_min_size);
println!(" Residual threshold: {:.1}", config.residual_threshold);
println!();
println!("Encoding...");
let encoder = Encoder::new(config);
let iff_image = encoder.encode(&image)?;
println!("Serializing...");
let iff_bytes = iff_image.to_bytes()?;
println!("Writing to: {}", output_path);
let mut file = File::create(output_path)?;
file.write_all(&iff_bytes)?;
let original_size = (width * height * 3) as usize; let compressed_size = iff_bytes.len();
let ratio = original_size as f64 / compressed_size as f64;
let savings = (1.0 - (compressed_size as f64 / original_size as f64)) * 100.0;
println!();
println!("Encoding complete!");
println!(" Original size: {} bytes ({:.2} KB)", original_size, original_size as f64 / 1024.0);
println!(" Compressed size: {} bytes ({:.2} KB)", compressed_size, compressed_size as f64 / 1024.0);
println!(" Compression ratio: {:.2}x", ratio);
println!(" Space savings: {:.1}%", savings);
println!();
println!("Layer statistics:");
let layer1_size = iff_image.layer1.y.data.len() + iff_image.layer1.co.data.len() + iff_image.layer1.cg.data.len();
println!(" Layer 1 (wavelet): {} bytes (compressed)", layer1_size);
println!(" Layer 2 (texture): {} regions", iff_image.layer2.regions.len());
println!(" Layer 3 (warp): {} vortices", iff_image.layer3.vortices.len());
println!(" Residual: {} bytes (compressed)", iff_image.residual.data.len());
Ok(())
}