-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
1,003 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
/* | ||
* // Copyright 2024 (c) the Radzivon Bartoshyk. All rights reserved. | ||
* // | ||
* // Use of this source code is governed by a BSD-style | ||
* // license that can be found in the LICENSE file. | ||
*/ | ||
use crate::image::ImageConfiguration; | ||
use crate::{Rgb, TransferFunction}; | ||
|
||
#[inline(always)] | ||
fn channels_to_lalphabeta<const CHANNELS_CONFIGURATION: u8>( | ||
src: &[u8], | ||
src_stride: u32, | ||
dst: &mut [f32], | ||
dst_stride: u32, | ||
width: u32, | ||
height: u32, | ||
transfer_function: TransferFunction, | ||
) { | ||
let image_configuration: ImageConfiguration = CHANNELS_CONFIGURATION.into(); | ||
|
||
let channels = image_configuration.get_channels_count(); | ||
|
||
let mut src_offset = 0usize; | ||
let mut dst_offset = 0usize; | ||
|
||
for _ in 0..height as usize { | ||
let mut _cx = 0usize; | ||
|
||
let src_ptr = unsafe { src.as_ptr().add(src_offset) }; | ||
let dst_ptr = unsafe { (dst.as_mut_ptr() as *mut u8).add(dst_offset) as *mut f32 }; | ||
|
||
for x in _cx..width as usize { | ||
let px = x * channels; | ||
|
||
let src = unsafe { src_ptr.add(px) }; | ||
let r = unsafe { | ||
src.add(image_configuration.get_r_channel_offset()) | ||
.read_unaligned() | ||
}; | ||
let g = unsafe { | ||
src.add(image_configuration.get_g_channel_offset()) | ||
.read_unaligned() | ||
}; | ||
let b = unsafe { | ||
src.add(image_configuration.get_b_channel_offset()) | ||
.read_unaligned() | ||
}; | ||
|
||
let rgb = Rgb::<u8>::new(r, g, b); | ||
let dst_store = unsafe { dst_ptr.add(px) }; | ||
let lalphabeta = rgb.to_lalphabeta(transfer_function); | ||
unsafe { | ||
dst_store.write_unaligned(lalphabeta.l); | ||
dst_store.add(1).write_unaligned(lalphabeta.alpha); | ||
dst_store.add(2).write_unaligned(lalphabeta.beta); | ||
} | ||
|
||
if image_configuration.has_alpha() { | ||
let a = unsafe { | ||
src.add(image_configuration.get_a_channel_offset()) | ||
.read_unaligned() | ||
}; | ||
let a_lin = a as f32 * (1f32 / 255f32); | ||
unsafe { | ||
dst_store.add(3).write_unaligned(a_lin); | ||
} | ||
} | ||
} | ||
|
||
src_offset += src_stride as usize; | ||
dst_offset += dst_stride as usize; | ||
} | ||
} | ||
|
||
/// This function converts RGB to *lαβ* against D65 white point. This is much more effective than naive direct transformation | ||
/// | ||
/// # Arguments | ||
/// * `src` - A slice contains RGB data | ||
/// * `src_stride` - Bytes per row for src data. | ||
/// * `width` - Image width | ||
/// * `height` - Image height | ||
/// * `dst` - A mutable slice to receive LAB(a) data | ||
/// * `dst_stride` - Bytes per row for dst data | ||
/// * `transfer_function` - transfer function to linear colorspace | ||
pub fn rgb_to_lalphabeta( | ||
src: &[u8], | ||
src_stride: u32, | ||
dst: &mut [f32], | ||
dst_stride: u32, | ||
width: u32, | ||
height: u32, | ||
transfer_function: TransferFunction, | ||
) { | ||
channels_to_lalphabeta::<{ ImageConfiguration::Rgb as u8 }>( | ||
src, | ||
src_stride, | ||
dst, | ||
dst_stride, | ||
width, | ||
height, | ||
transfer_function, | ||
); | ||
} | ||
|
||
/// This function converts RGBA to *lαβ* against D65 white point and preserving and normalizing alpha channels keeping it at last positions. This is much more effective than naive direct transformation | ||
/// | ||
/// # Arguments | ||
/// * `src` - A slice contains RGBA data | ||
/// * `src_stride` - Bytes per row for src data. | ||
/// * `width` - Image width | ||
/// * `height` - Image height | ||
/// * `dst` - A mutable slice to receive LAB(a) data | ||
/// * `dst_stride` - Bytes per row for dst data | ||
/// * `transfer_function` - transfer function to linear colorspace | ||
pub fn rgba_to_lalphabeta( | ||
src: &[u8], | ||
src_stride: u32, | ||
dst: &mut [f32], | ||
dst_stride: u32, | ||
width: u32, | ||
height: u32, | ||
transfer_function: TransferFunction, | ||
) { | ||
channels_to_lalphabeta::<{ ImageConfiguration::Rgba as u8 }>( | ||
src, | ||
src_stride, | ||
dst, | ||
dst_stride, | ||
width, | ||
height, | ||
transfer_function, | ||
); | ||
} | ||
|
||
/// This function converts BGRA to *lαβ* against D65 white point and preserving and normalizing alpha channels keeping it at last positions. This is much more effective than naive direct transformation | ||
/// | ||
/// # Arguments | ||
/// * `src` - A slice contains BGRA data | ||
/// * `src_stride` - Bytes per row for src data. | ||
/// * `width` - Image width | ||
/// * `height` - Image height | ||
/// * `dst` - A mutable slice to receive LAB(a) data | ||
/// * `dst_stride` - Bytes per row for dst data | ||
/// * `transfer_function` - transfer function to linear colorspace | ||
pub fn bgra_to_lalphabeta( | ||
src: &[u8], | ||
src_stride: u32, | ||
dst: &mut [f32], | ||
dst_stride: u32, | ||
width: u32, | ||
height: u32, | ||
transfer_function: TransferFunction, | ||
) { | ||
channels_to_lalphabeta::<{ ImageConfiguration::Bgra as u8 }>( | ||
src, | ||
src_stride, | ||
dst, | ||
dst_stride, | ||
width, | ||
height, | ||
transfer_function, | ||
); | ||
} | ||
|
||
/// This function converts BGR to *lαβ* against D65 white point. This is much more effective than naive direct transformation | ||
/// | ||
/// # Arguments | ||
/// * `src` - A slice contains BGR data | ||
/// * `src_stride` - Bytes per row for src data. | ||
/// * `width` - Image width | ||
/// * `height` - Image height | ||
/// * `dst` - A mutable slice to receive LAB(a) data | ||
/// * `dst_stride` - Bytes per row for dst data | ||
/// * `transfer_function` - transfer function to linear colorspace | ||
pub fn bgr_to_lalphabeta( | ||
src: &[u8], | ||
src_stride: u32, | ||
dst: &mut [f32], | ||
dst_stride: u32, | ||
width: u32, | ||
height: u32, | ||
transfer_function: TransferFunction, | ||
) { | ||
channels_to_lalphabeta::<{ ImageConfiguration::Bgr as u8 }>( | ||
src, | ||
src_stride, | ||
dst, | ||
dst_stride, | ||
width, | ||
height, | ||
transfer_function, | ||
); | ||
} |
Oops, something went wrong.