agb/agb-image-converter/src/lib.rs

91 lines
2.2 KiB
Rust
Raw Normal View History

use std::fs::File;
use std::io::BufWriter;
2021-04-21 07:52:23 +10:00
use std::path::PathBuf;
2021-06-06 02:45:21 +10:00
use typed_builder::TypedBuilder;
2021-04-20 08:15:03 +10:00
mod colour;
2021-04-20 09:40:07 +10:00
mod image_loader;
mod palette16;
2021-04-21 05:41:04 +10:00
mod rust_generator;
2021-04-20 09:40:07 +10:00
use image_loader::Image;
2021-04-20 08:15:03 +10:00
pub use colour::Colour;
#[derive(Debug, Clone, Copy)]
pub enum TileSize {
Tile8,
Tile16,
}
2021-04-20 09:40:07 +10:00
impl TileSize {
2021-04-21 07:56:47 +10:00
fn to_size(self) -> usize {
match self {
2021-04-20 09:40:07 +10:00
TileSize::Tile8 => 8,
TileSize::Tile16 => 16,
}
}
}
2021-06-06 02:45:21 +10:00
#[derive(TypedBuilder)]
2021-04-20 08:15:03 +10:00
pub struct ImageConverterConfig {
2021-06-06 02:45:21 +10:00
#[builder(default, setter(strip_option))]
transparent_colour: Option<Colour>,
tile_size: TileSize,
input_image: PathBuf,
output_file: PathBuf,
2021-06-06 02:47:13 +10:00
#[builder(default, setter(strip_option))]
crate_prefix: Option<String>,
2021-04-20 09:40:07 +10:00
}
2021-06-06 02:45:21 +10:00
pub fn convert_image(settings: ImageConverterConfig) {
2021-04-20 09:40:07 +10:00
let image = Image::load_from_file(&settings.input_image);
let tile_size = settings.tile_size.to_size();
if image.width % tile_size != 0 || image.height % tile_size != 0 {
panic!("Image size not a multiple of tile size");
}
let optimiser = optimiser_for_image(&image, tile_size);
let optimisation_results = optimiser.optimise_palettes(settings.transparent_colour);
let output_file = File::create(&settings.output_file).expect("Failed to create file");
let mut writer = BufWriter::new(output_file);
2021-04-21 05:41:04 +10:00
rust_generator::generate_code(
&mut writer,
&optimisation_results,
&image,
settings.tile_size,
2021-06-06 02:47:13 +10:00
settings.crate_prefix.unwrap_or("agb".to_owned()),
2021-04-21 05:41:04 +10:00
)
.expect("Failed to write data");
}
2021-04-20 09:40:07 +10:00
fn optimiser_for_image(image: &Image, tile_size: usize) -> palette16::Palette16Optimiser {
let tiles_x = image.width / tile_size;
let tiles_y = image.height / tile_size;
let mut palette_optimiser = palette16::Palette16Optimiser::new();
for y in 0..tiles_y {
for x in 0..tiles_x {
let mut palette = palette16::Palette16::new();
for j in 0..tile_size {
for i in 0..tile_size {
let colour = image.colour(x * tile_size + i, y * tile_size + j);
2021-04-20 09:57:47 +10:00
palette.add_colour(colour);
2021-04-20 09:40:07 +10:00
}
}
palette_optimiser.add_palette(palette);
}
}
palette_optimiser
}