From c3c5fbfc793abae969d3d3cbc302d3bc0372d45b Mon Sep 17 00:00:00 2001 From: Dude so hot Date: Sat, 14 Sep 2024 19:44:05 +0800 Subject: [PATCH] Extract with_bitmap_content Signed-off-by: Dude so hot --- app/src/main/rust/src/image/qr_code.rs | 19 +++++-------------- app/src/main/rust/src/lib.rs | 20 +++++++++++++++++++- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/src/main/rust/src/image/qr_code.rs b/app/src/main/rust/src/image/qr_code.rs index 55536fb17..eddeaeb25 100644 --- a/app/src/main/rust/src/image/qr_code.rs +++ b/app/src/main/rust/src/image/qr_code.rs @@ -1,15 +1,14 @@ -use crate::{get_bitmap_handle, jni_throwing}; -use anyhow::{anyhow, Result}; +use crate::{jni_throwing, with_bitmap_content}; +use anyhow::{Ok, Result}; use bardecoder::decode::Decode; use bardecoder::default_builder; use bardecoder::extract::QRExtractor; use bardecoder::util::qr::{QRData, QRError}; -use image::{GenericImageView, ImageBuffer, Rgba}; +use image::{GenericImageView, Rgba}; use jni::objects::JClass; use jni::sys::{jboolean, jobject}; use jni::JNIEnv; use jni_fn::jni_fn; -use std::ptr::slice_from_raw_parts; #[allow(dead_code)] struct Nothing {} @@ -33,15 +32,7 @@ where #[allow(non_snake_case)] #[jni_fn("com.hippo.ehviewer.image.ImageKt")] pub fn hasQrCode(mut env: JNIEnv, _class: JClass, object: jobject) -> jboolean { - let handle = get_bitmap_handle(&mut env, object); - jni_throwing(&mut env, |_| { - let bitmap_info = handle.info()?; - let (width, height) = (bitmap_info.width(), bitmap_info.height()); - let ptr = handle.lock_pixels()? as *const u8; - let buffer = unsafe { &*slice_from_raw_parts(ptr, (width * height * 4) as usize) }; - let image = ImageBuffer::from_raw(width, height, buffer); - let result = image.map(|img| detect_image_ad(&img)); - handle.unlock_pixels()?; - Ok(result.ok_or(anyhow!("Internal Error!"))? as jboolean) + jni_throwing(&mut env, |env| { + with_bitmap_content(env, object, |image| Ok(detect_image_ad(image) as jboolean)) }) } diff --git a/app/src/main/rust/src/lib.rs b/app/src/main/rust/src/lib.rs index 192f25976..55d404734 100644 --- a/app/src/main/rust/src/lib.rs +++ b/app/src/main/rust/src/lib.rs @@ -1,6 +1,7 @@ mod image; mod parser; +use ::image::{ImageBuffer, Rgba}; use android_logger::Config; use anyhow::{anyhow, ensure, Result}; use jni::objects::JByteBuffer; @@ -11,7 +12,7 @@ use ndk::bitmap::Bitmap; use serde::Serialize; use std::ffi::c_void; use std::io::Cursor; -use std::ptr::slice_from_raw_parts_mut; +use std::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut}; use std::str::from_utf8_unchecked; use tl::ParserOptions; use tl::{Bytes, Node, NodeHandle, Parser, VDom}; @@ -141,6 +142,23 @@ fn query_childs_first_match_attr<'a>( get_node_handle_attr(&iter.next()?, parser, attr) } +fn with_bitmap_content(env: &mut JNIEnv, bitmap: jobject, f: F) -> Result +where + F: FnOnce(&ImageBuffer, &[u8]>) -> Result, +{ + let handle = get_bitmap_handle(env, bitmap); + let info = handle.info()?; + let (width, height) = (info.width(), info.height()); + let ptr = handle.lock_pixels()? as *const u8; + let buffer = unsafe { &*slice_from_raw_parts(ptr, (width * height * 4) as usize) }; + let image = ImageBuffer::from_raw(width, height, buffer); + let result = image + .ok_or(anyhow!("Image buffer not RGBA8888!!!")) + .and_then(|img| f(&img)); + handle.unlock_pixels()?; + result +} + fn get_bitmap_handle(env: &mut JNIEnv, bitmap: jobject) -> Bitmap { unsafe { Bitmap::from_jni(env.get_raw(), bitmap) } }