• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use crate::internal_utils::*;
16 use crate::*;
17 
18 #[derive(Clone, Copy, Debug)]
19 pub struct PointerSlice<T> {
20     ptr: *mut [T],
21 }
22 
23 impl<T> PointerSlice<T> {
24     /// # Safety
25     /// `ptr` must live at least as long as the struct, and not be accessed other than through this
26     /// struct. It must point to a memory region of at least `size` elements.
create(ptr: *mut T, size: usize) -> AvifResult<Self>27     pub unsafe fn create(ptr: *mut T, size: usize) -> AvifResult<Self> {
28         if ptr.is_null() || size == 0 {
29             return Err(AvifError::NoContent);
30         }
31         // Ensure that size does not exceed isize::MAX.
32         let _ = isize_from_usize(size)?;
33         Ok(Self {
34             ptr: unsafe { std::slice::from_raw_parts_mut(ptr, size) },
35         })
36     }
37 
slice_impl(&self) -> &[T]38     fn slice_impl(&self) -> &[T] {
39         // SAFETY: We only construct this with `ptr` which is valid at least as long as this struct
40         // is alive, and ro/mut borrows of the whole struct to access the inner slice, which makes
41         // our access appropriately exclusive.
42         unsafe { &(*self.ptr) }
43     }
44 
slice_impl_mut(&mut self) -> &mut [T]45     fn slice_impl_mut(&mut self) -> &mut [T] {
46         // SAFETY: We only construct this with `ptr` which is valid at least as long as this struct
47         // is alive, and ro/mut borrows of the whole struct to access the inner slice, which makes
48         // our access appropriately exclusive.
49         unsafe { &mut (*self.ptr) }
50     }
51 
slice(&self, range: Range<usize>) -> AvifResult<&[T]>52     pub fn slice(&self, range: Range<usize>) -> AvifResult<&[T]> {
53         let data = self.slice_impl();
54         check_slice_range(data.len(), &range)?;
55         Ok(&data[range])
56     }
57 
slice_mut(&mut self, range: Range<usize>) -> AvifResult<&mut [T]>58     pub fn slice_mut(&mut self, range: Range<usize>) -> AvifResult<&mut [T]> {
59         let data = self.slice_impl_mut();
60         check_slice_range(data.len(), &range)?;
61         Ok(&mut data[range])
62     }
63 
ptr(&self) -> *const T64     pub fn ptr(&self) -> *const T {
65         self.slice_impl().as_ptr()
66     }
67 
ptr_mut(&mut self) -> *mut T68     pub fn ptr_mut(&mut self) -> *mut T {
69         self.slice_impl_mut().as_mut_ptr()
70     }
71 
is_empty(&self) -> bool72     pub fn is_empty(&self) -> bool {
73         self.slice_impl().is_empty()
74     }
75 }
76 
77 // This struct must not be derived from the default `Clone` trait as it has to be cloned with error
78 // checking using the `try_clone` function.
79 #[derive(Debug)]
80 pub enum Pixels {
81     // Intended for holding data from underlying native libraries. Used for 8-bit images.
82     Pointer(PointerSlice<u8>),
83     // Intended for holding data from underlying native libraries. Used for 10-bit, 12-bit and
84     // 16-bit images.
85     Pointer16(PointerSlice<u16>),
86     // Used for 8-bit images.
87     Buffer(Vec<u8>),
88     // Used for 10-bit, 12-bit and 16-bit images.
89     Buffer16(Vec<u16>),
90 }
91 
92 impl Pixels {
from_raw_pointer( ptr: *mut u8, depth: u32, height: u32, mut row_bytes: u32, ) -> AvifResult<Self>93     pub fn from_raw_pointer(
94         ptr: *mut u8,
95         depth: u32,
96         height: u32,
97         mut row_bytes: u32,
98     ) -> AvifResult<Self> {
99         if depth > 8 {
100             row_bytes /= 2;
101         }
102         let size = usize_from_u32(checked_mul!(height, row_bytes)?)?;
103         if depth > 8 {
104             Ok(Pixels::Pointer16(unsafe {
105                 PointerSlice::create(ptr as *mut u16, size)?
106             }))
107         } else {
108             Ok(Pixels::Pointer(unsafe { PointerSlice::create(ptr, size)? }))
109         }
110     }
111 
size(&self) -> usize112     pub fn size(&self) -> usize {
113         match self {
114             Pixels::Pointer(_) => 0,
115             Pixels::Pointer16(_) => 0,
116             Pixels::Buffer(buffer) => buffer.len(),
117             Pixels::Buffer16(buffer) => buffer.len(),
118         }
119     }
120 
pixel_bit_size(&self) -> usize121     pub(crate) fn pixel_bit_size(&self) -> usize {
122         match self {
123             Pixels::Pointer(_) => 0,
124             Pixels::Pointer16(_) => 0,
125             Pixels::Buffer(_) => 8,
126             Pixels::Buffer16(_) => 16,
127         }
128     }
129 
has_data(&self) -> bool130     pub(crate) fn has_data(&self) -> bool {
131         match self {
132             Pixels::Pointer(ptr) => !ptr.is_empty(),
133             Pixels::Pointer16(ptr) => !ptr.is_empty(),
134             Pixels::Buffer(buffer) => !buffer.is_empty(),
135             Pixels::Buffer16(buffer) => !buffer.is_empty(),
136         }
137     }
138 
resize(&mut self, size: usize, default: u16) -> AvifResult<()>139     pub(crate) fn resize(&mut self, size: usize, default: u16) -> AvifResult<()> {
140         match self {
141             Pixels::Pointer(_) => return Err(AvifError::InvalidArgument),
142             Pixels::Pointer16(_) => return Err(AvifError::InvalidArgument),
143             Pixels::Buffer(buffer) => {
144                 if buffer.capacity() < size && buffer.try_reserve_exact(size).is_err() {
145                     return Err(AvifError::OutOfMemory);
146                 }
147                 buffer.resize(size, default as u8);
148             }
149             Pixels::Buffer16(buffer) => {
150                 if buffer.capacity() < size && buffer.try_reserve_exact(size).is_err() {
151                     return Err(AvifError::OutOfMemory);
152                 }
153                 buffer.resize(size, default);
154             }
155         }
156         Ok(())
157     }
158 
is_pointer(&self) -> bool159     pub(crate) fn is_pointer(&self) -> bool {
160         matches!(self, Pixels::Pointer(_) | Pixels::Pointer16(_))
161     }
162 
ptr(&self) -> *const u8163     pub fn ptr(&self) -> *const u8 {
164         match self {
165             Pixels::Pointer(ptr) => ptr.ptr(),
166             Pixels::Buffer(buffer) => buffer.as_ptr(),
167             _ => std::ptr::null_mut(),
168         }
169     }
170 
ptr16(&self) -> *const u16171     pub fn ptr16(&self) -> *const u16 {
172         match self {
173             Pixels::Pointer16(ptr) => ptr.ptr(),
174             Pixels::Buffer16(buffer) => buffer.as_ptr(),
175             _ => std::ptr::null_mut(),
176         }
177     }
178 
ptr_mut(&mut self) -> *mut u8179     pub fn ptr_mut(&mut self) -> *mut u8 {
180         match self {
181             Pixels::Pointer(ptr) => ptr.ptr_mut(),
182             Pixels::Buffer(buffer) => buffer.as_mut_ptr(),
183             _ => std::ptr::null_mut(),
184         }
185     }
186 
ptr16_mut(&mut self) -> *mut u16187     pub fn ptr16_mut(&mut self) -> *mut u16 {
188         match self {
189             Pixels::Pointer16(ptr) => ptr.ptr_mut(),
190             Pixels::Buffer16(buffer) => buffer.as_mut_ptr(),
191             _ => std::ptr::null_mut(),
192         }
193     }
194 
try_clone(&self) -> AvifResult<Pixels>195     pub(crate) fn try_clone(&self) -> AvifResult<Pixels> {
196         match self {
197             Pixels::Pointer(ptr) => Ok(Pixels::Pointer(*ptr)),
198             Pixels::Pointer16(ptr) => Ok(Pixels::Pointer16(*ptr)),
199             Pixels::Buffer(buffer) => {
200                 let mut cloned_buffer: Vec<u8> = vec![];
201                 cloned_buffer
202                     .try_reserve_exact(buffer.len())
203                     .or(Err(AvifError::OutOfMemory))?;
204                 cloned_buffer.extend_from_slice(buffer);
205                 Ok(Pixels::Buffer(cloned_buffer))
206             }
207             Pixels::Buffer16(buffer16) => {
208                 let mut cloned_buffer16: Vec<u16> = vec![];
209                 cloned_buffer16
210                     .try_reserve_exact(buffer16.len())
211                     .or(Err(AvifError::OutOfMemory))?;
212                 cloned_buffer16.extend_from_slice(buffer16);
213                 Ok(Pixels::Buffer16(cloned_buffer16))
214             }
215         }
216     }
217 
slice(&self, offset: u32, size: u32) -> AvifResult<&[u8]>218     pub fn slice(&self, offset: u32, size: u32) -> AvifResult<&[u8]> {
219         let offset: usize = usize_from_u32(offset)?;
220         let size: usize = usize_from_u32(size)?;
221         match self {
222             Pixels::Pointer(ptr) => {
223                 let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
224                 ptr.slice(offset..end)
225             }
226             Pixels::Pointer16(_) => Err(AvifError::NoContent),
227             Pixels::Buffer(buffer) => {
228                 let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
229                 let range = offset..end;
230                 check_slice_range(buffer.len(), &range)?;
231                 Ok(&buffer[range])
232             }
233             Pixels::Buffer16(_) => Err(AvifError::NoContent),
234         }
235     }
236 
slice_mut(&mut self, offset: u32, size: u32) -> AvifResult<&mut [u8]>237     pub fn slice_mut(&mut self, offset: u32, size: u32) -> AvifResult<&mut [u8]> {
238         let offset: usize = usize_from_u32(offset)?;
239         let size: usize = usize_from_u32(size)?;
240         match self {
241             Pixels::Pointer(ptr) => {
242                 let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
243                 ptr.slice_mut(offset..end)
244             }
245             Pixels::Pointer16(_) => Err(AvifError::NoContent),
246             Pixels::Buffer(buffer) => {
247                 let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
248                 let range = offset..end;
249                 check_slice_range(buffer.len(), &range)?;
250                 Ok(&mut buffer[range])
251             }
252             Pixels::Buffer16(_) => Err(AvifError::NoContent),
253         }
254     }
255 
slice16(&self, offset: u32, size: u32) -> AvifResult<&[u16]>256     pub fn slice16(&self, offset: u32, size: u32) -> AvifResult<&[u16]> {
257         let offset: usize = usize_from_u32(offset)?;
258         let size: usize = usize_from_u32(size)?;
259         match self {
260             Pixels::Pointer(_) => Err(AvifError::NoContent),
261             Pixels::Pointer16(ptr) => {
262                 let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
263                 ptr.slice(offset..end)
264             }
265             Pixels::Buffer(_) => Err(AvifError::NoContent),
266             Pixels::Buffer16(buffer) => {
267                 let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
268                 let range = offset..end;
269                 check_slice_range(buffer.len(), &range)?;
270                 Ok(&buffer[range])
271             }
272         }
273     }
274 
slice16_mut(&mut self, offset: u32, size: u32) -> AvifResult<&mut [u16]>275     pub fn slice16_mut(&mut self, offset: u32, size: u32) -> AvifResult<&mut [u16]> {
276         let offset: usize = usize_from_u32(offset)?;
277         let size: usize = usize_from_u32(size)?;
278         match self {
279             Pixels::Pointer(_) => Err(AvifError::NoContent),
280             Pixels::Pointer16(ptr) => {
281                 let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
282                 ptr.slice_mut(offset..end)
283             }
284             Pixels::Buffer(_) => Err(AvifError::NoContent),
285             Pixels::Buffer16(buffer) => {
286                 let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
287                 let range = offset..end;
288                 check_slice_range(buffer.len(), &range)?;
289                 Ok(&mut buffer[range])
290             }
291         }
292     }
293 }
294