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 {
read(&mut self, offset: u64, size: usize) -> AvifResult<&[u8]>167 fn read(&mut self, offset: u64, size: usize) -> AvifResult<&[u8]> {
168 let res = unsafe {
169 (self.io.read)(
170 &mut self.io as *mut avifIO,
171 0,
172 offset,
173 size,
174 &mut self.data as *mut avifROData,
175 )
176 };
177 if res != avifResult::Ok {
178 let err: AvifError = res.into();
179 return Err(err);
180 }
181 if self.data.size == 0 {
182 Ok(&[])
183 } else if self.data.data.is_null() {
184 Err(AvifError::UnknownError(
185 "data pointer was null but size was not zero".into(),
186 ))
187 } else {
188 Ok(unsafe { std::slice::from_raw_parts(self.data.data, self.data.size) })
189 }
190 }
size_hint(&self) -> u64191 fn size_hint(&self) -> u64 {
192 self.io.sizeHint
193 }
persistent(&self) -> bool194 fn persistent(&self) -> bool {
195 self.io.persistent != 0
196 }
197 }
198
199 pub struct avifCIOWrapper {
200 io: GenericIO,
201 buf: Vec<u8>,
202 }
203
204 #[no_mangle]
cioDestroy(_io: *mut avifIO)205 unsafe extern "C" fn cioDestroy(_io: *mut avifIO) {}
206
207 #[no_mangle]
cioRead( io: *mut avifIO, _readFlags: u32, offset: u64, size: usize, out: *mut avifROData, ) -> avifResult208 unsafe extern "C" fn cioRead(
209 io: *mut avifIO,
210 _readFlags: u32,
211 offset: u64,
212 size: usize,
213 out: *mut avifROData,
214 ) -> avifResult {
215 unsafe {
216 if io.is_null() {
217 return avifResult::IoError;
218 }
219 let cio = (*io).data as *mut avifCIOWrapper;
220 match (*cio).io.read(offset, size) {
221 Ok(data) => {
222 (*cio).buf.clear();
223 if (*cio).buf.try_reserve_exact(data.len()).is_err() {
224 return avifResult::OutOfMemory;
225 }
226 (*cio).buf.extend_from_slice(data);
227 }
228 Err(_) => return avifResult::IoError,
229 }
230 (*out).data = (*cio).buf.as_ptr();
231 (*out).size = (*cio).buf.len();
232 avifResult::Ok
233 }
234 }
235
236 #[no_mangle]
cioWrite( _io: *mut avifIO, _writeFlags: u32, _offset: u64, _data: *const u8, _size: usize, ) -> avifResult237 unsafe extern "C" fn cioWrite(
238 _io: *mut avifIO,
239 _writeFlags: u32,
240 _offset: u64,
241 _data: *const u8,
242 _size: usize,
243 ) -> avifResult {
244 avifResult::Ok
245 }
246
247 #[no_mangle]
crabby_avifIOCreateMemoryReader( data: *const u8, size: usize, ) -> *mut avifIO248 pub unsafe extern "C" fn crabby_avifIOCreateMemoryReader(
249 data: *const u8,
250 size: usize,
251 ) -> *mut avifIO {
252 let cio = Box::new(avifCIOWrapper {
253 io: Box::new(unsafe { DecoderRawIO::create(data, size) }),
254 buf: Vec::new(),
255 });
256 let io = Box::new(avifIO {
257 destroy: cioDestroy,
258 read: cioRead,
259 write: cioWrite,
260 sizeHint: size as u64,
261 persistent: 0,
262 data: Box::into_raw(cio) as *mut c_void,
263 });
264 Box::into_raw(io)
265 }
266
267 #[no_mangle]
crabby_avifIOCreateFileReader(filename: *const c_char) -> *mut avifIO268 pub unsafe extern "C" fn crabby_avifIOCreateFileReader(filename: *const c_char) -> *mut avifIO {
269 let filename = unsafe { String::from(CStr::from_ptr(filename).to_str().unwrap_or("")) };
270 let file_io = match DecoderFileIO::create(&filename) {
271 Ok(x) => x,
272 Err(_) => return std::ptr::null_mut(),
273 };
274 let cio = Box::new(avifCIOWrapper {
275 io: Box::new(file_io),
276 buf: Vec::new(),
277 });
278 let io = Box::new(avifIO {
279 destroy: cioDestroy,
280 read: cioRead,
281 write: cioWrite,
282 sizeHint: cio.io.size_hint(),
283 persistent: 0,
284 data: Box::into_raw(cio) as *mut c_void,
285 });
286 Box::into_raw(io)
287 }
288
289 #[no_mangle]
crabby_avifIODestroy(io: *mut avifIO)290 pub unsafe extern "C" fn crabby_avifIODestroy(io: *mut avifIO) {
291 unsafe {
292 let _ = Box::from_raw((*io).data as *mut avifCIOWrapper);
293 let _ = Box::from_raw(io);
294 }
295 }
296