dicom_toolkit_codec/jp2k/
decoder.rs1use dicom_toolkit_core::error::{DcmError, DcmResult};
8
9#[derive(Debug, Clone)]
11pub struct DecodedFrame {
12 pub pixels: Vec<u8>,
15 pub width: u32,
17 pub height: u32,
19 pub bits_per_sample: u8,
21 pub components: u8,
23}
24
25pub fn decode_jp2k(data: &[u8]) -> DcmResult<DecodedFrame> {
32 use dicom_toolkit_jpeg2000::{DecodeSettings, Image};
33
34 if data.is_empty() {
35 return Err(DcmError::DecompressionError {
36 reason: "empty JPEG 2000 codestream".into(),
37 });
38 }
39
40 let settings = DecodeSettings {
41 resolve_palette_indices: false,
42 strict: false,
43 target_resolution: None,
44 };
45
46 let image = Image::new(data, &settings).map_err(|e| DcmError::DecompressionError {
47 reason: format!("JPEG 2000 parse error: {e}"),
48 })?;
49
50 let raw = image
51 .decode_native()
52 .map_err(|e| DcmError::DecompressionError {
53 reason: format!("JPEG 2000 decode error: {e}"),
54 })?;
55
56 Ok(DecodedFrame {
57 pixels: raw.data,
58 width: raw.width,
59 height: raw.height,
60 bits_per_sample: raw.bit_depth,
61 components: raw.num_components,
62 })
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
73 fn decode_empty_returns_error() {
74 let result = decode_jp2k(&[]);
75 assert!(result.is_err());
76 }
77
78 #[test]
79 fn decode_garbage_returns_error() {
80 let result = decode_jp2k(&[0x00, 0x01, 0x02, 0x03]);
81 assert!(result.is_err());
82 }
83}