mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 05:18:19 +00: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:
parent
a36491d6f1
commit
93b473abcd
3 changed files with 36 additions and 10 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2353,6 +2353,7 @@ dependencies = [
|
|||
"rand_chacha 0.3.1",
|
||||
"rustybuzz 0.17.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"specta",
|
||||
"spirv-std",
|
||||
"tokio",
|
||||
|
|
|
@ -73,6 +73,7 @@ image = { workspace = true, optional = true, default-features = false, features
|
|||
[dev-dependencies]
|
||||
# Workspace dependencies
|
||||
tokio = { workspace = true, features = ["rt", "macros"] }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
[lints.rust]
|
||||
# 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 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>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let u8_data = key.iter().flat_map(|color| color.to_bytes()).collect::<Vec<_>>();
|
||||
serializer.serialize_str(&base64::engine::general_purpose::STANDARD.encode(u8_data))
|
||||
let u8_data = bytemuck::cast_slice(key);
|
||||
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>
|
||||
|
@ -27,14 +28,15 @@ mod base64_serde {
|
|||
D: Deserializer<'a>,
|
||||
{
|
||||
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);
|
||||
|
||||
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)
|
||||
Ok(output)
|
||||
})
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue