diff --git a/Cargo.lock b/Cargo.lock index 8f62b71e..50613d1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "arbitrary" @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "as-slice" @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" +checksum = "4342d8937fc7e5dd9b1c60292261c0670c882a2cd1719cfc11b1af41731e32ad" dependencies = [ "aws-lc-sys", "zeroize", @@ -247,14 +247,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.41.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" +checksum = "6d9ceb1da931507a12f4fccea479dccd00da1943e1b4ae72d8e502d707361444" dependencies = [ "cc", "cmake", "dunce", "fs_extra", + "pkg-config", ] [[package]] @@ -480,9 +481,9 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "console" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" dependencies = [ "encode_unicode", "libc", @@ -908,6 +909,7 @@ dependencies = [ "dicom-object", "dicom-test-files", "flate2", + "hayro-jpeg2000", "jpeg-decoder", "jpeg-encoder", "jpeg2k", @@ -1133,6 +1135,12 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "fearless_simd" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97b65636e5b9ef369943878ac74335ba1c55c1cb6adbf1e2c293c624248d693" + [[package]] name = "find-msvc-tools" version = "0.1.9" @@ -1278,6 +1286,15 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +[[package]] +name = "hayro-jpeg2000" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab0c77d09c0d9b144d429d0bf0fcd4c63c01d5f6c33f9b8ed501283e0f1ef76" +dependencies = [ + "fearless_simd", +] + [[package]] name = "heck" version = "0.5.0" @@ -1384,9 +1401,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.18.4" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" +checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c" dependencies = [ "console", "portable-atomic", @@ -1493,9 +1510,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.102" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", @@ -1725,9 +1742,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "loop9" @@ -1882,9 +1899,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c863e9ab5e7bf9c99ba75e1050f1e4d624ae87ed3532d6238ffbdc7b585dbbe6" dependencies = [ "num-integer", "num-traits", @@ -2184,9 +2201,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -2448,9 +2465,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ "aws-lc-rs", "log", @@ -2490,9 +2507,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" dependencies = [ "zeroize", ] @@ -2926,9 +2943,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.49" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711a53c2d47bbd818258c498c8dbfe186a2526c631495cfe7e078567f86b8469" +checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" dependencies = [ "deranged", "num-conv", @@ -2946,9 +2963,9 @@ checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.29" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c652a3727a9cbb9a02f707f530b618ce00d0ccd762009c8c23bd191df3c17d" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" dependencies = [ "num-conv", "time-core", @@ -3216,9 +3233,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -3229,9 +3246,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3239,9 +3256,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", @@ -3252,9 +3269,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] diff --git a/fromimage/Cargo.toml b/fromimage/Cargo.toml index 604431f7..8865b61c 100644 --- a/fromimage/Cargo.toml +++ b/fromimage/Cargo.toml @@ -24,6 +24,6 @@ tracing = "0.1.34" tracing-subscriber = "0.3.20" [dependencies.image] -version = "0.25.1" +version = "0.25" default-features=false features = ["jpeg", "png", "pnm", "tiff", "webp", "bmp", "rayon", "exr"] diff --git a/pixeldata/Cargo.toml b/pixeldata/Cargo.toml index d54229cd..fddd4441 100644 --- a/pixeldata/Cargo.toml +++ b/pixeldata/Cargo.toml @@ -31,7 +31,7 @@ num-traits = "0.2.12" tracing = "0.1.34" [dependencies.image] -version = "0.25.1" +version = "0.25" default-features = false features = ["jpeg", "png", "pnm", "tiff", "webp", "bmp", "exr"] optional = true @@ -74,6 +74,8 @@ rle = ["dicom-transfer-syntax-registry/rle"] openjpeg-sys = ["dicom-transfer-syntax-registry/openjpeg-sys"] # JPEG 2000 decoding via Rust port of OpenJPEG openjp2 = ["dicom-transfer-syntax-registry/openjp2"] +# JPEG 2000 support via the hayro-jpeg2000 +hayro-jpeg2000 = ["dicom-transfer-syntax-registry/hayro-jpeg2000"] # JpegLS via CharLS charls = ["dicom-transfer-syntax-registry/charls"] # use vcpkg to build CharLS diff --git a/pixeldata/src/lib.rs b/pixeldata/src/lib.rs index a1fdd039..4e18d942 100644 --- a/pixeldata/src/lib.rs +++ b/pixeldata/src/lib.rs @@ -3025,19 +3025,19 @@ mod tests { #[rstest] // jpeg2000 encoding #[cfg_attr( - any(feature = "openjp2", feature = "openjpeg-sys"), + any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"), case("pydicom/emri_small_jpeg_2k_lossless.dcm", 10) )] #[cfg_attr( - any(feature = "openjp2", feature = "openjpeg-sys"), + any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"), case("pydicom/693_J2KI.dcm", 1) )] #[cfg_attr( - any(feature = "openjp2", feature = "openjpeg-sys"), + any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"), case("pydicom/693_J2KR.dcm", 1) )] #[cfg_attr( - any(feature = "openjp2", feature = "openjpeg-sys"), + any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"), case("pydicom/JPEG2000.dcm", 1) )] // diff --git a/transfer-syntax-registry/Cargo.toml b/transfer-syntax-registry/Cargo.toml index 2ebe15fe..cb96daec 100644 --- a/transfer-syntax-registry/Cargo.toml +++ b/transfer-syntax-registry/Cargo.toml @@ -47,6 +47,9 @@ simd = ["jpeg-encoder?/simd"] # conflicts with `openjp2` openjpeg-sys = ["dep:jpeg2k", "jpeg2k/openjpeg-sys"] +# JPEG 2000 support via the hayro-jpeg2000 +hayro-jpeg2000 = ["dep:hayro-jpeg2000"] + # jpeg LS support via charls bindings charls = ["dep:charls"] @@ -76,6 +79,12 @@ version = "0.10" optional = true default-features = false +[dependencies.hayro-jpeg2000] +version = "0.4.0" +optional = true +default-features = false +features = ["simd"] + [dependencies.jpeg-decoder] version = "0.3.0" optional = true diff --git a/transfer-syntax-registry/src/adapters/jpeg2k.rs b/transfer-syntax-registry/src/adapters/jpeg2k.rs index 27f0e851..8f180d76 100644 --- a/transfer-syntax-registry/src/adapters/jpeg2k.rs +++ b/transfer-syntax-registry/src/adapters/jpeg2k.rs @@ -2,7 +2,6 @@ use dicom_encoding::adapters::{DecodeResult, PixelDataObject, PixelDataReader, decode_error}; use dicom_encoding::snafu::prelude::*; -use jpeg2k::Image; use tracing::warn; // Check jpeg2k backend conflicts @@ -11,6 +10,16 @@ compile_error!( "feature \"openjp2\" and feature \"openjpeg-sys\" cannot be enabled at the same time" ); +#[cfg(all(feature = "openjp2", feature = "hayro-jpeg2000"))] +compile_error!( + "feature \"openjp2\" and feature \"hayro-jpeg2000\" cannot be enabled at the same time" +); + +#[cfg(all(feature = "hayro-jpeg2000", feature = "openjpeg-sys"))] +compile_error!( + "feature \"hayro-jpeg2000\" and feature \"openjpeg-sys\" cannot be enabled at the same time" +); + /// Pixel data adapter for transfer syntaxes based on JPEG 2000. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Jpeg2000Adapter; @@ -63,33 +72,73 @@ impl PixelDataReader for Jpeg2000Adapter { let frame_data = src .frame_pixel_data(frame) .context(decode_error::FrameRangeOutOfBoundsSnafu)?; - let image = Image::from_bytes(&frame_data).whatever_context("jpeg2k decoder failure")?; - - // Note: we cannot use `get_pixels` - // because the current implementation narrows the data - // down to 8 bits per sample - let components = image.components(); - - // write each component into the destination buffer - for (component_i, component) in components.iter().enumerate() { - if component_i > samples_per_pixel as usize { - warn!( - "JPEG 2000 image has more components than expected ({} > {})", - component_i, samples_per_pixel - ); - break; - } - // write in standard layout - for (i, sample) in component.data().iter().enumerate() { - let offset = base_offset - + i * samples_per_pixel as usize * bytes_per_sample as usize - + component_i * bytes_per_sample as usize; - dst[offset..offset + bytes_per_sample as usize] - .copy_from_slice(&sample.to_le_bytes()[..bytes_per_sample as usize]); + #[cfg(any(feature = "openjp2", feature = "openjpeg-sys"))] + { + use jpeg2k::Image; + + let image = + Image::from_bytes(&frame_data).whatever_context("jpeg2k decoder failure")?; + + // Note: we cannot use `get_pixels` + // because the current implementation narrows the data + // down to 8 bits per sample + let components = image.components(); + + // write each component into the destination buffer + for (component_i, component) in components.iter().enumerate() { + if component_i >= samples_per_pixel as usize { + warn!( + "JPEG 2000 image has more components than expected ({} >= {})", + component_i, samples_per_pixel + ); + break; + } + + // write in standard layout + for (i, sample) in component.data().iter().enumerate() { + let offset = base_offset + + i * samples_per_pixel as usize * bytes_per_sample as usize + + component_i * bytes_per_sample as usize; + dst[offset..offset + bytes_per_sample as usize] + .copy_from_slice(&sample.to_le_bytes()[..bytes_per_sample as usize]); + } } } + #[cfg(feature = "hayro-jpeg2000")] + { + use hayro_jpeg2000::{DecodeSettings, DecoderContext, Image}; + + let image = Image::new(&frame_data, &DecodeSettings::default()) + .whatever_context("hayro-jpeg2000 read image failure")?; + + let mut ctx = DecoderContext::default(); + let decoded = image + .decode(&mut ctx) + .whatever_context("hayro-jpeg2000 decoder failure")?; + + let components = decoded.components(); + for (component_i, component) in components.iter().enumerate() { + if component_i >= samples_per_pixel as usize { + warn!( + "JPEG 2000 image has more components than expected ({} >= {})", + component_i, samples_per_pixel + ); + break; + } + + for (i, sample) in component.samples().iter().enumerate() { + let offset = base_offset + + i * samples_per_pixel as usize * bytes_per_sample as usize + + component_i * bytes_per_sample as usize; + + let sample = sample.round() as u32; + dst[offset..offset + bytes_per_sample as usize] + .copy_from_slice(&sample.to_le_bytes()[..bytes_per_sample as usize]); + } + } + } Ok(()) } } diff --git a/transfer-syntax-registry/src/adapters/mod.rs b/transfer-syntax-registry/src/adapters/mod.rs index e8c4ad63..120725d4 100644 --- a/transfer-syntax-registry/src/adapters/mod.rs +++ b/transfer-syntax-registry/src/adapters/mod.rs @@ -32,7 +32,7 @@ pub mod deflated; #[cfg(feature = "jpeg")] pub mod jpeg; -#[cfg(any(feature = "openjp2", feature = "openjpeg-sys"))] +#[cfg(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"))] pub mod jpeg2k; #[cfg(feature = "charls")] pub mod jpegls; @@ -50,7 +50,7 @@ pub mod jpeg {} /// **Note:** This module is a stub. /// Enable either `openjp2` or `openjpeg-sys` to use this module. -#[cfg(not(any(feature = "openjp2", feature = "openjpeg-sys")))] +#[cfg(not(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000")))] pub mod jpeg2k {} /// **Note:** This module is a stub. diff --git a/transfer-syntax-registry/src/entries.rs b/transfer-syntax-registry/src/entries.rs index 1f730ee1..b59db185 100644 --- a/transfer-syntax-registry/src/entries.rs +++ b/transfer-syntax-registry/src/entries.rs @@ -27,14 +27,14 @@ use dicom_encoding::transfer_syntax::{AdapterFreeTransferSyntax as Ts, Codec}; use dicom_encoding::transfer_syntax::{NeverAdapter, TransferSyntax}; -#[cfg(any(feature = "rle", feature = "openjp2", feature = "openjpeg-sys"))] +#[cfg(any(feature = "rle", feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"))] use dicom_encoding::NeverPixelAdapter; #[cfg(feature = "deflate")] use crate::adapters::deflated::DeflatedImageFrameAdapter; #[cfg(feature = "jpeg")] use crate::adapters::jpeg::JpegAdapter; -#[cfg(any(feature = "openjp2", feature = "openjpeg-sys"))] +#[cfg(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"))] use crate::adapters::jpeg2k::Jpeg2000Adapter; #[cfg(feature = "charls")] use crate::adapters::jpegls::{JpegLsAdapter, JpegLsLosslessWriter}; @@ -261,11 +261,11 @@ pub const JPIP_HTJ2K_REFERENCED_DEFLATE: Ts = Ts::new_ele( /// An alias for a transfer syntax specifier with [`Jpeg2000Adapter`] /// (supports decoding and encoding to JPEG baseline, /// support for JPEG extended and JPEG lossless may vary). -#[cfg(any(feature = "openjp2", feature = "openjpeg-sys"))] +#[cfg(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"))] type Jpeg2000Ts = TransferSyntax; /// Create a transfer syntax with JPEG 2000 encapsulated pixel data -#[cfg(any(feature = "openjp2", feature = "openjpeg-sys"))] +#[cfg(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"))] const fn create_ts_jpeg2k(uid: &'static str, name: &'static str) -> Jpeg2000Ts { TransferSyntax::new_ele( uid, @@ -275,49 +275,49 @@ const fn create_ts_jpeg2k(uid: &'static str, name: &'static str) -> Jpeg2000Ts { } /// **Decoder implementation:** JPEG 2000 Image Compression (Lossless Only) -#[cfg(any(feature = "openjp2", feature = "openjpeg-sys"))] +#[cfg(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"))] pub const JPEG_2000_IMAGE_COMPRESSION_LOSSLESS_ONLY: Jpeg2000Ts = create_ts_jpeg2k( "1.2.840.10008.1.2.4.90", "JPEG 2000 Image Compression (Lossless Only)", ); /// **Stub descriptor:** JPEG 2000 Image Compression (Lossless Only) -#[cfg(not(any(feature = "openjp2", feature = "openjpeg-sys")))] +#[cfg(not(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000")))] pub const JPEG_2000_IMAGE_COMPRESSION_LOSSLESS_ONLY: Ts = create_ts_stub( "1.2.840.10008.1.2.4.90", "JPEG 2000 Image Compression (Lossless Only)", ); /// **Decoder implementation:** JPEG 2000 Image Compression -#[cfg(any(feature = "openjp2", feature = "openjpeg-sys"))] +#[cfg(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"))] pub const JPEG_2000_IMAGE_COMPRESSION: Jpeg2000Ts = create_ts_jpeg2k("1.2.840.10008.1.2.4.91", "JPEG 2000 Image Compression"); /// **Stub descriptor:** JPEG 2000 Image Compression -#[cfg(not(any(feature = "openjp2", feature = "openjpeg-sys")))] +#[cfg(not(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000")))] pub const JPEG_2000_IMAGE_COMPRESSION: Ts = create_ts_stub("1.2.840.10008.1.2.4.91", "JPEG 2000 Image Compression"); /// **Decoder implementation:** JPEG 2000 Part 2 Multi-component Image Compression (Lossless Only) -#[cfg(any(feature = "openjp2", feature = "openjpeg-sys"))] +#[cfg(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"))] pub const JPEG_2000_PART2_MULTI_COMPONENT_IMAGE_COMPRESSION_LOSSLESS_ONLY: Jpeg2000Ts = create_ts_jpeg2k( "1.2.840.10008.1.2.4.92", "JPEG 2000 Part 2 Multi-component Image Compression (Lossless Only)", ); /// **Stub descriptor:** JPEG 2000 Part 2 Multi-component Image Compression (Lossless Only) -#[cfg(not(any(feature = "openjp2", feature = "openjpeg-sys")))] +#[cfg(not(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000")))] pub const JPEG_2000_PART2_MULTI_COMPONENT_IMAGE_COMPRESSION_LOSSLESS_ONLY: Ts = create_ts_stub( "1.2.840.10008.1.2.4.92", "JPEG 2000 Part 2 Multi-component Image Compression (Lossless Only)", ); /// **Decoder implementation:** JPEG 2000 Part 2 Multi-component Image Compression -#[cfg(any(feature = "openjp2", feature = "openjpeg-sys"))] +#[cfg(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000"))] pub const JPEG_2000_PART2_MULTI_COMPONENT_IMAGE_COMPRESSION: Jpeg2000Ts = create_ts_jpeg2k( "1.2.840.10008.1.2.4.93", "JPEG 2000 Part 2 Multi-component Image Compression", ); /// **Stub descriptor:** JPEG 2000 Part 2 Multi-component Image Compression -#[cfg(not(any(feature = "openjp2", feature = "openjpeg-sys")))] +#[cfg(not(any(feature = "openjp2", feature = "openjpeg-sys", feature = "hayro-jpeg2000")))] pub const JPEG_2000_PART2_MULTI_COMPONENT_IMAGE_COMPRESSION: Ts = create_ts_stub( "1.2.840.10008.1.2.4.93", "JPEG 2000 Part 2 Multi-component Image Compression", diff --git a/transfer-syntax-registry/src/lib.rs b/transfer-syntax-registry/src/lib.rs index 1218aeaa..c75fd6f7 100644 --- a/transfer-syntax-registry/src/lib.rs +++ b/transfer-syntax-registry/src/lib.rs @@ -59,10 +59,10 @@ //! | JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14 [Selection Value 1]) | Cargo feature `jpeg` | x | //! | JPEG-LS Lossless | Cargo feature `charls` | ✓ | //! | JPEG-LS Lossy (Near-Lossless) | Cargo feature `charls` | ✓ | -//! | JPEG 2000 (Lossless Only) | Cargo feature `openjp2` or `openjpeg-sys` | x | -//! | JPEG 2000 | Cargo feature `openjp2` or `openjpeg-sys` | x | -//! | JPEG 2000 Part 2 Multi-component Image Compression (Lossless Only) | Cargo feature `openjp2` or `openjpeg-sys` | x | -//! | JPEG 2000 Part 2 Multi-component Image Compression | Cargo feature `openjp2` or `openjpeg-sys` | x | +//! | JPEG 2000 (Lossless Only) | Cargo feature `openjp2` or `openjpeg-sys` or `hayro-jpeg2000` | x | +//! | JPEG 2000 | Cargo feature `openjp2` or `openjpeg-sys` or `hayro-jpeg2000` | x | +//! | JPEG 2000 Part 2 Multi-component Image Compression (Lossless Only) | Cargo feature `openjp2` or `openjpeg-sys` or `hayro-jpeg2000` | x | +//! | JPEG 2000 Part 2 Multi-component Image Compression | Cargo feature `openjp2` or `openjpeg-sys` or `hayro-jpeg2000` | x | //! | JPIP Referenced Deflate | Cargo feature `deflate` | ✓ | //! | High-Throughput JPEG 2000 (Lossless Only) | Cargo feature `openjp2` or `openjpeg-sys` | x | //! | High-Throughput JPEG 2000 with RPCL Options (Lossless Only) | Cargo feature `openjp2` or `openjpeg-sys` | x | @@ -94,6 +94,7 @@ //! - `openjp2` provides a binding to a computer-translated Rust port of OpenJPEG. //! Due to the nature of this crate, //! it might not work on all modern platforms. +//! - `hayro-jpeg2000` A memory-safe, pure-Rust JPEG 2000 decoder. //! - `jxl-oxide` and `zune-jpegxl` offer JPEG XL decoding and encoding. //! //! Transfer syntaxes which are not supported,