use anyhow::Result;
use std::path::Path;
use crate::image::{Image, ImageSize};
use super::jpeg::{ImageDecoder, ImageEncoder};
pub fn read_image_jpeg(file_path: &Path) -> Result<Image<u8, 3>> {
if !file_path.exists() {
return Err(anyhow::anyhow!(
"File does not exist: {}",
file_path.to_str().unwrap()
));
}
if file_path.extension().map_or(true, |ext| {
ext.to_ascii_lowercase() != "jpg" && ext.to_ascii_lowercase() != "jpeg"
}) {
return Err(anyhow::anyhow!(
"File is not a JPEG: {}",
file_path.to_str().unwrap()
));
}
let file = std::fs::File::open(file_path)?;
let mmap = unsafe { memmap2::Mmap::map(&file)? };
let image: Image<u8, 3> = {
let mut decoder = ImageDecoder::new()?;
decoder.decode(&mmap)?
};
Ok(image)
}
pub fn write_image_jpeg(file_path: &Path, image: &Image<u8, 3>) -> Result<()> {
let jpeg_data = ImageEncoder::new()?.encode(image)?;
std::fs::write(file_path, jpeg_data)?;
Ok(())
}
pub fn read_image_any(file_path: &Path) -> Result<Image<u8, 3>> {
if !file_path.exists() {
return Err(anyhow::anyhow!(
"File does not exist: {}",
file_path.to_str().unwrap()
));
}
let file = std::fs::File::open(file_path)?;
let mmap = unsafe { memmap2::Mmap::map(&file)? };
let img = image::io::Reader::new(std::io::Cursor::new(&mmap))
.with_guessed_format()?
.decode()?;
let data = img.to_rgb8().to_vec();
let image = Image::new(
ImageSize {
width: img.width() as usize,
height: img.height() as usize,
},
data,
)?;
Ok(image)
}
#[cfg(test)]
mod tests {
use std::fs;
use std::path::Path;
use tempfile::tempdir;
use crate::io::functional::{read_image_any, read_image_jpeg, write_image_jpeg};
#[test]
fn read_jpeg() {
let image_path = Path::new("tests/data/dog.jpeg");
let image = read_image_jpeg(image_path).unwrap();
assert_eq!(image.size().width, 258);
assert_eq!(image.size().height, 195);
}
#[test]
fn read_any() {
let image_path = Path::new("tests/data/dog.jpeg");
let image = read_image_any(image_path).unwrap();
assert_eq!(image.size().width, 258);
assert_eq!(image.size().height, 195);
}
#[test]
fn read_write_jpeg() {
let image_path_read = Path::new("tests/data/dog.jpeg");
let tmp_dir = tempdir().unwrap();
fs::create_dir_all(tmp_dir.path()).unwrap();
let file_path = tmp_dir.path().join("dog.jpeg");
let image_data = read_image_jpeg(image_path_read).unwrap();
write_image_jpeg(&file_path, &image_data).unwrap();
let image_data_back = read_image_jpeg(&file_path).unwrap();
assert!(file_path.exists(), "File does not exist: {:?}", file_path);
assert_eq!(image_data_back.size().width, 258);
assert_eq!(image_data_back.size().height, 195);
assert_eq!(image_data_back.num_channels(), 3);
}
}