mirror of
https://github.com/Cykooz/fast_image_resize.git
synced 2026-10-07 17:01:09 +00:00
Fixed dividing image by alpha channel for images with U16x2 pixels.
This commit is contained in:
+9
-3
@@ -1,6 +1,12 @@
|
||||
## [Unreleased] - ReleaseDate
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed dividing image by alpha channel for images with `U16x2` pixels.
|
||||
|
||||
## [5.1.3] - 2025-04-06
|
||||
|
||||
## Fixed
|
||||
### Fixed
|
||||
|
||||
- Fixed error in `NEON` implementation of `MulDiv::multiply_alpha()` and
|
||||
`MulDiv::multiply_alpha_inplace()` for `U8x2` pixels
|
||||
@@ -10,7 +16,7 @@
|
||||
|
||||
## [5.1.2] - 2025-02-16
|
||||
|
||||
## Fixed
|
||||
### Fixed
|
||||
|
||||
- Fixed error in implementation of `ImageView::split_by_width()`, `ImageView::split_by_height()`,
|
||||
`ImageViewMut::split_by_width_mut()` and `ImageViewMut::split_by_height_mut()`
|
||||
@@ -18,7 +24,7 @@
|
||||
|
||||
## [5.1.1] - 2025-01-13
|
||||
|
||||
## Fixed
|
||||
### Fixed
|
||||
|
||||
- Fixed error in implementation of `ImageView::split_by_width()`, `ImageView::split_by_height()`,
|
||||
`ImageViewMut::split_by_width_mut()` and `ImageViewMut::split_by_height_mut()`
|
||||
|
||||
+3
-4
@@ -3,13 +3,12 @@ use std::path::PathBuf;
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use clap::Parser;
|
||||
use image::{ColorType, ImageReader};
|
||||
use log::debug;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use fast_image_resize as fr;
|
||||
use fast_image_resize::images::Image;
|
||||
use fast_image_resize::ResizeOptions;
|
||||
use image::{ColorType, ImageReader};
|
||||
use log::debug;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
mod structs;
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
use super::sse4;
|
||||
use crate::pixels::U16x2;
|
||||
use crate::utils::foreach_with_pre_reading;
|
||||
use crate::{ImageView, ImageViewMut};
|
||||
|
||||
use super::sse4;
|
||||
|
||||
#[target_feature(enable = "avx2")]
|
||||
pub(crate) unsafe fn multiply_alpha(
|
||||
src_view: &impl ImageView<Pixel = U16x2>,
|
||||
@@ -220,7 +219,10 @@ unsafe fn divide_alpha_8_pixels(pixels: __m256i) -> __m256i {
|
||||
let luma_f32x8 = _mm256_cvtepi32_ps(luma_i32x8);
|
||||
let scaled_luma_f32x8 = _mm256_mul_ps(luma_f32x8, alpha_max);
|
||||
let divided_luma_f32x8 = _mm256_div_ps(scaled_luma_f32x8, alpha_f32x8);
|
||||
let divided_luma_i32x8 = _mm256_cvtps_epi32(divided_luma_f32x8);
|
||||
let mut divided_luma_i32x8 = _mm256_cvtps_epi32(divided_luma_f32x8);
|
||||
// Clamp result to [0..0xffff]
|
||||
divided_luma_i32x8 = _mm256_max_epi32(divided_luma_i32x8, _mm256_setzero_si256());
|
||||
divided_luma_i32x8 = _mm256_min_epi32(divided_luma_i32x8, luma_mask);
|
||||
|
||||
let alpha = _mm256_and_si256(pixels, alpha_mask);
|
||||
_mm256_blendv_epi8(divided_luma_i32x8, alpha, alpha_mask)
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
use super::native;
|
||||
use crate::pixels::U16x2;
|
||||
use crate::utils::foreach_with_pre_reading;
|
||||
use crate::{ImageView, ImageViewMut};
|
||||
|
||||
use super::native;
|
||||
|
||||
#[target_feature(enable = "sse4.1")]
|
||||
pub(crate) unsafe fn multiply_alpha(
|
||||
src_view: &impl ImageView<Pixel = U16x2>,
|
||||
@@ -210,7 +209,10 @@ unsafe fn divide_alpha_4_pixels(pixels: __m128i) -> __m128i {
|
||||
let alpha_f32x4 = _mm_cvtepi32_ps(_mm_shuffle_epi8(pixels, alpha32_sh));
|
||||
let luma_f32x4 = _mm_cvtepi32_ps(_mm_and_si128(pixels, luma_mask));
|
||||
let scaled_luma_f32x4 = _mm_mul_ps(luma_f32x4, alpha_max);
|
||||
let divided_luma_i32x4 = _mm_cvtps_epi32(_mm_div_ps(scaled_luma_f32x4, alpha_f32x4));
|
||||
let mut divided_luma_i32x4 = _mm_cvtps_epi32(_mm_div_ps(scaled_luma_f32x4, alpha_f32x4));
|
||||
// Clamp result to [0..0xffff]
|
||||
divided_luma_i32x4 = _mm_max_epi32(divided_luma_i32x4, _mm_setzero_si128());
|
||||
divided_luma_i32x4 = _mm_min_epi32(divided_luma_i32x4, luma_mask);
|
||||
|
||||
let alpha = _mm_and_si128(pixels, alpha_mask);
|
||||
_mm_blendv_epi8(divided_luma_i32x4, alpha, alpha_mask)
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
use super::sse4;
|
||||
use crate::pixels::U16x4;
|
||||
use crate::utils::foreach_with_pre_reading;
|
||||
use crate::{ImageView, ImageViewMut};
|
||||
|
||||
use super::sse4;
|
||||
|
||||
#[target_feature(enable = "avx2")]
|
||||
pub(crate) unsafe fn multiply_alpha(
|
||||
src_view: &impl ImageView<Pixel = U16x4>,
|
||||
@@ -238,6 +237,7 @@ unsafe fn divide_alpha_4_pixels(pixels: __m256i) -> __m256i {
|
||||
let divided_pix0_i32x8 = _mm256_cvtps_epi32(_mm256_div_ps(scaled_pix0_f32x8, alpha0_f32x8));
|
||||
let divided_pix1_i32x8 = _mm256_cvtps_epi32(_mm256_div_ps(scaled_pix1_f32x8, alpha1_f32x8));
|
||||
|
||||
// All negative values will be stored as 0.
|
||||
let two_pixels_i16x16 = _mm256_packus_epi32(divided_pix0_i32x8, divided_pix1_i32x8);
|
||||
let alpha = _mm256_and_si256(pixels, alpha_mask);
|
||||
_mm256_blendv_epi8(two_pixels_i16x16, alpha, alpha_mask)
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
use super::native;
|
||||
use crate::pixels::U8x2;
|
||||
use crate::utils::foreach_with_pre_reading;
|
||||
use crate::{ImageView, ImageViewMut};
|
||||
|
||||
use super::native;
|
||||
|
||||
#[target_feature(enable = "sse4.1")]
|
||||
pub(crate) unsafe fn multiply_alpha(
|
||||
src_view: &impl ImageView<Pixel = U8x2>,
|
||||
@@ -212,7 +211,7 @@ unsafe fn divide_alpha_8_pixels(pixels: __m128i) -> __m128i {
|
||||
let scaled_alpha_lo_i32 = _mm_cvtps_epi32(_mm_div_ps(alpha_scale, alpha_lo_f32));
|
||||
let alpha_hi_f32 = _mm_cvtepi32_ps(_mm_shuffle_epi8(pixels, alpha32_sh_hi));
|
||||
let scaled_alpha_hi_i32 = _mm_cvtps_epi32(_mm_div_ps(alpha_scale, alpha_hi_f32));
|
||||
// All negative values will stored as 0.
|
||||
// All negative values will be stored as 0.
|
||||
let scaled_alpha_i16 = _mm_packus_epi32(scaled_alpha_lo_i32, scaled_alpha_hi_i32);
|
||||
|
||||
let luma_i16 = _mm_and_si128(pixels, luma_mask);
|
||||
|
||||
@@ -330,6 +330,7 @@ mod u16_tests {
|
||||
new_case_16(0xffff, 0, 0),
|
||||
new_case_16(0x8000, 0, 0),
|
||||
new_case_16(0, 0, 0),
|
||||
new_case_16(0xffff, 0xc0c0, 0xffff),
|
||||
];
|
||||
let mut scr_pixels = vec![];
|
||||
let mut expected_pixels = vec![];
|
||||
@@ -456,6 +457,8 @@ mod f32_tests {
|
||||
new_case_f32(1., 0., 0.),
|
||||
new_case_f32(0.5, 0., 0.),
|
||||
new_case_f32(0., 0., 0.),
|
||||
// f32 can afford to have a value greater than 1.0
|
||||
new_case_f32(1., 0.7, 1. / 0.7),
|
||||
];
|
||||
let mut scr_pixels = vec![];
|
||||
let mut expected_pixels = vec![];
|
||||
|
||||
@@ -858,9 +858,10 @@ mod not_u8x4 {
|
||||
}
|
||||
|
||||
mod u8x4 {
|
||||
use std::f64::consts::PI;
|
||||
|
||||
use fast_image_resize::ResizeError;
|
||||
use image::ImageReader;
|
||||
use std::f64::consts::PI;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
+1
-3
@@ -3,12 +3,10 @@ use std::io::BufReader;
|
||||
use std::num::NonZeroU32;
|
||||
use std::ops::Deref;
|
||||
|
||||
use image::ImageReader;
|
||||
use image::{ColorType, ExtendedColorType, ImageBuffer};
|
||||
|
||||
use fast_image_resize::images::Image;
|
||||
use fast_image_resize::pixels::*;
|
||||
use fast_image_resize::{change_type_of_pixel_components, CpuExtensions, PixelTrait, PixelType};
|
||||
use image::{ColorType, ExtendedColorType, ImageBuffer, ImageReader};
|
||||
|
||||
pub fn non_zero_u32(v: u32) -> NonZeroU32 {
|
||||
NonZeroU32::new(v).unwrap()
|
||||
|
||||
Reference in New Issue
Block a user