From 61bb34e275793a60cd097f147b3b1edc627cecfa Mon Sep 17 00:00:00 2001 From: awxkee Date: Thu, 6 Jun 2024 00:11:51 +0100 Subject: [PATCH] Fixed LUV --- Cargo.lock | 4 +- README.md | 2 - app/src/main.rs | 20 +++---- src/luv_scaler.rs | 138 ++++++++++++++++++---------------------------- 4 files changed, 66 insertions(+), 98 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 25c58ee..cffda72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,9 +164,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorutils-rs" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0bc3649f6fb739e49909ccc380cf76d945ba9b67991c7e10050f2ba8bc9b18" +checksum = "bfdfc58089ac71a9a0922e9509b62802ffce9f067351e35c58e3ceb9a1e76d3a" dependencies = [ "half", ] diff --git a/README.md b/README.md index f748326..238755e 100644 --- a/README.md +++ b/README.md @@ -149,8 +149,6 @@ Hann, Bicubic, Hamming, Hanning, -EwaHanning, Blackman, -EwaBlackman, ``` And others \ No newline at end of file diff --git a/app/src/main.rs b/app/src/main.rs index 80fc214..b57187b 100644 --- a/app/src/main.rs +++ b/app/src/main.rs @@ -1,20 +1,19 @@ -use std::fmt::format; use std::time::Instant; -use fast_image_resize::images::Image; -use fast_image_resize::FilterType::Lanczos3; use fast_image_resize::{ CpuExtensions, IntoImageView, PixelType, ResizeAlg, ResizeOptions, Resizer, }; -use image::io::Reader as ImageReader; +use fast_image_resize::FilterType::Lanczos3; +use fast_image_resize::images::Image; use image::{EncodableLayout, GenericImageView}; +use image::io::Reader as ImageReader; -use pic_scale::{ImageSize, ImageStore, ResamplingFunction, Scaler, Scaling, ThreadingPolicy}; +use pic_scale::{ImageSize, ImageStore, LuvScaler, ResamplingFunction, Scaling, ThreadingPolicy}; fn main() { // test_fast_image(); - let img = ImageReader::open("./assets/beach_horizon.png") + let img = ImageReader::open("./assets/asset_middle.jpg") .unwrap() .decode() .unwrap(); @@ -23,14 +22,13 @@ fn main() { let start_time = Instant::now(); - let mut scaler = Scaler::new(ResamplingFunction::Hanning); - scaler.set_threading_policy(ThreadingPolicy::Adaptive); + let mut scaler = LuvScaler::new(ResamplingFunction::Hanning); + scaler.set_threading_policy(ThreadingPolicy::Single); let store = - ImageStore::::from_slice(&mut bytes, dimensions.0 as usize, dimensions.1 as usize); - let resized = scaler.resize_rgba( + ImageStore::::from_slice(&mut bytes, dimensions.0 as usize, dimensions.1 as usize); + let resized = scaler.resize_rgb( ImageSize::new(dimensions.0 as usize / 3, dimensions.1 as usize / 3), store, - true, ); let elapsed_time = start_time.elapsed(); diff --git a/src/luv_scaler.rs b/src/luv_scaler.rs index 7cf1e76..deaa2d3 100644 --- a/src/luv_scaler.rs +++ b/src/luv_scaler.rs @@ -5,7 +5,7 @@ * // license that can be found in the LICENSE file. */ -use colorutils_rs::{Luv, Rgb}; +use colorutils_rs::{luv_to_rgb, luv_with_alpha_to_rgba, rgb_to_luv, rgba_to_luv_with_alpha}; use crate::{ImageSize, ImageStore, ResamplingFunction, Scaler, Scaling, ThreadingPolicy}; @@ -21,80 +21,31 @@ impl LuvScaler { } } - fn rgbx_to_luv( - &self, - store: ImageStore, - ) -> ImageStore { - let mut new_store = ImageStore::::alloc(store.width, store.height); - let mut src_offset = 0usize; - let mut dst_offset = 0usize; - let src_buffer = store.buffer.borrow(); - let dst_buffer = new_store.buffer.borrow_mut(); - for _ in 0..store.height { - for x in 0..store.width { - let px = x * CHANNELS; - let r = *unsafe { src_buffer.get_unchecked(src_offset + px) }; - let g = *unsafe { src_buffer.get_unchecked(src_offset + px + 1) }; - let b = *unsafe { src_buffer.get_unchecked(src_offset + px + 2) }; - - let rgb = Rgb::new(r, g, b); - let luv = rgb.to_luv(); - unsafe { - *dst_buffer.get_unchecked_mut(dst_offset + px) = luv.l; - *dst_buffer.get_unchecked_mut(dst_offset + px + 1) = luv.u; - *dst_buffer.get_unchecked_mut(dst_offset + px + 2) = luv.v; - } - if CHANNELS == 4 { - let a = *unsafe { src_buffer.get_unchecked(src_offset + px + 3) }; - let a_f = a as f32 * (1f32 / 255f32); - unsafe { - *dst_buffer.get_unchecked_mut(dst_offset + px + 3) = a_f; - } - } - } - - src_offset += store.width * CHANNELS; - dst_offset += new_store.width * CHANNELS; - } - new_store + fn rgba_to_laba(store: ImageStore) -> ImageStore { + let mut new_store = ImageStore::::alloc(store.width, store.height); + let lab_stride = store.width as u32 * 4u32 * std::mem::size_of::() as u32; + rgba_to_luv_with_alpha( + &store.buffer.borrow(), + store.width as u32 * 4u32, + &mut new_store.buffer.borrow_mut(), + lab_stride, + store.width as u32, + store.height as u32, + ); + return new_store; } - fn luv_to_rgbx( - &self, - store: ImageStore, - ) -> ImageStore { - let mut new_store = ImageStore::::alloc(store.width, store.height); - let mut src_offset = 0usize; - let mut dst_offset = 0usize; - let src_buffer = store.buffer.borrow(); - let dst_buffer = new_store.buffer.borrow_mut(); - for _ in 0..store.height { - for x in 0..store.width { - let px = x * CHANNELS; - let l = *unsafe { src_buffer.get_unchecked(src_offset + px) }; - let u = *unsafe { src_buffer.get_unchecked(src_offset + px + 1) }; - let v = *unsafe { src_buffer.get_unchecked(src_offset + px + 2) }; - - let luv = Luv::new(l, u, v); - let rgb = luv.to_rgb(); - unsafe { - *dst_buffer.get_unchecked_mut(dst_offset + px) = rgb.r; - *dst_buffer.get_unchecked_mut(dst_offset + px + 1) = rgb.g; - *dst_buffer.get_unchecked_mut(dst_offset + px + 2) = rgb.b; - } - if CHANNELS == 4 { - let a = *unsafe { src_buffer.get_unchecked(src_offset + px + 3) }; - let a_f = a * 255f32; - unsafe { - *dst_buffer.get_unchecked_mut(dst_offset + px + 3) = a_f as u8; - } - } - } - - src_offset += store.width * CHANNELS; - dst_offset += new_store.width * CHANNELS; - } - new_store + fn laba_to_srgba(store: ImageStore) -> ImageStore { + let mut new_store = ImageStore::::alloc(store.width, store.height); + luv_with_alpha_to_rgba( + &store.buffer.borrow(), + store.width as u32 * 4u32 * std::mem::size_of::() as u32, + &mut new_store.buffer.borrow_mut(), + store.width as u32 * 4u32, + store.width as u32, + store.height as u32, + ); + return new_store; } } @@ -104,10 +55,31 @@ impl Scaling for LuvScaler { } fn resize_rgb(&self, new_size: ImageSize, store: ImageStore) -> ImageStore { - let luv_image = self.rgbx_to_luv(store); - let new_store = self.scaler.resize_rgb_f32(new_size, luv_image); - let unorm_image = self.luv_to_rgbx(new_store); - unorm_image + const COMPONENTS: usize = 3; + let mut lab_store = ImageStore::::alloc(store.width, store.height); + let lab_stride = + lab_store.width as u32 * COMPONENTS as u32 * std::mem::size_of::() as u32; + rgb_to_luv( + &store.buffer.borrow(), + store.width as u32 * COMPONENTS as u32, + &mut lab_store.buffer.borrow_mut(), + lab_stride, + lab_store.width as u32, + lab_store.height as u32, + ); + let new_store = self.scaler.resize_rgb_f32(new_size, lab_store); + let mut new_u8_store = ImageStore::::alloc(new_size.width, new_size.height); + let new_lab_stride = + new_store.width as u32 * COMPONENTS as u32 * std::mem::size_of::() as u32; + luv_to_rgb( + &new_store.buffer.borrow(), + new_lab_stride, + &mut new_u8_store.buffer.borrow_mut(), + new_u8_store.width as u32 * COMPONENTS as u32, + new_store.width as u32, + new_store.height as u32, + ); + return new_u8_store; } fn resize_rgb_f32(&self, new_size: ImageSize, store: ImageStore) -> ImageStore { @@ -127,16 +99,16 @@ impl Scaling for LuvScaler { src_store.unpremultiply_alpha(&mut premultiplied_store); src_store = premultiplied_store; } - let luv_image = self.rgbx_to_luv(src_store); - let new_store = self.scaler.resize_rgba_f32(new_size, luv_image); - let unorm_image = self.luv_to_rgbx(new_store); + let lab_store = Self::rgba_to_laba(src_store); + let new_store = self.scaler.resize_rgba_f32(new_size, lab_store); + let rgba_store = Self::laba_to_srgba(new_store); if is_alpha_premultiplied { let mut premultiplied_store = - ImageStore::::alloc(unorm_image.width, unorm_image.height); - unorm_image.premultiply_alpha(&mut premultiplied_store); + ImageStore::::alloc(rgba_store.width, rgba_store.height); + rgba_store.premultiply_alpha(&mut premultiplied_store); return premultiplied_store; } - return unorm_image; + return rgba_store; } fn resize_rgba_f32(