jpegxl_rs/parallel/
resizable_runner.rs1use std::{ffi::c_void, ptr::null_mut};
21
22use jpegxl_sys::threads::resizable_parallel_runner as api;
23
24use super::{JxlParallelRunner, ParallelRunner};
25
26use crate::{decode::BasicInfo, memory::MemoryManager};
27
28pub struct ResizableRunner<'mm> {
30 runner_ptr: *mut c_void,
31 _memory_manager: Option<&'mm dyn MemoryManager>,
32}
33
34impl<'mm> ResizableRunner<'mm> {
35 #[must_use]
37 pub fn new(memory_manager: Option<&'mm dyn MemoryManager>) -> Option<Self> {
38 let mm = memory_manager.map(MemoryManager::manager);
39 let runner_ptr = unsafe {
40 api::JxlResizableParallelRunnerCreate(mm.as_ref().map_or(null_mut(), |mm| mm))
41 };
42
43 if runner_ptr.is_null() {
44 None
45 } else {
46 Some(Self {
47 runner_ptr,
48 _memory_manager: memory_manager,
49 })
50 }
51 }
52
53 pub fn set_num_threads(&self, width: u64, height: u64) {
55 let num = unsafe { api::JxlResizableParallelRunnerSuggestThreads(width, height) };
56 unsafe { api::JxlResizableParallelRunnerSetThreads(self.runner_ptr, num as usize) };
57 }
58}
59
60impl Default for ResizableRunner<'_> {
61 fn default() -> Self {
62 Self {
63 runner_ptr: unsafe { api::JxlResizableParallelRunnerCreate(std::ptr::null()) },
64 _memory_manager: None,
65 }
66 }
67}
68
69impl ParallelRunner for ResizableRunner<'_> {
70 fn runner(&self) -> JxlParallelRunner {
71 api::JxlResizableParallelRunner
72 }
73
74 fn as_opaque_ptr(&self) -> *mut c_void {
75 self.runner_ptr
76 }
77
78 fn callback_basic_info(&self, info: &BasicInfo) {
79 self.set_num_threads(info.xsize.into(), info.ysize.into());
80 }
81}
82
83impl Drop for ResizableRunner<'_> {
84 fn drop(&mut self) {
85 unsafe { api::JxlResizableParallelRunnerDestroy(self.runner_ptr) };
86 }
87}
88
89#[cfg(test)]
90mod tests {
91
92 use crate::memory::tests::BumpManager;
93
94 use super::*;
95
96 #[test]
97 #[cfg_attr(coverage_nightly, coverage(off))]
98 fn test_construction() {
99 let memory_manager = BumpManager::new(1024);
100 let parallel_runner = ResizableRunner::new(Some(&memory_manager));
101 assert!(parallel_runner.is_some());
102 }
103}