|
@@ -1,28 +1,48 @@
|
|
|
trait Sealed {}
|
|
|
|
|
|
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
|
|
+#[repr(u8)]
|
|
|
+pub enum PixelFormat {
|
|
|
+ A8,
|
|
|
+ Abgr32,
|
|
|
+ Bgr24,
|
|
|
+ Bgr32,
|
|
|
+ Rgb24,
|
|
|
+ Rgb32,
|
|
|
+ Rgba32,
|
|
|
+}
|
|
|
+
|
|
|
+pub(crate) const NUM_PIXEL_FORMATS: usize = 7;
|
|
|
+pub(crate) const MAX_PIXEL_WIDTH: usize = 4;
|
|
|
+
|
|
|
#[derive(Clone, PartialEq, Debug, Default)]
|
|
|
-pub struct Mask(std::ops::Range<usize>);
|
|
|
+pub struct PackedLocation(Option<u8>);
|
|
|
|
|
|
-impl Mask {
|
|
|
+impl PackedLocation {
|
|
|
const fn empty() -> Self {
|
|
|
- Self(0..0)
|
|
|
+ Self(None)
|
|
|
}
|
|
|
- const fn select_byte(index: usize) -> Self {
|
|
|
- Self((index * 8)..(index * 8 + 8))
|
|
|
+ const fn select_byte(index: u8) -> Self {
|
|
|
+ Self(Some(index))
|
|
|
+ }
|
|
|
+
|
|
|
+ pub const fn index(&self) -> Option<u8> {
|
|
|
+ self.0
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#[allow(private_bounds)]
|
|
|
-pub trait PixelFormat: Sealed + Clone + Copy {
|
|
|
+pub trait PixelFormatSpec: Sealed + Clone + Copy {
|
|
|
+ const FORMAT_ENUM: PixelFormat;
|
|
|
const CHANNELS: usize;
|
|
|
const PIXEL_WIDTH: usize;
|
|
|
|
|
|
const NAME: &'static str;
|
|
|
|
|
|
- const RED_MASK: Mask;
|
|
|
- const GREEN_MASK: Mask;
|
|
|
- const BLUE_MASK: Mask;
|
|
|
- const ALPHA_MASK: Mask;
|
|
|
+ const RED_PACK: PackedLocation;
|
|
|
+ const GREEN_PACK: PackedLocation;
|
|
|
+ const BLUE_PACK: PackedLocation;
|
|
|
+ const ALPHA_PACK: PackedLocation;
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
@@ -33,16 +53,17 @@ pub trait PixelFormat: Sealed + Clone + Copy {
|
|
|
#[derive(Clone, Copy, PartialEq)]
|
|
|
pub struct A8;
|
|
|
impl Sealed for A8 {}
|
|
|
-impl PixelFormat for A8 {
|
|
|
+impl PixelFormatSpec for A8 {
|
|
|
+ const FORMAT_ENUM: PixelFormat = PixelFormat::A8;
|
|
|
const CHANNELS: usize = 1;
|
|
|
const PIXEL_WIDTH: usize = 1;
|
|
|
|
|
|
const NAME: &'static str = "A8";
|
|
|
|
|
|
- const RED_MASK: Mask = Mask::empty();
|
|
|
- const GREEN_MASK: Mask = Mask::empty();
|
|
|
- const BLUE_MASK: Mask = Mask::empty();
|
|
|
- const ALPHA_MASK: Mask = Mask::select_byte(0);
|
|
|
+ const RED_PACK: PackedLocation = PackedLocation::empty();
|
|
|
+ const GREEN_PACK: PackedLocation = PackedLocation::empty();
|
|
|
+ const BLUE_PACK: PackedLocation = PackedLocation::empty();
|
|
|
+ const ALPHA_PACK: PackedLocation = PackedLocation::select_byte(0);
|
|
|
}
|
|
|
|
|
|
/// RGBA with 8 bits per channel, stored big-endian
|
|
@@ -57,16 +78,17 @@ impl PixelFormat for A8 {
|
|
|
pub struct Abgr32;
|
|
|
|
|
|
impl Sealed for Abgr32 {}
|
|
|
-impl PixelFormat for Abgr32 {
|
|
|
+impl PixelFormatSpec for Abgr32 {
|
|
|
+ const FORMAT_ENUM: PixelFormat = PixelFormat::Abgr32;
|
|
|
const CHANNELS: usize = 4;
|
|
|
const PIXEL_WIDTH: usize = 4;
|
|
|
|
|
|
const NAME: &'static str = "Abgr32";
|
|
|
|
|
|
- const RED_MASK: Mask = Mask::select_byte(3);
|
|
|
- const GREEN_MASK: Mask = Mask::select_byte(2);
|
|
|
- const BLUE_MASK: Mask = Mask::select_byte(1);
|
|
|
- const ALPHA_MASK: Mask = Mask::select_byte(0);
|
|
|
+ const RED_PACK: PackedLocation = PackedLocation::select_byte(3);
|
|
|
+ const GREEN_PACK: PackedLocation = PackedLocation::select_byte(2);
|
|
|
+ const BLUE_PACK: PackedLocation = PackedLocation::select_byte(1);
|
|
|
+ const ALPHA_PACK: PackedLocation = PackedLocation::select_byte(0);
|
|
|
}
|
|
|
|
|
|
/// 24bpp colour densly packed into 24-bit words
|
|
@@ -81,16 +103,17 @@ impl PixelFormat for Abgr32 {
|
|
|
#[derive(Clone, Copy, PartialEq)]
|
|
|
pub struct Bgr24;
|
|
|
impl Sealed for Bgr24 {}
|
|
|
-impl PixelFormat for Bgr24 {
|
|
|
+impl PixelFormatSpec for Bgr24 {
|
|
|
+ const FORMAT_ENUM: PixelFormat = PixelFormat::Bgr24;
|
|
|
const CHANNELS: usize = 3;
|
|
|
const PIXEL_WIDTH: usize = 3;
|
|
|
|
|
|
const NAME: &'static str = "Bgr24";
|
|
|
|
|
|
- const RED_MASK: Mask = Mask::select_byte(0);
|
|
|
- const GREEN_MASK: Mask = Mask::select_byte(1);
|
|
|
- const BLUE_MASK: Mask = Mask::select_byte(2);
|
|
|
- const ALPHA_MASK: Mask = Mask::empty();
|
|
|
+ const RED_PACK: PackedLocation = PackedLocation::select_byte(0);
|
|
|
+ const GREEN_PACK: PackedLocation = PackedLocation::select_byte(1);
|
|
|
+ const BLUE_PACK: PackedLocation = PackedLocation::select_byte(2);
|
|
|
+ const ALPHA_PACK: PackedLocation = PackedLocation::empty();
|
|
|
}
|
|
|
|
|
|
/// 24bpp colour packed into 32-bit words
|
|
@@ -105,16 +128,17 @@ impl PixelFormat for Bgr24 {
|
|
|
#[derive(Clone, Copy, PartialEq)]
|
|
|
pub struct Bgr32;
|
|
|
impl Sealed for Bgr32 {}
|
|
|
-impl PixelFormat for Bgr32 {
|
|
|
+impl PixelFormatSpec for Bgr32 {
|
|
|
+ const FORMAT_ENUM: PixelFormat = PixelFormat::Bgr32;
|
|
|
const CHANNELS: usize = 3;
|
|
|
const PIXEL_WIDTH: usize = 4;
|
|
|
|
|
|
const NAME: &'static str = "Bgr32";
|
|
|
|
|
|
- const RED_MASK: Mask = Mask::select_byte(2);
|
|
|
- const GREEN_MASK: Mask = Mask::select_byte(1);
|
|
|
- const BLUE_MASK: Mask = Mask::select_byte(0);
|
|
|
- const ALPHA_MASK: Mask = Mask::empty();
|
|
|
+ const RED_PACK: PackedLocation = PackedLocation::select_byte(2);
|
|
|
+ const GREEN_PACK: PackedLocation = PackedLocation::select_byte(1);
|
|
|
+ const BLUE_PACK: PackedLocation = PackedLocation::select_byte(0);
|
|
|
+ const ALPHA_PACK: PackedLocation = PackedLocation::empty();
|
|
|
}
|
|
|
|
|
|
/// 24bpp colour densly packed into 24-bit words
|
|
@@ -129,16 +153,17 @@ impl PixelFormat for Bgr32 {
|
|
|
#[derive(Clone, Copy, PartialEq)]
|
|
|
pub struct Rgb24;
|
|
|
impl Sealed for Rgb24 {}
|
|
|
-impl PixelFormat for Rgb24 {
|
|
|
+impl PixelFormatSpec for Rgb24 {
|
|
|
+ const FORMAT_ENUM: PixelFormat = PixelFormat::Rgb24;
|
|
|
const CHANNELS: usize = 3;
|
|
|
const PIXEL_WIDTH: usize = 3;
|
|
|
|
|
|
const NAME: &'static str = "Rgb24";
|
|
|
|
|
|
- const RED_MASK: Mask = Mask::select_byte(2);
|
|
|
- const GREEN_MASK: Mask = Mask::select_byte(1);
|
|
|
- const BLUE_MASK: Mask = Mask::select_byte(0);
|
|
|
- const ALPHA_MASK: Mask = Mask::empty();
|
|
|
+ const RED_PACK: PackedLocation = PackedLocation::select_byte(2);
|
|
|
+ const GREEN_PACK: PackedLocation = PackedLocation::select_byte(1);
|
|
|
+ const BLUE_PACK: PackedLocation = PackedLocation::select_byte(0);
|
|
|
+ const ALPHA_PACK: PackedLocation = PackedLocation::empty();
|
|
|
}
|
|
|
|
|
|
/// 24bpp colour packed into 32-bit words
|
|
@@ -153,16 +178,17 @@ impl PixelFormat for Rgb24 {
|
|
|
#[derive(Clone, Copy, PartialEq)]
|
|
|
pub struct Rgb32;
|
|
|
impl Sealed for Rgb32 {}
|
|
|
-impl PixelFormat for Rgb32 {
|
|
|
+impl PixelFormatSpec for Rgb32 {
|
|
|
+ const FORMAT_ENUM: PixelFormat = PixelFormat::Rgb32;
|
|
|
const CHANNELS: usize = 3;
|
|
|
const PIXEL_WIDTH: usize = 4;
|
|
|
|
|
|
const NAME: &'static str = "Rgb32";
|
|
|
|
|
|
- const RED_MASK: Mask = Mask::select_byte(2);
|
|
|
- const GREEN_MASK: Mask = Mask::select_byte(1);
|
|
|
- const BLUE_MASK: Mask = Mask::select_byte(0);
|
|
|
- const ALPHA_MASK: Mask = Mask::empty();
|
|
|
+ const RED_PACK: PackedLocation = PackedLocation::select_byte(2);
|
|
|
+ const GREEN_PACK: PackedLocation = PackedLocation::select_byte(1);
|
|
|
+ const BLUE_PACK: PackedLocation = PackedLocation::select_byte(0);
|
|
|
+ const ALPHA_PACK: PackedLocation = PackedLocation::empty();
|
|
|
}
|
|
|
|
|
|
/// RGBA with 8 bits per channel, stored little-endian
|
|
@@ -177,14 +203,15 @@ impl PixelFormat for Rgb32 {
|
|
|
pub struct Rgba32;
|
|
|
|
|
|
impl Sealed for Rgba32 {}
|
|
|
-impl PixelFormat for Rgba32 {
|
|
|
+impl PixelFormatSpec for Rgba32 {
|
|
|
+ const FORMAT_ENUM: PixelFormat = PixelFormat::Rgba32;
|
|
|
const CHANNELS: usize = 4;
|
|
|
const PIXEL_WIDTH: usize = 4;
|
|
|
|
|
|
const NAME: &'static str = "Rgba32";
|
|
|
|
|
|
- const RED_MASK: Mask = Mask::select_byte(0);
|
|
|
- const GREEN_MASK: Mask = Mask::select_byte(1);
|
|
|
- const BLUE_MASK: Mask = Mask::select_byte(2);
|
|
|
- const ALPHA_MASK: Mask = Mask::select_byte(3);
|
|
|
+ const RED_PACK: PackedLocation = PackedLocation::select_byte(0);
|
|
|
+ const GREEN_PACK: PackedLocation = PackedLocation::select_byte(1);
|
|
|
+ const BLUE_PACK: PackedLocation = PackedLocation::select_byte(2);
|
|
|
+ const ALPHA_PACK: PackedLocation = PackedLocation::select_byte(3);
|
|
|
}
|