From dd2d8e3a6c9e82efd9b1e8ae9ce6c4cd61029843 Mon Sep 17 00:00:00 2001 From: Inflation <2375962+inflation@users.noreply.github.com> Date: Thu, 19 Sep 2024 12:25:37 +0800 Subject: [PATCH] feat: Add gain map utility functions Add utility functions to manipulate jhgm (gain map) boxes. Includes structures and functions for serializing and deserializing gain map data. --- .gitignore | 2 + .gitmodules | 2 +- Cargo.lock | 6 +- jpegxl-src/Cargo.toml | 2 +- jpegxl-sys/Cargo.toml | 5 +- jpegxl-sys/src/lib.rs | 4 +- jpegxl-sys/src/metadata/compressed_icc.rs | 73 ++++++++++++ jpegxl-sys/src/metadata/gain_map.rs | 134 ++++++++++++++++++++++ jpegxl-sys/src/types.rs | 6 +- 9 files changed, 223 insertions(+), 11 deletions(-) create mode 100644 jpegxl-sys/src/metadata/compressed_icc.rs create mode 100644 jpegxl-sys/src/metadata/gain_map.rs diff --git a/.gitignore b/.gitignore index face367..4f5cc1c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ sweep.timestamp build/ lcov.info .pijul +compile_commands.json +.cache/ diff --git a/.gitmodules b/.gitmodules index fd4337c..33ba59e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "libjxl"] path = jpegxl-src/libjxl url = https://github.com/libjxl/libjxl - branch = refs/tags/v0.10.3 + branch = refs/tags/v0.11.0 diff --git a/Cargo.lock b/Cargo.lock index 44890ee..d5f550d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,7 +434,7 @@ dependencies = [ [[package]] name = "jpegxl-rs" -version = "0.10.4+libjxl-0.10.3" +version = "0.10.5+libjxl-0.11.0" dependencies = [ "byteorder", "criterion", @@ -450,14 +450,14 @@ dependencies = [ [[package]] name = "jpegxl-src" -version = "0.10.5" +version = "0.11.0" dependencies = [ "cmake", ] [[package]] name = "jpegxl-sys" -version = "0.10.4+libjxl-0.10.3" +version = "0.11.0+libjxl-0.11.0" dependencies = [ "image", "jpegxl-src", diff --git a/jpegxl-src/Cargo.toml b/jpegxl-src/Cargo.toml index 06e6dd8..2627f6c 100644 --- a/jpegxl-src/Cargo.toml +++ b/jpegxl-src/Cargo.toml @@ -6,7 +6,7 @@ license = "BSD-3-Clause" name = "jpegxl-src" readme = "README.md" repository = "https://github.com/inflation/jpegxl-rs" -version = "0.10.5" +version = "0.11.0" rust-version.workspace = true exclude = [ "libjxl/third_party/libpng", diff --git a/jpegxl-sys/Cargo.toml b/jpegxl-sys/Cargo.toml index a06c510..9721e1e 100644 --- a/jpegxl-sys/Cargo.toml +++ b/jpegxl-sys/Cargo.toml @@ -9,7 +9,7 @@ links = "jxl" name = "jpegxl-sys" readme = "README.md" repository = "https://github.com/inflation/jpegxl-rs" -version = "0.10.4+libjxl-0.10.3" +version = "0.11.0+libjxl-0.11.0" rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -21,6 +21,9 @@ unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage_nightly)'] } pedantic = "warn" module_name_repetitions = "allow" +[lints.rustdoc] +broken_intra_doc_links = "deny" + [package.metadata.docs.rs] features = ["docs"] diff --git a/jpegxl-sys/src/lib.rs b/jpegxl-sys/src/lib.rs index febe373..4d7992e 100644 --- a/jpegxl-sys/src/lib.rs +++ b/jpegxl-sys/src/lib.rs @@ -81,8 +81,8 @@ mod test { #[cfg_attr(coverage_nightly, coverage(off))] fn test_bindings_version() { unsafe { - assert_eq!(JxlDecoderVersion(), 10003); - assert_eq!(JxlEncoderVersion(), 10003); + assert_eq!(JxlDecoderVersion(), 11000); + assert_eq!(JxlEncoderVersion(), 11000); } } diff --git a/jpegxl-sys/src/metadata/compressed_icc.rs b/jpegxl-sys/src/metadata/compressed_icc.rs new file mode 100644 index 0000000..046e370 --- /dev/null +++ b/jpegxl-sys/src/metadata/compressed_icc.rs @@ -0,0 +1,73 @@ +/* +This file is part of jpegxl-sys. + +jpegxl-sys is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +jpegxl-sys is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with jpegxl-sys. If not, see . +*/ + +//! Utility functions to compress and decompress ICC streams. + +use crate::{memory_manager, types::JxlBool}; + +extern "C" { + /// Allocates a buffer using the memory manager, fills it with a compressed + /// representation of an ICC profile, returns the result through `output_buffer` + /// and indicates its size through `output_size`. + /// + /// The result must be freed using the memory manager once it is not of any more + /// use. + /// + /// # Parameters + /// + /// - `memory_manager`: Pointer to a `JxlMemoryManager`. + /// - `icc`: Pointer to a buffer containing the uncompressed ICC profile. + /// - `icc_size`: Size of the buffer containing the ICC profile. + /// - `compressed_icc`: Will be set to a pointer to the buffer containing the result. + /// - `compressed_icc_size`: Will be set to the size of the buffer containing the result. + /// + /// # Returns + /// + /// Whether compressing the profile was successful. + pub fn JxlICCProfileEncode( + memory_manager: *const memory_manager::JxlMemoryManager, + icc: *const u8, + icc_size: usize, + compressed_icc: *mut *mut u8, + compressed_icc_size: *mut usize, + ) -> JxlBool; + + /// Allocates a buffer using the memory manager, fills it with the decompressed + /// version of the ICC profile in `compressed_icc`, returns the result through + /// `icc` and indicates its size through `icc_size`. + /// + /// The result must be freed using the memory manager once it is no longer needed. + /// + /// # Parameters + /// + /// - `memory_manager`: Pointer to a `JxlMemoryManager`. + /// - `compressed_icc`: Pointer to a buffer containing the compressed ICC profile. + /// - `compressed_icc_size`: Size of the buffer containing the compressed ICC profile. + /// - `icc`: Will be set to a pointer to the buffer containing the result. + /// - `icc_size`: Will be set to the size of the buffer containing the result. + /// + /// # Returns + /// + /// Whether decompressing the profile was successful. + pub fn JxlICCProfileDecode( + memory_manager: *const memory_manager::JxlMemoryManager, + compressed_icc: *const u8, + compressed_icc_size: usize, + icc: *mut *mut u8, + icc_size: *mut usize, + ) -> JxlBool; +} diff --git a/jpegxl-sys/src/metadata/gain_map.rs b/jpegxl-sys/src/metadata/gain_map.rs new file mode 100644 index 0000000..1d42f15 --- /dev/null +++ b/jpegxl-sys/src/metadata/gain_map.rs @@ -0,0 +1,134 @@ +/* +This file is part of jpegxl-sys. + +jpegxl-sys is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +jpegxl-sys is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with jpegxl-sys. If not, see . +*/ + +//! Utility functions to manipulate jhgm (gain map) boxes. + +use crate::{color::color_encoding::JxlColorEncoding, types::JxlBool}; + +/// Gain map bundle +/// +/// This structure is used to serialize gain map data to and from an input +/// buffer. It holds pointers to sections within the buffer, and different parts +/// of the gain map data such as metadata, ICC profile data, and the gain map +/// itself. +/// +/// The pointers in this structure do not take ownership of the memory they point +/// to. Instead, they reference specific locations within the provided buffer. It +/// is the caller's responsibility to ensure that the buffer remains valid and is +/// not deallocated as long as these pointers are in use. The structure should be +/// considered as providing a view into the buffer, not as an owner of the data. +#[repr(C)] +#[derive(Debug, Clone)] +pub struct JxlGainMapBundle { + /// Version number of the gain map bundle. + pub jhgm_version: u8, + /// Size of the gain map metadata in bytes. + pub gain_map_metadata_size: u16, + /// Pointer to the gain map metadata, which is a binary + /// blob following ISO 21496-1. This pointer references data within the input + /// buffer. + pub gain_map_metadata: *const u8, + /// Indicates whether a color encoding is present. + pub has_color_encoding: JxlBool, + /// If `has_color_encoding` is true, this field contains the + /// uncompressed color encoding data. + pub color_encoding: JxlColorEncoding, + /// Size of the alternative ICC profile in bytes (compressed + /// size). + pub alt_icc_size: u32, + /// Pointer to the compressed ICC profile. This pointer references + /// data within the input buffer. + pub alt_icc: *const u8, + /// Size of the gain map in bytes. + pub gain_map_size: u32, + /// Pointer to the gain map data, which is a JPEG XL naked + /// codestream. This pointer references data within the input buffer. + pub gain_map: *const u8, +} + +extern "C" { + /// Calculates the total size required to serialize the gain map bundle into a + /// binary buffer. This function accounts for all the necessary space to + /// serialize fields such as gain map metadata, color encoding, compressed ICC + /// profile data, and the gain map itself. + /// + /// # Parameters + /// - `map_bundle`: A reference to the [`JxlGainMapBundle`] containing all + /// necessary data to compute the size. + /// - `bundle_size`: A mutable reference to a `usize` where the size in bytes + /// required to serialize the bundle will be stored. + /// + /// # Returns + /// - A boolean indicating whether setting the size was successful. + pub fn JxlGainMapGetBundleSize( + map_bundle: *const JxlGainMapBundle, + bundle_size: *mut usize, + ) -> JxlBool; + + /// Serializes the gain map bundle into a preallocated buffer. The function + /// ensures that all parts of the bundle such as metadata, color encoding, + /// compressed ICC profile, and the gain map are correctly encoded into the + /// buffer. First call [`JxlGainMapGetBundleSize`] to get the size needed for + /// the buffer. + /// + /// # Parameters + /// - `map_bundle`: A pointer to the [`JxlGainMapBundle`] to serialize. + /// - `output_buffer`: A pointer to the buffer where the serialized data + /// will be written. + /// - `output_buffer_size`: The size of the output buffer in bytes. Must be + /// large enough to hold the entire serialized data. + /// - `bytes_written`: A mutable reference to a `usize` where the number of bytes + /// written to the output buffer will be stored. + /// + /// # Returns + /// - A boolean indicating whether writing the bundle was successful. + pub fn JxlGainMapWriteBundle( + map_bundle: *const JxlGainMapBundle, + output_buffer: *mut u8, + output_buffer_size: usize, + bytes_written: *mut usize, + ) -> JxlBool; + + /// Deserializes a gain map bundle from a provided buffer and populates a + /// [`JxlGainMapBundle`] structure with the data extracted. This function assumes + /// the buffer contains a valid serialized gain map bundle. After successful + /// execution, the [`JxlGainMapBundle`] structure will reference three different + /// sections within the buffer: + /// - `gain_map_metadata` + /// - `alt_icc` + /// - `gain_map` + /// + /// These sections will be accompanied by their respective sizes. Users must + /// ensure that the buffer remains valid as long as these pointers are in use. + /// + /// # Parameters + /// - `map_bundle`: Pointer to a preallocated [`JxlGainMapBundle`] where + /// the deserialized data will be stored. + /// - `input_buffer`: Pointer to the buffer containing the serialized gain + /// map bundle data. + /// - `input_buffer_size`: The size of the input buffer in bytes. + /// - `bytes_read`: The number of bytes read from the input buffer. + /// + /// # Returns + /// - A boolean indicating whether reading the bundle was successful. + pub fn JxlGainMapReadBundle( + map_bundle: *mut JxlGainMapBundle, + input_buffer: *const u8, + input_buffer_size: usize, + bytes_read: *mut usize, + ) -> JxlBool; +} diff --git a/jpegxl-sys/src/types.rs b/jpegxl-sys/src/types.rs index 32dbfdd..d9306ef 100644 --- a/jpegxl-sys/src/types.rs +++ b/jpegxl-sys/src/types.rs @@ -63,9 +63,9 @@ pub struct JxlPixelFormat { #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum JxlBitDepthType { - BitDepthFromPixelFormat = 0, - BitDepthFromCodestream = 1, - BitDepthCustom = 2, + FromPixelFormat = 0, + FromCodestream = 1, + Custom = 2, } #[repr(C)]