Skip to content

Commit

Permalink
doc: Convert libjxl doc to rustdoc format with help from @copilot
Browse files Browse the repository at this point in the history
  • Loading branch information
inflation committed Sep 19, 2024
1 parent 70ca2bd commit b948790
Show file tree
Hide file tree
Showing 19 changed files with 4,144 additions and 72 deletions.
94 changes: 33 additions & 61 deletions jpegxl-rs/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,97 +17,68 @@

//! Memory manager interface
use std::ffi::c_void;

use jpegxl_sys::memory_manager::JxlMemoryManager;

/// Allocating function type
pub type AllocFn = unsafe extern "C-unwind" fn(opaque: *mut c_void, size: usize) -> *mut c_void;
/// Deallocating function type
pub type FreeFn = unsafe extern "C-unwind" fn(opaque: *mut c_void, address: *mut c_void);
use jpegxl_sys::common::memory_manager::{JpegxlAllocFunc, JpegxlFreeFunc, JxlMemoryManager};

/// General trait for a memory manager
#[allow(clippy::module_name_repetitions)]
pub trait MemoryManager {
/// Return a custom allocating function
fn alloc(&self) -> AllocFn;
fn alloc(&self) -> JpegxlAllocFunc;
/// Return a custom deallocating function
fn free(&self) -> FreeFn;
fn free(&self) -> JpegxlFreeFunc;

/// Helper conversion function for C API
#[must_use]
fn manager(&self) -> JxlMemoryManager {
JxlMemoryManager {
opaque: (self as *const Self).cast_mut().cast(),
alloc: self.alloc(),
free: self.free(),
alloc: Some(self.alloc()),
free: Some(self.free()),
}
}
}

