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::gainmap::*;
16 use super::image::*;
17 use super::io::*;
18 use super::types::*;
19 
20 use std::ffi::CStr;
21 use std::os::raw::c_char;
22 
23 use crate::decoder::track::*;
24 use crate::decoder::*;
25 use crate::*;
26 
27 #[repr(C)]
28 pub struct avifDecoder {
29     pub codecChoice: avifCodecChoice,
30     pub maxThreads: i32,
31     pub requestedSource: Source,
32     pub allowProgressive: avifBool,
33     pub allowIncremental: avifBool,
34     pub ignoreExif: avifBool,
35     pub ignoreXMP: avifBool,
36     pub imageSizeLimit: u32,
37     pub imageDimensionLimit: u32,
38     pub imageCountLimit: u32,
39     pub strictFlags: avifStrictFlags,
40 
41     // Output params.
42     pub image: *mut avifImage,
43     pub imageIndex: i32,
44     pub imageCount: i32,
45     pub progressiveState: ProgressiveState,
46     pub imageTiming: ImageTiming,
47     pub timescale: u64,
48     pub duration: f64,
49     pub durationInTimescales: u64,
50     pub repetitionCount: i32,
51     pub alphaPresent: avifBool,
52     pub ioStats: IOStats,
53     pub diag: avifDiagnostics,
54     pub data: *mut avifDecoderData,
55     pub imageContentToDecode: avifImageContentTypeFlags,
56     pub imageSequenceTrackPresent: avifBool,
57 
58     // These fields are not part of libavif. Any new fields that are to be header file compatible
59     // with libavif must be added before this line.
60     pub androidMediaCodecOutputColorFormat: AndroidMediaCodecOutputColorFormat,
61     pub compressionFormat: CompressionFormat,
62 
63     // Rust specific fields that are not accessed from the C/C++ layer.
64     rust_decoder: Box<Decoder>,
65     image_object: avifImage,
66     gainmap_object: avifGainMap,
67     gainmap_image_object: avifImage,
68 }
69 
70 impl Default for avifDecoder {
default() -> Self71     fn default() -> Self {
72         Self {
73             codecChoice: avifCodecChoice::Auto,
74             maxThreads: 1,
75             requestedSource: Source::Auto,
76             allowIncremental: AVIF_FALSE,
77             allowProgressive: AVIF_FALSE,
78             ignoreExif: AVIF_FALSE,
79             ignoreXMP: AVIF_FALSE,
80             imageSizeLimit: DEFAULT_IMAGE_SIZE_LIMIT,
81             imageDimensionLimit: DEFAULT_IMAGE_DIMENSION_LIMIT,
82             imageCountLimit: DEFAULT_IMAGE_COUNT_LIMIT,
83             strictFlags: AVIF_STRICT_ENABLED,
84             image: std::ptr::null_mut(),
85             imageIndex: -1,
86             imageCount: 0,
87             progressiveState: ProgressiveState::Unavailable,
88             imageTiming: ImageTiming::default(),
89             timescale: 0,
90             duration: 0.0,
91             durationInTimescales: 0,
92             repetitionCount: 0,
93             alphaPresent: AVIF_FALSE,
94             ioStats: Default::default(),
95             diag: avifDiagnostics::default(),
96             data: std::ptr::null_mut(),
97             imageContentToDecode: AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA,
98             imageSequenceTrackPresent: AVIF_FALSE,
99             androidMediaCodecOutputColorFormat: AndroidMediaCodecOutputColorFormat::default(),
100             compressionFormat: CompressionFormat::default(),
101             rust_decoder: Box::<Decoder>::default(),
102             image_object: avifImage::default(),
103             gainmap_image_object: avifImage::default(),
104             gainmap_object: avifGainMap::default(),
105         }
106     }
107 }
108 
109 #[no_mangle]
crabby_avifDecoderCreate() -> *mut avifDecoder110 pub unsafe extern "C" fn crabby_avifDecoderCreate() -> *mut avifDecoder {
111     Box::into_raw(Box::<avifDecoder>::default())
112 }
113 
114 #[no_mangle]
crabby_avifDecoderSetIO(decoder: *mut avifDecoder, io: *mut avifIO)115 pub unsafe extern "C" fn crabby_avifDecoderSetIO(decoder: *mut avifDecoder, io: *mut avifIO) {
116     unsafe {
117         let rust_decoder = &mut (*decoder).rust_decoder;
118         rust_decoder.set_io(Box::new(avifIOWrapper::create(*io)));
119     }
120 }
121 
122 #[no_mangle]
crabby_avifDecoderSetIOFile( decoder: *mut avifDecoder, filename: *const c_char, ) -> avifResult123 pub unsafe extern "C" fn crabby_avifDecoderSetIOFile(
124     decoder: *mut avifDecoder,
125     filename: *const c_char,
126 ) -> avifResult {
127     unsafe {
128         let rust_decoder = &mut (*decoder).rust_decoder;
129         let filename = String::from(CStr::from_ptr(filename).to_str().unwrap_or(""));
130         to_avifResult(&rust_decoder.set_io_file(&filename))
131     }
132 }
133 
134 #[no_mangle]
crabby_avifDecoderSetIOMemory( decoder: *mut avifDecoder, data: *const u8, size: usize, ) -> avifResult135 pub unsafe extern "C" fn crabby_avifDecoderSetIOMemory(
136     decoder: *mut avifDecoder,
137     data: *const u8,
138     size: usize,
139 ) -> avifResult {
140     let rust_decoder = unsafe { &mut (*decoder).rust_decoder };
141     to_avifResult(unsafe { &rust_decoder.set_io_raw(data, size) })
142 }
143 
144 #[no_mangle]
crabby_avifDecoderSetSource( decoder: *mut avifDecoder, source: Source, ) -> avifResult145 pub unsafe extern "C" fn crabby_avifDecoderSetSource(
146     decoder: *mut avifDecoder,
147     source: Source,
148 ) -> avifResult {
149     unsafe {
150         (*decoder).requestedSource = source;
151     }
152     avifResult::Ok
153 }
154 
155 impl From<&avifDecoder> for Settings {
from(decoder: &avifDecoder) -> Self156     fn from(decoder: &avifDecoder) -> Self {
157         let strictness = if decoder.strictFlags == AVIF_STRICT_DISABLED {
158             Strictness::None
159         } else if decoder.strictFlags == AVIF_STRICT_ENABLED {
160             Strictness::All
161         } else {
162             let mut flags: Vec<StrictnessFlag> = Vec::new();
163             if (decoder.strictFlags & AVIF_STRICT_PIXI_REQUIRED) != 0 {
164                 flags.push(StrictnessFlag::PixiRequired);
165             }
166             if (decoder.strictFlags & AVIF_STRICT_CLAP_VALID) != 0 {
167                 flags.push(StrictnessFlag::ClapValid);
168             }
169             if (decoder.strictFlags & AVIF_STRICT_ALPHA_ISPE_REQUIRED) != 0 {
170                 flags.push(StrictnessFlag::AlphaIspeRequired);
171             }
172             Strictness::SpecificInclude(flags)
173         };
174         let image_content_to_decode_flags: ImageContentType = match decoder.imageContentToDecode {
175             AVIF_IMAGE_CONTENT_ALL => ImageContentType::All,
176             AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA => ImageContentType::ColorAndAlpha,
177             AVIF_IMAGE_CONTENT_GAIN_MAP => ImageContentType::GainMap,
178             _ => ImageContentType::None,
179         };
180         Self {
181             source: decoder.requestedSource,
182             strictness,
183             allow_progressive: decoder.allowProgressive == AVIF_TRUE,
184             allow_incremental: decoder.allowIncremental == AVIF_TRUE,
185             ignore_exif: decoder.ignoreExif == AVIF_TRUE,
186             ignore_xmp: decoder.ignoreXMP == AVIF_TRUE,
187             image_content_to_decode: image_content_to_decode_flags,
188             codec_choice: match decoder.codecChoice {
189                 avifCodecChoice::Auto => CodecChoice::Auto,
190                 avifCodecChoice::Dav1d => CodecChoice::Dav1d,
191                 avifCodecChoice::Libgav1 => CodecChoice::Libgav1,
192                 // Silently treat all other choices the same as Auto.
193                 _ => CodecChoice::Auto,
194             },
195             image_size_limit: decoder.imageSizeLimit,
196             image_dimension_limit: decoder.imageDimensionLimit,
197             image_count_limit: decoder.imageCountLimit,
198             max_threads: u32::try_from(decoder.maxThreads).unwrap_or(0),
199             android_mediacodec_output_color_format: decoder.androidMediaCodecOutputColorFormat,
200         }
201     }
202 }
203 
rust_decoder_to_avifDecoder(src: &Decoder, dst: &mut avifDecoder)204 fn rust_decoder_to_avifDecoder(src: &Decoder, dst: &mut avifDecoder) {
205     // Copy image.
206     let image = src.image().unwrap();
207     dst.image_object = image.into();
208 
209     // Copy decoder properties.
210     dst.alphaPresent = to_avifBool(image.alpha_present);
211     dst.imageSequenceTrackPresent = to_avifBool(image.image_sequence_track_present);
212     dst.progressiveState = image.progressive_state;
213 
214     dst.imageTiming = src.image_timing();
215     dst.imageCount = src.image_count() as i32;
216     dst.imageIndex = src.image_index();
217     dst.repetitionCount = match src.repetition_count() {
218         RepetitionCount::Unknown => AVIF_REPETITION_COUNT_UNKNOWN,
219         RepetitionCount::Infinite => AVIF_REPETITION_COUNT_INFINITE,
220         RepetitionCount::Finite(x) => x,
221     };
222     dst.timescale = src.timescale();
223     dst.durationInTimescales = src.duration_in_timescales();
224     dst.duration = src.duration();
225     dst.ioStats = src.io_stats();
226     dst.compressionFormat = src.compression_format();
227 
228     if src.gainmap_present() {
229         dst.gainmap_image_object = (&src.gainmap().image).into();
230         dst.gainmap_object = src.gainmap().into();
231         if src.settings.image_content_to_decode.gainmap() {
232             dst.gainmap_object.image = (&mut dst.gainmap_image_object) as *mut avifImage;
233         }
234         dst.image_object.gainMap = (&mut dst.gainmap_object) as *mut avifGainMap;
235     }
236     dst.image = (&mut dst.image_object) as *mut avifImage;
237 }
238 
239 #[no_mangle]
crabby_avifDecoderParse(decoder: *mut avifDecoder) -> avifResult240 pub unsafe extern "C" fn crabby_avifDecoderParse(decoder: *mut avifDecoder) -> avifResult {
241     unsafe {
242         let rust_decoder = &mut (*decoder).rust_decoder;
243         rust_decoder.settings = (&(*decoder)).into();
244 
245         let res = rust_decoder.parse();
246         (*decoder).diag.set_from_result(&res);
247         if res.is_err() {
248             return to_avifResult(&res);
249         }
250         rust_decoder_to_avifDecoder(rust_decoder, &mut (*decoder));
251         avifResult::Ok
252     }
253 }
254 
255 #[no_mangle]
crabby_avifDecoderNextImage(decoder: *mut avifDecoder) -> avifResult256 pub unsafe extern "C" fn crabby_avifDecoderNextImage(decoder: *mut avifDecoder) -> avifResult {
257     unsafe {
258         let rust_decoder = &mut (*decoder).rust_decoder;
259         rust_decoder.settings = (&(*decoder)).into();
260 
261         let previous_decoded_row_count = rust_decoder.decoded_row_count();
262 
263         let res = rust_decoder.next_image();
264         (*decoder).diag.set_from_result(&res);
265         let mut early_return = false;
266         if res.is_err() {
267             early_return = true;
268             if rust_decoder.settings.allow_incremental
269                 && matches!(res.as_ref().err().unwrap(), AvifError::WaitingOnIo)
270             {
271                 early_return = previous_decoded_row_count == rust_decoder.decoded_row_count();
272             }
273         }
274         if early_return {
275             return to_avifResult(&res);
276         }
277         rust_decoder_to_avifDecoder(rust_decoder, &mut (*decoder));
278         to_avifResult(&res)
279     }
280 }
281 
282 #[no_mangle]
crabby_avifDecoderNthImage( decoder: *mut avifDecoder, frameIndex: u32, ) -> avifResult283 pub unsafe extern "C" fn crabby_avifDecoderNthImage(
284     decoder: *mut avifDecoder,
285     frameIndex: u32,
286 ) -> avifResult {
287     unsafe {
288         let rust_decoder = &mut (*decoder).rust_decoder;
289         rust_decoder.settings = (&(*decoder)).into();
290 
291         let previous_decoded_row_count = rust_decoder.decoded_row_count();
292         let image_index = (rust_decoder.image_index() + 1) as u32;
293 
294         let res = rust_decoder.nth_image(frameIndex);
295         (*decoder).diag.set_from_result(&res);
296         let mut early_return = false;
297         if res.is_err() {
298             early_return = true;
299             if rust_decoder.settings.allow_incremental
300                 && matches!(res.as_ref().err().unwrap(), AvifError::WaitingOnIo)
301             {
302                 if image_index != frameIndex {
303                     early_return = false;
304                 } else {
305                     early_return = previous_decoded_row_count == rust_decoder.decoded_row_count();
306                 }
307             }
308         }
309         if early_return {
310             return to_avifResult(&res);
311         }
312         rust_decoder_to_avifDecoder(rust_decoder, &mut (*decoder));
313         to_avifResult(&res)
314     }
315 }
316 
317 #[no_mangle]
crabby_avifDecoderNthImageTiming( decoder: *const avifDecoder, frameIndex: u32, outTiming: *mut ImageTiming, ) -> avifResult318 pub unsafe extern "C" fn crabby_avifDecoderNthImageTiming(
319     decoder: *const avifDecoder,
320     frameIndex: u32,
321     outTiming: *mut ImageTiming,
322 ) -> avifResult {
323     let rust_decoder = unsafe { &(*decoder).rust_decoder };
324     let image_timing = rust_decoder.nth_image_timing(frameIndex);
325     if let Ok(timing) = image_timing {
326         unsafe {
327             *outTiming = timing;
328         }
329     }
330     to_avifResult(&image_timing)
331 }
332 
333 #[no_mangle]
crabby_avifDecoderDestroy(decoder: *mut avifDecoder)334 pub unsafe extern "C" fn crabby_avifDecoderDestroy(decoder: *mut avifDecoder) {
335     unsafe {
336         let _ = Box::from_raw(decoder);
337     }
338 }
339 
340 #[no_mangle]
crabby_avifDecoderRead( decoder: *mut avifDecoder, image: *mut avifImage, ) -> avifResult341 pub unsafe extern "C" fn crabby_avifDecoderRead(
342     decoder: *mut avifDecoder,
343     image: *mut avifImage,
344 ) -> avifResult {
345     unsafe {
346         let rust_decoder = &mut (*decoder).rust_decoder;
347         rust_decoder.settings = (&(*decoder)).into();
348 
349         let res = rust_decoder.parse();
350         if res.is_err() {
351             return to_avifResult(&res);
352         }
353         let res = rust_decoder.next_image();
354         if res.is_err() {
355             return to_avifResult(&res);
356         }
357         rust_decoder_to_avifDecoder(rust_decoder, &mut (*decoder));
358         *image = (*decoder).image_object.clone();
359         avifResult::Ok
360     }
361 }
362 
363 #[no_mangle]
crabby_avifDecoderReadMemory( decoder: *mut avifDecoder, image: *mut avifImage, data: *const u8, size: usize, ) -> avifResult364 pub unsafe extern "C" fn crabby_avifDecoderReadMemory(
365     decoder: *mut avifDecoder,
366     image: *mut avifImage,
367     data: *const u8,
368     size: usize,
369 ) -> avifResult {
370     unsafe {
371         let res = crabby_avifDecoderSetIOMemory(decoder, data, size);
372         if res != avifResult::Ok {
373             return res;
374         }
375         crabby_avifDecoderRead(decoder, image)
376     }
377 }
378 
379 #[no_mangle]
crabby_avifDecoderReadFile( decoder: *mut avifDecoder, image: *mut avifImage, filename: *const c_char, ) -> avifResult380 pub unsafe extern "C" fn crabby_avifDecoderReadFile(
381     decoder: *mut avifDecoder,
382     image: *mut avifImage,
383     filename: *const c_char,
384 ) -> avifResult {
385     unsafe {
386         let res = crabby_avifDecoderSetIOFile(decoder, filename);
387         if res != avifResult::Ok {
388             return res;
389         }
390         crabby_avifDecoderRead(decoder, image)
391     }
392 }
393 
394 #[no_mangle]
crabby_avifDecoderIsKeyframe( decoder: *const avifDecoder, frameIndex: u32, ) -> avifBool395 pub unsafe extern "C" fn crabby_avifDecoderIsKeyframe(
396     decoder: *const avifDecoder,
397     frameIndex: u32,
398 ) -> avifBool {
399     let rust_decoder = unsafe { &(*decoder).rust_decoder };
400     to_avifBool(rust_decoder.is_keyframe(frameIndex))
401 }
402 
403 #[no_mangle]
crabby_avifDecoderNearestKeyframe( decoder: *const avifDecoder, frameIndex: u32, ) -> u32404 pub unsafe extern "C" fn crabby_avifDecoderNearestKeyframe(
405     decoder: *const avifDecoder,
406     frameIndex: u32,
407 ) -> u32 {
408     let rust_decoder = unsafe { &(*decoder).rust_decoder };
409     rust_decoder.nearest_keyframe(frameIndex)
410 }
411 
412 #[no_mangle]
crabby_avifDecoderDecodedRowCount(decoder: *const avifDecoder) -> u32413 pub unsafe extern "C" fn crabby_avifDecoderDecodedRowCount(decoder: *const avifDecoder) -> u32 {
414     let rust_decoder = unsafe { &(*decoder).rust_decoder };
415     rust_decoder.decoded_row_count()
416 }
417 
418 #[allow(non_camel_case_types)]
419 pub type avifExtent = Extent;
420 
421 #[no_mangle]
crabby_avifDecoderNthImageMaxExtent( decoder: *const avifDecoder, frameIndex: u32, outExtent: *mut avifExtent, ) -> avifResult422 pub unsafe extern "C" fn crabby_avifDecoderNthImageMaxExtent(
423     decoder: *const avifDecoder,
424     frameIndex: u32,
425     outExtent: *mut avifExtent,
426 ) -> avifResult {
427     let rust_decoder = unsafe { &(*decoder).rust_decoder };
428     let res = rust_decoder.nth_image_max_extent(frameIndex);
429     if res.is_err() {
430         return to_avifResult(&res);
431     }
432     unsafe {
433         *outExtent = res.unwrap();
434     }
435     avifResult::Ok
436 }
437 
438 #[no_mangle]
crabby_avifPeekCompatibleFileType(input: *const avifROData) -> avifBool439 pub unsafe extern "C" fn crabby_avifPeekCompatibleFileType(input: *const avifROData) -> avifBool {
440     let data = unsafe { std::slice::from_raw_parts((*input).data, (*input).size) };
441     to_avifBool(Decoder::peek_compatible_file_type(data))
442 }
443