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 17 use std::fs::File; 18 use std::io::Read; 19 use std::io::Seek; 20 use std::io::SeekFrom; 21 22 #[derive(Debug, Default)] 23 pub struct DecoderFileIO { 24 file: Option<File>, 25 buffer: Vec<u8>, 26 } 27 28 impl DecoderFileIO { create(filename: &String) -> AvifResult<DecoderFileIO>29 pub fn create(filename: &String) -> AvifResult<DecoderFileIO> { 30 let file = File::open(filename).or(Err(AvifError::IoError))?; 31 Ok(DecoderFileIO { 32 file: Some(file), 33 buffer: Vec::new(), 34 }) 35 } 36 } 37 38 impl decoder::IO for DecoderFileIO { read(&mut self, offset: u64, max_read_size: usize) -> AvifResult<&[u8]>39 fn read(&mut self, offset: u64, max_read_size: usize) -> AvifResult<&[u8]> { 40 let file_size = self.size_hint(); 41 if offset > file_size { 42 return Err(AvifError::IoError); 43 } 44 let available_size: usize = (file_size - offset) as usize; 45 let size_to_read: usize = 46 if max_read_size > available_size { available_size } else { max_read_size }; 47 if size_to_read > 0 { 48 if self.buffer.capacity() < size_to_read 49 && self.buffer.try_reserve_exact(size_to_read).is_err() 50 { 51 return Err(AvifError::OutOfMemory); 52 } 53 self.buffer.resize(size_to_read, 0); 54 if self 55 .file 56 .unwrap_ref() 57 .seek(SeekFrom::Start(offset)) 58 .is_err() 59 || self.file.unwrap_ref().read_exact(&mut self.buffer).is_err() 60 { 61 return Err(AvifError::IoError); 62 } 63 } else { 64 self.buffer.clear(); 65 } 66 Ok(self.buffer.as_slice()) 67 } 68 size_hint(&self) -> u6469 fn size_hint(&self) -> u64 { 70 let metadata = self.file.unwrap_ref().metadata(); 71 if metadata.is_err() { 72 return 0; 73 } 74 metadata.unwrap().len() 75 } 76 persistent(&self) -> bool77 fn persistent(&self) -> bool { 78 false 79 } 80 } 81 82 pub struct DecoderRawIO<'a> { 83 pub data: &'a [u8], 84 } 85 86 impl DecoderRawIO<'_> { 87 // SAFETY: This function is only used from the C/C++ API when the input comes from native 88 // callers. The assumption is that the caller will always pass in a valid pointer and size. create(data: *const u8, size: usize) -> Self89 pub unsafe fn create(data: *const u8, size: usize) -> Self { 90 Self { 91 data: unsafe { std::slice::from_raw_parts(data, size) }, 92 } 93 } 94 } 95 96 impl decoder::IO for DecoderRawIO<'_> { read(&mut self, offset: u64, max_read_size: usize) -> AvifResult<&[u8]>97 fn read(&mut self, offset: u64, max_read_size: usize) -> AvifResult<&[u8]> { 98 let data_len = self.data.len() as u64; 99 if offset > data_len { 100 return Err(AvifError::IoError); 101 } 102 let available_size: usize = (data_len - offset) as usize; 103 let size_to_read: usize = 104 if max_read_size > available_size { available_size } else { max_read_size }; 105 let slice_start = usize_from_u64(offset)?; 106 let slice_end = checked_add!(slice_start, size_to_read)?; 107 let range = slice_start..slice_end; 108 check_slice_range(self.data.len(), &range)?; 109 Ok(&self.data[range]) 110 } 111 size_hint(&self) -> u64112 fn size_hint(&self) -> u64 { 113 self.data.len() as u64 114 } 115 persistent(&self) -> bool116 fn persistent(&self) -> bool { 117 true 118 } 119 } 120 121 pub struct DecoderMemoryIO { 122 pub data: Vec<u8>, 123 } 124 125 impl decoder::IO for DecoderMemoryIO { read(&mut self, offset: u64, max_read_size: usize) -> AvifResult<&[u8]>126 fn read(&mut self, offset: u64, max_read_size: usize) -> AvifResult<&[u8]> { 127 let data_len = self.data.len() as u64; 128 if offset > data_len { 129 return Err(AvifError::IoError); 130 } 131 let available_size: usize = (data_len - offset) as usize; 132 let size_to_read: usize = 133 if max_read_size > available_size { available_size } else { max_read_size }; 134 let slice_start = usize_from_u64(offset)?; 135 let slice_end = checked_add!(slice_start, size_to_read)?; 136 let range = slice_start..slice_end; 137 check_slice_range(self.data.len(), &range)?; 138 Ok(&self.data[range]) 139 } 140 size_hint(&self) -> u64141 fn size_hint(&self) -> u64 { 142 self.data.len() as u64 143 } 144 persistent(&self) -> bool145 fn persistent(&self) -> bool { 146 true 147 } 148 } 149