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