palette-bin 0.1.0

Apply an ACT palette to and optionally resize an image
Documentation
pub mod args;
pub mod palette;
pub mod resize;

#[derive(Debug, PartialEq, clap::ValueEnum, Clone)]
pub enum RatioMode {
    Maintain,
    Stretch,
    Crop,
}

#[cfg(test)]
pub mod test_utils {
    use image::{ImageBuffer, Rgb};
    use std::fs::File;
    use std::{io, io::Write, path::PathBuf};

    /// Creates a pattern for testing. The top left is always pure black, bottom right pure white.
    pub fn create_test_image(width: u32, height: u32) -> image::RgbImage {
        let mut img = ImageBuffer::new(width, height);
        for (x, y, pixel) in img.enumerate_pixels_mut() {
            let r = (x * 255 / (width - 1)) as u8;
            let g = (y * 255 / (height - 1)) as u8;
            let b = ((x + y) * 255 / (width + height - 2)) as u8;
            *pixel = Rgb([r, g, b]);
        }
        img
    }

    // Helper function to create a simple ACT palette for testing with 5 basic colors
    pub fn create_test_act_file(path: &PathBuf) -> Result<(), io::Error> {
        let mut file = File::create(path)?;

        // Define our 5 colors: black, white, red, green, blue
        let colors = [
            [0, 0, 0],       // Black
            [255, 255, 255], // White
            [255, 0, 0],     // Red
            [0, 255, 0],     // Green
            [0, 0, 255],     // Blue
        ];

        // Write the color data
        let mut palette_data = Vec::new();

        // First write all the defined colors
        for color in &colors {
            palette_data.push(color[0]); // R
            palette_data.push(color[1]); // G
            palette_data.push(color[2]); // B
        }

        // Pad the rest of the 256-color palette with zeros
        // Each color takes 3 bytes, we have 5 colors, so need 251 more colors worth of padding
        // That's 251 * 3 = 753 bytes of padding
        palette_data.extend(vec![0; 251 * 3]);

        // Write the number of actual colors at offset 768 (2 bytes)
        palette_data.push(0); // High byte of 5 (0x0005)
        palette_data.push(5); // Low byte of 5

        // Write the transparent color index as -1 (0xFFFF) meaning no transparent color
        palette_data.push(0xFF);
        palette_data.push(0xFF);

        // Write all the data to the file
        file.write_all(&palette_data)?;
        Ok(())
    }
}