1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std::{array, fmt, mem, ops::IndexMut};

use num_traits::Num;

/// Pixel backing type
pub trait StorageType: Num + Copy + Send + Sync {}

impl<T: Num + Copy + Send + Sync> StorageType for T {}

/// Generic pixel container
pub trait Pixel: Sized + Copy + Send + Sync + IndexMut<usize> {
    /// Type of the container elements
    type T: StorageType;

    /// Returns the channel value at the specified index
    fn at(&self, index: usize) -> Self::T;

    /// Convert a memory region into a pixel by copying the bytes
    fn try_from(raw: &[Self::T]) -> Result<Self, array::TryFromSliceError>;

    /// Number of channels for this pixel
    fn channels() -> u8;

    /// Size of one pixel in bytes
    fn len() -> usize {
        Self::channels() as usize * mem::size_of::<Self::T>()
    }

    /// Number of image pixels for this pixel
    fn subpixels() -> u8;
}

/// Macropixel container
pub trait Macropixel: Pixel {
    /// Type of the image pixel
    type Subpixel: Pixel;

    /// Convert image pixels into a macropixel
    fn from_subpixels(pixels: &[Self::Subpixel]) -> Self;

    /// Convert into image pixels
    fn to_subpixels(&self) -> [Self::Subpixel];
}

/// View into an image, provides read-only pixel access
pub trait GenericImageView<'a> {
    /// Pixel type
    type T: Pixel;

    /// Type of sub images
    type SubImage;

    /// Width in pixels
    fn width(&self) -> u32;

    /// Height in pixels
    fn height(&self) -> u32;

    /// Returns the pixel at the specified coordinates
    fn pixel(&self, x: u32, y: u32) -> Option<Self::T>;

    /// Returns a sub image view backed by the same data
    fn view(&'a self, x: u32, y: u32, width: u32, height: u32) -> Option<Self::SubImage>;
}

/// Buffered image, provides read-write pixel access
pub trait GenericImage<'a>: GenericImageView<'a> {
    /// Sets the pixel values at the specified coordinates
    fn set_pixel(&mut self, x: u32, y: u32, pix: &Self::T) -> Result<(), ()>;
}

/// Convert between images
pub trait TryConvert<B> {
    type Error: fmt::Debug;

    /// Converts the buffer into another, possibly with a different format
    fn try_convert(&self, output: &mut B) -> Result<(), Self::Error>;
}

/// Convert into a slice of types
pub trait TryConvertSlice<DP: Pixel>: Sized {
    type Error: fmt::Debug;

    /// Converts the buffer into another, possibly with a different format
    fn try_convert(input: &[Self], output: &mut [DP]) -> Result<(), Self::Error>;
}