feat: opening jxls

This commit is contained in:
electria 2026-07-03 14:27:02 -07:00
commit 9b9c04c470
Signed by: electria
SSH key fingerprint: SHA256:8LlB3ucPbBHqozqkhsNbaV5oG3SlzzqUj8FZDL6IPQs

View file

@ -14,7 +14,7 @@ use iced::{
use image::{ use image::{
DynamicImage, EncodableLayout, ImageDecoder, ImageReader, RgbImage, RgbaImage, imageops, DynamicImage, EncodableLayout, ImageDecoder, ImageReader, RgbImage, RgbaImage, imageops,
}; };
use jpegxl_rs::decode::JxlDecoder; use jpegxl_rs::image::ToDynamic;
use rfd::FileDialog; use rfd::FileDialog;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -123,12 +123,43 @@ impl State {
} }
fn load_image(&mut self, path: impl AsRef<Path>) -> Option<String> { fn load_image(&mut self, path: impl AsRef<Path>) -> Option<String> {
let path = path.as_ref();
let decoded_image = match path.extension().map(OsStr::to_string_lossy).as_deref() {
Some("jxl") => {
let data = match std::fs::read(path) {
Ok(d) => d,
Err(e) => {
return Some(format!(
"failed to read data from '{}': {e}",
path.display()
));
}
};
match jpegxl_rs::decoder_builder()
.build()
.unwrap()
.decode_to_image(&data)
{
Ok(Some(decoded_image)) => decoded_image,
Ok(None) => {
return Some(format!(
"failed to convert jxl '{}' to DynamicImage",
path.display()
));
}
Err(e) => return Some(format!("faled to decode '{}' {e}", path.display())),
}
}
_ => {
let reader = match ImageReader::open(&path) { let reader = match ImageReader::open(&path) {
Ok(r) => r, Ok(r) => r,
Err(e) => { Err(e) => {
return Some(format!( return Some(format!(
"failed to create reader for '{}': {e}", "failed to create reader for '{}': {e}",
path.as_ref().display() path.display()
)); ));
} }
}; };
@ -138,7 +169,7 @@ impl State {
Err(e) => { Err(e) => {
return Some(format!( return Some(format!(
"failed to create decoder for '{}': {e}", "failed to create decoder for '{}': {e}",
path.as_ref().display() path.display()
)); ));
} }
}; };
@ -148,7 +179,7 @@ impl State {
Err(e) => { Err(e) => {
return Some(format!( return Some(format!(
"failed to get oreintation of '{}': {e}", "failed to get oreintation of '{}': {e}",
path.as_ref().display() path.display()
)); ));
} }
}; };
@ -156,15 +187,16 @@ impl State {
let mut decoded_image = match DynamicImage::from_decoder(decoder) { let mut decoded_image = match DynamicImage::from_decoder(decoder) {
Ok(i) => i, Ok(i) => i,
Err(e) => { Err(e) => {
return Some(format!( return Some(format!("failed to decode image '{}': {e}", path.display()));
"failed to decode image '{}': {e}",
path.as_ref().display()
));
} }
}; };
decoded_image.apply_orientation(oreintation); decoded_image.apply_orientation(oreintation);
decoded_image
}
};
self.image = Some(decoded_image.into_rgba8()); self.image = Some(decoded_image.into_rgba8());
None None
@ -219,7 +251,7 @@ impl State {
return Some(format!("failed to write jxl to '{}': {e}", path.display())); return Some(format!("failed to write jxl to '{}': {e}", path.display()));
}; };
} }
None | Some(_) => { _ => {
if let Err(e) = image.save(&path) { if let Err(e) = image.save(&path) {
return Some(format!("failed to save '{}': {e}", path.display())); return Some(format!("failed to save '{}': {e}", path.display()));
}; };