cargo: Update to glycin 4.0.0-alpha

This commit is contained in:
Sophie Herold 2026-06-25 16:52:58 +02:00
parent 95e473207f
commit 05edeb1418
7 changed files with 540 additions and 174 deletions

View file

@ -65,15 +65,15 @@ pub enum DecoderUpdate {
#[derive(Debug, Clone)]
pub enum DecoderError {
/// Image format not supported or unknown
UnsupportedFormat(String, glycin::ErrorCtx),
UnsupportedFormat(String, glycin::Error),
/// No glycin-loaders installed
NoLoadersConfigured(glycin::ErrorCtx),
NoLoadersConfigured(glycin::Error),
/// Memory limit exceeded
OutOfMemory(glycin::ErrorCtx),
OutOfMemory(glycin::Error),
/// Failed to load image
ImageSource(glib::Error, glycin::ErrorCtx),
ImageSource(glib::Error, glycin::Error),
Generic(glycin::ErrorCtx),
Generic(glycin::Error),
}
impl UpdateSender {
@ -90,13 +90,13 @@ impl UpdateSender {
/// Send occurring errors to renderer
pub fn spawn_error_handled<F>(&self, f: F) -> glib::JoinHandle<()>
where
F: std::future::Future<Output = Result<(), glycin::ErrorCtx>> + Send + 'static,
F: std::future::Future<Output = Result<(), glycin::Error>> + Send + 'static,
{
let update_sender = self.clone();
glib::spawn_future(async move {
let update_sender = update_sender.clone();
let result: Result<(), glycin::ErrorCtx> = f.await;
let result: Result<(), glycin::Error> = f.await;
if let Err(err) = result {
update_sender.send_error(err);
@ -104,7 +104,7 @@ impl UpdateSender {
})
}
pub fn send_error(&self, err: glycin::ErrorCtx) {
pub fn send_error(&self, err: glycin::Error) {
if let Some(mime_type) = err.unsupported_format() {
let mut metadata = Metadata::default();
metadata.set_mime_type(mime_type.clone());
@ -115,14 +115,13 @@ impl UpdateSender {
))));
} else if err.is_out_of_memory() {
self.send(DecoderUpdate::Error(Some(DecoderError::OutOfMemory(err))));
} else if matches!(err.error(), glycin::Error::NoLoadersConfigured(_)) {
} else if err.has_no_processor_configured() {
self.send(DecoderUpdate::Error(Some(
DecoderError::NoLoadersConfigured(err),
)));
} else if let glycin::Error::ImageSource(glib_err) = err.error() {
} else if let Some(glib_err) = err.failed_image_source() {
self.send(DecoderUpdate::Error(Some(DecoderError::ImageSource(
glib_err.clone(),
err,
glib_err, err,
))));
} else {
self.send(DecoderUpdate::Error(Some(DecoderError::Generic(err))));

View file

@ -43,7 +43,11 @@ impl Drop for Glycin {
}
impl Glycin {
pub fn new(image: glycin::Image, updater: UpdateSender, tiles: Arc<SharedFrameBuffer>) -> Self {
pub fn new(
mut image: glycin::Image,
updater: UpdateSender,
tiles: Arc<SharedFrameBuffer>,
) -> Self {
let cancellable = image.cancellable();
let (next_frame_send, next_frame_recv) = async_channel::bounded(2);

View file

@ -61,7 +61,11 @@ impl Drop for Svg {
}
impl Svg {
pub fn new(image: glycin::Image, updater: UpdateSender, tiles: Arc<SharedFrameBuffer>) -> Self {
pub fn new(
mut image: glycin::Image,
updater: UpdateSender,
tiles: Arc<SharedFrameBuffer>,
) -> Self {
let current_request: Arc<std::sync::RwLock<Request>> = Default::default();
let request_store = current_request.clone();
let cancellable = image.cancellable();
@ -187,7 +191,7 @@ impl Svg {
#[allow(unused_mut)]
let loader = glycin::Loader::new(file.clone());
let image = loader.load().await?;
let mut image = loader.load().await?;
let frame_request = glycin::FrameRequest::new().scale(width as u32, height as u32);
let frame = image.specific_frame(frame_request).await?;

View file

@ -62,19 +62,11 @@ impl Metadata {
}
pub fn set_image_info(&mut self, image_info: ImageDetails) {
if let Some(exif_raw) = image_info
.metadata_exif()
.as_ref()
.and_then(|x| x.get_full().ok())
{
self.set_exif_bytes(exif_raw);
if let Some(exif_raw) = image_info.metadata_exif() {
self.set_exif_bytes(exif_raw.to_owned());
}
if let Some(exif_xmp) = image_info
.metadata_xmp()
.as_ref()
.and_then(|x| x.get_full().ok())
{
self.set_xmp_bytes(exif_xmp);
if let Some(exif_xmp) = image_info.metadata_xmp() {
self.set_xmp_bytes(exif_xmp.to_owned());
}
self.image_info = Some(image_info);
}
@ -261,8 +253,8 @@ impl Metadata {
}
pub fn exposure_time(&self) -> Option<String> {
if let Some((num, denom)) = self.metadata.exposure_time() {
let speed = num as f64 / denom as f64;
if let Some(exposure_time) = self.metadata.exposure_time() {
let speed = exposure_time.as_f64();
if speed <= 0.5 {
let exposure = format!("{:.0}", 1. / speed);
// Translators: Fractional exposure time (photography) in seconds
@ -288,7 +280,7 @@ impl Metadata {
pub fn focal_length(&self) -> Option<String> {
self.metadata
.focal_length()
.map(|focal_length| gettext_f(r"{}\u{202F}mm", [focal_length.to_string()]))
.map(|focal_length| gettext_f(r"{}\u{202F}mm", [focal_length.as_f32().to_string()]))
}
/// Combined maker and model info

View file

@ -364,7 +364,7 @@ mod imp {
Err(err) => Err(err),
};
match result {
Err(err) if matches!(err.error(), glycin::Error::Canceled(_)) => {
Err(err) if err.is_cancelled() => {
tracing::debug!("Computing edited image canceled");
}
Err(err) => {
@ -377,41 +377,32 @@ mod imp {
}
Ok(edit) => {
tracing::debug!("Saving edited image to '{}'", new_file.uri());
match edit.data().get() {
Err(err) => {
obj.window_show_error(
&gettext("Failed to Save Image"),
&format!("Failed to get binary data: {err}"),
ErrorType::General,
);
}
Ok(data) => {
self.set_saving_status(Some(gettext("Saving Image")));
self.set_saving_status(Some(gettext("Saving Image")));
let save_result = gio::CancellableFuture::new(
new_file.replace_contents_future(
data,
None,
true,
gio::FileCreateFlags::NONE,
),
cancellable,
)
.await;
// TODO: Clone might be avoidable
let data = edit.data().to_vec();
let save_result = gio::CancellableFuture::new(
new_file.replace_contents_future(
data,
None,
true,
gio::FileCreateFlags::NONE,
),
cancellable,
)
.await;
if save_result.is_err() {
tracing::debug!("Saving image canceled");
} else if let Ok(Err(err)) = save_result {
obj.window_show_error(
&gettext("Failed to Save Image"),
&format!("Failed to write file:\n\n{err:?}"),
ErrorType::General,
);
} else {
tracing::debug!("Image saved");
return true;
}
}
if save_result.is_err() {
tracing::debug!("Saving image canceled");
} else if let Ok(Err(err)) = save_result {
obj.window_show_error(
&gettext("Failed to Save Image"),
&format!("Failed to write file:\n\n{err:?}"),
ErrorType::General,
);
} else {
tracing::debug!("Image saved");
return true;
}
}
}