Skip to main content

gltforge_unity/
unity_image.rs

1use crate::unity_gltf::UnityGltf;
2
3/// A glTF image entry.
4pub struct UnityImage {
5    /// The image name. Falls back to the image index as a string if unnamed.
6    pub name: String,
7
8    /// The URI of the image, if it references an external file.
9    /// `None` for buffer-view-embedded images (e.g. GLB).
10    pub uri: Option<String>,
11
12    /// The raw encoded image bytes (PNG, JPEG, …) for buffer-view-embedded images.
13    /// `None` when the image is URI-based.
14    pub bytes: Option<Vec<u8>>,
15}
16
17// ─── FFI ────────────────────────────────────────────────────────────────────
18
19/// Return the number of images.
20///
21/// # Safety
22/// `ptr` must be a valid, non-null handle.
23#[unsafe(no_mangle)]
24pub unsafe extern "C" fn gltforge_image_count(ptr: *const UnityGltf) -> u32 {
25    unsafe { &*ptr }.images.len() as u32
26}
27
28/// Return a pointer to the UTF-8 name bytes for image `image_idx`.
29/// `out_len` receives the byte length. Returns null if `image_idx` is out of range.
30///
31/// # Safety
32/// `ptr` must be a valid, non-null handle. `out_len` may be null.
33#[unsafe(no_mangle)]
34pub unsafe extern "C" fn gltforge_image_name(
35    ptr: *const UnityGltf,
36    image_idx: u32,
37    out_len: *mut u32,
38) -> *const u8 {
39    unsafe { crate::write_name({ &*ptr }.images.get(&image_idx).map(|i| &i.name), out_len) }
40}
41
42/// Return a pointer to the UTF-8 URI bytes for image `image_idx`.
43/// `out_len` receives the byte length.
44/// Returns null if `image_idx` is out of range or the image is buffer-view-embedded.
45///
46/// # Safety
47/// `ptr` must be a valid, non-null handle. `out_len` may be null.
48#[unsafe(no_mangle)]
49pub unsafe extern "C" fn gltforge_image_uri(
50    ptr: *const UnityGltf,
51    image_idx: u32,
52    out_len: *mut u32,
53) -> *const u8 {
54    unsafe {
55        crate::write_name(
56            { &*ptr }
57                .images
58                .get(&image_idx)
59                .and_then(|i| i.uri.as_ref()),
60            out_len,
61        )
62    }
63}
64
65/// Return a pointer to the raw encoded image bytes (PNG, JPEG, …) for a
66/// buffer-view-embedded image. `out_len` receives the byte count.
67/// Returns null if `image_idx` is out of range or the image is URI-based.
68///
69/// # Safety
70/// `ptr` must be a valid, non-null handle. `out_len` may be null.
71/// The returned pointer is valid for the lifetime of the [`UnityGltf`] handle.
72#[unsafe(no_mangle)]
73pub unsafe extern "C" fn gltforge_image_bytes(
74    ptr: *const UnityGltf,
75    image_idx: u32,
76    out_len: *mut u32,
77) -> *const u8 {
78    let image = unsafe { &*ptr }.images.get(&image_idx);
79    match image.and_then(|i| i.bytes.as_ref()) {
80        Some(bytes) => {
81            if !out_len.is_null() {
82                unsafe { *out_len = bytes.len() as u32 };
83            }
84            bytes.as_ptr()
85        }
86        None => {
87            if !out_len.is_null() {
88                unsafe { *out_len = 0 };
89            }
90            std::ptr::null()
91        }
92    }
93}