1use std::ffi::{CStr, CString};
17use std::fmt;
18
19use crate::bindings;
20use crate::result::MagickError;
21
22use super::MagickTrue;
23use crate::result::Result;
24
25#[derive(Default, Debug)]
26pub struct HSL {
27 pub hue: f64,
28 pub saturation: f64,
29 pub lightness: f64,
30}
31
32wand_common!(
33 PixelWand,
34 NewPixelWand,
35 ClearPixelWand,
36 IsPixelWand,
37 ClonePixelWand,
38 DestroyPixelWand,
39 PixelClearException,
40 PixelGetExceptionType,
41 PixelGetException
42);
43
44impl PixelWand {
45 pub fn is_similar(&self, other: &PixelWand, fuzz: f64) -> bool {
46 let result = unsafe { bindings::IsPixelWandSimilar(self.wand, other.wand, fuzz) };
47 result == MagickTrue
48 }
49
50 pub fn get_hsl(&self) -> HSL {
51 let mut hsl = HSL::default();
52 unsafe {
53 bindings::PixelGetHSL(
54 self.wand,
55 &mut hsl.hue as *mut _,
56 &mut hsl.saturation as *mut _,
57 &mut hsl.lightness as *mut _,
58 );
59 }
60 hsl
61 }
62
63 pub fn set_hsl(&self, hsl: &HSL) {
64 unsafe {
65 bindings::PixelSetHSL(self.wand, hsl.hue, hsl.saturation, hsl.lightness);
66 }
67 }
68
69 pub fn fmt_w_prefix(&self, f: &mut fmt::Formatter, prefix: &str) -> fmt::Result {
70 let mut prf = prefix.to_string();
71 prf.push_str(" ");
72 writeln!(f, "{prefix}PixelWand {{")?;
73 writeln!(f, "{}Exception: {:?}", prf, self.get_exception())?;
74 writeln!(f, "{}IsWand: {:?}", prf, self.is_wand())?;
75 self.fmt_unchecked_settings(f, &prf)?;
76 self.fmt_color_settings(f, &prf)?;
77 writeln!(f, "{prefix}}}")
78 }
79
80 pub fn set_color(&mut self, s: &str) -> Result<()> {
81 let c_string = CString::new(s).map_err(|_| "could not convert to cstring")?;
82 match unsafe { bindings::PixelSetColor(self.wand, c_string.as_ptr()) } {
83 MagickTrue => Ok(()),
84 _ => Err(MagickError(self.get_exception()?.0)),
85 }
86 }
87
88 string_get!(get_color_as_string, PixelGetColorAsString);
89 string_get!(
90 get_color_as_normalized_string,
91 PixelGetColorAsNormalizedString
92 );
93
94 set_get_unchecked!(
95 get_color_count, set_color_count, PixelGetColorCount, PixelSetColorCount, usize
96 get_index, set_index, PixelGetIndex, PixelSetIndex, bindings::Quantum
97 get_fuzz, set_fuzz, PixelGetFuzz, PixelSetFuzz, f64
98 );
99
100 color_set_get!(
101 get_alpha, get_alpha_quantum, set_alpha, set_alpha_quantum,
102 PixelGetAlpha, PixelGetAlphaQuantum, PixelSetAlpha, PixelSetAlphaQuantum
103 get_black, get_black_quantum, set_black, set_black_quantum,
104 PixelGetBlack, PixelGetBlackQuantum, PixelSetBlack, PixelSetBlackQuantum
105 get_blue, get_blue_quantum, set_blue, set_blue_quantum,
106 PixelGetBlue, PixelGetBlueQuantum, PixelSetBlue, PixelSetBlueQuantum
107 get_cyan, get_cyan_quantum, set_cyan, set_cyan_quantum,
108 PixelGetCyan, PixelGetCyanQuantum, PixelSetCyan, PixelSetCyanQuantum
109 get_green, get_green_quantum, set_green, set_green_quantum,
110 PixelGetGreen, PixelGetGreenQuantum, PixelSetGreen, PixelSetGreenQuantum
111 get_magenta, get_magenta_quantum, set_magenta, set_magenta_quantum,
112 PixelGetMagenta, PixelGetMagentaQuantum, PixelSetMagenta, PixelSetMagentaQuantum
113 get_red, get_red_quantum, set_red, set_red_quantum,
114 PixelGetRed, PixelGetRedQuantum, PixelSetRed, PixelSetRedQuantum
115 get_yellow, get_yellow_quantum, set_yellow, set_yellow_quantum,
116 PixelGetYellow, PixelGetYellowQuantum, PixelSetYellow, PixelSetYellowQuantum
117 );
118}
119
120impl fmt::Debug for PixelWand {
121 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122 self.fmt_w_prefix(f, "")
123 }
124}