Skip to main content

zenavif_parse/
c_api.rs

1#![allow(unsafe_code)]
2#![allow(deprecated)]
3
4use crate::AvifData as AvifDataRust;
5
6/// Result of parsing an AVIF file. Contains AV1-compressed data.
7#[allow(bad_style)]
8#[repr(C)]
9pub struct avif_data_t {
10    /// AV1 data for color channels
11    pub primary_data: *const u8,
12    pub primary_size: usize,
13    /// AV1 data for alpha channel (may be NULL if the image is fully opaque)
14    pub alpha_data: *const u8,
15    pub alpha_size: usize,
16    /// 0 = normal, uncorrelated alpha channel
17    /// 1 = premultiplied alpha. You must divide RGB values by alpha.
18    ///
19    /// ```c
20    /// if (a != 0) {r = r * 255 / a}
21    /// ```
22    pub premultiplied_alpha: u8,
23    rusty_handle: *mut AvifDataRust,
24}
25
26/// Parse AVIF image file and return results. Returns `NULL` if the file can't be parsed.
27///
28/// Call [`avif_data_free`] on the result when done.
29#[unsafe(no_mangle)]
30pub unsafe extern "C" fn avif_parse(bytes: *const u8, bytes_len: usize) -> *const avif_data_t {
31    if bytes.is_null() || bytes_len == 0 {
32        return std::ptr::null();
33    }
34    let mut data = unsafe { std::slice::from_raw_parts(bytes, bytes_len) };
35    match crate::read_avif(&mut data) {
36        Ok(data) => Box::into_raw(Box::new(avif_data_t {
37            primary_data: data.primary_item.as_ptr(),
38            primary_size: data.primary_item.len(),
39            alpha_data: data
40                .alpha_item
41                .as_ref()
42                .map_or(std::ptr::null(), |a| a.as_ptr()),
43            alpha_size: data.alpha_item.as_ref().map_or(0, |a| a.len()),
44            premultiplied_alpha: u8::from(data.premultiplied_alpha),
45            rusty_handle: Box::into_raw(Box::new(data)),
46        })),
47        Err(_) => std::ptr::null(),
48    }
49}
50
51/// Free all data related to [`avif_data_t`]
52#[unsafe(no_mangle)]
53pub unsafe extern "C" fn avif_data_free(data: *const avif_data_t) {
54    if data.is_null() {
55        return;
56    }
57    unsafe {
58        let _ = Box::from_raw((*data).rusty_handle);
59        let _ = Box::from_raw(data.cast_mut());
60    }
61}