Skip to main content

fre_rs/
utils.rs

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