libheif_rs/
utils.rs

1use std::ffi::{CStr, CString};
2use std::os::raw::c_char;
3use std::path::Path;
4
5use libheif_sys as lh;
6
7use crate::{FileTypeResult, HeifError, HeifErrorCode, HeifErrorSubCode, Result};
8
9#[inline]
10pub(crate) fn cstr_to_str<'a>(c_str: *const c_char) -> Option<&'a str> {
11    if c_str.is_null() {
12        None
13    } else {
14        let res = unsafe { CStr::from_ptr(c_str).to_str() };
15        res.ok()
16    }
17}
18
19pub(crate) fn str_to_cstring(s: &str, name: &str) -> Result<CString> {
20    CString::new(s).map_err(|e| HeifError {
21        code: HeifErrorCode::UsageError,
22        sub_code: HeifErrorSubCode::InvalidParameterValue,
23        message: format!("Invalid value of '{}': {}", name, e),
24    })
25}
26
27pub(crate) fn path_to_cstring(path: &Path) -> CString {
28    #[cfg(unix)]
29    {
30        use std::os::unix::ffi::OsStrExt;
31        CString::new(path.as_os_str().as_bytes()).unwrap_or_default()
32    }
33
34    #[cfg(windows)]
35    {
36        use std::os::windows::ffi::OsStrExt;
37        let mut buf = Vec::new();
38        buf.extend(
39            path.as_os_str()
40                .encode_wide()
41                .chain(Some(0))
42                .flat_map(|b| b.to_ne_bytes()),
43        );
44        CString::new(buf).unwrap_or_default()
45    }
46}
47
48#[cfg(feature = "v1_18")]
49pub(crate) fn get_non_null_ptr<T>(ptr: *mut T) -> Result<std::ptr::NonNull<T>> {
50    std::ptr::NonNull::new(ptr).ok_or_else(|| HeifError {
51        code: HeifErrorCode::MemoryAllocationError,
52        sub_code: HeifErrorSubCode::Unspecified,
53        message: "".to_string(),
54    })
55}
56
57/// Check a file type by it first bytes.
58/// Input data should be at least 12 bytes.
59pub fn check_file_type(data: &[u8]) -> FileTypeResult {
60    let res = unsafe { lh::heif_check_filetype(data.as_ptr(), data.len() as _) };
61    FileTypeResult::n(res).unwrap_or(FileTypeResult::No)
62}