mirror of
https://github.com/immich-app/immich.git
synced 2026-07-28 22:51:21 -07:00
feat(mobile): free native core buffers through a dedicated export
This commit is contained in:
@@ -86,7 +86,7 @@ void main() {
|
||||
expect(pixels[i], 255, reason: 'alpha at $i');
|
||||
}
|
||||
expect(pixels.toSet().length, greaterThan(2));
|
||||
malloc.free(ptr);
|
||||
immich_core_free(ptr);
|
||||
|
||||
expect(immich_core_thumbhash_decode(hashPtr, 4, info), equals(nullptr));
|
||||
} finally {
|
||||
|
||||
@@ -35,7 +35,7 @@ Uint8List? decodeDriftThumbHash(String? thumbHash) {
|
||||
try {
|
||||
return _rgbaToBmp(rgba, info[0], info[1], info[2]);
|
||||
} finally {
|
||||
malloc.free(rgba);
|
||||
immich_core_free(rgba);
|
||||
}
|
||||
} finally {
|
||||
malloc.free(hashPtr);
|
||||
|
||||
@@ -20,6 +20,15 @@ char *immich_core_version(void);
|
||||
*/
|
||||
void immich_core_free_string(char *ptr);
|
||||
|
||||
/**
|
||||
* Release a buffer returned by this library, such as a decoded ThumbHash.
|
||||
*
|
||||
* # Safety
|
||||
* `ptr` must be a buffer previously returned by this library, or null, and
|
||||
* must not be released twice.
|
||||
*/
|
||||
void immich_core_free(uint8_t *ptr);
|
||||
|
||||
/**
|
||||
* Returns whether an EXIF orientation swaps width and height.
|
||||
*/
|
||||
@@ -55,8 +64,8 @@ bool immich_core_rgba1010102_to_rgba8888(const uint8_t *src,
|
||||
uintptr_t dst_len);
|
||||
|
||||
/**
|
||||
* Decodes a ThumbHash into a libc buffer and writes width, height, and row bytes to `out_info`.
|
||||
* Free the buffer with `free`; malformed hashes return null.
|
||||
* Decodes a ThumbHash into a new buffer and writes width, height, and row bytes to `out_info`.
|
||||
* Free the buffer with `immich_core_free`; malformed hashes return null.
|
||||
*
|
||||
* # Safety
|
||||
* `hash` must be valid for `hash_len` bytes and `out_info` for three u32 writes.
|
||||
|
||||
@@ -28,6 +28,17 @@ pub unsafe extern "C" fn immich_core_free_string(ptr: *mut c_char) {
|
||||
});
|
||||
}
|
||||
|
||||
/// Release a buffer returned by this library, such as a decoded ThumbHash.
|
||||
///
|
||||
/// # Safety
|
||||
/// `ptr` must be a buffer previously returned by this library, or null, and
|
||||
/// must not be released twice.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn immich_core_free(ptr: *mut u8) {
|
||||
// SAFETY: the buffer came from this library's libc allocation; free accepts null.
|
||||
unsafe { libc::free(ptr as *mut core::ffi::c_void) };
|
||||
}
|
||||
|
||||
fn guard<T>(sentinel: T, f: impl FnOnce() -> T + std::panic::UnwindSafe) -> T {
|
||||
crate::log::ensure_panic_hook();
|
||||
std::panic::catch_unwind(f).unwrap_or(sentinel)
|
||||
|
||||
@@ -22,8 +22,8 @@ pub(crate) fn decode_malloc(hash: &[u8]) -> Option<(*mut u8, u32, u32)> {
|
||||
Some((dst, w, h))
|
||||
}
|
||||
|
||||
/// Decodes a ThumbHash into a libc buffer and writes width, height, and row bytes to `out_info`.
|
||||
/// Free the buffer with `free`; malformed hashes return null.
|
||||
/// Decodes a ThumbHash into a new buffer and writes width, height, and row bytes to `out_info`.
|
||||
/// Free the buffer with `immich_core_free`; malformed hashes return null.
|
||||
///
|
||||
/// # Safety
|
||||
/// `hash` must be valid for `hash_len` bytes and `out_info` for three u32 writes.
|
||||
|
||||
@@ -18,4 +18,4 @@ pub use capi::image::{
|
||||
immich_core_rotate_rgba8888,
|
||||
};
|
||||
pub use capi::thumbhash::immich_core_thumbhash_decode;
|
||||
pub use capi::{immich_core_free_string, immich_core_version};
|
||||
pub use capi::{immich_core_free, immich_core_free_string, immich_core_version};
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::ffi::CStr;
|
||||
use std::ptr;
|
||||
|
||||
use immich_core_ffi::{
|
||||
immich_core_free_string, immich_core_orientation_swaps_dims,
|
||||
immich_core_free, immich_core_free_string, immich_core_orientation_swaps_dims,
|
||||
immich_core_rgba1010102_to_rgba8888, immich_core_rotate_rgba8888, immich_core_thumbhash_decode,
|
||||
immich_core_version,
|
||||
};
|
||||
@@ -186,7 +186,12 @@ fn thumbhash_decodes_into_a_malloc_buffer() {
|
||||
let pixels = unsafe { std::slice::from_raw_parts(ptr, len) };
|
||||
assert!(pixels.chunks_exact(4).all(|px| px[3] == 255));
|
||||
assert!(pixels.chunks_exact(4).any(|px| px[0] != pixels[0]));
|
||||
unsafe { libc::free(ptr as *mut libc::c_void) };
|
||||
unsafe { immich_core_free(ptr) };
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn free_accepts_null() {
|
||||
unsafe { immich_core_free(ptr::null_mut()) };
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -18,6 +18,14 @@ external ffi.Pointer<ffi.Char> immich_core_version();
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Char>)>()
|
||||
external void immich_core_free_string(ffi.Pointer<ffi.Char> ptr);
|
||||
|
||||
/// Release a buffer returned by this library, such as a decoded ThumbHash.
|
||||
///
|
||||
/// # Safety
|
||||
/// `ptr` must be a buffer previously returned by this library, or null, and
|
||||
/// must not be released twice.
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Uint8>)>()
|
||||
external void immich_core_free(ffi.Pointer<ffi.Uint8> ptr);
|
||||
|
||||
/// Returns whether an EXIF orientation swaps width and height.
|
||||
@ffi.Native<ffi.Bool Function(ffi.Int32)>()
|
||||
external bool immich_core_orientation_swaps_dims(int orientation);
|
||||
@@ -74,8 +82,8 @@ external bool immich_core_rgba1010102_to_rgba8888(
|
||||
int dst_len,
|
||||
);
|
||||
|
||||
/// Decodes a ThumbHash into a libc buffer and writes width, height, and row bytes to `out_info`.
|
||||
/// Free the buffer with `free`; malformed hashes return null.
|
||||
/// Decodes a ThumbHash into a new buffer and writes width, height, and row bytes to `out_info`.
|
||||
/// Free the buffer with `immich_core_free`; malformed hashes return null.
|
||||
///
|
||||
/// # Safety
|
||||
/// `hash` must be valid for `hash_len` bytes and `out_info` for three u32 writes.
|
||||
|
||||
@@ -125,7 +125,7 @@ void main() {
|
||||
expect(pixels[i], 255, reason: 'alpha at $i');
|
||||
}
|
||||
expect(pixels.toSet().length, greaterThan(2));
|
||||
malloc.free(ptr);
|
||||
immich_core_free(ptr);
|
||||
|
||||
expect(immich_core_thumbhash_decode(hashPtr, 4, info), equals(nullptr));
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user