mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-21 04:34:47 +03:00
SIMD Filter. move ImagingFilterxxx functions to separate files
This commit is contained in:
parent
256eb37439
commit
b561752597
237
libImaging/FilterSIMD_3x3f_4u8.c
Normal file
237
libImaging/FilterSIMD_3x3f_4u8.c
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
void
|
||||||
|
ImagingFilter3x3f_4u8(Imaging imOut, Imaging im, const float* kernel,
|
||||||
|
float offset)
|
||||||
|
{
|
||||||
|
#define MM_KERNEL1x3_LOAD(row, x) \
|
||||||
|
pix0##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in1[x])); \
|
||||||
|
pix1##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in0[x])); \
|
||||||
|
pix2##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in_1[x]));
|
||||||
|
|
||||||
|
#define MM_KERNEL1x3_SUM(row, kindex) \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix0##row, _mm_set1_ps(kernel[0 + kindex]))); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix1##row, _mm_set1_ps(kernel[3 + kindex]))); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix2##row, _mm_set1_ps(kernel[6 + kindex])));
|
||||||
|
|
||||||
|
int x = 0, y = 0;
|
||||||
|
|
||||||
|
memcpy(imOut->image32[0], im->image32[0], im->linesize);
|
||||||
|
|
||||||
|
for (y = 1; y < im->ysize-1; y++) {
|
||||||
|
INT32* in_1 = im->image32[y-1];
|
||||||
|
INT32* in0 = im->image32[y];
|
||||||
|
INT32* in1 = im->image32[y+1];
|
||||||
|
INT32* out = imOut->image32[y];
|
||||||
|
|
||||||
|
#if defined(__AVX2__)
|
||||||
|
|
||||||
|
#define MM256_LOAD(row, x) \
|
||||||
|
pix0##row = _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(*(__m128i*) &in1[x])); \
|
||||||
|
pix1##row = _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(*(__m128i*) &in0[x])); \
|
||||||
|
pix2##row = _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(*(__m128i*) &in_1[x]));
|
||||||
|
|
||||||
|
#define MM256_SUM(pixrow, kernelrow) \
|
||||||
|
ss = _mm256_add_ps(ss, _mm256_mul_ps(pix0##pixrow, kernel0##kernelrow)); \
|
||||||
|
ss = _mm256_add_ps(ss, _mm256_mul_ps(pix1##pixrow, kernel1##kernelrow)); \
|
||||||
|
ss = _mm256_add_ps(ss, _mm256_mul_ps(pix2##pixrow, kernel2##kernelrow));
|
||||||
|
|
||||||
|
#define MM256_PERMUTE(row, from0, from1, control) \
|
||||||
|
pix0##row = _mm256_permute2f128_ps(pix0##from0, pix0##from1, control); \
|
||||||
|
pix1##row = _mm256_permute2f128_ps(pix1##from0, pix1##from1, control); \
|
||||||
|
pix2##row = _mm256_permute2f128_ps(pix2##from0, pix2##from1, control);
|
||||||
|
|
||||||
|
#define MM256_OUT(x) \
|
||||||
|
_mm_cvtps_epi32(_mm_add_ps( \
|
||||||
|
_mm256_extractf128_ps(ss, 0), \
|
||||||
|
_mm256_extractf128_ps(ss, 1) \
|
||||||
|
))
|
||||||
|
|
||||||
|
__m256 kernel00 = _mm256_insertf128_ps(
|
||||||
|
_mm256_set1_ps(kernel[0+0]),
|
||||||
|
_mm_set1_ps(kernel[0+1]), 1);
|
||||||
|
__m256 kernel01 = _mm256_castps128_ps256(_mm_set1_ps(kernel[0+2]));
|
||||||
|
__m256 kernel10 = _mm256_insertf128_ps(
|
||||||
|
_mm256_set1_ps(kernel[3+0]),
|
||||||
|
_mm_set1_ps(kernel[3+1]), 1);
|
||||||
|
__m256 kernel11 = _mm256_castps128_ps256(_mm_set1_ps(kernel[3+2]));
|
||||||
|
__m256 kernel20 = _mm256_insertf128_ps(
|
||||||
|
_mm256_set1_ps(kernel[6+0]),
|
||||||
|
_mm_set1_ps(kernel[6+1]), 1);
|
||||||
|
__m256 kernel21 = _mm256_castps128_ps256(_mm_set1_ps(kernel[6+2]));
|
||||||
|
__m256 pix00, pix10, pix20;
|
||||||
|
__m256 pix01, pix11, pix21;
|
||||||
|
__m256 pix02, pix12, pix22;
|
||||||
|
|
||||||
|
out[0] = in0[0];
|
||||||
|
x = 1;
|
||||||
|
MM256_LOAD(0, 0);
|
||||||
|
for (; x < im->xsize-1-7; x += 8) {
|
||||||
|
__m256 ss;
|
||||||
|
__m128i ssi0, ssi1, ssi2, ssi3;
|
||||||
|
|
||||||
|
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
||||||
|
MM256_SUM(0, 0);
|
||||||
|
MM256_LOAD(1, x+1);
|
||||||
|
MM256_SUM(1, 1);
|
||||||
|
ssi0 = MM256_OUT(x);
|
||||||
|
|
||||||
|
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
||||||
|
MM256_SUM(1, 0);
|
||||||
|
MM256_LOAD(2, x+3);
|
||||||
|
MM256_SUM(2, 1);
|
||||||
|
ssi2 = MM256_OUT(x+2);
|
||||||
|
|
||||||
|
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
||||||
|
MM256_PERMUTE(0, 0, 1, 0x21);
|
||||||
|
MM256_SUM(0, 0);
|
||||||
|
MM256_PERMUTE(1, 1, 2, 0x21);
|
||||||
|
MM256_SUM(1, 1);
|
||||||
|
ssi1 = MM256_OUT(x+1);
|
||||||
|
|
||||||
|
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
||||||
|
MM256_SUM(1, 0);
|
||||||
|
MM256_PERMUTE(0, 2, 2, 0x21);
|
||||||
|
MM256_SUM(0, 1);
|
||||||
|
ssi3 = MM256_OUT(x+3);
|
||||||
|
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi1);
|
||||||
|
ssi2 = _mm_packs_epi32(ssi2, ssi3);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi2);
|
||||||
|
_mm_storeu_si128((__m128i*) &out[x], ssi0);
|
||||||
|
|
||||||
|
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
||||||
|
MM256_SUM(2, 0);
|
||||||
|
MM256_LOAD(1, x+5);
|
||||||
|
MM256_SUM(1, 1);
|
||||||
|
ssi0 = MM256_OUT(x+4);
|
||||||
|
|
||||||
|
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
||||||
|
MM256_SUM(1, 0);
|
||||||
|
MM256_LOAD(0, x+7);
|
||||||
|
MM256_SUM(0, 1);
|
||||||
|
ssi2 = MM256_OUT(x+6);
|
||||||
|
|
||||||
|
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
||||||
|
MM256_PERMUTE(2, 2, 1, 0x21);
|
||||||
|
MM256_SUM(2, 0);
|
||||||
|
MM256_PERMUTE(1, 1, 0, 0x21);
|
||||||
|
MM256_SUM(1, 1);
|
||||||
|
ssi1 = MM256_OUT(x+5);
|
||||||
|
|
||||||
|
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
||||||
|
MM256_SUM(1, 0);
|
||||||
|
MM256_PERMUTE(2, 0, 0, 0x21);
|
||||||
|
MM256_SUM(2, 1);
|
||||||
|
ssi3 = MM256_OUT(x+7);
|
||||||
|
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi1);
|
||||||
|
ssi2 = _mm_packs_epi32(ssi2, ssi3);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi2);
|
||||||
|
_mm_storeu_si128((__m128i*) &out[x+4], ssi0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; x < im->xsize-1-1; x += 2) {
|
||||||
|
__m256 ss;
|
||||||
|
__m128i ssi0, ssi1;
|
||||||
|
|
||||||
|
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
||||||
|
MM256_SUM(0, 0);
|
||||||
|
MM256_LOAD(1, x+1);
|
||||||
|
MM256_SUM(1, 1);
|
||||||
|
ssi0 = MM256_OUT(x);
|
||||||
|
|
||||||
|
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
||||||
|
MM256_PERMUTE(0, 0, 1, 0x21);
|
||||||
|
MM256_SUM(0, 0);
|
||||||
|
MM256_PERMUTE(1, 0, 1, 0xf3);
|
||||||
|
MM256_SUM(1, 1);
|
||||||
|
ssi1 = MM256_OUT(x+1);
|
||||||
|
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi1);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
_mm_storel_epi64((__m128i*) &out[x], ssi0);
|
||||||
|
|
||||||
|
MM256_PERMUTE(0, 0, 1, 0x21);
|
||||||
|
}
|
||||||
|
for (; x < im->xsize-1; x++) {
|
||||||
|
__m128 pix00, pix10, pix20;
|
||||||
|
__m128 ss = _mm_set1_ps(offset);
|
||||||
|
__m128i ssi0;
|
||||||
|
MM_KERNEL1x3_LOAD(0, x-1);
|
||||||
|
MM_KERNEL1x3_SUM(0, 0);
|
||||||
|
MM_KERNEL1x3_LOAD(0, x+0);
|
||||||
|
MM_KERNEL1x3_SUM(0, 1);
|
||||||
|
MM_KERNEL1x3_LOAD(0, x+1);
|
||||||
|
MM_KERNEL1x3_SUM(0, 2);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
out[x] = _mm_cvtsi128_si32(ssi0);
|
||||||
|
}
|
||||||
|
out[x] = in0[x];
|
||||||
|
|
||||||
|
#undef MM256_LOAD
|
||||||
|
#undef MM256_SUM
|
||||||
|
#undef MM256_PERMUTE
|
||||||
|
#undef MM256_OUT
|
||||||
|
|
||||||
|
#else
|
||||||
|
__m128 pix00, pix10, pix20;
|
||||||
|
__m128 pix01, pix11, pix21;
|
||||||
|
__m128 pix02, pix12, pix22;
|
||||||
|
MM_KERNEL1x3_LOAD(0, 0);
|
||||||
|
MM_KERNEL1x3_LOAD(1, 1);
|
||||||
|
|
||||||
|
out[0] = in0[0];
|
||||||
|
x = 1;
|
||||||
|
for (; x < im->xsize-1-2; x += 3) {
|
||||||
|
__m128 ss;
|
||||||
|
__m128i ssi0, ssi1, ssi2;
|
||||||
|
|
||||||
|
ss = _mm_set1_ps(offset);
|
||||||
|
MM_KERNEL1x3_SUM(0, 0);
|
||||||
|
MM_KERNEL1x3_SUM(1, 1);
|
||||||
|
MM_KERNEL1x3_LOAD(2, x+1);
|
||||||
|
MM_KERNEL1x3_SUM(2, 2);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss);
|
||||||
|
|
||||||
|
ss = _mm_set1_ps(offset);
|
||||||
|
MM_KERNEL1x3_SUM(1, 0);
|
||||||
|
MM_KERNEL1x3_SUM(2, 1);
|
||||||
|
MM_KERNEL1x3_LOAD(0, x+2);
|
||||||
|
MM_KERNEL1x3_SUM(0, 2);
|
||||||
|
ssi1 = _mm_cvtps_epi32(ss);
|
||||||
|
|
||||||
|
ss = _mm_set1_ps(offset);
|
||||||
|
MM_KERNEL1x3_SUM(2, 0);
|
||||||
|
MM_KERNEL1x3_SUM(0, 1);
|
||||||
|
MM_KERNEL1x3_LOAD(1, x+3);
|
||||||
|
MM_KERNEL1x3_SUM(1, 2);
|
||||||
|
ssi2 = _mm_cvtps_epi32(ss);
|
||||||
|
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi1);
|
||||||
|
ssi1 = _mm_packs_epi32(ssi2, ssi2);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi1);
|
||||||
|
_mm_storeu_si128((__m128i*) &out[x], ssi0);
|
||||||
|
}
|
||||||
|
for (; x < im->xsize-1; x++) {
|
||||||
|
__m128 ss = _mm_set1_ps(offset);
|
||||||
|
__m128i ssi0;
|
||||||
|
MM_KERNEL1x3_LOAD(0, x-1);
|
||||||
|
MM_KERNEL1x3_SUM(0, 0);
|
||||||
|
MM_KERNEL1x3_LOAD(0, x+0);
|
||||||
|
MM_KERNEL1x3_SUM(0, 1);
|
||||||
|
MM_KERNEL1x3_LOAD(0, x+1);
|
||||||
|
MM_KERNEL1x3_SUM(0, 2);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
out[x] = _mm_cvtsi128_si32(ssi0);
|
||||||
|
}
|
||||||
|
out[x] = in0[x];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
memcpy(imOut->image32[y], im->image32[y], im->linesize);
|
||||||
|
|
||||||
|
#undef MM_KERNEL1x3_LOAD
|
||||||
|
#undef MM_KERNEL1x3_SUM
|
||||||
|
}
|
135
libImaging/FilterSIMD_3x3f_u8.c
Normal file
135
libImaging/FilterSIMD_3x3f_u8.c
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
void
|
||||||
|
ImagingFilter3x3f_u8(Imaging imOut, Imaging im, const float* kernel,
|
||||||
|
float offset)
|
||||||
|
{
|
||||||
|
#define MM_KERNEL1x3_SUM1(ss, row, kernel) \
|
||||||
|
ss = _mm_set1_ps(offset); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix0##row, kernel0##kernel)); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix1##row, kernel1##kernel)); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix2##row, kernel2##kernel));
|
||||||
|
|
||||||
|
#define MM_KERNEL1x3_SUM1_2(ss, row, kernel) \
|
||||||
|
ss = _mm_set1_ps(offset); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix3##row, kernel0##kernel)); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix0##row, kernel1##kernel)); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix1##row, kernel2##kernel));
|
||||||
|
|
||||||
|
#define MM_KERNEL1x3_LOAD(row, x) \
|
||||||
|
pix0##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in1[x])); \
|
||||||
|
pix1##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in0[x])); \
|
||||||
|
pix2##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in_1[x]));
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
__m128 kernel00 = _mm_set_ps(0, kernel[2], kernel[1], kernel[0]);
|
||||||
|
__m128 kernel10 = _mm_set_ps(0, kernel[5], kernel[4], kernel[3]);
|
||||||
|
__m128 kernel20 = _mm_set_ps(0, kernel[8], kernel[7], kernel[6]);
|
||||||
|
__m128 kernel01 = _mm_set_ps(kernel[2], kernel[1], kernel[0], 0);
|
||||||
|
__m128 kernel11 = _mm_set_ps(kernel[5], kernel[4], kernel[3], 0);
|
||||||
|
__m128 kernel21 = _mm_set_ps(kernel[8], kernel[7], kernel[6], 0);
|
||||||
|
|
||||||
|
memcpy(imOut->image8[0], im->image8[0], im->linesize);
|
||||||
|
y = 1;
|
||||||
|
for (; y < im->ysize-1-1; y += 2) {
|
||||||
|
UINT8* in_1 = im->image8[y-1];
|
||||||
|
UINT8* in0 = im->image8[y];
|
||||||
|
UINT8* in1 = im->image8[y+1];
|
||||||
|
UINT8* in2 = im->image8[y+2];
|
||||||
|
UINT8* out0 = imOut->image8[y];
|
||||||
|
UINT8* out1 = imOut->image8[y+1];
|
||||||
|
|
||||||
|
out0[0] = in0[0];
|
||||||
|
out1[0] = in1[0];
|
||||||
|
x = 1;
|
||||||
|
for (; x < im->xsize-1-3; x += 4) {
|
||||||
|
__m128 ss0, ss1, ss2, ss3, ss4, ss5;
|
||||||
|
__m128 pix00, pix10, pix20, pix30;
|
||||||
|
__m128i ssi0;
|
||||||
|
|
||||||
|
MM_KERNEL1x3_LOAD(0, x-1);
|
||||||
|
MM_KERNEL1x3_SUM1(ss0, 0, 0);
|
||||||
|
MM_KERNEL1x3_SUM1(ss1, 0, 1);
|
||||||
|
ss0 = _mm_hadd_ps(ss0, ss1);
|
||||||
|
pix30 = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in2[x-1]));
|
||||||
|
MM_KERNEL1x3_SUM1_2(ss3, 0, 0);
|
||||||
|
MM_KERNEL1x3_SUM1_2(ss4, 0, 1);
|
||||||
|
ss3 = _mm_hadd_ps(ss3, ss4);
|
||||||
|
|
||||||
|
MM_KERNEL1x3_LOAD(0, x+1);
|
||||||
|
MM_KERNEL1x3_SUM1(ss1, 0, 0);
|
||||||
|
MM_KERNEL1x3_SUM1(ss2, 0, 1);
|
||||||
|
ss1 = _mm_hadd_ps(ss1, ss2);
|
||||||
|
pix30 = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in2[x+1]));
|
||||||
|
MM_KERNEL1x3_SUM1_2(ss4, 0, 0);
|
||||||
|
MM_KERNEL1x3_SUM1_2(ss5, 0, 1);
|
||||||
|
ss4 = _mm_hadd_ps(ss4, ss5);
|
||||||
|
|
||||||
|
ss0 = _mm_hadd_ps(ss0, ss1);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss0);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
*((UINT32*) &out0[x]) = _mm_cvtsi128_si32(ssi0);
|
||||||
|
|
||||||
|
ss3 = _mm_hadd_ps(ss3, ss4);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss3);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
*((UINT32*) &out1[x]) = _mm_cvtsi128_si32(ssi0);
|
||||||
|
}
|
||||||
|
for (; x < im->xsize-1; x++) {
|
||||||
|
__m128 ss0, ss1;
|
||||||
|
__m128 pix00, pix10, pix20, pix30;
|
||||||
|
__m128i ssi0;
|
||||||
|
|
||||||
|
MM_KERNEL1x3_LOAD(0, x-1);
|
||||||
|
MM_KERNEL1x3_SUM1(ss0, 0, 0);
|
||||||
|
pix30 = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in2[x-1]));
|
||||||
|
MM_KERNEL1x3_SUM1_2(ss1, 0, 0);
|
||||||
|
|
||||||
|
ss0 = _mm_hadd_ps(ss0, ss0);
|
||||||
|
ss0 = _mm_hadd_ps(ss0, ss0);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss0);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
out0[x] = _mm_cvtsi128_si32(ssi0);
|
||||||
|
|
||||||
|
ss1 = _mm_hadd_ps(ss1, ss1);
|
||||||
|
ss1 = _mm_hadd_ps(ss1, ss1);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss1);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
out1[x] = _mm_cvtsi128_si32(ssi0);
|
||||||
|
}
|
||||||
|
out0[x] = in0[x];
|
||||||
|
out1[x] = in1[x];
|
||||||
|
}
|
||||||
|
for (; y < im->ysize-1; y++) {
|
||||||
|
UINT8* in_1 = im->image8[y-1];
|
||||||
|
UINT8* in0 = im->image8[y];
|
||||||
|
UINT8* in1 = im->image8[y+1];
|
||||||
|
UINT8* out = imOut->image8[y];
|
||||||
|
|
||||||
|
out[0] = in0[0];
|
||||||
|
x = 1;
|
||||||
|
for (; x < im->xsize-1; x++) {
|
||||||
|
__m128 ss;
|
||||||
|
__m128 pix00, pix10, pix20;
|
||||||
|
__m128i ssi0;
|
||||||
|
|
||||||
|
MM_KERNEL1x3_LOAD(0, x-1);
|
||||||
|
MM_KERNEL1x3_SUM1(ss, 0, 0);
|
||||||
|
|
||||||
|
ss = _mm_hadd_ps(ss, ss);
|
||||||
|
ss = _mm_hadd_ps(ss, ss);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
out[x] = _mm_cvtsi128_si32(ssi0);
|
||||||
|
}
|
||||||
|
out[x] = in0[x];
|
||||||
|
}
|
||||||
|
memcpy(imOut->image8[y], im->image8[y], im->linesize);
|
||||||
|
|
||||||
|
#undef MM_KERNEL1x3_SUM1
|
||||||
|
#undef MM_KERNEL1x3_SUM1_2
|
||||||
|
#undef MM_KERNEL1x3_LOAD
|
||||||
|
}
|
126
libImaging/FilterSIMD_5x5f_4u8.c
Normal file
126
libImaging/FilterSIMD_5x5f_4u8.c
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
void
|
||||||
|
ImagingFilter5x5f_4u8(Imaging imOut, Imaging im, const float* kernel,
|
||||||
|
float offset)
|
||||||
|
{
|
||||||
|
#define MM_KERNEL1x5_LOAD(row, x) \
|
||||||
|
pix0##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in2[x])); \
|
||||||
|
pix1##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in1[x])); \
|
||||||
|
pix2##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in0[x])); \
|
||||||
|
pix3##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in_1[x])); \
|
||||||
|
pix4##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in_2[x]));
|
||||||
|
|
||||||
|
#define MM_KERNEL1x5_SUM(row, kindex) \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix0##row, _mm_set1_ps(kernel[0 + kindex]))); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix1##row, _mm_set1_ps(kernel[5 + kindex]))); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix2##row, _mm_set1_ps(kernel[10 + kindex]))); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix3##row, _mm_set1_ps(kernel[15 + kindex]))); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix4##row, _mm_set1_ps(kernel[20 + kindex])));
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
memcpy(imOut->image32[0], im->image32[0], im->linesize);
|
||||||
|
memcpy(imOut->image32[1], im->image32[1], im->linesize);
|
||||||
|
for (y = 2; y < im->ysize-2; y++) {
|
||||||
|
INT32* in_2 = im->image32[y-2];
|
||||||
|
INT32* in_1 = im->image32[y-1];
|
||||||
|
INT32* in0 = im->image32[y];
|
||||||
|
INT32* in1 = im->image32[y+1];
|
||||||
|
INT32* in2 = im->image32[y+2];
|
||||||
|
INT32* out = imOut->image32[y];
|
||||||
|
__m128 pix00, pix10, pix20, pix30, pix40;
|
||||||
|
__m128 pix01, pix11, pix21, pix31, pix41;
|
||||||
|
__m128 pix02, pix12, pix22, pix32, pix42;
|
||||||
|
__m128 pix03, pix13, pix23, pix33, pix43;
|
||||||
|
__m128 pix04, pix14, pix24, pix34, pix44;
|
||||||
|
MM_KERNEL1x5_LOAD(0, 0);
|
||||||
|
MM_KERNEL1x5_LOAD(1, 1);
|
||||||
|
MM_KERNEL1x5_LOAD(2, 2);
|
||||||
|
MM_KERNEL1x5_LOAD(3, 3);
|
||||||
|
|
||||||
|
out[0] = in0[0];
|
||||||
|
out[1] = in0[1];
|
||||||
|
x = 2;
|
||||||
|
for (; x < im->xsize-2-4; x += 5) {
|
||||||
|
__m128 ss;
|
||||||
|
__m128i ssi0, ssi1, ssi2, ssi3;
|
||||||
|
|
||||||
|
ss = _mm_set1_ps(offset);
|
||||||
|
MM_KERNEL1x5_SUM(0, 0);
|
||||||
|
MM_KERNEL1x5_SUM(1, 1);
|
||||||
|
MM_KERNEL1x5_SUM(2, 2);
|
||||||
|
MM_KERNEL1x5_SUM(3, 3);
|
||||||
|
MM_KERNEL1x5_LOAD(4, x+2);
|
||||||
|
MM_KERNEL1x5_SUM(4, 4);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss);
|
||||||
|
|
||||||
|
ss = _mm_set1_ps(offset);
|
||||||
|
MM_KERNEL1x5_SUM(1, 0);
|
||||||
|
MM_KERNEL1x5_SUM(2, 1);
|
||||||
|
MM_KERNEL1x5_SUM(3, 2);
|
||||||
|
MM_KERNEL1x5_SUM(4, 3);
|
||||||
|
MM_KERNEL1x5_LOAD(0, x+3);
|
||||||
|
MM_KERNEL1x5_SUM(0, 4);
|
||||||
|
ssi1 = _mm_cvtps_epi32(ss);
|
||||||
|
|
||||||
|
ss = _mm_set1_ps(offset);
|
||||||
|
MM_KERNEL1x5_SUM(2, 0);
|
||||||
|
MM_KERNEL1x5_SUM(3, 1);
|
||||||
|
MM_KERNEL1x5_SUM(4, 2);
|
||||||
|
MM_KERNEL1x5_SUM(0, 3);
|
||||||
|
MM_KERNEL1x5_LOAD(1, x+4);
|
||||||
|
MM_KERNEL1x5_SUM(1, 4);
|
||||||
|
ssi2 = _mm_cvtps_epi32(ss);
|
||||||
|
|
||||||
|
ss = _mm_set1_ps(offset);
|
||||||
|
MM_KERNEL1x5_SUM(3, 0);
|
||||||
|
MM_KERNEL1x5_SUM(4, 1);
|
||||||
|
MM_KERNEL1x5_SUM(0, 2);
|
||||||
|
MM_KERNEL1x5_SUM(1, 3);
|
||||||
|
MM_KERNEL1x5_LOAD(2, x+5);
|
||||||
|
MM_KERNEL1x5_SUM(2, 4);
|
||||||
|
ssi3 = _mm_cvtps_epi32(ss);
|
||||||
|
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi1);
|
||||||
|
ssi1 = _mm_packs_epi32(ssi2, ssi3);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi1);
|
||||||
|
_mm_storeu_si128((__m128i*) &out[x], ssi0);
|
||||||
|
|
||||||
|
ss = _mm_set1_ps(offset);
|
||||||
|
MM_KERNEL1x5_SUM(4, 0);
|
||||||
|
MM_KERNEL1x5_SUM(0, 1);
|
||||||
|
MM_KERNEL1x5_SUM(1, 2);
|
||||||
|
MM_KERNEL1x5_SUM(2, 3);
|
||||||
|
MM_KERNEL1x5_LOAD(3, x+6);
|
||||||
|
MM_KERNEL1x5_SUM(3, 4);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
out[x+4] = _mm_cvtsi128_si32(ssi0);
|
||||||
|
}
|
||||||
|
for (; x < im->xsize-2; x++) {
|
||||||
|
__m128 ss = _mm_set1_ps(offset);
|
||||||
|
__m128i ssi0;
|
||||||
|
MM_KERNEL1x5_LOAD(0, x-2);
|
||||||
|
MM_KERNEL1x5_SUM(0, 0);
|
||||||
|
MM_KERNEL1x5_LOAD(0, x-1);
|
||||||
|
MM_KERNEL1x5_SUM(0, 1);
|
||||||
|
MM_KERNEL1x5_LOAD(0, x+0);
|
||||||
|
MM_KERNEL1x5_SUM(0, 2);
|
||||||
|
MM_KERNEL1x5_LOAD(0, x+1);
|
||||||
|
MM_KERNEL1x5_SUM(0, 3);
|
||||||
|
MM_KERNEL1x5_LOAD(0, x+2);
|
||||||
|
MM_KERNEL1x5_SUM(0, 4);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
out[x] = _mm_cvtsi128_si32(ssi0);
|
||||||
|
}
|
||||||
|
out[x] = in0[x];
|
||||||
|
out[x+1] = in0[x+1];
|
||||||
|
}
|
||||||
|
memcpy(imOut->image32[y], im->image32[y], im->linesize);
|
||||||
|
memcpy(imOut->image32[y+1], im->image32[y+1], im->linesize);
|
||||||
|
|
||||||
|
#undef MM_KERNEL1x5_LOAD
|
||||||
|
#undef MM_KERNEL1x5_SUM
|
||||||
|
}
|
101
libImaging/FilterSIMD_5x5f_u8.c
Normal file
101
libImaging/FilterSIMD_5x5f_u8.c
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
void
|
||||||
|
ImagingFilter5x5f_u8(Imaging imOut, Imaging im, const float* kernel,
|
||||||
|
float offset)
|
||||||
|
{
|
||||||
|
#define MM_KERNEL1x5_LOAD(row, x) \
|
||||||
|
pix0##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in2[x])); \
|
||||||
|
pix1##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in1[x])); \
|
||||||
|
pix2##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in0[x])); \
|
||||||
|
pix3##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in_1[x])); \
|
||||||
|
pix4##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in_2[x]));
|
||||||
|
|
||||||
|
#define MM_KERNEL1x5_SUM(ss, row, krow) \
|
||||||
|
ss = _mm_setzero_ps(); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix0##row, kernel0##krow)); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix1##row, kernel1##krow)); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix2##row, kernel2##krow)); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix3##row, kernel3##krow)); \
|
||||||
|
ss = _mm_add_ps(ss, _mm_mul_ps(pix4##row, kernel4##krow));
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
memcpy(imOut->image8[0], im->image8[0], im->linesize);
|
||||||
|
memcpy(imOut->image8[1], im->image8[1], im->linesize);
|
||||||
|
for (y = 2; y < im->ysize-2; y++) {
|
||||||
|
UINT8* in_2 = im->image8[y-2];
|
||||||
|
UINT8* in_1 = im->image8[y-1];
|
||||||
|
UINT8* in0 = im->image8[y];
|
||||||
|
UINT8* in1 = im->image8[y+1];
|
||||||
|
UINT8* in2 = im->image8[y+2];
|
||||||
|
UINT8* out = imOut->image8[y];
|
||||||
|
__m128 kernelx0 = _mm_set_ps(kernel[15], kernel[10], kernel[5], kernel[0]);
|
||||||
|
__m128 kernel00 = _mm_loadu_ps(&kernel[0+1]);
|
||||||
|
__m128 kernel10 = _mm_loadu_ps(&kernel[5+1]);
|
||||||
|
__m128 kernel20 = _mm_loadu_ps(&kernel[10+1]);
|
||||||
|
__m128 kernel30 = _mm_loadu_ps(&kernel[15+1]);
|
||||||
|
__m128 kernel40 = _mm_loadu_ps(&kernel[20+1]);
|
||||||
|
__m128 kernelx1 = _mm_set_ps(kernel[19], kernel[14], kernel[9], kernel[4]);
|
||||||
|
__m128 kernel01 = _mm_loadu_ps(&kernel[0+0]);
|
||||||
|
__m128 kernel11 = _mm_loadu_ps(&kernel[5+0]);
|
||||||
|
__m128 kernel21 = _mm_loadu_ps(&kernel[10+0]);
|
||||||
|
__m128 kernel31 = _mm_loadu_ps(&kernel[15+0]);
|
||||||
|
__m128 kernel41 = _mm_loadu_ps(&kernel[20+0]);
|
||||||
|
|
||||||
|
out[0] = in0[0];
|
||||||
|
out[1] = in0[1];
|
||||||
|
x = 2;
|
||||||
|
for (; x < im->xsize-2-1; x += 2) {
|
||||||
|
__m128 ss0, ss1;
|
||||||
|
__m128i ssi0;
|
||||||
|
__m128 pix00, pix10, pix20, pix30, pix40;
|
||||||
|
|
||||||
|
MM_KERNEL1x5_LOAD(0, x-1);
|
||||||
|
MM_KERNEL1x5_SUM(ss0, 0, 0);
|
||||||
|
ss0 = _mm_add_ps(ss0, _mm_mul_ps(
|
||||||
|
_mm_set_ps(in_1[x-2], in0[x-2], in1[x-2], in2[x-2]),
|
||||||
|
kernelx0));
|
||||||
|
|
||||||
|
MM_KERNEL1x5_SUM(ss1, 0, 1);
|
||||||
|
ss1 = _mm_add_ps(ss1, _mm_mul_ps(
|
||||||
|
_mm_set_ps(in_1[x+3], in0[x+3], in1[x+3], in2[x+3]),
|
||||||
|
kernelx1));
|
||||||
|
|
||||||
|
ss0 = _mm_hadd_ps(ss0, ss1);
|
||||||
|
ss0 = _mm_add_ps(ss0, _mm_set_ps(
|
||||||
|
offset, kernel[24] * in_2[x+3],
|
||||||
|
offset, kernel[20] * in_2[x-2]));
|
||||||
|
ss0 = _mm_hadd_ps(ss0, ss0);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss0);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
*((UINT32*) &out[x]) = _mm_cvtsi128_si32(ssi0);
|
||||||
|
}
|
||||||
|
for (; x < im->xsize-2; x ++) {
|
||||||
|
__m128 ss0;
|
||||||
|
__m128i ssi0;
|
||||||
|
__m128 pix00, pix10, pix20, pix30, pix40;
|
||||||
|
|
||||||
|
MM_KERNEL1x5_LOAD(0, x-2);
|
||||||
|
MM_KERNEL1x5_SUM(ss0, 0, 1);
|
||||||
|
ss0 = _mm_add_ps(ss0, _mm_mul_ps(
|
||||||
|
_mm_set_ps(in_1[x+2], in0[x+2], in1[x+2], in2[x+2]),
|
||||||
|
kernelx1));
|
||||||
|
|
||||||
|
ss0 = _mm_add_ps(ss0, _mm_set_ps(
|
||||||
|
0, 0, offset, kernel[24] * in_2[x+2]));
|
||||||
|
ss0 = _mm_hadd_ps(ss0, ss0);
|
||||||
|
ss0 = _mm_hadd_ps(ss0, ss0);
|
||||||
|
ssi0 = _mm_cvtps_epi32(ss0);
|
||||||
|
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
||||||
|
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
||||||
|
out[x] = _mm_cvtsi128_si32(ssi0);
|
||||||
|
}
|
||||||
|
out[x+0] = in0[x+0];
|
||||||
|
out[x+1] = in0[x+1];
|
||||||
|
}
|
||||||
|
memcpy(imOut->image8[y], im->image8[y], im->linesize);
|
||||||
|
memcpy(imOut->image8[y+1], im->image8[y+1], im->linesize);
|
||||||
|
|
||||||
|
#undef MM_KERNEL1x5_LOAD
|
||||||
|
#undef MM_KERNEL1x5_SUM
|
||||||
|
}
|
|
@ -34,6 +34,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "FilterSIMD_3x3f_u8.c"
|
||||||
|
#include "FilterSIMD_3x3f_4u8.c"
|
||||||
|
#include "FilterSIMD_5x5f_u8.c"
|
||||||
|
#include "FilterSIMD_5x5f_4u8.c"
|
||||||
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode) {
|
ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode) {
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
|
@ -90,573 +96,6 @@ ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode) {
|
||||||
return imOut;
|
return imOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ImagingFilter3x3(Imaging imOut, Imaging im, const float* kernel,
|
|
||||||
float offset)
|
|
||||||
{
|
|
||||||
#define MM_KERNEL1x3_SUM1(ss, row, kernel) \
|
|
||||||
ss = _mm_set1_ps(offset); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix0##row, kernel0##kernel)); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix1##row, kernel1##kernel)); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix2##row, kernel2##kernel));
|
|
||||||
|
|
||||||
#define MM_KERNEL1x3_SUM1_2(ss, row, kernel) \
|
|
||||||
ss = _mm_set1_ps(offset); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix3##row, kernel0##kernel)); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix0##row, kernel1##kernel)); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix1##row, kernel2##kernel));
|
|
||||||
|
|
||||||
#define MM_KERNEL1x3_LOAD(row, x) \
|
|
||||||
pix0##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in1[x])); \
|
|
||||||
pix1##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in0[x])); \
|
|
||||||
pix2##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in_1[x]));
|
|
||||||
|
|
||||||
#define MM_KERNEL1x3_SUM(row, kindex) \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix0##row, _mm_set1_ps(kernel[0 + kindex]))); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix1##row, _mm_set1_ps(kernel[3 + kindex]))); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix2##row, _mm_set1_ps(kernel[6 + kindex])));
|
|
||||||
|
|
||||||
int x = 0, y = 0;
|
|
||||||
|
|
||||||
memcpy(imOut->image[0], im->image[0], im->linesize);
|
|
||||||
if (im->bands == 1) {
|
|
||||||
__m128 kernel00 = _mm_set_ps(0, kernel[2], kernel[1], kernel[0]);
|
|
||||||
__m128 kernel10 = _mm_set_ps(0, kernel[5], kernel[4], kernel[3]);
|
|
||||||
__m128 kernel20 = _mm_set_ps(0, kernel[8], kernel[7], kernel[6]);
|
|
||||||
__m128 kernel01 = _mm_set_ps(kernel[2], kernel[1], kernel[0], 0);
|
|
||||||
__m128 kernel11 = _mm_set_ps(kernel[5], kernel[4], kernel[3], 0);
|
|
||||||
__m128 kernel21 = _mm_set_ps(kernel[8], kernel[7], kernel[6], 0);
|
|
||||||
y = 1;
|
|
||||||
for (; y < im->ysize-1-1; y += 2) {
|
|
||||||
UINT8* in_1 = (UINT8*) im->image[y-1];
|
|
||||||
UINT8* in0 = (UINT8*) im->image[y];
|
|
||||||
UINT8* in1 = (UINT8*) im->image[y+1];
|
|
||||||
UINT8* in2 = (UINT8*) im->image[y+2];
|
|
||||||
UINT8* out0 = (UINT8*) imOut->image[y];
|
|
||||||
UINT8* out1 = (UINT8*) imOut->image[y+1];
|
|
||||||
|
|
||||||
out0[0] = in0[0];
|
|
||||||
out1[0] = in1[0];
|
|
||||||
x = 1;
|
|
||||||
for (; x < im->xsize-1-3; x += 4) {
|
|
||||||
__m128 ss0, ss1, ss2, ss3, ss4, ss5;
|
|
||||||
__m128 pix00, pix10, pix20, pix30;
|
|
||||||
__m128i ssi0;
|
|
||||||
|
|
||||||
MM_KERNEL1x3_LOAD(0, x-1);
|
|
||||||
MM_KERNEL1x3_SUM1(ss0, 0, 0);
|
|
||||||
MM_KERNEL1x3_SUM1(ss1, 0, 1);
|
|
||||||
ss0 = _mm_hadd_ps(ss0, ss1);
|
|
||||||
pix30 = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in2[x-1]));
|
|
||||||
MM_KERNEL1x3_SUM1_2(ss3, 0, 0);
|
|
||||||
MM_KERNEL1x3_SUM1_2(ss4, 0, 1);
|
|
||||||
ss3 = _mm_hadd_ps(ss3, ss4);
|
|
||||||
|
|
||||||
MM_KERNEL1x3_LOAD(0, x+1);
|
|
||||||
MM_KERNEL1x3_SUM1(ss1, 0, 0);
|
|
||||||
MM_KERNEL1x3_SUM1(ss2, 0, 1);
|
|
||||||
ss1 = _mm_hadd_ps(ss1, ss2);
|
|
||||||
pix30 = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in2[x+1]));
|
|
||||||
MM_KERNEL1x3_SUM1_2(ss4, 0, 0);
|
|
||||||
MM_KERNEL1x3_SUM1_2(ss5, 0, 1);
|
|
||||||
ss4 = _mm_hadd_ps(ss4, ss5);
|
|
||||||
|
|
||||||
ss0 = _mm_hadd_ps(ss0, ss1);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss0);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
*((UINT32*) &out0[x]) = _mm_cvtsi128_si32(ssi0);
|
|
||||||
|
|
||||||
ss3 = _mm_hadd_ps(ss3, ss4);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss3);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
*((UINT32*) &out1[x]) = _mm_cvtsi128_si32(ssi0);
|
|
||||||
}
|
|
||||||
for (; x < im->xsize-1; x++) {
|
|
||||||
__m128 ss0, ss1;
|
|
||||||
__m128 pix00, pix10, pix20, pix30;
|
|
||||||
__m128i ssi0;
|
|
||||||
|
|
||||||
MM_KERNEL1x3_LOAD(0, x-1);
|
|
||||||
MM_KERNEL1x3_SUM1(ss0, 0, 0);
|
|
||||||
pix30 = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in2[x-1]));
|
|
||||||
MM_KERNEL1x3_SUM1_2(ss1, 0, 0);
|
|
||||||
|
|
||||||
ss0 = _mm_hadd_ps(ss0, ss0);
|
|
||||||
ss0 = _mm_hadd_ps(ss0, ss0);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss0);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
out0[x] = _mm_cvtsi128_si32(ssi0);
|
|
||||||
|
|
||||||
ss1 = _mm_hadd_ps(ss1, ss1);
|
|
||||||
ss1 = _mm_hadd_ps(ss1, ss1);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss1);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
out1[x] = _mm_cvtsi128_si32(ssi0);
|
|
||||||
}
|
|
||||||
out0[x] = in0[x];
|
|
||||||
out1[x] = in1[x];
|
|
||||||
}
|
|
||||||
for (; y < im->ysize-1; y++) {
|
|
||||||
UINT8* in_1 = (UINT8*) im->image[y-1];
|
|
||||||
UINT8* in0 = (UINT8*) im->image[y];
|
|
||||||
UINT8* in1 = (UINT8*) im->image[y+1];
|
|
||||||
UINT8* out = (UINT8*) imOut->image[y];
|
|
||||||
|
|
||||||
out[0] = in0[0];
|
|
||||||
x = 1;
|
|
||||||
for (; x < im->xsize-1; x++) {
|
|
||||||
__m128 ss;
|
|
||||||
__m128 pix00, pix10, pix20;
|
|
||||||
__m128i ssi0;
|
|
||||||
|
|
||||||
MM_KERNEL1x3_LOAD(0, x-1);
|
|
||||||
MM_KERNEL1x3_SUM1(ss, 0, 0);
|
|
||||||
|
|
||||||
ss = _mm_hadd_ps(ss, ss);
|
|
||||||
ss = _mm_hadd_ps(ss, ss);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
out[x] = _mm_cvtsi128_si32(ssi0);
|
|
||||||
}
|
|
||||||
out[x] = in0[x];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (y = 1; y < im->ysize-1; y++) {
|
|
||||||
UINT32* in_1 = (UINT32*) im->image[y-1];
|
|
||||||
UINT32* in0 = (UINT32*) im->image[y];
|
|
||||||
UINT32* in1 = (UINT32*) im->image[y+1];
|
|
||||||
UINT32* out = (UINT32*) imOut->image[y];
|
|
||||||
#if defined(__AVX2__)
|
|
||||||
|
|
||||||
#define MM256_LOAD(row, x) \
|
|
||||||
pix0##row = _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(*(__m128i*) &in1[x])); \
|
|
||||||
pix1##row = _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(*(__m128i*) &in0[x])); \
|
|
||||||
pix2##row = _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(*(__m128i*) &in_1[x]));
|
|
||||||
|
|
||||||
#define MM256_SUM(pixrow, kernelrow) \
|
|
||||||
ss = _mm256_add_ps(ss, _mm256_mul_ps(pix0##pixrow, kernel0##kernelrow)); \
|
|
||||||
ss = _mm256_add_ps(ss, _mm256_mul_ps(pix1##pixrow, kernel1##kernelrow)); \
|
|
||||||
ss = _mm256_add_ps(ss, _mm256_mul_ps(pix2##pixrow, kernel2##kernelrow));
|
|
||||||
|
|
||||||
#define MM256_PERMUTE(row, from0, from1, control) \
|
|
||||||
pix0##row = _mm256_permute2f128_ps(pix0##from0, pix0##from1, control); \
|
|
||||||
pix1##row = _mm256_permute2f128_ps(pix1##from0, pix1##from1, control); \
|
|
||||||
pix2##row = _mm256_permute2f128_ps(pix2##from0, pix2##from1, control);
|
|
||||||
|
|
||||||
#define MM256_OUT(x) \
|
|
||||||
_mm_cvtps_epi32(_mm_add_ps( \
|
|
||||||
_mm256_extractf128_ps(ss, 0), \
|
|
||||||
_mm256_extractf128_ps(ss, 1) \
|
|
||||||
))
|
|
||||||
|
|
||||||
__m256 kernel00 = _mm256_insertf128_ps(
|
|
||||||
_mm256_set1_ps(kernel[0+0]),
|
|
||||||
_mm_set1_ps(kernel[0+1]), 1);
|
|
||||||
__m256 kernel01 = _mm256_castps128_ps256(_mm_set1_ps(kernel[0+2]));
|
|
||||||
__m256 kernel10 = _mm256_insertf128_ps(
|
|
||||||
_mm256_set1_ps(kernel[3+0]),
|
|
||||||
_mm_set1_ps(kernel[3+1]), 1);
|
|
||||||
__m256 kernel11 = _mm256_castps128_ps256(_mm_set1_ps(kernel[3+2]));
|
|
||||||
__m256 kernel20 = _mm256_insertf128_ps(
|
|
||||||
_mm256_set1_ps(kernel[6+0]),
|
|
||||||
_mm_set1_ps(kernel[6+1]), 1);
|
|
||||||
__m256 kernel21 = _mm256_castps128_ps256(_mm_set1_ps(kernel[6+2]));
|
|
||||||
__m256 pix00, pix10, pix20;
|
|
||||||
__m256 pix01, pix11, pix21;
|
|
||||||
__m256 pix02, pix12, pix22;
|
|
||||||
|
|
||||||
out[0] = in0[0];
|
|
||||||
x = 1;
|
|
||||||
MM256_LOAD(0, 0);
|
|
||||||
for (; x < im->xsize-1-7; x += 8) {
|
|
||||||
__m256 ss;
|
|
||||||
__m128i ssi0, ssi1, ssi2, ssi3;
|
|
||||||
|
|
||||||
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
|
||||||
MM256_SUM(0, 0);
|
|
||||||
MM256_LOAD(1, x+1);
|
|
||||||
MM256_SUM(1, 1);
|
|
||||||
ssi0 = MM256_OUT(x);
|
|
||||||
|
|
||||||
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
|
||||||
MM256_SUM(1, 0);
|
|
||||||
MM256_LOAD(2, x+3);
|
|
||||||
MM256_SUM(2, 1);
|
|
||||||
ssi2 = MM256_OUT(x+2);
|
|
||||||
|
|
||||||
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
|
||||||
MM256_PERMUTE(0, 0, 1, 0x21);
|
|
||||||
MM256_SUM(0, 0);
|
|
||||||
MM256_PERMUTE(1, 1, 2, 0x21);
|
|
||||||
MM256_SUM(1, 1);
|
|
||||||
ssi1 = MM256_OUT(x+1);
|
|
||||||
|
|
||||||
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
|
||||||
MM256_SUM(1, 0);
|
|
||||||
MM256_PERMUTE(0, 2, 2, 0x21);
|
|
||||||
MM256_SUM(0, 1);
|
|
||||||
ssi3 = MM256_OUT(x+3);
|
|
||||||
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi1);
|
|
||||||
ssi2 = _mm_packs_epi32(ssi2, ssi3);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi2);
|
|
||||||
_mm_storeu_si128((__m128i*) &out[x], ssi0);
|
|
||||||
|
|
||||||
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
|
||||||
MM256_SUM(2, 0);
|
|
||||||
MM256_LOAD(1, x+5);
|
|
||||||
MM256_SUM(1, 1);
|
|
||||||
ssi0 = MM256_OUT(x+4);
|
|
||||||
|
|
||||||
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
|
||||||
MM256_SUM(1, 0);
|
|
||||||
MM256_LOAD(0, x+7);
|
|
||||||
MM256_SUM(0, 1);
|
|
||||||
ssi2 = MM256_OUT(x+6);
|
|
||||||
|
|
||||||
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
|
||||||
MM256_PERMUTE(2, 2, 1, 0x21);
|
|
||||||
MM256_SUM(2, 0);
|
|
||||||
MM256_PERMUTE(1, 1, 0, 0x21);
|
|
||||||
MM256_SUM(1, 1);
|
|
||||||
ssi1 = MM256_OUT(x+5);
|
|
||||||
|
|
||||||
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
|
||||||
MM256_SUM(1, 0);
|
|
||||||
MM256_PERMUTE(2, 0, 0, 0x21);
|
|
||||||
MM256_SUM(2, 1);
|
|
||||||
ssi3 = MM256_OUT(x+7);
|
|
||||||
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi1);
|
|
||||||
ssi2 = _mm_packs_epi32(ssi2, ssi3);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi2);
|
|
||||||
_mm_storeu_si128((__m128i*) &out[x+4], ssi0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; x < im->xsize-1-1; x += 2) {
|
|
||||||
__m256 ss;
|
|
||||||
__m128i ssi0, ssi1;
|
|
||||||
|
|
||||||
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
|
||||||
MM256_SUM(0, 0);
|
|
||||||
MM256_LOAD(1, x+1);
|
|
||||||
MM256_SUM(1, 1);
|
|
||||||
ssi0 = MM256_OUT(x);
|
|
||||||
|
|
||||||
ss = _mm256_castps128_ps256(_mm_set1_ps(offset));
|
|
||||||
MM256_PERMUTE(0, 0, 1, 0x21);
|
|
||||||
MM256_SUM(0, 0);
|
|
||||||
MM256_PERMUTE(1, 0, 1, 0xf3);
|
|
||||||
MM256_SUM(1, 1);
|
|
||||||
ssi1 = MM256_OUT(x+1);
|
|
||||||
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi1);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
_mm_storel_epi64((__m128i*) &out[x], ssi0);
|
|
||||||
|
|
||||||
MM256_PERMUTE(0, 0, 1, 0x21);
|
|
||||||
}
|
|
||||||
for (; x < im->xsize-1; x++) {
|
|
||||||
__m128 pix00, pix10, pix20;
|
|
||||||
__m128 ss = _mm_set1_ps(offset);
|
|
||||||
__m128i ssi0;
|
|
||||||
MM_KERNEL1x3_LOAD(0, x-1);
|
|
||||||
MM_KERNEL1x3_SUM(0, 0);
|
|
||||||
MM_KERNEL1x3_LOAD(0, x+0);
|
|
||||||
MM_KERNEL1x3_SUM(0, 1);
|
|
||||||
MM_KERNEL1x3_LOAD(0, x+1);
|
|
||||||
MM_KERNEL1x3_SUM(0, 2);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
out[x] = _mm_cvtsi128_si32(ssi0);
|
|
||||||
}
|
|
||||||
out[x] = in0[x];
|
|
||||||
#else
|
|
||||||
__m128 pix00, pix10, pix20;
|
|
||||||
__m128 pix01, pix11, pix21;
|
|
||||||
__m128 pix02, pix12, pix22;
|
|
||||||
MM_KERNEL1x3_LOAD(0, 0);
|
|
||||||
MM_KERNEL1x3_LOAD(1, 1);
|
|
||||||
|
|
||||||
out[0] = in0[0];
|
|
||||||
x = 1;
|
|
||||||
for (; x < im->xsize-1-2; x += 3) {
|
|
||||||
__m128 ss;
|
|
||||||
__m128i ssi0, ssi1, ssi2;
|
|
||||||
|
|
||||||
ss = _mm_set1_ps(offset);
|
|
||||||
MM_KERNEL1x3_SUM(0, 0);
|
|
||||||
MM_KERNEL1x3_SUM(1, 1);
|
|
||||||
MM_KERNEL1x3_LOAD(2, x+1);
|
|
||||||
MM_KERNEL1x3_SUM(2, 2);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss);
|
|
||||||
|
|
||||||
ss = _mm_set1_ps(offset);
|
|
||||||
MM_KERNEL1x3_SUM(1, 0);
|
|
||||||
MM_KERNEL1x3_SUM(2, 1);
|
|
||||||
MM_KERNEL1x3_LOAD(0, x+2);
|
|
||||||
MM_KERNEL1x3_SUM(0, 2);
|
|
||||||
ssi1 = _mm_cvtps_epi32(ss);
|
|
||||||
|
|
||||||
ss = _mm_set1_ps(offset);
|
|
||||||
MM_KERNEL1x3_SUM(2, 0);
|
|
||||||
MM_KERNEL1x3_SUM(0, 1);
|
|
||||||
MM_KERNEL1x3_LOAD(1, x+3);
|
|
||||||
MM_KERNEL1x3_SUM(1, 2);
|
|
||||||
ssi2 = _mm_cvtps_epi32(ss);
|
|
||||||
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi1);
|
|
||||||
ssi1 = _mm_packs_epi32(ssi2, ssi2);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi1);
|
|
||||||
_mm_storeu_si128((__m128i*) &out[x], ssi0);
|
|
||||||
}
|
|
||||||
for (; x < im->xsize-1; x++) {
|
|
||||||
__m128 ss = _mm_set1_ps(offset);
|
|
||||||
__m128i ssi0;
|
|
||||||
MM_KERNEL1x3_LOAD(0, x-1);
|
|
||||||
MM_KERNEL1x3_SUM(0, 0);
|
|
||||||
MM_KERNEL1x3_LOAD(0, x+0);
|
|
||||||
MM_KERNEL1x3_SUM(0, 1);
|
|
||||||
MM_KERNEL1x3_LOAD(0, x+1);
|
|
||||||
MM_KERNEL1x3_SUM(0, 2);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
out[x] = _mm_cvtsi128_si32(ssi0);
|
|
||||||
}
|
|
||||||
out[x] = in0[x];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memcpy(imOut->image[y], im->image[y], im->linesize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ImagingFilter5x5(Imaging imOut, Imaging im, const float *kernel, float offset) {
|
|
||||||
#define KERNEL1x5(in0, x, kernel, d) \
|
|
||||||
(_i2f((UINT8)in0[x - d - d]) * (kernel)[0] + \
|
|
||||||
_i2f((UINT8)in0[x - d]) * (kernel)[1] + _i2f((UINT8)in0[x]) * (kernel)[2] + \
|
|
||||||
_i2f((UINT8)in0[x + d]) * (kernel)[3] + \
|
|
||||||
_i2f((UINT8)in0[x + d + d]) * (kernel)[4])
|
|
||||||
|
|
||||||
#define MM_KERNEL1x5_LOAD(row, x) \
|
|
||||||
pix0##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in2[x])); \
|
|
||||||
pix1##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in1[x])); \
|
|
||||||
pix2##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in0[x])); \
|
|
||||||
pix3##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in_1[x])); \
|
|
||||||
pix4##row = _mm_cvtepi32_ps(_mm_cvtepu8_epi32(*(__m128i*) &in_2[x]));
|
|
||||||
|
|
||||||
#define MM_KERNEL1x5_SUM(row, kindex) \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix0##row, _mm_set1_ps(kernel[0 + kindex]))); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix1##row, _mm_set1_ps(kernel[5 + kindex]))); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix2##row, _mm_set1_ps(kernel[10 + kindex]))); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix3##row, _mm_set1_ps(kernel[15 + kindex]))); \
|
|
||||||
ss = _mm_add_ps(ss, _mm_mul_ps(pix4##row, _mm_set1_ps(kernel[20 + kindex])));
|
|
||||||
|
|
||||||
int x = 0, y = 0;
|
|
||||||
|
|
||||||
memcpy(imOut->image[0], im->image[0], im->linesize);
|
|
||||||
memcpy(imOut->image[1], im->image[1], im->linesize);
|
|
||||||
if (im->bands == 1) {
|
|
||||||
for (y = 2; y < im->ysize-2; y++) {
|
|
||||||
UINT8* in_2 = (UINT8*) im->image[y-2];
|
|
||||||
UINT8* in_1 = (UINT8*) im->image[y-1];
|
|
||||||
UINT8* in0 = (UINT8*) im->image[y];
|
|
||||||
UINT8* in1 = (UINT8*) im->image[y+1];
|
|
||||||
UINT8* in2 = (UINT8*) im->image[y+2];
|
|
||||||
UINT8* out = (UINT8*) imOut->image[y];
|
|
||||||
__m128 kernelx0 = _mm_set_ps(kernel[15], kernel[10], kernel[5], kernel[0]);
|
|
||||||
__m128 kernel00 = _mm_loadu_ps(&kernel[0+1]);
|
|
||||||
__m128 kernel10 = _mm_loadu_ps(&kernel[5+1]);
|
|
||||||
__m128 kernel20 = _mm_loadu_ps(&kernel[10+1]);
|
|
||||||
__m128 kernel30 = _mm_loadu_ps(&kernel[15+1]);
|
|
||||||
__m128 kernel40 = _mm_loadu_ps(&kernel[20+1]);
|
|
||||||
__m128 kernelx1 = _mm_set_ps(kernel[19], kernel[14], kernel[9], kernel[4]);
|
|
||||||
__m128 kernel01 = _mm_loadu_ps(&kernel[0+0]);
|
|
||||||
__m128 kernel11 = _mm_loadu_ps(&kernel[5+0]);
|
|
||||||
__m128 kernel21 = _mm_loadu_ps(&kernel[10+0]);
|
|
||||||
__m128 kernel31 = _mm_loadu_ps(&kernel[15+0]);
|
|
||||||
__m128 kernel41 = _mm_loadu_ps(&kernel[20+0]);
|
|
||||||
|
|
||||||
out[0] = in0[0];
|
|
||||||
out[1] = in0[1];
|
|
||||||
x = 2;
|
|
||||||
for (; x < im->xsize-2-1; x += 2) {
|
|
||||||
__m128 ss0, ss1;
|
|
||||||
__m128i ssi0;
|
|
||||||
__m128 pix00, pix10, pix20, pix30, pix40;
|
|
||||||
|
|
||||||
MM_KERNEL1x5_LOAD(0, x-1);
|
|
||||||
|
|
||||||
ss0 = _mm_setzero_ps();
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(pix00, kernel00));
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(pix10, kernel10));
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(pix20, kernel20));
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(pix30, kernel30));
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(pix40, kernel40));
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(
|
|
||||||
_mm_set_ps(in_1[x-2], in0[x-2], in1[x-2], in2[x-2]),
|
|
||||||
kernelx0));
|
|
||||||
|
|
||||||
ss1 = _mm_setzero_ps();
|
|
||||||
ss1 = _mm_add_ps(ss1, _mm_mul_ps(pix00, kernel01));
|
|
||||||
ss1 = _mm_add_ps(ss1, _mm_mul_ps(pix10, kernel11));
|
|
||||||
ss1 = _mm_add_ps(ss1, _mm_mul_ps(pix20, kernel21));
|
|
||||||
ss1 = _mm_add_ps(ss1, _mm_mul_ps(pix30, kernel31));
|
|
||||||
ss1 = _mm_add_ps(ss1, _mm_mul_ps(pix40, kernel41));
|
|
||||||
ss1 = _mm_add_ps(ss1, _mm_mul_ps(
|
|
||||||
_mm_set_ps(in_1[x+3], in0[x+3], in1[x+3], in2[x+3]),
|
|
||||||
kernelx1));
|
|
||||||
|
|
||||||
ss0 = _mm_hadd_ps(ss0, ss1);
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_set_ps(
|
|
||||||
offset, kernel[24] * in_2[x+3],
|
|
||||||
offset, kernel[20] * in_2[x-2]));
|
|
||||||
ss0 = _mm_hadd_ps(ss0, ss0);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss0);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
*((UINT32*) &out[x]) = _mm_cvtsi128_si32(ssi0);
|
|
||||||
}
|
|
||||||
for (; x < im->xsize-2; x ++) {
|
|
||||||
__m128 ss0;
|
|
||||||
__m128i ssi0;
|
|
||||||
__m128 pix00, pix10, pix20, pix30, pix40;
|
|
||||||
|
|
||||||
MM_KERNEL1x5_LOAD(0, x-2);
|
|
||||||
|
|
||||||
ss0 = _mm_setzero_ps();
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(pix00, kernel01));
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(pix10, kernel11));
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(pix20, kernel21));
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(pix30, kernel31));
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(pix40, kernel41));
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_mul_ps(
|
|
||||||
_mm_set_ps(in_1[x+2], in0[x+2], in1[x+2], in2[x+2]),
|
|
||||||
kernelx1));
|
|
||||||
|
|
||||||
ss0 = _mm_add_ps(ss0, _mm_set_ps(
|
|
||||||
0, 0, offset, kernel[24] * in_2[x+2]));
|
|
||||||
ss0 = _mm_hadd_ps(ss0, ss0);
|
|
||||||
ss0 = _mm_hadd_ps(ss0, ss0);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss0);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
out[x] = _mm_cvtsi128_si32(ssi0);
|
|
||||||
}
|
|
||||||
out[x + 0] = in0[x + 0];
|
|
||||||
out[x + 1] = in0[x + 1];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (y = 2; y < im->ysize-2; y++) {
|
|
||||||
UINT32* in_2 = (UINT32*) im->image[y-2];
|
|
||||||
UINT32* in_1 = (UINT32*) im->image[y-1];
|
|
||||||
UINT32* in0 = (UINT32*) im->image[y];
|
|
||||||
UINT32* in1 = (UINT32*) im->image[y+1];
|
|
||||||
UINT32* in2 = (UINT32*) im->image[y+2];
|
|
||||||
UINT32* out = (UINT32*) imOut->image[y];
|
|
||||||
__m128 pix00, pix10, pix20, pix30, pix40;
|
|
||||||
__m128 pix01, pix11, pix21, pix31, pix41;
|
|
||||||
__m128 pix02, pix12, pix22, pix32, pix42;
|
|
||||||
__m128 pix03, pix13, pix23, pix33, pix43;
|
|
||||||
__m128 pix04, pix14, pix24, pix34, pix44;
|
|
||||||
MM_KERNEL1x5_LOAD(0, 0);
|
|
||||||
MM_KERNEL1x5_LOAD(1, 1);
|
|
||||||
MM_KERNEL1x5_LOAD(2, 2);
|
|
||||||
MM_KERNEL1x5_LOAD(3, 3);
|
|
||||||
|
|
||||||
out[0] = in0[0];
|
|
||||||
out[1] = in0[1];
|
|
||||||
x = 2;
|
|
||||||
for (; x < im->xsize-2-4; x += 5) {
|
|
||||||
__m128 ss;
|
|
||||||
__m128i ssi0, ssi1, ssi2, ssi3;
|
|
||||||
|
|
||||||
ss = _mm_set1_ps(offset);
|
|
||||||
MM_KERNEL1x5_SUM(0, 0);
|
|
||||||
MM_KERNEL1x5_SUM(1, 1);
|
|
||||||
MM_KERNEL1x5_SUM(2, 2);
|
|
||||||
MM_KERNEL1x5_SUM(3, 3);
|
|
||||||
MM_KERNEL1x5_LOAD(4, x+2);
|
|
||||||
MM_KERNEL1x5_SUM(4, 4);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss);
|
|
||||||
|
|
||||||
ss = _mm_set1_ps(offset);
|
|
||||||
MM_KERNEL1x5_SUM(1, 0);
|
|
||||||
MM_KERNEL1x5_SUM(2, 1);
|
|
||||||
MM_KERNEL1x5_SUM(3, 2);
|
|
||||||
MM_KERNEL1x5_SUM(4, 3);
|
|
||||||
MM_KERNEL1x5_LOAD(0, x+3);
|
|
||||||
MM_KERNEL1x5_SUM(0, 4);
|
|
||||||
ssi1 = _mm_cvtps_epi32(ss);
|
|
||||||
|
|
||||||
ss = _mm_set1_ps(offset);
|
|
||||||
MM_KERNEL1x5_SUM(2, 0);
|
|
||||||
MM_KERNEL1x5_SUM(3, 1);
|
|
||||||
MM_KERNEL1x5_SUM(4, 2);
|
|
||||||
MM_KERNEL1x5_SUM(0, 3);
|
|
||||||
MM_KERNEL1x5_LOAD(1, x+4);
|
|
||||||
MM_KERNEL1x5_SUM(1, 4);
|
|
||||||
ssi2 = _mm_cvtps_epi32(ss);
|
|
||||||
|
|
||||||
ss = _mm_set1_ps(offset);
|
|
||||||
MM_KERNEL1x5_SUM(3, 0);
|
|
||||||
MM_KERNEL1x5_SUM(4, 1);
|
|
||||||
MM_KERNEL1x5_SUM(0, 2);
|
|
||||||
MM_KERNEL1x5_SUM(1, 3);
|
|
||||||
MM_KERNEL1x5_LOAD(2, x+5);
|
|
||||||
MM_KERNEL1x5_SUM(2, 4);
|
|
||||||
ssi3 = _mm_cvtps_epi32(ss);
|
|
||||||
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi1);
|
|
||||||
ssi1 = _mm_packs_epi32(ssi2, ssi3);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi1);
|
|
||||||
_mm_storeu_si128((__m128i*) &out[x], ssi0);
|
|
||||||
|
|
||||||
ss = _mm_set1_ps(offset);
|
|
||||||
MM_KERNEL1x5_SUM(4, 0);
|
|
||||||
MM_KERNEL1x5_SUM(0, 1);
|
|
||||||
MM_KERNEL1x5_SUM(1, 2);
|
|
||||||
MM_KERNEL1x5_SUM(2, 3);
|
|
||||||
MM_KERNEL1x5_LOAD(3, x+6);
|
|
||||||
MM_KERNEL1x5_SUM(3, 4);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
out[x+4] = _mm_cvtsi128_si32(ssi0);
|
|
||||||
}
|
|
||||||
for (; x < im->xsize-2; x++) {
|
|
||||||
__m128 ss = _mm_set1_ps(offset);
|
|
||||||
__m128i ssi0;
|
|
||||||
MM_KERNEL1x5_LOAD(0, x-2);
|
|
||||||
MM_KERNEL1x5_SUM(0, 0);
|
|
||||||
MM_KERNEL1x5_LOAD(0, x-1);
|
|
||||||
MM_KERNEL1x5_SUM(0, 1);
|
|
||||||
MM_KERNEL1x5_LOAD(0, x+0);
|
|
||||||
MM_KERNEL1x5_SUM(0, 2);
|
|
||||||
MM_KERNEL1x5_LOAD(0, x+1);
|
|
||||||
MM_KERNEL1x5_SUM(0, 3);
|
|
||||||
MM_KERNEL1x5_LOAD(0, x+2);
|
|
||||||
MM_KERNEL1x5_SUM(0, 4);
|
|
||||||
ssi0 = _mm_cvtps_epi32(ss);
|
|
||||||
ssi0 = _mm_packs_epi32(ssi0, ssi0);
|
|
||||||
ssi0 = _mm_packus_epi16(ssi0, ssi0);
|
|
||||||
out[x] = _mm_cvtsi128_si32(ssi0);
|
|
||||||
}
|
|
||||||
out[x] = in0[x];
|
|
||||||
out[x+1] = in0[x+1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memcpy(imOut->image[y], im->image[y], im->linesize);
|
|
||||||
memcpy(imOut->image[y + 1], im->image[y + 1], im->linesize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Imaging
|
Imaging
|
||||||
ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32 *kernel, FLOAT32 offset) {
|
ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32 *kernel, FLOAT32 offset) {
|
||||||
Imaging imOut;
|
Imaging imOut;
|
||||||
|
@ -682,10 +121,18 @@ ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32 *kernel, FLOAT32 o
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
if (xsize == 3) {
|
if (xsize == 3) {
|
||||||
/* 3x3 kernel. */
|
/* 3x3 kernel. */
|
||||||
ImagingFilter3x3(imOut, im, kernel, offset);
|
if (im->image8) {
|
||||||
|
ImagingFilter3x3f_u8(imOut, im, kernel, offset);
|
||||||
|
} else {
|
||||||
|
ImagingFilter3x3f_4u8(imOut, im, kernel, offset);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* 5x5 kernel. */
|
/* 5x5 kernel. */
|
||||||
ImagingFilter5x5(imOut, im, kernel, offset);
|
if (im->image8) {
|
||||||
|
ImagingFilter5x5f_u8(imOut, im, kernel, offset);
|
||||||
|
} else {
|
||||||
|
ImagingFilter5x5f_4u8(imOut, im, kernel, offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
return imOut;
|
return imOut;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user