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