use std::collections::BTreeMap;
use std::os::fd::AsRawFd;
use std::time::Duration;
use glycin_common::{BinaryData, MemoryFormat, MemoryFormatInfo};
use gufo_common::orientation::Orientation;
use memmap::MmapMut;
use serde::{Deserialize, Serialize};
use zbus::zvariant::as_value::{self, optional};
use zbus::zvariant::{self, DeserializeDict, Optional, SerializeDict, Type};
use crate::ImgBuf;
use crate::error::DimensionTooLargerError;
use crate::safe_math::{SafeConversion, SafeMath};
#[derive(Deserialize, Serialize, Type, Debug)]
pub struct InitRequest {
pub fd: zvariant::OwnedFd,
pub mime_type: String,
pub details: InitializationDetails,
}
#[derive(DeserializeDict, SerializeDict, Type, Debug, Default)]
#[zvariant(signature = "dict")]
#[non_exhaustive]
pub struct InitializationDetails {
pub base_dir: Option<std::path::PathBuf>,
}
const fn true_const() -> bool {
true
}
#[derive(Deserialize, Serialize, Type, Debug, Clone, Default)]
#[zvariant(signature = "dict")]
#[non_exhaustive]
pub struct FrameRequest {
#[serde(with = "optional", skip_serializing_if = "Option::is_none", default)]
pub scale: Option<(u32, u32)>,
#[serde(with = "optional", skip_serializing_if = "Option::is_none", default)]
pub clip: Option<(u32, u32, u32, u32)>,
#[serde(with = "as_value", default = "true_const")]
pub loop_animation: bool,
}
#[derive(Deserialize, Serialize, Type, Debug, Clone)]
pub struct RemoteImage {
pub frame_request: zvariant::OwnedObjectPath,
pub details: ImageDetails,
}
impl RemoteImage {
pub fn new(details: ImageDetails, frame_request: zvariant::OwnedObjectPath) -> Self {
Self {
frame_request,
details,
}
}
}
#[derive(DeserializeDict, SerializeDict, Type, Debug, Clone, Default)]
#[zvariant(signature = "dict")]
#[non_exhaustive]
pub struct ImageDetails {
pub width: u32,
pub height: u32,
pub dimensions_inch: Option<(f64, f64)>,
pub info_format_name: Option<String>,
pub info_dimensions_text: Option<String>,
pub metadata_exif: Option<BinaryData>,
pub metadata_xmp: Option<BinaryData>,
pub metadata_key_value: Option<BTreeMap<String, String>>,
pub transformation_ignore_exif: bool,
pub transformation_orientation: Option<Orientation>,
}
impl ImageDetails {
pub fn new(width: u32, height: u32) -> Self {
Self {
width,
height,
dimensions_inch: None,
info_dimensions_text: None,
info_format_name: None,
metadata_exif: None,
metadata_xmp: None,
metadata_key_value: None,
transformation_ignore_exif: false,
transformation_orientation: None,
}
}
}
#[derive(Deserialize, Serialize, Type, Debug)]
pub struct Frame {
pub width: u32,
pub height: u32,
pub stride: u32,
pub memory_format: MemoryFormat,
pub texture: BinaryData,
pub delay: Optional<Duration>,
pub details: FrameDetails,
}
impl Frame {
pub fn n_bytes(&self) -> Result<usize, DimensionTooLargerError> {
self.stride.try_usize()?.smul(self.height.try_usize()?)
}
}
#[derive(DeserializeDict, SerializeDict, Type, Debug, Default, Clone)]
#[zvariant(signature = "dict")]
#[non_exhaustive]
pub struct FrameDetails {
pub color_icc_profile: Option<BinaryData>,
pub color_cicp: Option<[u8; 4]>,
pub info_bit_depth: Option<u8>,
pub info_alpha_channel: Option<bool>,
pub info_grayscale: Option<bool>,
pub n_frame: Option<u64>,
}
impl Frame {
pub fn new(
width: u32,
height: u32,
memory_format: MemoryFormat,
texture: BinaryData,
) -> Result<Self, DimensionTooLargerError> {
let stride = memory_format
.n_bytes()
.u32()
.checked_mul(width)
.ok_or(DimensionTooLargerError)?;
Ok(Self {
width,
height,
stride,
memory_format,
texture,
delay: None.into(),
details: Default::default(),
})
}
}
impl Frame {
pub fn as_img_buf(&self) -> std::io::Result<ImgBuf> {
let raw_fd = self.texture.as_raw_fd();
let original_mmap = unsafe { MmapMut::map_mut(raw_fd) }?;
Ok(ImgBuf::MMap {
mmap: original_mmap,
raw_fd,
})
}
}
#[derive(Deserialize, Serialize, Type, Debug, Clone)]
pub struct RemoteEditableImage {
pub edit_request: zvariant::OwnedObjectPath,
}
impl RemoteEditableImage {
pub fn new(frame_request: zvariant::OwnedObjectPath) -> Self {
Self {
edit_request: frame_request,
}
}
}
#[derive(DeserializeDict, SerializeDict, Type, Debug)]
#[zvariant(signature = "dict")]
#[non_exhaustive]
pub struct NewImage {
pub image_info: ImageDetails,
pub frames: Vec<Frame>,
}
impl NewImage {
pub fn new(image_info: ImageDetails, frames: Vec<Frame>) -> Self {
Self { image_info, frames }
}
}
#[derive(DeserializeDict, SerializeDict, Type, Debug, Default)]
#[zvariant(signature = "dict")]
#[non_exhaustive]
pub struct EncodingOptions {
pub quality: Option<u8>,
pub compression: Option<u8>,
}
#[derive(DeserializeDict, SerializeDict, Type, Debug)]
#[zvariant(signature = "dict")]
#[non_exhaustive]
pub struct EncodedImage {
pub data: BinaryData,
}
impl EncodedImage {
pub fn new(data: BinaryData) -> Self {
Self { data }
}
}