Skip to main content

fre_rs/
utils.rs

1use super::*;
2
3
4#[inline]
5#[allow(unsafe_op_in_unsafe_fn)]
6pub(crate) unsafe fn transmute_unchecked <O:, T: Copy> (any: O) -> T {
7    debug_assert_eq!(std::mem::size_of::<O>(), std::mem::size_of::<T>());
8    *(std::ptr::addr_of!(any) as *const T)
9}
10
11
12#[derive(Debug, Clone)]
13pub struct ArrayIter<'a> {
14    arr: as3::Array<'a>,
15    len: u32,
16    idx: u32,
17}
18impl<'a> ArrayIter<'a> {
19    pub(crate) fn new (arr: as3::Array<'a>) -> Self {
20        Self { arr, len: arr.get_length(), idx: 0 }
21    }
22}
23impl<'a> Iterator for ArrayIter<'a> {
24    type Item = as3::Object<'a>;
25    fn next(&mut self) -> Option<as3::Object<'a>> {
26        if self.idx != self.len {
27            let elem = self.arr.get(self.idx);
28            self.idx = unsafe {self.idx.unchecked_add(1)};
29            Some(elem)
30        } else {None}
31    }
32}
33#[derive(Debug, Clone)]
34pub struct VectorIter<'a> {
35    arr: as3::Vector<'a>,
36    len: u32,
37    idx: u32,
38}
39impl<'a> VectorIter<'a> {
40    pub(crate) fn new (arr: as3::Vector<'a>) -> Self {
41        Self { arr, len: arr.get_length(), idx: 0 }
42    }
43}
44impl<'a> Iterator for VectorIter<'a> {
45    type Item = as3::Object<'a>;
46    fn next(&mut self) -> Option<as3::Object<'a>> {
47        if self.idx != self.len {
48            let elem = self.arr.get(self.idx).unwrap();
49            self.idx = unsafe {self.idx.unchecked_add(1)};
50            Some(elem)
51        } else {None}
52    }
53}
54
55
56#[derive(Debug)]
57pub struct BitmapDataAdapter<'a> {
58    object: FREObject,
59    width: usize,
60    height: usize,
61    height_sub_one: usize,
62    has_alpha: bool,
63    is_premultiplied: bool,
64    stride: usize,
65    is_inverted_y: bool,
66    data: &'a mut [u32],
67}
68impl<'a> BitmapDataAdapter<'a> {
69    pub fn width(self) -> usize {self.width}
70    pub fn height(self) -> usize {self.height}
71    pub fn has_alpha(self) -> bool {self.has_alpha}
72    pub fn is_premultiplied(self) -> bool {self.is_premultiplied}
73    #[allow(unsafe_op_in_unsafe_fn)]
74    pub(crate) unsafe fn new (object: FREObject, descriptor: FREBitmapData2) -> Self {
75        debug_assert!(descriptor.lineStride32 >= descriptor.width);
76        assert!(!descriptor.bits32.is_null());
77        let (width, height) = (descriptor.width as usize, descriptor.height as usize);
78        let line_stride = descriptor.lineStride32 as usize;
79        Self {
80            object,
81            width,
82            height,
83            height_sub_one: unsafe {height.unchecked_sub(1)},
84            has_alpha: descriptor.hasAlpha != 0,
85            is_premultiplied: descriptor.isPremultiplied != 0,
86            stride: line_stride,
87            is_inverted_y: descriptor.isInvertedY != 0,
88            data: std::slice::from_raw_parts_mut(descriptor.bits32, line_stride*height),
89        }
90    }
91    pub fn pixel (&self, x: usize, y: usize) -> u32 {
92        debug_assert!(x < self.width);
93        debug_assert!(y < self.height);
94        let offset = unsafe {
95            if self.is_inverted_y {self.height_sub_one-y} else {y}
96                .unchecked_mul(self.stride)
97                .unchecked_add(x)
98        };
99        unsafe {*(self.data.as_ptr().add(offset))}
100    }
101    pub fn pixel_mut (&mut self, x: usize, y: usize) -> &'a mut u32 {
102        debug_assert!(x < self.width);
103        debug_assert!(y < self.height);
104        let offset = unsafe {
105            if self.is_inverted_y {self.height_sub_one-y} else {y}
106                .unchecked_mul(self.stride)
107                .unchecked_add(x)
108        };
109        unsafe {&mut *(self.data.as_mut_ptr().add(offset))}
110    }
111    pub fn row (&self, y: usize) -> &'a [u32] {
112        debug_assert!(y < self.height);
113        let offset = unsafe {
114            if self.is_inverted_y {self.height_sub_one-y} else {y}
115                .unchecked_mul(self.stride)
116        };
117        unsafe {std::slice::from_raw_parts(self.data.as_ptr().add(offset), self.width)}
118    }
119    pub fn row_mut (&mut self, y: usize) -> &'a mut [u32] {
120        debug_assert!(y < self.height);
121        let offset = unsafe {
122            if self.is_inverted_y {self.height_sub_one-y} else {y}
123                .unchecked_mul(self.stride)
124        };
125        unsafe {std::slice::from_raw_parts_mut(self.data.as_mut_ptr().add(offset), self.width)}
126    }
127    pub fn iter (&'a self) -> BitmapDataIter<'a> {BitmapDataIter::new(self)}
128    pub fn iter_mut (&'a mut self) -> BitmapDataIterMut<'a> {BitmapDataIterMut::new(self)}
129    pub fn invalidate_rect (&self, x: u32, y: u32, width: u32, height: u32) {
130        let r = unsafe {FREInvalidateBitmapDataRect(self.object, x, y, width, height)};
131        debug_assert!(r.is_ok());
132    }
133}
134#[derive(Debug, Clone)]
135pub struct BitmapDataIter<'a> {
136    adapter: &'a BitmapDataAdapter<'a>,
137    y: usize,
138}
139impl<'a> BitmapDataIter<'a> {
140    fn new (adapter: &'a BitmapDataAdapter<'a>) -> Self {
141        Self { adapter, y: 0 }
142    }
143}
144impl<'a> Iterator for BitmapDataIter<'a> {
145    type Item = &'a [u32];
146    fn next(&mut self) -> Option<Self::Item> {
147        if self.y != self.adapter.height {
148            let row = self.adapter.row(self.y);
149            self.y = unsafe {self.y.unchecked_add(1)};
150            Some(row)
151        } else {None}
152    }
153}
154#[derive(Debug)]
155pub struct BitmapDataIterMut<'a> {
156    adapter: &'a mut BitmapDataAdapter<'a>,
157    y: usize,
158}
159impl<'a> BitmapDataIterMut<'a> {
160    fn new (adapter: &'a mut BitmapDataAdapter<'a>) -> Self {
161        Self { adapter, y: 0 }
162    }
163}
164impl<'a> Iterator for BitmapDataIterMut<'a> {
165    type Item = &'a mut [u32];
166    fn next(&mut self) -> Option<Self::Item> {
167        if self.y != self.adapter.height {
168            let row = self.adapter.row_mut(self.y);
169            self.y = unsafe {self.y.unchecked_add(1)};
170            Some(row)
171        } else {None}
172    }
173}
174
175
176#[derive(Debug)]
177pub struct MediaBufferDataAdapter<'a> {
178    width: usize,
179    height: usize,
180    stride: usize,
181    format: u32,
182    data: &'a mut [u8],
183}
184impl<'a> MediaBufferDataAdapter<'a> {
185    pub fn width(self) -> usize {self.width}
186    pub fn height(self) -> usize {self.height}
187    /// For future usage: currently images are ARGB format.
188    pub fn format(self) -> u32 {self.format}
189    #[allow(unsafe_op_in_unsafe_fn)]
190    pub(crate) unsafe fn new (bytes: *mut u8, width: u32, height: u32, stride: u32, format: u32) -> Self {
191        debug_assert!(stride >= width);
192        debug_assert!(!bytes.is_null());
193        let (width, height) = (width as usize, height as usize);
194        let stride = stride as usize;
195        Self {
196            width,
197            height,
198            stride,
199            format,
200            data: std::slice::from_raw_parts_mut(bytes, stride * height * 4),
201        }
202    }
203    pub fn pixel (&self, x: usize, y: usize) -> u32 {
204        debug_assert!(x < self.width);
205        debug_assert!(y < self.height);
206        unsafe {
207            let offset = y.unchecked_mul(self.stride).unchecked_add(x);
208            let ptr = self.data.as_ptr() as *const u32;
209            *(ptr.add(offset))
210        }
211    }
212    pub fn pixel_mut (&mut self, x: usize, y: usize) -> &'a mut u32 {
213        debug_assert!(x < self.width);
214        debug_assert!(y < self.height);
215        unsafe {
216            let offset = y.unchecked_mul(self.stride).unchecked_add(x);
217            let ptr = self.data.as_mut_ptr() as *mut u32;
218            &mut *(ptr.add(offset))
219        }
220    }
221    pub fn row (&self, y: usize) -> &'a [u32] {
222        debug_assert!(y < self.height);
223        unsafe {
224            let offset = y.unchecked_mul(self.stride);
225            let ptr = self.data.as_ptr() as *const u32;
226            std::slice::from_raw_parts(ptr.add(offset), self.width)
227        }
228    }
229    pub fn row_mut (&mut self, y: usize) -> &'a mut [u32] {
230        debug_assert!(y < self.height);
231        unsafe {
232            let offset = y.unchecked_mul(self.stride);
233            let ptr = self.data.as_mut_ptr() as *mut u32;
234            std::slice::from_raw_parts_mut(ptr.add(offset), self.width)
235        }
236    }
237    pub fn iter (&'a self) -> MediaBufferDataIter<'a> {MediaBufferDataIter::new(self)}
238    pub fn iter_mut (&'a mut self) -> MediaBufferDataIterMut<'a> {MediaBufferDataIterMut::new(self)}
239}
240#[derive(Debug, Clone)]
241pub struct MediaBufferDataIter<'a> {
242    adapter: &'a MediaBufferDataAdapter<'a>,
243    y: usize,
244}
245impl<'a> MediaBufferDataIter<'a> {
246    fn new (adapter: &'a MediaBufferDataAdapter<'a>) -> Self {
247        Self { adapter, y: 0 }
248    }
249}
250impl<'a> Iterator for MediaBufferDataIter<'a> {
251    type Item = &'a [u32];
252    fn next(&mut self) -> Option<Self::Item> {
253        if self.y != self.adapter.height {
254            let row = self.adapter.row(self.y);
255            self.y = unsafe {self.y.unchecked_add(1)};
256            Some(row)
257        } else {None}
258    }
259}
260#[derive(Debug)]
261pub struct MediaBufferDataIterMut<'a> {
262    adapter: &'a mut MediaBufferDataAdapter<'a>,
263    y: usize,
264}
265impl<'a> MediaBufferDataIterMut<'a> {
266    fn new (adapter: &'a mut MediaBufferDataAdapter<'a>) -> Self {
267        Self { adapter, y: 0 }
268    }
269}
270impl<'a> Iterator for MediaBufferDataIterMut<'a> {
271    type Item = &'a mut [u32];
272    fn next(&mut self) -> Option<Self::Item> {
273        if self.y != self.adapter.height {
274            let row = self.adapter.row_mut(self.y);
275            self.y = unsafe {self.y.unchecked_add(1)};
276            Some(row)
277        } else {None}
278    }
279}
280