ass_renderer/renderer/
frame.rs1#[cfg(feature = "nostd")]
4use alloc::{sync::Arc, vec, vec::Vec};
5#[cfg(not(feature = "nostd"))]
6use std::{sync::Arc, vec::Vec};
7
8#[derive(Clone)]
15pub struct Frame {
16 buffer: Arc<Vec<u8>>,
17 width: u32,
18 height: u32,
19 timestamp: u32,
20 format: PixelFormat,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub enum PixelFormat {
26 Rgba8,
28 Bgra8,
30 Rgb8,
32}
33
34impl Frame {
35 pub fn new(buffer: Vec<u8>, width: u32, height: u32, timestamp: u32) -> Self {
37 Self {
38 buffer: Arc::new(buffer),
39 width,
40 height,
41 timestamp,
42 format: PixelFormat::Rgba8,
43 }
44 }
45
46 pub fn from_rgba(buffer: Vec<u8>, width: u32, height: u32) -> Self {
48 Self::new(buffer, width, height, 0)
49 }
50
51 pub fn with_format(
53 buffer: Vec<u8>,
54 width: u32,
55 height: u32,
56 timestamp: u32,
57 format: PixelFormat,
58 ) -> Self {
59 Self {
60 buffer: Arc::new(buffer),
61 width,
62 height,
63 timestamp,
64 format,
65 }
66 }
67
68 pub fn empty(width: u32, height: u32, timestamp: u32) -> Self {
70 let size = (width * height * 4) as usize;
71 Self::new(vec![0; size], width, height, timestamp)
72 }
73
74 pub fn with_timestamp(&self, timestamp: u32) -> Self {
77 Self {
78 buffer: Arc::clone(&self.buffer),
79 timestamp,
80 ..*self
81 }
82 }
83
84 pub fn data(&self) -> &[u8] {
86 self.buffer.as_slice()
87 }
88
89 pub fn pixels(&self) -> &[u8] {
91 self.buffer.as_slice()
92 }
93
94 pub fn data_mut(&mut self) -> &mut [u8] {
96 Arc::make_mut(&mut self.buffer).as_mut_slice()
97 }
98
99 pub fn into_buffer(self) -> Vec<u8> {
101 Arc::try_unwrap(self.buffer).unwrap_or_else(|arc| (*arc).clone())
102 }
103
104 pub fn width(&self) -> u32 {
106 self.width
107 }
108
109 pub fn height(&self) -> u32 {
111 self.height
112 }
113
114 pub fn timestamp(&self) -> u32 {
116 self.timestamp
117 }
118
119 pub fn format(&self) -> PixelFormat {
121 self.format
122 }
123
124 pub fn bytes_per_pixel(&self) -> usize {
126 match self.format {
127 PixelFormat::Rgba8 | PixelFormat::Bgra8 => 4,
128 PixelFormat::Rgb8 => 3,
129 }
130 }
131
132 pub fn stride(&self) -> usize {
134 self.width as usize * self.bytes_per_pixel()
135 }
136
137 pub fn to_rgba(mut self) -> Self {
139 match self.format {
140 PixelFormat::Rgba8 => self,
141 PixelFormat::Bgra8 => {
142 for chunk in Arc::make_mut(&mut self.buffer).chunks_exact_mut(4) {
143 chunk.swap(0, 2);
144 }
145 self.format = PixelFormat::Rgba8;
146 self
147 }
148 PixelFormat::Rgb8 => {
149 let mut rgba = Vec::with_capacity((self.width * self.height * 4) as usize);
150 for chunk in self.buffer.chunks_exact(3) {
151 rgba.extend_from_slice(&[chunk[0], chunk[1], chunk[2], 255]);
152 }
153 self.buffer = Arc::new(rgba);
154 self.format = PixelFormat::Rgba8;
155 self
156 }
157 }
158 }
159
160 pub fn is_empty(&self) -> bool {
162 match self.format {
163 PixelFormat::Rgba8 | PixelFormat::Bgra8 => {
164 self.buffer.chunks_exact(4).all(|pixel| pixel[3] == 0)
165 }
166 PixelFormat::Rgb8 => false,
167 }
168 }
169}