wagahai_lut 0.1.0

CUBE LUT parser and image processing library with SIMD
Documentation
/*
 * SPDX-FileCopyrightText: © 2026 Jinwoo Park (pmnxis@gmail.com)
 *
 * SPDX-License-Identifier: MIT
 */

use std::env;
use std::time::Instant;
use wagahai_lut::CubeParser;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args: Vec<String> = env::args().collect();

    if args.len() < 2 {
        println!(
            "Usage: {} <cube-file> [input-image] [output-image]",
            args[0]
        );
        println!("\nExamples:");
        println!(
            "  {} lut.cube                              # Parse and display LUT info",
            args[0]
        );
        println!(
            "  {} lut.cube input.jpg out.jpg            # Apply LUT to image",
            args[0]
        );
        return Ok(());
    }

    let cube_path = &args[1];

    // Parse CUBE LUT file
    println!("Loading CUBE LUT from: {}", cube_path);
    let lut = CubeParser::from_file(cube_path)?;

    // Display LUT information
    println!("\nLUT Information:");
    if let Some(ref title) = lut.title {
        println!("  Title: {}", title);
    }
    println!("  Type: {:?}", lut.get_lut_type());
    println!("  Domain Min: {:?}", lut.domain_min);
    println!("  Domain Max: {:?}", lut.domain_max);

    if let Some(lut_1d) = lut.lut_1d() {
        println!("  1D LUT Size: {}", lut_1d.size());
    } else if let Some(lut_3d) = lut.lut_3d() {
        let size = lut_3d.size();
        println!(
            "  3D LUT Size: {} ({}x{}x{} total points)",
            size * size * size,
            size,
            size,
            size,
        );
    }

    // If image paths are provided, apply LUT to image
    if args.len() >= 4 {
        let input_path = &args[2];
        let output_path = &args[3];

        println!("\nApplying LUT to image: {}", input_path);

        let load_start = Instant::now();
        let image = image::open(input_path)?;
        let load_duration = load_start.elapsed();
        println!("  Image size: {}x{}", image.width(), image.height());
        println!("  Image load time: {:?}", load_duration);

        let apply_start = Instant::now();
        let processed = lut.apply_to_image(&image)?;
        let apply_duration = apply_start.elapsed();
        println!("  LUT apply time: {:?}", apply_duration);

        let save_start = Instant::now();
        processed.save(output_path)?;
        let save_duration = save_start.elapsed();
        println!("  Image save time: {:?}", save_duration);
        println!(
            "  Total time: {:?}",
            load_duration + apply_duration + save_duration
        );
        println!("  Saved to: {}", output_path);
    }

    // Test with basic colors
    println!("\nTest LUT with basic colors:");

    let colors = [
        ("Red  ", [1.0, 0.0, 0.0]),
        ("Green", [0.0, 1.0, 0.0]),
        ("Blue ", [0.0, 0.0, 1.0]),
        ("White", [1.0, 1.0, 1.0]),
        ("Black", [0.0, 0.0, 0.0]),
    ];

    for (name, color) in colors {
        let result = lut.apply_to_color(color)?;
        println!(
            "Apply LUT to pure {} [{:.1}, {:.1}, {:.1}] -> [{:.4}, {:.4}, {:.4}]",
            name, color[0], color[1], color[2], result[0], result[1], result[2]
        );
    }

    Ok(())
}