modelassetlib_native/jniimpl/
image.rs

1extern 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}