modelassetlib_native/jniimpl/
image.rs1extern crate jni;
2extern crate image;
3extern crate lazy_static;
4
5use std::io::Cursor;
6use std::sync::Mutex;
7use jni::JNIEnv;
8use jni::objects::{JByteArray, JClass, JObject};
9use anyhow::Result;
10use image::RgbaImage;
11use jni::sys::{jbyte, jbyteArray, jint, jsize, jstring};
12use crate::util;
13use crate::util::error_message::ErrorMessage;
14
15lazy_static::lazy_static! {
16 pub static ref ERROR_MESSAGE: Mutex<ErrorMessage> = Mutex::new(ErrorMessage::new());
17}
18
19pub fn record_error(msg: &str) {
20 let err_msg = ERROR_MESSAGE.lock().unwrap();
21 err_msg.mark_occurred();
22 err_msg.set(msg);
23}
24
25pub fn handle_native_init<'a>(
26 env: &mut JNIEnv<'a>,
27 this: &JObject<'a>,
28 raw_data: &JByteArray
29) -> Result<()> {
30 let raw_data_len = env.get_array_length(raw_data)?;
31 let mut data: Vec<jbyte> = util::new_buffer_vec(raw_data_len as usize, 0);
32 env.get_byte_array_region(raw_data, 0, data.as_mut_slice())?;
33 let data_u8: Vec<u8> = data.iter().map(|x| *x as u8).collect();
34 let image = image::io::Reader::new(Cursor::new(data_u8.as_slice()))
35 .with_guessed_format()?.decode()?;
36 let rgba8_image: RgbaImage = image.to_rgba8();
37
38 unsafe {
39 env.set_rust_field(this, "rust_imageObj", rgba8_image)?;
40 }
41
42 Ok(())
43}
44
45pub fn handle_native_init_with_format<'a>(
46 env: &mut JNIEnv<'a>,
47 this: &JObject<'a>,
48 raw_data: &JByteArray,
49 format_id: jint
50) -> Result<()> {
51 let raw_data_len = env.get_array_length(raw_data)?;
52 let mut data: Vec<jbyte> = util::new_buffer_vec(raw_data_len as usize, 0);
53 env.get_byte_array_region(raw_data, 0, data.as_mut_slice())?;
54
55 let format = util::image::image_format_from_id(format_id)?;
56 let data_u8: Vec<u8> = data.iter().map(|x| *x as u8).collect();
57 let mut image_reader = image::io::Reader::new(Cursor::new(data_u8.as_slice()));
58 image_reader.set_format(format);
59 let image = image_reader.decode()?;
60 let rgba8_image: RgbaImage = image.to_rgba8();
61
62 unsafe {
63 env.set_rust_field(this, "rust_imageObj", rgba8_image)?;
64 }
65
66 Ok(())
67}
68
69pub fn handle_native_destroy<'a>(
70 env: &mut JNIEnv<'a>,
71 this: &JObject<'a>
72) -> Result<()> {
73 let image: RgbaImage;
74 unsafe {
75 image = env.take_rust_field(this, "rust_imageObj")?;
76 }
77 drop(image);
78 Ok(())
79}
80
81pub fn handle_is_error_occurred<'a>(
82 _: &mut JNIEnv<'a>,
83 _: &JClass<'a>
84) -> bool {
85 ERROR_MESSAGE.lock().unwrap().is_occurred()
86}
87
88pub fn handle_get_error_message<'a>(
89 env: &mut JNIEnv<'a>,
90 _: &JClass<'a>
91) -> jstring {
92 let msg = ERROR_MESSAGE.lock().unwrap().get();
93 let msg_jstr = env.new_string(msg).unwrap();
94 msg_jstr.as_raw()
95}
96
97pub fn handle_clear_error<'a>(
98 _: &mut JNIEnv<'a>,
99 _: &JClass<'a>
100) {
101 let msg = ERROR_MESSAGE.lock().unwrap();
102 msg.set("");
103 msg.clear_mark();
104}
105
106pub fn handle_get_width<'a>(
107 env: &mut JNIEnv<'a>,
108 this: &JObject<'a>
109) -> Result<jint> {
110 let image: RgbaImage;
111 unsafe {
112 image = env.take_rust_field(this, "rust_imageObj")?;
113 }
114
115 let result = image.width();
116
117 unsafe {
118 env.set_rust_field(this, "rust_imageObj", image)?;
119 }
120
121 Ok(result as jint)
122}
123
124pub fn handle_get_height<'a>(
125 env: &mut JNIEnv<'a>,
126 this: &JObject<'a>
127) -> Result<jint> {
128 let image: RgbaImage;
129 unsafe {
130 image = env.take_rust_field(this, "rust_imageObj")?;
131 }
132
133 let result = image.height();
134
135 unsafe {
136 env.set_rust_field(this, "rust_imageObj", image)?;
137 }
138
139 Ok(result as jint)
140}
141
142pub fn handle_get_rgba_data<'a>(
143 env: &mut JNIEnv<'a>,
144 this: &JObject<'a>
145) -> Result<jbyteArray> {
146 let image: RgbaImage;
147 unsafe {
148 image = env.take_rust_field(this, "rust_imageObj")?;
149 }
150
151 let data: Vec<jbyte> = image.as_raw().iter().map(|x| *x as jbyte).collect();
152 let data_jarr = env.new_byte_array(data.len() as jsize)?;
153 env.set_byte_array_region(&data_jarr, 0, data.as_slice())?;
154
155 unsafe {
156 env.set_rust_field(this, "rust_imageObj", image)?;
157 }
158
159 Ok(data_jarr.as_raw())
160}