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)]