numcodecs_jpeg2000/ffi/
codec.rs1use std::ptr::NonNull;
4
5use super::Jpeg2000Error;
6
7pub struct Decoder {
8 codec: NonNull<openjpeg_sys::opj_codec_t>,
9}
10
11impl Drop for Decoder {
12 fn drop(&mut self) {
13 unsafe {
14 openjpeg_sys::opj_destroy_codec(self.codec.as_ptr());
15 }
16 }
17}
18
19impl Decoder {
20 pub fn j2k() -> Result<Self, Jpeg2000Error> {
21 let codec = NonNull::new(unsafe {
22 openjpeg_sys::opj_create_decompress(openjpeg_sys::OPJ_CODEC_FORMAT::OPJ_CODEC_J2K)
23 })
24 .ok_or(Jpeg2000Error::DecoderSetupError)?;
25
26 unsafe {
27 setup_codec_logging(codec);
28 }
29
30 Ok(Self { codec })
31 }
32
33 #[allow(clippy::needless_pass_by_ref_mut)]
34 pub fn as_raw(&mut self) -> *mut openjpeg_sys::opj_codec_t {
35 self.codec.as_ptr()
36 }
37}
38
39pub struct Encoder {
40 codec: NonNull<openjpeg_sys::opj_codec_t>,
41}
42
43impl Drop for Encoder {
44 fn drop(&mut self) {
45 unsafe {
46 openjpeg_sys::opj_destroy_codec(self.codec.as_ptr());
47 }
48 }
49}
50
51impl Encoder {
52 pub fn j2k() -> Result<Self, Jpeg2000Error> {
53 let codec = NonNull::new(unsafe {
54 openjpeg_sys::opj_create_compress(openjpeg_sys::OPJ_CODEC_FORMAT::OPJ_CODEC_J2K)
55 })
56 .ok_or(Jpeg2000Error::EncoderSetupError)?;
57
58 unsafe {
59 setup_codec_logging(codec);
60 }
61
62 Ok(Self { codec })
63 }
64
65 #[allow(clippy::needless_pass_by_ref_mut)]
66 pub fn as_raw(&mut self) -> *mut openjpeg_sys::opj_codec_t {
67 self.codec.as_ptr()
68 }
69}
70
71unsafe fn setup_codec_logging(codec: NonNull<openjpeg_sys::opj_codec_t>) {
72 extern "C" fn log_info(msg: *const std::ffi::c_char, _data: *mut std::ffi::c_void) {
73 unsafe { log(msg, log::Level::Info) }
74 }
75
76 extern "C" fn log_warning(msg: *const std::ffi::c_char, _data: *mut std::ffi::c_void) {
77 unsafe { log(msg, log::Level::Warn) }
78 }
79
80 extern "C" fn log_error(msg: *const std::ffi::c_char, _data: *mut std::ffi::c_void) {
81 unsafe { log(msg, log::Level::Error) }
82 }
83
84 unsafe fn log(msg: *const std::ffi::c_char, level: log::Level) {
85 let msg = unsafe { std::ffi::CStr::from_ptr(msg) }.to_string_lossy();
86
87 log::log!(level, "{msg}");
88 }
89
90 unsafe {
91 openjpeg_sys::opj_set_info_handler(codec.as_ptr(), Some(log_info), std::ptr::null_mut());
92 }
93 unsafe {
94 openjpeg_sys::opj_set_warning_handler(
95 codec.as_ptr(),
96 Some(log_warning),
97 std::ptr::null_mut(),
98 );
99 }
100 unsafe {
101 openjpeg_sys::opj_set_error_handler(codec.as_ptr(), Some(log_error), std::ptr::null_mut());
102 }
103}