#[cfg(test)]
pub(crate) mod tests {
use std::{
ffi::c_void,
ptr::null_mut,
sync::atomic::{AtomicUsize, Ordering},
};

use testresult::TestResult;

use crate::{decoder_builder, encoder_builder};

use super::*;

pub struct NoManager {}

impl MemoryManager for NoManager {
fn alloc(&self) -> AllocFn {
#[cfg_attr(coverage_nightly, coverage(off))]
unsafe extern "C-unwind" fn alloc(_opaque: *mut c_void, _size: usize) -> *mut c_void {
null_mut()
}

alloc
}

fn free(&self) -> FreeFn {
#[cfg_attr(coverage_nightly, coverage(off))]
unsafe extern "C-unwind" fn free(_opaque: *mut c_void, _address: *mut c_void) {
debug_assert!(false, "Should not be called");
}

free
}
}

/// Example implementation of [`MemoryManager`] of a fixed size allocator
pub struct BumpManager<const N: usize> {
arena: Box<[u8; N]>,
pub struct BumpManager {
arena: Vec<u8>,
footer: AtomicUsize,
}

impl<const N: usize> Default for BumpManager<N> {
fn default() -> Self {
impl BumpManager {
pub(crate) fn new(n: usize) -> Self {
Self {
arena: Box::new([0_u8; N]),
arena: vec![0; n],
footer: AtomicUsize::new(0),
}
}
}

impl<const N: usize> MemoryManager for BumpManager<N> {
fn alloc(&self) -> AllocFn {
impl MemoryManager for BumpManager {
fn alloc(&self) -> JpegxlAllocFunc {
#[cfg_attr(coverage_nightly, coverage(off))]
unsafe extern "C-unwind" fn alloc<const N: usize>(
opaque: *mut c_void,
size: usize,
) -> *mut c_void {
let mm = &mut *opaque.cast::<BumpManager<{ N }>>();
unsafe extern "C-unwind" fn alloc(opaque: *mut c_void, size: usize) -> *mut c_void {
let mm = &mut *opaque.cast::<BumpManager>();

let footer = mm.footer.load(Ordering::Acquire);
let mut new = footer + size;

loop {
if new > N {
if new > mm.arena.len() {
println!("Out of memory");
break null_mut();
} else if let Err(s) = mm.footer.compare_exchange_weak(
footer,
Expand All @@ -123,10 +94,10 @@ pub(crate) mod tests {
}
}

alloc::<N>
alloc
}

fn free(&self) -> FreeFn {
fn free(&self) -> JpegxlFreeFunc {
#[cfg_attr(coverage_nightly, coverage(off))]
unsafe extern "C-unwind" fn free(_opaque: *mut c_void, _address: *mut c_void) {}

Expand All @@ -136,7 +107,7 @@ pub(crate) mod tests {
pub struct PanicManager {}

impl MemoryManager for PanicManager {
fn alloc(&self) -> AllocFn {
fn alloc(&self) -> JpegxlAllocFunc {
#[cfg_attr(coverage_nightly, coverage(off))]
unsafe extern "C-unwind" fn alloc(_opaque: *mut c_void, _size: usize) -> *mut c_void {
panic!("Stack unwind test")
Expand All @@ -145,7 +116,7 @@ pub(crate) mod tests {
alloc
}

fn free(&self) -> FreeFn {
fn free(&self) -> JpegxlFreeFunc {
#[cfg_attr(coverage_nightly, coverage(off))]
unsafe extern "C-unwind" fn free(_opaque: *mut c_void, _address: *mut c_void) {
debug_assert!(false, "Should not be called");
Expand All @@ -156,20 +127,21 @@ pub(crate) mod tests {
}

#[test]
fn test_mm() {
let mm = NoManager {};
assert!(decoder_builder().memory_manager(&mm).build().is_err());
assert!(encoder_builder().memory_manager(&mm).build().is_err());

let mm = BumpManager::<{ 1024 * 10 }>::default();
assert!(decoder_builder().memory_manager(&mm).build().is_ok());
assert!(encoder_builder().memory_manager(&mm).build().is_ok());
fn test_mm() -> TestResult {
let mm = BumpManager::new(1024 * 1024 * 50);
let dec = decoder_builder().memory_manager(&mm).build()?;
let (meta, img) = dec.decode_with::<u8>(crate::tests::SAMPLE_JXL)?;

let mut enc = encoder_builder().memory_manager(&mm).build()?;
let _ = enc.encode::<u8, u8>(&img, meta.width, meta.height)?;

Ok(())
}

#[test]
#[should_panic = "Stack unwind test"]
fn test_unwind() {
let mm = PanicManager {};
let _ = decoder_builder().memory_manager(&mm).build();
let _ = decoder_builder().memory_manager(&mm).build().unwrap();
}
}
5 changes: 4 additions & 1 deletion jpegxl-rs/src/tests/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,10 @@ fn gray() -> TestResult {
)?;
_ = decoder.decode(&result)?;

encoder.set_frame_option(jpegxl_sys::encoder::encode::FrameSetting::BrotliEffort, 1)?;
encoder.set_frame_option(
jpegxl_sys::encoder::encode::JxlEncoderFrameSettingId::BrotliEffort,
1,
)?;

Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion jpegxl-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ features = ["docs"]
pkg-config = "0.3.31"

[build-dependencies.jpegxl-src]
version = "0.10.4"
version = "0.11.0"
path = "../jpegxl-src"
optional = true

Expand Down
22 changes: 22 additions & 0 deletions jpegxl-sys/src/color.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
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 <https://www.gnu.org/licenses/>.
*/

//! `jxl_color`: ICC profiles and color space conversions.
pub mod cms;
pub mod cms_interface;
pub mod color_encoding;
86 changes: 86 additions & 0 deletions jpegxl-sys/src/color/cms_interface.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
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 <https://www.gnu.org/licenses/>.
*/

//! Interface to allow the injection of different color management systems
//! (CMSes, also called color management modules, or CMMs) in JPEG XL.
//!
//! A CMS is needed by the JPEG XL encoder and decoder to perform colorspace
//! conversions. This defines an interface that can be implemented for different
//! CMSes and then passed to the library.
use std::ffi::c_void;

use crate::common::types::JxlBool;

use super::color_encoding::JxlColorEncoding;

pub type JpegXlCmsSetFieldsFromIccFunc = extern "C" fn(
user_data: *mut c_void,
icc_data: *const u8,
icc_size: usize,
c: *mut JxlColorEncoding,
cmyk: *mut JxlBool,
) -> JxlBool;

#[repr(C)]
#[derive(Debug, Clone)]
pub struct JxlColorProfileIcc {
data: *const u8,
size: usize,
}

#[repr(C)]
#[derive(Debug, Clone)]
pub struct JxlColorProfile {
pub icc: JxlColorProfileIcc,
pub color_encoding: JxlColorEncoding,
pub num_channels: usize,
}

pub type JpegXlCmsInitFunc = extern "C" fn(
init_data: *mut c_void,
num_threads: usize,
pixels_per_thread: usize,
input_profile: *const JxlColorProfile,
output_profile: *const JxlColorProfile,
intensity_target: f32,
) -> *mut c_void;

pub type JpegXlCmsGetBufferFunc = extern "C" fn(user_data: *mut c_void, thread: usize) -> *mut f32;

pub type JpegXlCmsRunFunc = extern "C" fn(
user_data: *mut c_void,
thread: usize,
input_buffer: *const f32,
output_buffer: *mut f32,
num_pixels: usize,
) -> JxlBool;

pub type JpegXlCmsDestroyFun = extern "C" fn(user_data: *mut c_void);

#[repr(C)]
#[derive(Debug, Clone)]
pub struct JxlCmsInterface {
pub set_fields_data: *mut c_void,
pub set_fields_from_icc: JpegXlCmsSetFieldsFromIccFunc,
pub init_data: *mut c_void,
pub init: JpegXlCmsInitFunc,
pub get_src_buf: JpegXlCmsGetBufferFunc,
pub get_dst_buf: JpegXlCmsGetBufferFunc,
pub run: JpegXlCmsRunFunc,
pub destroy: JpegXlCmsDestroyFun,
}
Loading

0 comments on commit b948790

Please sign in to comment.