yuv2rgb/
pixel.rs

1use std::fmt::{Debug, Display};
2
3use num_traits::{AsPrimitive, PrimInt};
4
5/// Trait for casting between primitive types.
6pub trait CastFromPrimitive<T>: Copy + 'static {
7    /// Casts the given value into `Self`.
8    fn cast_from(v: T) -> Self;
9}
10
11macro_rules! impl_cast_from_primitive {
12    ( $T:ty => $U:ty ) => {
13      impl CastFromPrimitive<$U> for $T {
14        #[inline(always)]
15        fn cast_from(v: $U) -> Self { v as Self }
16      }
17    };
18    ( $T:ty => { $( $U:ty ),* } ) => {
19      $( impl_cast_from_primitive!($T => $U); )*
20    };
21  }
22
23// casts to { u8, u16 } are implemented separately using Pixel, so that the
24// compiler understands that CastFromPrimitive<T: Pixel> is always implemented
25impl_cast_from_primitive!(u8 => { u32, u64, usize });
26impl_cast_from_primitive!(u8 => { i8, i64, isize });
27impl_cast_from_primitive!(u16 => { u32, u64, usize });
28impl_cast_from_primitive!(u16 => { i8, i64, isize });
29impl_cast_from_primitive!(i16 => { u32, u64, usize });
30impl_cast_from_primitive!(i16 => { i8, i64, isize });
31impl_cast_from_primitive!(i32 => { u32, u64, usize });
32impl_cast_from_primitive!(i32 => { i8, i64, isize });
33
34pub trait RegisteredPrimitive:
35    PrimInt
36    + AsPrimitive<u8>
37    + AsPrimitive<i16>
38    + AsPrimitive<u16>
39    + AsPrimitive<i32>
40    + AsPrimitive<u32>
41    + AsPrimitive<usize>
42    + CastFromPrimitive<u8>
43    + CastFromPrimitive<i16>
44    + CastFromPrimitive<u16>
45    + CastFromPrimitive<i32>
46    + CastFromPrimitive<u32>
47    + CastFromPrimitive<usize>
48{
49}
50
51impl RegisteredPrimitive for u8 {}
52impl RegisteredPrimitive for u16 {}
53impl RegisteredPrimitive for i16 {}
54impl RegisteredPrimitive for i32 {}
55
56macro_rules! impl_cast_from_pixel_to_primitive {
57    ( $T:ty ) => {
58        impl<T: RegisteredPrimitive> CastFromPrimitive<T> for $T {
59            #[inline(always)]
60            fn cast_from(v: T) -> Self {
61                v.as_()
62            }
63        }
64    };
65}
66
67impl_cast_from_pixel_to_primitive!(u8);
68impl_cast_from_pixel_to_primitive!(i16);
69impl_cast_from_pixel_to_primitive!(u16);
70impl_cast_from_pixel_to_primitive!(i32);
71impl_cast_from_pixel_to_primitive!(u32);
72
73/// Types that can be used as pixel types.
74pub enum PixelType {
75    /// 8 bits per pixel, stored in a `u8`.
76    U8,
77    /// 10 or 12 bits per pixel, stored in a `u16`.
78    U16,
79}
80
81/// A type that can be used as a pixel type.
82pub trait Pixel:
83    RegisteredPrimitive + Into<u32> + Into<i32> + Debug + Display + Send + Sync + 'static
84{
85    /// Returns a [`PixelType`] variant corresponding to this type.
86    ///
87    /// [`PixelType`]: enum.PixelType.html
88    fn type_enum() -> PixelType;
89}
90
91impl Pixel for u8 {
92    #[inline]
93    fn type_enum() -> PixelType {
94        PixelType::U8
95    }
96}
97
98impl Pixel for u16 {
99    #[inline]
100    fn type_enum() -> PixelType {
101        PixelType::U16
102    }
103}