use crate::parsers::FileType;
use crate::utils::filetypes::get_extensions_for_file_type;
use super::{bmp, gif, jpeg, png, tiff, webp};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ImageFormat {
Jpeg,
Png,
Gif,
WebP,
Bmp,
Tiff,
}
pub trait FormatMetadata {
fn extract_compression(&self, data_ref: &[u8]) -> Option<String>;
fn extract_chroma_subsampling(&self, _data_ref: &[u8]) -> Option<String> {
None }
fn extract_bit_depth(&self, _data_ref: &[u8]) -> Option<u32> {
None }
fn extract_color_type(&self, _data_ref: &[u8]) -> Option<String> {
None }
}
impl FormatMetadata for ImageFormat {
fn extract_compression(&self, data_ref: &[u8]) -> Option<String> {
match self {
ImageFormat::Jpeg => Some(jpeg::extract_compression(data_ref)),
ImageFormat::Png => png::extract_compression(data_ref),
ImageFormat::Gif => gif::extract_compression(data_ref),
ImageFormat::WebP => webp::extract_compression(data_ref),
ImageFormat::Bmp => bmp::extract_compression(data_ref),
ImageFormat::Tiff => tiff::extract_compression(data_ref),
}
}
fn extract_chroma_subsampling(&self, data_ref: &[u8]) -> Option<String> {
match self {
ImageFormat::Jpeg => jpeg::extract_subsampling(data_ref),
_ => None, }
}
fn extract_bit_depth(&self, data_ref: &[u8]) -> Option<u32> {
match self {
ImageFormat::Jpeg => jpeg::extract_bit_depth(data_ref),
ImageFormat::Png => png::extract_bit_depth(data_ref),
ImageFormat::Bmp => bmp::extract_bit_depth(data_ref),
ImageFormat::Tiff => tiff::extract_bit_depth(data_ref),
ImageFormat::Gif | ImageFormat::WebP => Some(8),
}
}
fn extract_color_type(&self, data_ref: &[u8]) -> Option<String> {
match self {
ImageFormat::Jpeg => jpeg::extract_color_type(data_ref),
ImageFormat::Png => png::extract_color_type(data_ref),
ImageFormat::Gif => gif::extract_color_type(data_ref),
ImageFormat::Bmp => bmp::extract_color_type(data_ref),
ImageFormat::WebP => webp::extract_color_type(data_ref),
ImageFormat::Tiff => Some(tiff::extract_color_type(data_ref)),
}
}
}
const IMAGE_FORMAT_MAP: &[(&str, ImageFormat)] = &[
("jpeg", ImageFormat::Jpeg),
("jpg", ImageFormat::Jpeg),
("png", ImageFormat::Png),
("gif", ImageFormat::Gif),
("webp", ImageFormat::WebP),
("bmp", ImageFormat::Bmp),
("tiff", ImageFormat::Tiff),
("tif", ImageFormat::Tiff),
];
#[must_use]
pub fn format_from_string(format_str_ref: &str) -> Option<ImageFormat> {
let format_lower = format_str_ref.to_lowercase();
let image_extensions = get_extensions_for_file_type(FileType::Image);
IMAGE_FORMAT_MAP
.iter()
.find(|(ext, _)| format_lower.contains(ext) && image_extensions.contains(ext))
.map(|(_, format)| *format)
}