mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-15 00:06:47 +00:00
105 lines
3.3 KiB
Rust
105 lines
3.3 KiB
Rust
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
/// Individual pixel data containing raw channel values.
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
|
pub struct Pixel {
|
|
pub red: u8,
|
|
pub green: u8,
|
|
pub blue: u8,
|
|
}
|
|
|
|
/// Pixel format that defines the memory layout of each pixel in the framebuffer.
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
|
pub enum PixelFormat {
|
|
/// Each pixel uses 8 bits to represent its grayscale intensity, ranging from 0 (black) to 255 (white).
|
|
Grayscale8,
|
|
/// Each pixel uses 16 bits, with 5 bits for Red, 6 bits for Green, and 5 bits for Blue.
|
|
Rgb565,
|
|
/// Each pixel uses 24 bits, with 8 bits for Red, 8 bits for Green, and 8 bits for Blue.
|
|
Rgb888,
|
|
/// Each pixel uses 32 bits, with 8 bits for Blue, 8 bits for Green, 8 bits for Red, and 8 bits reserved.
|
|
BgrReserved,
|
|
}
|
|
|
|
/// A rendered pixel in a specific format.
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub struct RenderedPixel {
|
|
buf: [u8; 4],
|
|
len: u8,
|
|
}
|
|
|
|
impl Pixel {
|
|
/// Renders the pixel into a specific format.
|
|
pub fn render(&self, format: PixelFormat) -> RenderedPixel {
|
|
let mut buf = [0; 4];
|
|
match format {
|
|
PixelFormat::Grayscale8 => {
|
|
// Calculate the grayscale value
|
|
let red_weight = 77 * self.red as u16; // Equivalent to 0.299 * 256
|
|
let green_weight = 150 * self.green as u16; // Equivalent to 0.587 * 256
|
|
let blue_weight = 29 * self.blue as u16; // Equivalent to 0.114 * 256
|
|
let grayscale = (red_weight + green_weight + blue_weight) >> 8; // Normalize to 0-255
|
|
buf[0] = grayscale as u8;
|
|
RenderedPixel { buf, len: 1 }
|
|
}
|
|
PixelFormat::Rgb565 => {
|
|
let r = (self.red >> 3) as u16; // Red (5 bits)
|
|
let g = (self.green >> 2) as u16; // Green (6 bits)
|
|
let b = (self.blue >> 3) as u16; // Blue (5 bits)
|
|
let rgb565 = (r << 11) | (g << 5) | b; // Combine into RGB565 format
|
|
buf[0..2].copy_from_slice(&rgb565.to_be_bytes());
|
|
RenderedPixel { buf, len: 2 }
|
|
}
|
|
PixelFormat::Rgb888 => {
|
|
buf[0] = self.red;
|
|
buf[1] = self.green;
|
|
buf[2] = self.blue;
|
|
RenderedPixel { buf, len: 3 }
|
|
}
|
|
PixelFormat::BgrReserved => {
|
|
buf[0] = self.blue;
|
|
buf[1] = self.green;
|
|
buf[2] = self.red;
|
|
RenderedPixel { buf, len: 4 }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PixelFormat {
|
|
/// Returns the number of bytes per pixel (color depth).
|
|
pub fn nbytes(&self) -> usize {
|
|
match self {
|
|
PixelFormat::Grayscale8 => 1,
|
|
PixelFormat::Rgb565 => 2,
|
|
PixelFormat::Rgb888 => 3,
|
|
PixelFormat::BgrReserved => 4,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl RenderedPixel {
|
|
/// Returns the number of bytes in the rendered pixel.
|
|
pub fn nbytes(&self) -> usize {
|
|
self.len as usize
|
|
}
|
|
|
|
/// Returns a slice to the rendered pixel data.
|
|
pub fn as_slice(&self) -> &[u8] {
|
|
&self.buf[..self.nbytes()]
|
|
}
|
|
}
|
|
|
|
impl Pixel {
|
|
pub const WHITE: Pixel = Pixel {
|
|
red: 0xFF,
|
|
green: 0xFF,
|
|
blue: 0xFF,
|
|
};
|
|
pub const BLACK: Pixel = Pixel {
|
|
red: 0x00,
|
|
green: 0x00,
|
|
blue: 0x00,
|
|
};
|
|
}
|