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}