12 #include <mrpt/config.h> 36 template <
bool MemIsAligned>
44 const __m128i m = _mm_set_epi8(0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff);
47 SSE_RESTORE_SIGN_WARNINGS
49 const int sw =
w / 16;
51 const int rest_w =
w - (16 *
w);
53 for (
int i = 0; i < sh; i++)
55 auto inp =
reinterpret_cast<const __m128i*
>(
in);
57 for (
int j = 0; j < sw; j++)
60 _mm_and_si128(mm_load_si128<MemIsAligned>(inp++), m);
61 auto o =
reinterpret_cast<__m128i*
>(outp);
62 _mm_storel_epi64(o, _mm_packus_epi16(
x,
x));
69 for (
int p = 0;
p < rest_w / 2;
p++)
81 template <
bool MemIsAligned>
89 const __m128i m = _mm_set_epi8(0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff);
92 SSE_RESTORE_SIGN_WARNINGS
94 const int sw =
w / 16;
96 const int rest_w =
w - (16 *
w);
98 for (
int i = 0; i < sh; i++)
100 auto inp =
reinterpret_cast<const __m128i*
>(
in);
101 auto nextRow =
reinterpret_cast<const __m128i*
>(
in + step_in);
104 for (
int j = 0; j < sw; j++)
106 __m128i here = mm_load_si128<MemIsAligned>(inp++);
107 __m128i next = mm_load_si128<MemIsAligned>(nextRow++);
108 here = _mm_avg_epu8(here, next);
109 next = _mm_and_si128(_mm_srli_si128(here, 1), m);
110 here = _mm_and_si128(here, m);
111 here = _mm_avg_epu16(here, next);
113 reinterpret_cast<__m128i*>(outp), _mm_packus_epi16(here, here));
122 for (
int p = 0;
p < rest_w / 2;
p++)
124 *outp++ = (ir[0] + ir[1] + irr[0] + irr[1]) / 4;
149 if (mrpt::system::is_aligned<16>(
in) && mrpt::system::is_aligned<16>(out) &&
150 is_multiple<16>(step_in) && is_multiple<16>(step_out))
152 impl_image_SSE2_scale_half_1c8u<true>(
in, out,
w, h, step_in, step_out);
156 impl_image_SSE2_scale_half_1c8u<false>(
157 in, out,
w, h, step_in, step_out);
174 if (mrpt::system::is_aligned<16>(
in) && mrpt::system::is_aligned<16>(out) &&
175 is_multiple<16>(step_in) && is_multiple<16>(step_out))
177 impl_image_SSE2_scale_half_smooth_1c8u<true>(
178 in, out,
w, h, step_in, step_out);
182 impl_image_SSE2_scale_half_smooth_1c8u<false>(
183 in, out,
w, h, step_in, step_out);
192 #endif // end if MRPT_HAS_SSE2
void image_SSE2_scale_half_smooth_1c8u(const uint8_t *in, uint8_t *out, int w, int h, size_t step_in, size_t step_out)
Average each 2x2 pixels into 1x1 pixel (arithmetic average)
void impl_image_SSE2_scale_half_smooth_1c8u(const uint8_t *in, uint8_t *out, int w, int h, size_t step_in, size_t step_out)
void image_SSE2_scale_half_1c8u(const uint8_t *in, uint8_t *out, int w, int h, size_t step_in, size_t step_out)
Subsample each 2x2 pixel block into 1x1 pixel, taking the first pixel & ignoring the other 3...
GLubyte GLubyte GLubyte GLubyte w
void impl_image_SSE2_scale_half_1c8u(const uint8_t *in, uint8_t *out, int w, int h, size_t step_in, size_t step_out)