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 super::types::*;
16
17 use std::ffi::CStr;
18 use std::os::raw::c_char;
19 use std::os::raw::c_void;
20
21 use crate::decoder::GenericIO;
22 use crate::internal_utils::io::DecoderFileIO;
23 use crate::internal_utils::io::DecoderRawIO;
24 use crate::*;
25
26 #[repr(C)]
27 #[derive(Clone)]
28 pub struct avifROData {
29 pub data: *const u8,
30 pub size: usize,
31 }
32
33 impl Default for avifROData {
default() -> Self34 fn default() -> Self {
35 avifROData {
36 data: std::ptr::null(),
37 size: 0,
38 }
39 }
40 }
41
42 #[repr(C)]
43 #[derive(Clone, Debug)]
44 pub struct avifRWData {
45 pub data: *mut u8,
46 pub size: usize,
47 }
48
49 impl Default for avifRWData {
default() -> Self50 fn default() -> Self {
51 avifRWData {
52 data: std::ptr::null_mut(),
53 size: 0,
54 }
55 }
56 }
57
58 impl From<&Vec<u8>> for avifRWData {
from(v: &Vec<u8>) -> Self59 fn from(v: &Vec<u8>) -> Self {
60 avifRWData {
61 data: v.as_ptr() as *mut u8,
62 size: v.len(),
63 }
64 }
65 }
66
67 #[no_mangle]
crabby_avifRWDataRealloc( raw: *mut avifRWData, newSize: usize, ) -> avifResult68 pub unsafe extern "C" fn crabby_avifRWDataRealloc(
69 raw: *mut avifRWData,
70 newSize: usize,
71 ) -> avifResult {
72 unsafe {
73 if (*raw).size == newSize {
74 return avifResult::Ok;
75 }
76 // Ok to use size as capacity here since we use reserve_exact.
77 let mut newData: Vec<u8> = Vec::new();
78 if newData.try_reserve_exact(newSize).is_err() {
79 return avifResult::OutOfMemory;
80 }
81 if !(*raw).data.is_null() {
82 let oldData = Box::from_raw(std::slice::from_raw_parts_mut((*raw).data, (*raw).size));
83 let sizeToCopy = std::cmp::min(newSize, oldData.len());
84 newData.extend_from_slice(&oldData[..sizeToCopy]);
85 }
86 newData.resize(newSize, 0);
87 let mut b = newData.into_boxed_slice();
88 (*raw).data = b.as_mut_ptr();
89 std::mem::forget(b);
90 (*raw).size = newSize;
91 avifResult::Ok
92 }
93 }
94
95 #[no_mangle]
crabby_avifRWDataSet( raw: *mut avifRWData, data: *const u8, size: usize, ) -> avifResult96 pub unsafe extern "C" fn crabby_avifRWDataSet(
97 raw: *mut avifRWData,
98 data: *const u8,
99 size: usize,
100 ) -> avifResult {
101 unsafe {
102 if size != 0 {
103 let res = crabby_avifRWDataRealloc(raw, size);
104 if res != avifResult::Ok {
105 return res;
106 }
107 std::ptr::copy_nonoverlapping(data, (*raw).data, size);
108 } else {
109 crabby_avifRWDataFree(raw);
110 }
111 avifResult::Ok
112 }
113 }
114
115 #[no_mangle]
crabby_avifRWDataFree(raw: *mut avifRWData)116 pub unsafe extern "C" fn crabby_avifRWDataFree(raw: *mut avifRWData) {
117 unsafe {
118 if (*raw).data.is_null() {
119 return;
120 }
121 let _ = Box::from_raw(std::slice::from_raw_parts_mut((*raw).data, (*raw).size));
122 }
123 }
124
125 pub type avifIODestroyFunc = unsafe extern "C" fn(io: *mut avifIO);
126 pub type avifIOReadFunc = unsafe extern "C" fn(
127 io: *mut avifIO,
128 readFlags: u32,
129 offset: u64,
130 size: usize,
131 out: *mut avifROData,
132 ) -> avifResult;
133 pub type avifIOWriteFunc = unsafe extern "C" fn(
134 io: *mut avifIO,
135 writeFlags: u32,
136 offset: u64,
137 data: *const u8,
138 size: usize,
139 ) -> avifResult;
140
141 #[repr(C)]
142 #[derive(Clone, Copy)]
143 pub struct avifIO {
144 destroy: avifIODestroyFunc,
145 read: avifIOReadFunc,
146 write: avifIOWriteFunc,
147 sizeHint: u64,
148 persistent: avifBool,
149 data: *mut c_void,
150 }
151
152 pub struct avifIOWrapper {
153 data: avifROData,
154 io: avifIO,
155 }
156
157 impl avifIOWrapper {
create(io: avifIO) -> Self158 pub fn create(io: avifIO) -> Self {
159 Self {
160 io,
161 data: Default::default(),
162 }
163 }
164 }
165
166 impl crate::decoder::IO for avifIOWrapper {
167 #[cfg_attr(feature = "disable_cfi", no_sanitize(cfi))]
read(&mut self, offset: u64, size: usize) -> AvifResult<&[u8]>168 fn read(&mut self, offset: u64, size: usize) -> AvifResult<&[u8]> {
169 let res = unsafe {
170 (self.io.read)(
171 &mut self.io as *mut avifIO,
172 0,
173 offset,
174 size,
175 &mut self.data as *mut avifROData,
176 )
177 };
178 if res != avifResult::Ok {
179 let err: AvifError = res.into();
180 return Err(err);
181 }
182 if self.data.size == 0 {
183 Ok(&[])
184 } else if self.data.data.is_null() {
185 Err(AvifError::UnknownError(
186 "data pointer was null but size was not zero".into(),
187 ))
188 } else {
189 Ok(unsafe { std::slice::from_raw_parts(self.data.data, self.data.size) })
190 }
191 }
size_hint(&self) -> u64192 fn size_hint(&self) -> u64 {
193 self.io.sizeHint
194 }
persistent(&self) -> bool195 fn persistent(&self) -> bool {
196 self.io.persistent != 0
197 }
198 }
199
200 pub struct avifCIOWrapper {
201 io: GenericIO,
202 buf: Vec<u8>,
203 }
204
205 #[no_mangle]
cioDestroy(_io: *mut avifIO)206 unsafe extern "C" fn cioDestroy(_io: *mut avifIO) {}
207
208 #[no_mangle]
cioRead( io: *mut avifIO, _readFlags: u32, offset: u64, size: usize, out: *mut avifROData, ) -> avifResult209 unsafe extern "C" fn cioRead(
210 io: *mut avifIO,
211 _readFlags: u32,
212 offset: u64,
213 size: usize,
214 out: *mut avifROData,
215 ) -> avifResult {
216 unsafe {
217 if io.is_null() {
218 return avifResult::IoError;
219 }
220 let cio = (*io).data as *mut avifCIOWrapper;
221 match (*cio).io.read(offset, size) {
222 Ok(data) => {
223 (*cio).buf.clear();
224 if (*cio).buf.try_reserve_exact(data.len()).is_err() {
225 return avifResult::OutOfMemory;
226 }
227 (*cio).buf.extend_from_slice(data);
228 }
229 Err(_) => return avifResult::IoError,
230 }
231 (*out).data = (*cio).buf.as_ptr();
232 (*out).size = (*cio).buf.len();
233 avifResult::Ok
234 }
235 }
236
237 #[no_mangle]
cioWrite( _io: *mut avifIO, _writeFlags: u32, _offset: u64, _data: *const u8, _size: usize, ) -> avifResult238 unsafe extern "C" fn cioWrite(
239 _io: *mut avifIO,
240 _writeFlags: u32,
241 _offset: u64,
242 _data: *const u8,
243 _size: usize,
244 ) -> avifResult {
245 avifResult::Ok
246 }
247
248 #[no_mangle]
crabby_avifIOCreateMemoryReader( data: *const u8, size: usize, ) -> *mut avifIO249 pub unsafe extern "C" fn crabby_avifIOCreateMemoryReader(
250 data: *const u8,
251 size: usize,
252 ) -> *mut avifIO {
253 let cio = Box::new(avifCIOWrapper {
254 io: Box::new(unsafe { DecoderRawIO::create(data, size) }),
255 buf: Vec::new(),
256 });
257 let io = Box::new(avifIO {
258 destroy: cioDestroy,
259 read: cioRead,
260 write: cioWrite,
261 sizeHint: size as u64,
262 persistent: 0,
263 data: Box::into_raw(cio) as *mut c_void,
264 });
265 Box::into_raw(io)
266 }
267
268 #[no_mangle]
crabby_avifIOCreateFileReader(filename: *const c_char) -> *mut avifIO269 pub unsafe extern "C" fn crabby_avifIOCreateFileReader(filename: *const c_char) -> *mut avifIO {
270 let filename = unsafe { String::from(CStr::from_ptr(filename).to_str().unwrap_or("")) };
271 let file_io = match DecoderFileIO::create(&filename) {
272 Ok(x) => x,
273 Err(_) => return std::ptr::null_mut(),
274 };
275 let cio = Box::new(avifCIOWrapper {
276 io: Box::new(file_io),
277 buf: Vec::new(),
278 });
279 let io = Box::new(avifIO {
280 destroy: cioDestroy,
281 read: cioRead,
282 write: cioWrite,
283 sizeHint: cio.io.size_hint(),
284 persistent: 0,
285 data: Box::into_raw(cio) as *mut c_void,
286 });
287 Box::into_raw(io)
288 }
289
290 #[no_mangle]
crabby_avifIODestroy(io: *mut avifIO)291 pub unsafe extern "C" fn crabby_avifIODestroy(io: *mut avifIO) {
292 unsafe {
293 let _ = Box::from_raw((*io).data as *mut avifCIOWrapper);
294 let _ = Box::from_raw(io);
295 }
296 }
297