use psdk_father::args::{ArgContext, PsdkArgBase, PsdkEasyArg};
use psdk_father::command::CommandClause;
use psdk_father::errors::{PsdkFatherError, PsdkFatherResult};
use std::sync::{Arc, Mutex};
use tiny_skia::Pixmap;
use super::CImagePixels;
use psdk_extension::imagep::{ThresholdEdgeDitherDepth, ThresholdEdgeDitherMode};
#[derive(Clone, Debug)]
pub struct CImageBytesOptions {
pub x: i32,
pub y: i32,
pub bytes: Vec<u8>,
pub compress: bool,
pub reverse: bool,
pub gray_threshold: Option<i32>,
pub smooth_weight: i32,
pub edge_dither_mode: Option<ThresholdEdgeDitherMode>,
pub edge_dither_depth: ThresholdEdgeDitherDepth,
}
#[derive(Clone, Debug)]
pub struct CImageBytes {
image_pixels: CImagePixels,
}
impl CImageBytes {
pub fn new(options: CImageBytesOptions) -> PsdkFatherResult<Self> {
let pixmap =
Pixmap::decode_png(&options.bytes).map_err(|e| PsdkFatherError::Image(format!("{:?}", e)))?;
let width = pixmap.width();
let height = pixmap.height();
Ok(Self {
image_pixels: CImagePixels::new(super::CImagePixelsOptions {
x: options.x,
y: options.y,
pixels: pixmap.take(),
width,
height,
compress: options.compress,
reverse: options.reverse,
gray_threshold: options.gray_threshold,
smooth_weight: options.smooth_weight,
edge_dither_mode: options.edge_dither_mode,
edge_dither_depth: options.edge_dither_depth,
}),
})
}
}
impl TryFrom<(i32, i32, Vec<u8>)> for CImageBytes {
type Error = PsdkFatherError;
fn try_from((x, y, bytes): (i32, i32, Vec<u8>)) -> Result<Self, Self::Error> {
Self::new(CImageBytesOptions {
x,
y,
bytes,
compress: false,
reverse: false,
gray_threshold: None,
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
})
}
}
impl PsdkEasyArg<String> for CImageBytes {
fn context(&self) -> Arc<Mutex<ArgContext>> {
self.image_pixels.context()
}
}
impl PsdkArgBase<String> for CImageBytes {
fn header(&self) -> String {
self.image_pixels.header()
}
fn clause(&self) -> PsdkFatherResult<CommandClause> {
self.image_pixels.clause()
}
}
psdk_father::impl_psdk_arg_to_easy_arg!(String, CImageBytes, true);