mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 05:38:13 +08:00
Serialize documents with images in linear space instead of sRGB (#1856)
Serialize Images in linear space instead of srgb
This commit is contained in:
Generated
+1
@@ -2353,6 +2353,7 @@ dependencies = [
|
|||||||
"rand_chacha 0.3.1",
|
"rand_chacha 0.3.1",
|
||||||
"rustybuzz 0.17.0",
|
"rustybuzz 0.17.0",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"specta",
|
"specta",
|
||||||
"spirv-std",
|
"spirv-std",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ image = { workspace = true, optional = true, default-features = false, features
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
# Workspace dependencies
|
# Workspace dependencies
|
||||||
tokio = { workspace = true, features = ["rt", "macros"] }
|
tokio = { workspace = true, features = ["rt", "macros"] }
|
||||||
|
serde_json = { workspace = true }
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
# the spirv target is not in the list of common cfgs so must be added manually
|
# the spirv target is not in the list of common cfgs so must be added manually
|
||||||
|
|||||||
@@ -12,14 +12,15 @@ mod base64_serde {
|
|||||||
|
|
||||||
use super::super::Pixel;
|
use super::super::Pixel;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use serde::{Deserialize, Deserializer, Serializer};
|
use serde::{ser::SerializeTuple, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
pub fn as_base64<S, P: Pixel>(key: &[P], serializer: S) -> Result<S::Ok, S::Error>
|
pub fn as_base64<S, P: Pixel>(key: &[P], serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
let u8_data = key.iter().flat_map(|color| color.to_bytes()).collect::<Vec<_>>();
|
let u8_data = bytemuck::cast_slice(key);
|
||||||
serializer.serialize_str(&base64::engine::general_purpose::STANDARD.encode(u8_data))
|
let string = base64::engine::general_purpose::STANDARD.encode(u8_data);
|
||||||
|
(key.len() as u64, string).serialize(serializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_base64<'a, D, P: Pixel>(deserializer: D) -> Result<Vec<P>, D::Error>
|
pub fn from_base64<'a, D, P: Pixel>(deserializer: D) -> Result<Vec<P>, D::Error>
|
||||||
@@ -27,14 +28,15 @@ mod base64_serde {
|
|||||||
D: Deserializer<'a>,
|
D: Deserializer<'a>,
|
||||||
{
|
{
|
||||||
use serde::de::Error;
|
use serde::de::Error;
|
||||||
|
<(u64, &[u8])>::deserialize(deserializer)
|
||||||
|
.and_then(|(len, str)| {
|
||||||
|
let mut output: Vec<P> = vec![P::zeroed(); len as usize];
|
||||||
|
base64::engine::general_purpose::STANDARD
|
||||||
|
.decode_slice(str, bytemuck::cast_slice_mut(output.as_mut_slice()))
|
||||||
|
.map_err(|err| Error::custom(err.to_string()))?;
|
||||||
|
|
||||||
let color_from_chunk = |chunk: &[u8]| P::from_bytes(chunk);
|
Ok(output)
|
||||||
|
})
|
||||||
let colors_from_bytes = |bytes: Vec<u8>| bytes.chunks_exact(P::byte_size()).map(color_from_chunk).collect();
|
|
||||||
|
|
||||||
String::deserialize(deserializer)
|
|
||||||
.and_then(|string| base64::engine::general_purpose::STANDARD.decode(string).map_err(|err| Error::custom(err.to_string())))
|
|
||||||
.map(colors_from_bytes)
|
|
||||||
.map_err(serde::de::Error::custom)
|
.map_err(serde::de::Error::custom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -414,3 +416,25 @@ impl From<ImageFrame<SRGBA8>> for ImageFrame<Color> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
#[test]
|
||||||
|
fn test_image_serialization_roundtrip() {
|
||||||
|
use super::*;
|
||||||
|
use crate::Color;
|
||||||
|
let image = Image {
|
||||||
|
width: 2,
|
||||||
|
height: 2,
|
||||||
|
data: vec![Color::WHITE, Color::BLACK, Color::RED, Color::GREEN],
|
||||||
|
base64_string: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let serialized = serde_json::to_string(&image).unwrap();
|
||||||
|
println!("{}", serialized);
|
||||||
|
let deserialized: Image<Color> = serde_json::from_str(&serialized).unwrap();
|
||||||
|
println!("{:?}", deserialized);
|
||||||
|
|
||||||
|
assert_eq!(image, deserialized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user