1use std::borrow::Cow;
16
17use crate::{
18 buffer::Buffer,
19 pixel::{self, Pixel},
20};
21
22pub trait Into<P, C>
25where
26 P: Pixel<C>,
27 C: pixel::Channel,
28{
29 fn into(self) -> Buffer<P, C, Vec<C>>;
31}
32
33pub trait Bytes<P, C>
36where
37 P: Pixel<C>,
38 C: pixel::Channel,
39{
40 fn bytes(&self) -> Cow<[u8]>;
42}
43
44#[cfg(not(feature = "nightly"))]
45mod stable {
46 use std::{borrow::Cow, ops::Deref};
47
48 use crate::{buffer::Buffer, pixel};
49
50 impl<PI, CI, DI, PO, CO> super::Into<PO, CO> for Buffer<PI, CI, DI>
51 where
52 PI: pixel::Read<CI>,
53 CI: pixel::Channel,
54 DI: Deref<Target = [CI]>,
55 PO: pixel::Write<CO>,
56 PO: From<PI>,
57 CO: pixel::Channel,
58 {
59 #[inline]
60 fn into(self) -> Buffer<PO, CO, Vec<CO>> {
61 self.convert::<PO, CO>()
62 }
63 }
64
65 impl<PI, CI, DI, PO, CO> super::Bytes<PO, CO> for Buffer<PI, CI, DI>
66 where
67 PI: pixel::Read<CI>,
68 PI: Into<PO>,
69 CI: pixel::Channel,
70 DI: Deref<Target = [CI]>,
71 PO: pixel::Write<CO> + pixel::Write<u8>,
72 CO: pixel::Channel,
73 {
74 #[inline]
75 fn bytes(&self) -> Cow<[u8]> {
76 Cow::Owned(self.convert::<PO, u8>().into_raw())
77 }
78 }
79}
80
81#[cfg(feature = "nightly")]
82mod nightly {
83 use std::{borrow::Cow, mem, ops::Deref, slice};
84
85 use buffer::Buffer;
86 use color::{Hsl, Hsla, Hsv, Hsva, Hwb, Hwba, Lab, Laba, Lch, Lcha, Luma, Lumaa, Rgb, Rgba, Xyz, Xyza, Yxy, Yxya};
87 use num::Float;
88 use pixel;
89
90 impl<PI, CI, DI, CO, PO> super::Into<PO, CO> for Buffer<PI, CI, DI>
91 where
92 PI: pixel::Read<CI>,
93 CI: pixel::Channel,
94 DI: Deref<Target = [CI]>,
95 PO: pixel::Write<CO>,
96 PO: From<PI>,
97 CO: pixel::Channel,
98 {
99 #[inline]
100 default fn into(self) -> Buffer<PO, CO, Vec<CO>> {
101 self.convert::<PO, CO>()
102 }
103 }
104
105 impl<PI, CI, DI, PO, CO> super::Bytes<PO, CO> for Buffer<PI, CI, DI>
106 where
107 PI: pixel::Read<CI>,
108 PI: Into<PO>,
109 CI: pixel::Channel,
110 DI: Deref<Target = [CI]>,
111 PO: pixel::Write<CO> + pixel::Write<u8>,
112 CO: pixel::Channel,
113 {
114 #[inline]
115 default fn bytes(&self) -> Cow<[u8]> {
116 Cow::Owned(self.convert::<PO, u8>().into_raw())
117 }
118 }
119
120 macro_rules! impl_for {
121 () => ();
122 (impl) => ();
123
124 (impl ($ch:ident, $px:ident)) => (
125 impl<T: Float + Copy + 'static> super::Into<$px<T>, $ch> for Buffer<$px<T>, $ch, Vec<$ch>> {
126 #[inline]
127 fn into(self) -> Self {
128 self
129 }
130 }
131
132 impl<T: Float + Copy + 'static> super::Bytes<$px<T>, $ch> for Buffer<$px<T>, $ch, Vec<$ch>> {
133 #[inline]
134 fn bytes(&self) -> Cow<[u8]> {
135 let slice: &[$ch] = &*self;
136
137 Cow::Borrowed(unsafe {
138 slice::from_raw_parts(slice.as_ptr() as *const _, slice.len() * mem::size_of::<$ch>())
139 })
140 }
141 }
142 );
143
144 (impl ($ch:ident, $px:ident), $($rest:tt)*) => (
145 impl_for!(impl ($ch, $px));
146 impl_for!(impl $($rest)*);
147 );
148
149 ($($rest:tt)*) => (
150 impl_for!(impl $($rest)*);
151 );
152 }
153
154 impl_for! {
155 (u8, Luma), (u8, Rgb), (u8, Hsl), (u8, Hsv), (u8, Hwb), (u8, Lab), (u8, Lch), (u8, Xyz), (u8, Yxy),
156 (u8, Lumaa), (u8, Rgba), (u8, Hsla), (u8, Hsva), (u8, Hwba), (u8, Laba), (u8, Lcha), (u8, Xyza), (u8, Yxya),
157 }
158
159 impl_for! {
160 (u16, Luma), (u16, Rgb), (u16, Hsl), (u16, Hsv), (u16, Hwb), (u16, Lab), (u16, Lch), (u16, Xyz), (u16, Yxy),
161 (u16, Lumaa), (u16, Rgba), (u16, Hsla), (u16, Hsva), (u16, Hwba), (u16, Laba), (u16, Lcha), (u16, Xyza), (u16, Yxya),
162 }
163
164 impl_for! {
165 (f32, Luma), (f32, Rgb), (f32, Hsl), (f32, Hsv), (f32, Hwb), (f32, Lab), (f32, Lch), (f32, Xyz), (f32, Yxy),
166 (f32, Lumaa), (f32, Rgba), (f32, Hsla), (f32, Hsva), (f32, Hwba), (f32, Laba), (f32, Lcha), (f32, Xyza), (f32, Yxya),
167 }
168
169 impl_for! {
170 (f64, Luma), (f64, Rgb), (f64, Hsl), (f64, Hsv), (f64, Hwb), (f64, Lab), (f64, Lch), (f64, Xyz), (f64, Yxy),
171 (f64, Lumaa), (f64, Rgba), (f64, Hsla), (f64, Hsva), (f64, Hwba), (f64, Laba), (f64, Lcha), (f64, Xyza), (f64, Yxya),
172 }
173}