Skip to content
Snippets Groups Projects
format.rs 1.6 KiB
Newer Older
Louis's avatar
Louis committed
use std::path::Path;

use clap::ValueEnum;
Louis's avatar
Louis committed
use image::io::Reader;
use image::{ImageError, ImageFormat, RgbaImage};
use serde::{Deserialize, Serialize};
use thiserror::Error;

#[derive(
	Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug, Serialize, Deserialize, Default,
Louis's avatar
Louis committed
)]
pub enum PaletteFormat {
	#[serde(alias = "txt")]
Louis's avatar
Louis committed
	Txt,
Louis's avatar
Louis committed
	#[default]
	#[serde(alias = "png")]
Louis's avatar
Louis committed
	Png,
	#[serde(alias = "columns")]
	Columns,
Louis's avatar
Louis committed
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)]
Louis's avatar
Louis committed
pub enum Format {
Louis's avatar
Louis committed
	Png,
	Jpg,
	Gif,
	Ico,
	Tga,
	Tiff,
	Bmp,
Louis's avatar
Louis committed
}

impl Format {
	pub fn as_image_format(&self) -> ImageFormat {
		use Format::*;
		match self {
Louis's avatar
Louis committed
			Png => ImageFormat::Png,
			Jpg => ImageFormat::Jpeg,
			Gif => ImageFormat::Gif,
			Ico => ImageFormat::Ico,
			Tga => ImageFormat::Tga,
			Tiff => ImageFormat::Tiff,
			Bmp => ImageFormat::Bmp,
Louis's avatar
Louis committed
		}
	}
}

#[derive(Error, Debug)]
pub enum ImageLoadingError {
	#[error("Failed to load image data; {0}")]
	IoError(#[from] std::io::Error),
	#[error("Failed to process image; {0}")]
	ImageError(#[from] ImageError),
}

pub fn load_image(
	path: impl ToString,
Louis's avatar
Louis committed
	format: Option<Format>,
) -> anyhow::Result<RgbaImage, ImageLoadingError> {
	let mut image = Reader::open(path.to_string())?;
Louis's avatar
Louis committed
	let file = match format {
		Some(format) => {
			image.set_format(format.as_image_format());
			image.decode()?.into_rgba8()
		}
		None => image.with_guessed_format()?.decode()?.into_rgba8(),
	};

	Ok(file)
}

pub fn make_paths<T: AsRef<Path>>(path: T) -> anyhow::Result<(), std::io::Error> {
	if let Some(target) = path.as_ref().parent() {
		std::fs::create_dir_all(target)
	} else {
		Ok(())
	}
}