Update to glycin 2.0 alpha.7
This commit is contained in:
parent
1b0b68c773
commit
b3d972c5c3
8 changed files with 62 additions and 29 deletions
32
Cargo.lock
generated
32
Cargo.lock
generated
|
|
@ -860,9 +860,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glycin"
|
name = "glycin"
|
||||||
version = "3.0.0-alpha.5"
|
version = "3.0.0-alpha.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8016964f551c43438a8f0dba2bcfe52b8691e19149708492a83a830b605f05b8"
|
checksum = "96c2cf69d077fa279fc3a2e6941fd05fc2f3f161910b495bc55e8f2068a50c0b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-fs",
|
"async-fs",
|
||||||
"async-io",
|
"async-io",
|
||||||
|
|
@ -874,6 +874,7 @@ dependencies = [
|
||||||
"gdk4",
|
"gdk4",
|
||||||
"gio",
|
"gio",
|
||||||
"glib",
|
"glib",
|
||||||
|
"glycin-common",
|
||||||
"glycin-utils",
|
"glycin-utils",
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
"gufo-exif",
|
"gufo-exif",
|
||||||
|
|
@ -892,16 +893,36 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glycin-utils"
|
name = "glycin-common"
|
||||||
version = "4.0.0-alpha.4"
|
version = "1.0.0-alpha.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "301cc1196f9ef49a11e98eb11fe6d587beae746f1f06ed99569ca34b50e49e66"
|
checksum = "72f726fe14063e230fd79a77a602469d1a7c721c6fe1037bb69786df08b79cdc"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.1",
|
||||||
|
"gufo-common",
|
||||||
|
"half",
|
||||||
|
"memmap2",
|
||||||
|
"nix",
|
||||||
|
"paste",
|
||||||
|
"rmp-serde",
|
||||||
|
"serde",
|
||||||
|
"thiserror",
|
||||||
|
"zerocopy",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glycin-utils"
|
||||||
|
version = "4.0.0-alpha.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c87e6f0bedff21f6592368212277d232908f9d9fbf330a5f6558e6907a5b33c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-lock",
|
"async-lock",
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"blocking",
|
"blocking",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"glycin-common",
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
"half",
|
"half",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
@ -911,7 +932,6 @@ dependencies = [
|
||||||
"nix",
|
"nix",
|
||||||
"paste",
|
"paste",
|
||||||
"rayon",
|
"rayon",
|
||||||
"rmp-serde",
|
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"zbus",
|
"zbus",
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ chrono = { version = "0.4.38", default-features = false, features = ["std"] }
|
||||||
gettext-rs = { version = "0.7.0", features = ["gettext-system"] }
|
gettext-rs = { version = "0.7.0", features = ["gettext-system"] }
|
||||||
gettext-sys = { version = "0.22.5", features = ["gettext-system"] }
|
gettext-sys = { version = "0.22.5", features = ["gettext-system"] }
|
||||||
gio = { version = "0.20.0", features = ["v2_74"] }
|
gio = { version = "0.20.0", features = ["v2_74"] }
|
||||||
glycin = { version = "3.0.0-alpha.4", features = ["gdk4"] }
|
glycin = { version = "3.0.0-alpha.7", features = ["gdk4"] }
|
||||||
gtk = { package = "gtk4", version = "0.9.5", features = [
|
gtk = { package = "gtk4", version = "0.9.5", features = [
|
||||||
"v4_14",
|
"v4_14",
|
||||||
"xml_validation",
|
"xml_validation",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2023-2024 Sophie Herold
|
// Copyright (c) 2023-2025 Sophie Herold
|
||||||
// Copyright (c) 2023 Automeris naranja
|
// Copyright (c) 2023 Automeris naranja
|
||||||
// Copyright (c) 2023 Christopher Davis
|
// Copyright (c) 2023 Christopher Davis
|
||||||
// Copyright (c) 2024 Andre Klapper
|
// Copyright (c) 2024 Andre Klapper
|
||||||
|
|
|
||||||
|
|
@ -59,11 +59,11 @@ impl Glycin {
|
||||||
log::trace!("Image info received");
|
log::trace!("Image info received");
|
||||||
|
|
||||||
let mut metadata: Metadata = Metadata::default();
|
let mut metadata: Metadata = Metadata::default();
|
||||||
metadata.set_image_info(image.info().clone());
|
metadata.set_image_info(image.details().clone());
|
||||||
metadata.set_mime_type(image.mime_type().to_string());
|
metadata.set_mime_type(image.mime_type().to_string());
|
||||||
updater.send(DecoderUpdate::Metadata(Box::new(metadata)));
|
updater.send(DecoderUpdate::Metadata(Box::new(metadata)));
|
||||||
|
|
||||||
let dimensions = (image.info().width, image.info().height);
|
let dimensions = (image.details().width(), image.details().height());
|
||||||
tiles.set_original_dimensions(dimensions);
|
tiles.set_original_dimensions(dimensions);
|
||||||
|
|
||||||
let frame = image.next_frame().await?;
|
let frame = image.next_frame().await?;
|
||||||
|
|
|
||||||
|
|
@ -77,11 +77,11 @@ impl Svg {
|
||||||
let image = loader.load().await?;
|
let image = loader.load().await?;
|
||||||
|
|
||||||
let mut metadata: Metadata = Metadata::default();
|
let mut metadata: Metadata = Metadata::default();
|
||||||
metadata.set_image_info(image.info().clone());
|
metadata.set_image_info(image.details().clone());
|
||||||
metadata.set_mime_type(image.mime_type().to_string());
|
metadata.set_mime_type(image.mime_type().to_string());
|
||||||
updater.send(DecoderUpdate::Metadata(Box::new(metadata)));
|
updater.send(DecoderUpdate::Metadata(Box::new(metadata)));
|
||||||
|
|
||||||
tiles.set_original_dimensions((image.info().width, image.info().height));
|
tiles.set_original_dimensions((image.details().width(), image.details().height()));
|
||||||
|
|
||||||
let mut is_first_frame = true;
|
let mut is_first_frame = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ impl Queue {
|
||||||
async fn apply(&self, image: LpImage) -> anyhow::Result<()> {
|
async fn apply(&self, image: LpImage) -> anyhow::Result<()> {
|
||||||
let file = image.file().unwrap();
|
let file = image.file().unwrap();
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let editor = glycin::Editor::new(file.clone());
|
let editor = glycin::Editor::new(file.clone()).edit().await?;
|
||||||
|
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
self.operations.rcu(|current_operations| {
|
self.operations.rcu(|current_operations| {
|
||||||
|
|
@ -69,7 +69,7 @@ impl Queue {
|
||||||
});
|
});
|
||||||
|
|
||||||
let operations = Operations::new(list);
|
let operations = Operations::new(list);
|
||||||
let edit_instruction = editor.apply_sparse(operations).await?;
|
let edit_instruction = editor.apply_sparse(&operations).await?;
|
||||||
|
|
||||||
if edit_instruction.apply_to(file).await? == EditOutcome::Unchanged {
|
if edit_instruction.apply_to(file).await? == EditOutcome::Unchanged {
|
||||||
log::warn!("Writing new files is not supported yet");
|
log::warn!("Writing new files is not supported yet");
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ use std::str::FromStr;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
pub use file::FileInfo;
|
pub use file::FileInfo;
|
||||||
use glib::TimeZone;
|
use glib::TimeZone;
|
||||||
use glycin::{Frame, FrameDetails, ImageInfo, MemoryFormat};
|
use glycin::{Frame, FrameDetails, ImageDetails, MemoryFormat};
|
||||||
use gufo::common::datetime::DateTime;
|
use gufo::common::datetime::DateTime;
|
||||||
use gufo::common::orientation::Orientation;
|
use gufo::common::orientation::Orientation;
|
||||||
|
|
||||||
|
|
@ -38,7 +38,7 @@ pub struct Metadata {
|
||||||
mime_type: Option<String>,
|
mime_type: Option<String>,
|
||||||
metadata: gufo::Metadata,
|
metadata: gufo::Metadata,
|
||||||
file_info: Option<FileInfo>,
|
file_info: Option<FileInfo>,
|
||||||
image_info: Option<glycin::ImageInfo>,
|
image_info: Option<glycin::ImageDetails>,
|
||||||
frame_info: Option<FrameDetails>,
|
frame_info: Option<FrameDetails>,
|
||||||
memory_format: Option<MemoryFormat>,
|
memory_format: Option<MemoryFormat>,
|
||||||
}
|
}
|
||||||
|
|
@ -60,11 +60,19 @@ impl Metadata {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_image_info(&mut self, image_info: ImageInfo) {
|
pub fn set_image_info(&mut self, image_info: ImageDetails) {
|
||||||
if let Some(exif_raw) = image_info.exif.as_ref().and_then(|x| x.get_full().ok()) {
|
if let Some(exif_raw) = image_info
|
||||||
|
.metadata_exif()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.get_full().ok())
|
||||||
|
{
|
||||||
self.set_exif_bytes(exif_raw);
|
self.set_exif_bytes(exif_raw);
|
||||||
}
|
}
|
||||||
if let Some(exif_xmp) = image_info.xmp.as_ref().and_then(|x| x.get_full().ok()) {
|
if let Some(exif_xmp) = image_info
|
||||||
|
.metadata_xmp()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.get_full().ok())
|
||||||
|
{
|
||||||
self.set_xmp_bytes(exif_xmp);
|
self.set_xmp_bytes(exif_xmp);
|
||||||
}
|
}
|
||||||
self.image_info = Some(image_info);
|
self.image_info = Some(image_info);
|
||||||
|
|
@ -125,20 +133,22 @@ impl Metadata {
|
||||||
pub fn format_name(&self) -> Option<String> {
|
pub fn format_name(&self) -> Option<String> {
|
||||||
self.image_info
|
self.image_info
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|x| x.format_name.clone())
|
.and_then(|x| x.info_format_name().map(|x| x.to_string()))
|
||||||
.or_else(|| self.unreliable_mime_type())
|
.or_else(|| self.unreliable_mime_type())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alpha_channel(&self) -> Option<bool> {
|
pub fn alpha_channel(&self) -> Option<bool> {
|
||||||
self.frame_info.as_ref().and_then(|x| x.alpha_channel)
|
self.frame_info
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.info_alpha_channel())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn grayscale(&self) -> Option<bool> {
|
pub fn grayscale(&self) -> Option<bool> {
|
||||||
self.frame_info.as_ref().and_then(|x| x.grayscale)
|
self.frame_info.as_ref().and_then(|x| x.info_grayscale())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bit_depth(&self) -> Option<u8> {
|
pub fn bit_depth(&self) -> Option<u8> {
|
||||||
self.frame_info.as_ref().and_then(|x| x.bit_depth)
|
self.frame_info.as_ref().and_then(|x| x.info_bit_depth())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_svg(&self) -> bool {
|
pub fn is_svg(&self) -> bool {
|
||||||
|
|
@ -155,7 +165,7 @@ impl Metadata {
|
||||||
pub fn transformations_applied(&self) -> bool {
|
pub fn transformations_applied(&self) -> bool {
|
||||||
self.image_info
|
self.image_info
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|x| x.transformations_applied)
|
.map(|x| x.transformation_ignore_exif())
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,13 +179,13 @@ impl Metadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dimensions_inch(&self) -> Option<(f64, f64)> {
|
pub fn dimensions_inch(&self) -> Option<(f64, f64)> {
|
||||||
self.image_info.as_ref().and_then(|x| x.dimensions_inch)
|
self.image_info.as_ref().and_then(|x| x.dimensions_inch())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dimensions_text(&self) -> Option<String> {
|
pub fn dimensions_text(&self) -> Option<String> {
|
||||||
self.image_info
|
self.image_info
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|x| x.dimensions_text.clone())
|
.and_then(|x| x.info_dimensions_text().map(|x| x.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_name(&self) -> Option<String> {
|
pub fn file_name(&self) -> Option<String> {
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,10 @@ mod imp {
|
||||||
|
|
||||||
if let Some(operations) = obj.operations() {
|
if let Some(operations) = obj.operations() {
|
||||||
log::debug!("Computing edited image.");
|
log::debug!("Computing edited image.");
|
||||||
let result = editor.apply_complete(dbg!(&operations)).await;
|
let result = match editor.edit().await {
|
||||||
|
Ok(editable_image) => editable_image.apply_complete(&operations).await,
|
||||||
|
Err(err) => Err(err),
|
||||||
|
};
|
||||||
match result {
|
match result {
|
||||||
Err(err) if matches!(err.error(), glycin::Error::Canceled(_)) => {
|
Err(err) if matches!(err.error(), glycin::Error::Canceled(_)) => {
|
||||||
log::debug!("Computing edited image canceled");
|
log::debug!("Computing edited image canceled");
|
||||||
|
|
@ -362,9 +365,9 @@ mod imp {
|
||||||
ErrorType::Loader,
|
ErrorType::Loader,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Ok(binary_data) => {
|
Ok(edit) => {
|
||||||
log::debug!("Saving edited image to '{}'", new_file.uri());
|
log::debug!("Saving edited image to '{}'", new_file.uri());
|
||||||
match binary_data.get() {
|
match edit.data().get() {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
obj.window().show_error(
|
obj.window().show_error(
|
||||||
&gettext("Failed to Save Image"),
|
&gettext("Failed to Save Image"),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue