1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use crate::core::{def::NSTDChar, slice::NSTDSlice};
use image::{ColorType, DynamicImage as Image, GenericImageView};
use std::ffi::CStr;
pub type NSTDImageHandle = *mut Image;
#[repr(C)]
#[allow(non_camel_case_types)]
pub enum NSTDImageFormat {
NSTD_IMAGE_FORMAT_UNKNOWN,
NSTD_IMAGE_FORMAT_LUMA8,
NSTD_IMAGE_FORMAT_LUMAA8,
NSTD_IMAGE_FORMAT_RGB8,
NSTD_IMAGE_FORMAT_RGBA8,
NSTD_IMAGE_FORMAT_LUMA16,
NSTD_IMAGE_FORMAT_LUMAA16,
NSTD_IMAGE_FORMAT_RGB16,
NSTD_IMAGE_FORMAT_RGBA16,
NSTD_IMAGE_FORMAT_RGB32F,
NSTD_IMAGE_FORMAT_RGBA32F,
}
impl From<&Image> for NSTDImageFormat {
#[inline]
fn from(image: &Image) -> Self {
match image.color() {
ColorType::L8 => Self::NSTD_IMAGE_FORMAT_LUMA8,
ColorType::La8 => Self::NSTD_IMAGE_FORMAT_LUMAA8,
ColorType::Rgb8 => Self::NSTD_IMAGE_FORMAT_RGB8,
ColorType::Rgba8 => Self::NSTD_IMAGE_FORMAT_RGBA8,
ColorType::L16 => Self::NSTD_IMAGE_FORMAT_LUMA16,
ColorType::La16 => Self::NSTD_IMAGE_FORMAT_LUMAA16,
ColorType::Rgb16 => Self::NSTD_IMAGE_FORMAT_RGB16,
ColorType::Rgba16 => Self::NSTD_IMAGE_FORMAT_RGBA16,
ColorType::Rgb32F => Self::NSTD_IMAGE_FORMAT_RGB32F,
ColorType::Rgba32F => Self::NSTD_IMAGE_FORMAT_RGBA32F,
_ => Self::NSTD_IMAGE_FORMAT_UNKNOWN,
}
}
}
#[repr(C)]
pub struct NSTDImage {
pub image: NSTDImageHandle,
pub raw: *const u8,
pub format: NSTDImageFormat,
pub width: u32,
pub height: u32,
}
impl Default for NSTDImage {
#[inline]
fn default() -> Self {
Self {
image: std::ptr::null_mut(),
raw: std::ptr::null_mut(),
format: NSTDImageFormat::NSTD_IMAGE_FORMAT_UNKNOWN,
width: 0,
height: 0,
}
}
}
impl From<Image> for NSTDImage {
#[inline]
fn from(image: Image) -> Self {
unsafe {
let image = Box::into_raw(Box::new(image));
let raw = (*image).as_bytes().as_ptr();
let format = NSTDImageFormat::from(&*image);
let (width, height) = (*image).dimensions();
Self {
image,
raw,
format,
width,
height,
}
}
}
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_image_open(file_name: *const NSTDChar) -> NSTDImage {
if let Ok(file_name) = CStr::from_ptr(file_name).to_str() {
if let Ok(image) = image::open(file_name) {
return NSTDImage::from(image);
}
}
NSTDImage::default()
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_image_load(bytes: &NSTDSlice) -> NSTDImage {
if bytes.ptr.size == 1 {
if let Ok(image) = image::load_from_memory(bytes.as_byte_slice()) {
return NSTDImage::from(image);
}
}
NSTDImage::default()
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_image_free(image: &mut NSTDImage) {
Box::from_raw(image.image);
image.image = std::ptr::null_mut();
}