use psdk_extension::imagep;
use psdk_extension::imagep::ConvertBitmapOptions;
pub use psdk_extension::imagep::{ThresholdEdgeDitherDepth, ThresholdEdgeDitherMode};
use psdk_father::args::{ArgContext, PsdkArgBase, PsdkEasyArg, Raw};
use psdk_father::command::{CommandClause, Commander, PsdkCommand, PsdkTextCommand};
use psdk_father::errors::{PsdkFatherError, PsdkFatherResult};
use std::sync::{Arc, Mutex};
#[derive(Clone, Debug)]
pub struct CImagePixelsOptions {
pub x: i32,
pub y: i32,
pub pixels: Vec<u8>,
pub width: u32,
pub height: u32,
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 CImagePixels {
options: CImagePixelsOptions,
ctx: Arc<Mutex<ArgContext>>,
}
impl CImagePixels {
pub fn new(options: CImagePixelsOptions) -> Self {
Self {
options,
ctx: Default::default(),
}
}
}
impl From<(i32, i32, Vec<u8>, u32, u32)> for CImagePixels {
fn from((x, y, pixels, width, height): (i32, i32, Vec<u8>, u32, u32)) -> Self {
Self::new(CImagePixelsOptions {
x,
y,
pixels,
width,
height,
compress: false,
reverse: false,
gray_threshold: None,
smooth_weight: 0,
edge_dither_mode: None,
edge_dither_depth: Default::default(),
})
}
}
impl PsdkEasyArg<String> for CImagePixels {
fn context(&self) -> Arc<Mutex<ArgContext>> {
self.ctx.clone()
}
}
impl PsdkArgBase<String> for CImagePixels {
fn header(&self) -> String {
if self.options.compress {
"ZG".to_string()
} else {
"CG".to_string()
}
}
fn clause(&self) -> PsdkFatherResult<CommandClause> {
let cbi = imagep::convert_to_bitmap(ConvertBitmapOptions {
compress: self.options.compress,
reverse: self.options.reverse,
width: self.options.width,
height: self.options.height,
pixels: self.options.pixels.clone(),
gray_threshold: self.options.gray_threshold,
smooth_weight: self.options.smooth_weight,
edge_dither_mode: self.options.edge_dither_mode,
edge_dither_depth: self.options.edge_dither_depth,
})
.map_err(|e| PsdkFatherError::Custom(format!("Extension: {:?}", e)))?;
let height = self.options.height;
let byte_width = cbi.byte_width;
let converted_bitmap_data = cbi.data;
let mut commander = Commander::new();
let mut ptc = PsdkTextCommand::with_header_format_cpcl(self.header());
ptc
.append(byte_width)
.append(height)
.append(if self.options.compress {
self.options.x / 8
} else {
self.options.x
})
.append(self.options.y);
if self.options.compress {
ptc.append(converted_bitmap_data.len());
}
commander
.push_clause(ptc.clause(), false)
.push_text_with_newline(" ", false)
.push_binary_with_newline(&converted_bitmap_data, false)
.newline();
let command = commander.command()?;
Raw::new().push_binary(command.binary()).clause()
}
}
psdk_father::impl_psdk_arg_to_easy_arg!(String, CImagePixels, true);