39#if defined(OJPH_ARCH_I386) || defined(OJPH_ARCH_X86_64)
57 void sse2_cnvrt_float_to_si32_shftd(
const float *sp,
si32 *dp,
float mul,
60 uint32_t rounding_mode = _MM_GET_ROUNDING_MODE();
61 _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
62 __m128 shift = _mm_set1_ps(0.5f);
63 __m128 m = _mm_set1_ps(mul);
64 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
66 __m128 t = _mm_loadu_ps(sp);
67 __m128 s = _mm_add_ps(t, shift);
69 _mm_storeu_si128((__m128i*)dp, _mm_cvtps_epi32(s));
71 _MM_SET_ROUNDING_MODE(rounding_mode);
75 void sse2_cnvrt_float_to_si32(
const float *sp,
si32 *dp,
float mul,
78 uint32_t rounding_mode = _MM_GET_ROUNDING_MODE();
79 _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
80 __m128 m = _mm_set1_ps(mul);
81 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
83 __m128 t = _mm_loadu_ps(sp);
84 __m128 s = _mm_mul_ps(t, m);
85 _mm_storeu_si128((__m128i*)dp, _mm_cvtps_epi32(s));
87 _MM_SET_ROUNDING_MODE(rounding_mode);
92 __m128i ojph_mm_max_ge_epi32(__m128i a, __m128i b, __m128 x, __m128 y)
94 __m128 ct = _mm_cmpge_ps(x, y);
95 __m128i c = _mm_castps_si128(ct);
96 __m128i d = _mm_and_si128(c, a);
97 __m128i e = _mm_andnot_si128(c, b);
98 return _mm_or_si128(d, e);
103 __m128i ojph_mm_min_lt_epi32(__m128i a, __m128i b, __m128 x, __m128 y)
105 __m128 ct = _mm_cmplt_ps(x, y);
106 __m128i c = _mm_castps_si128(ct);
107 __m128i d = _mm_and_si128(c, a);
108 __m128i e = _mm_andnot_si128(c, b);
109 return _mm_or_si128(d, e);
113 template <
bool NLT_TYPE3>
115 void local_sse2_irv_convert_to_integer(
const line_buf *src_line,
116 line_buf *dst_line,
ui32 dst_line_offset,
117 ui32 bit_depth,
bool is_signed,
ui32 width)
124 assert(bit_depth <= 32);
125 uint32_t rounding_mode = _MM_GET_ROUNDING_MODE();
126 _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
128 const float* sp = src_line->f32;
129 si32* dp = dst_line->i32 + dst_line_offset;
136 si32 neg_limit = (
si32)INT_MIN >> (32 - bit_depth);
137 __m128 mul = _mm_set1_ps((
float)(1ull << bit_depth));
138 __m128 fl_up_lim = _mm_set1_ps(-(
float)neg_limit);
139 __m128 fl_low_lim = _mm_set1_ps((
float)neg_limit);
140 __m128i s32_up_lim = _mm_set1_epi32(INT_MAX >> (32 - bit_depth));
141 __m128i s32_low_lim = _mm_set1_epi32(INT_MIN >> (32 - bit_depth));
145 __m128i zero = _mm_setzero_si128();
146 __m128i bias = _mm_set1_epi32(-(
si32)((1ULL << (bit_depth - 1)) + 1));
147 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
148 __m128 t = _mm_loadu_ps(sp);
149 t = _mm_mul_ps(t, mul);
150 __m128i u = _mm_cvtps_epi32(t);
151 u = ojph_mm_max_ge_epi32(u, s32_low_lim, t, fl_low_lim);
152 u = ojph_mm_min_lt_epi32(u, s32_up_lim, t, fl_up_lim);
155 __m128i c = _mm_cmpgt_epi32(zero, u);
156 __m128i neg = _mm_sub_epi32(bias, u);
157 neg = _mm_and_si128(c, neg);
158 u = _mm_andnot_si128(c, u);
159 u = _mm_or_si128(neg, u);
161 _mm_storeu_si128((__m128i*)dp, u);
166 __m128i half = _mm_set1_epi32((
si32)(1ULL << (bit_depth - 1)));
167 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
168 __m128 t = _mm_loadu_ps(sp);
169 t = _mm_mul_ps(t, mul);
170 __m128i u = _mm_cvtps_epi32(t);
171 u = ojph_mm_max_ge_epi32(u, s32_low_lim, t, fl_low_lim);
172 u = ojph_mm_min_lt_epi32(u, s32_up_lim, t, fl_up_lim);
173 u = _mm_add_epi32(u, half);
174 _mm_storeu_si128((__m128i*)dp, u);
178 _MM_SET_ROUNDING_MODE(rounding_mode);
183 line_buf *dst_line,
ui32 dst_line_offset,
184 ui32 bit_depth,
bool is_signed,
ui32 width)
186 local_sse2_irv_convert_to_integer<false>(src_line, dst_line,
187 dst_line_offset, bit_depth, is_signed, width);
192 line_buf *dst_line,
ui32 dst_line_offset,
193 ui32 bit_depth,
bool is_signed,
ui32 width)
195 local_sse2_irv_convert_to_integer<true>(src_line, dst_line,
196 dst_line_offset, bit_depth, is_signed, width);
200 template<
int NLT_TYPE>
202 void local_sse2_irv_convert_to_integer_nlt2or4(
const line_buf *src_line,
203 line_buf *dst_line,
ui32 dst_line_offset,
214 assert(bit_depth <= 32);
215 uint32_t rounding_mode = _MM_GET_ROUNDING_MODE();
216 _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
218 const float* sp = src_line->f32;
219 si32* dp = dst_line->i32 + dst_line_offset;
221 __m128 mul = _mm_set1_ps(rec->multiplier);
222 __m128 fd_min = _mm_set1_ps(rec->fd_min);
223 __m128 fd_max = _mm_set1_ps(rec->fd_max);
224 __m128 delta = _mm_set1_ps(rec->delta);
225 __m128 inv_delta = _mm_set1_ps(rec->inv_delta);
226 const float* lut = rec->dec_points;
228 __m128 half_ps = _mm_set1_ps(0.5f);
230 if (rec->is_signed())
232 __m128 half = _mm_set1_ps((
float)(1ULL << (rec->get_bit_depth() - 1)));
234 _mm_set1_epi32(-(
si32)((1ULL << (rec->get_bit_depth() - 1)) + 1));
235 __m128i zero = _mm_setzero_si128();
236 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
237 __m128 t = _mm_loadu_ps(sp);
238 t = _mm_add_ps(t, half_ps);
239 t = _mm_max_ps(t, fd_min);
240 t = _mm_min_ps(t, fd_max);
241 __m128i k = _mm_cvttps_epi32(
242 _mm_mul_ps(_mm_sub_ps(t, fd_min), inv_delta));
243 __m128 d_k = _mm_add_ps(fd_min,
244 _mm_mul_ps(_mm_cvtepi32_ps(k), delta));
248 _mm_storeu_si128((__m128i*)kk, k);
249 __m128 t_k = _mm_set_ps(lut[kk[3]], lut[kk[2]],
250 lut[kk[1]], lut[kk[0]]);
251 __m128 t_kp1 = _mm_set_ps(lut[kk[3] + 1], lut[kk[2] + 1],
252 lut[kk[1] + 1], lut[kk[0] + 1]);
253 __m128 z = _mm_add_ps(t_k,
254 _mm_mul_ps(_mm_mul_ps(_mm_sub_ps(t, d_k), inv_delta),
255 _mm_sub_ps(t_kp1, t_k)));
257 _mm_cvtps_epi32(_mm_sub_ps(_mm_mul_ps(z, mul), half));
260 __m128i c = _mm_cmpgt_epi32(zero, v);
261 __m128i neg = _mm_sub_epi32(bias, v);
262 neg = _mm_and_si128(c, neg);
263 v = _mm_andnot_si128(c, v);
264 v = _mm_or_si128(neg, v);
266 _mm_storeu_si128((__m128i*)dp, v);
271 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
272 __m128 t = _mm_loadu_ps(sp);
273 t = _mm_add_ps(t, half_ps);
274 t = _mm_max_ps(t, fd_min);
275 t = _mm_min_ps(t, fd_max);
276 __m128i k = _mm_cvttps_epi32(
277 _mm_mul_ps(_mm_sub_ps(t, fd_min), inv_delta));
278 __m128 d_k = _mm_add_ps(fd_min,
279 _mm_mul_ps(_mm_cvtepi32_ps(k), delta));
283 _mm_storeu_si128((__m128i*)kk, k);
284 __m128 t_k = _mm_set_ps(lut[kk[3]], lut[kk[2]],
285 lut[kk[1]], lut[kk[0]]);
286 __m128 t_kp1 = _mm_set_ps(lut[kk[3] + 1], lut[kk[2] + 1],
287 lut[kk[1] + 1], lut[kk[0] + 1]);
288 __m128 z = _mm_add_ps(t_k,
289 _mm_mul_ps(_mm_mul_ps(_mm_sub_ps(t, d_k), inv_delta),
290 _mm_sub_ps(t_kp1, t_k)));
291 __m128i v = _mm_cvtps_epi32(_mm_mul_ps(z, mul));
292 _mm_storeu_si128((__m128i*)dp, v);
296 _MM_SET_ROUNDING_MODE(rounding_mode);
301 line_buf *dst_line,
ui32 dst_line_offset,
305 if (rec->get_type() == nl::OJPH_NLT_LUT_STYLE_NLT)
306 local_sse2_irv_convert_to_integer_nlt2or4<2>(src_line, dst_line,
307 dst_line_offset, bit_depth, is_signed, width, rec);
308 else if (rec->get_type() == nl::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
309 local_sse2_irv_convert_to_integer_nlt2or4<4>(src_line, dst_line,
310 dst_line_offset, bit_depth, is_signed, width, rec);
317 static inline __m128i sse2_mm_srai_epi64(__m128i a,
int amt, __m128i m)
321 __m128i x = _mm_srli_epi64(a, amt);
322 x = _mm_xor_si128(x, m);
323 __m128i result = _mm_sub_epi64(x, m);
328 static inline __m128i sse2_cvtlo_epi32_epi64(__m128i a, __m128i zero)
331 t = _mm_cmplt_epi32(a, zero);
332 t = _mm_unpacklo_epi32(a, t);
337 static inline __m128i sse2_cvthi_epi32_epi64(__m128i a, __m128i zero)
340 t = _mm_cmplt_epi32(a, zero);
341 t = _mm_unpackhi_epi32(a, t);
347 const ui32 src_line_offset,
349 const ui32 dst_line_offset,
356 const si32 *sp = src_line->i32 + src_line_offset;
357 si32 *dp = dst_line->i32 + dst_line_offset;
358 __m128i sh = _mm_set1_epi32((
si32)shift);
359 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
361 __m128i s = _mm_loadu_si128((__m128i*)sp);
362 s = _mm_add_epi32(s, sh);
363 _mm_storeu_si128((__m128i*)dp, s);
368 const si32 *sp = src_line->i32 + src_line_offset;
369 si64 *dp = dst_line->i64 + dst_line_offset;
370 __m128i zero = _mm_setzero_si128();
371 __m128i sh = _mm_set1_epi64x(shift);
372 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
375 s = _mm_loadu_si128((__m128i*)sp);
377 t = sse2_cvtlo_epi32_epi64(s, zero);
378 t = _mm_add_epi64(t, sh);
379 _mm_storeu_si128((__m128i*)dp, t);
381 t = sse2_cvthi_epi32_epi64(s, zero);
382 t = _mm_add_epi64(t, sh);
383 _mm_storeu_si128((__m128i*)dp + 1, t);
391 const si64 *sp = src_line->i64 + src_line_offset;
392 si32 *dp = dst_line->i32 + dst_line_offset;
393 __m128i low_bits = _mm_set_epi64x(0, (
si64)ULLONG_MAX);
394 __m128i sh = _mm_set1_epi64x(shift);
395 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
398 s = _mm_loadu_si128((__m128i*)sp);
399 s = _mm_add_epi64(s, sh);
401 t = _mm_shuffle_epi32(s, _MM_SHUFFLE(0, 0, 2, 0));
402 t = _mm_and_si128(low_bits, t);
404 s = _mm_loadu_si128((__m128i*)sp + 1);
405 s = _mm_add_epi64(s, sh);
407 s = _mm_shuffle_epi32(s, _MM_SHUFFLE(2, 0, 0, 0));
408 s = _mm_andnot_si128(low_bits, s);
410 t = _mm_or_si128(s, t);
411 _mm_storeu_si128((__m128i*)dp, t);
418 const ui32 src_line_offset,
420 const ui32 dst_line_offset,
427 const si32 *sp = src_line->i32 + src_line_offset;
428 si32 *dp = dst_line->i32 + dst_line_offset;
429 __m128i sh = _mm_set1_epi32((
si32)(-shift));
430 __m128i zero = _mm_setzero_si128();
431 for (
int i = (width + 3) >> 2; i > 0; --i, sp += 4, dp += 4)
433 __m128i s = _mm_loadu_si128((__m128i*)sp);
434 __m128i c = _mm_cmplt_epi32(s, zero);
435 __m128i v_m_sh = _mm_sub_epi32(sh, s);
436 v_m_sh = _mm_and_si128(c, v_m_sh);
437 s = _mm_andnot_si128(c, s);
438 s = _mm_or_si128(s, v_m_sh);
439 _mm_storeu_si128((__m128i*)dp, s);
444 const si32 *sp = src_line->i32 + src_line_offset;
445 si64 *dp = dst_line->i64 + dst_line_offset;
446 __m128i sh = _mm_set1_epi64x(-shift);
447 __m128i zero = _mm_setzero_si128();
448 for (
int i = (width + 3) >> 2; i > 0; --i, sp += 4, dp += 4)
450 __m128i s, t, u, c, v_m_sh;
451 s = _mm_loadu_si128((__m128i*)sp);
453 t = _mm_cmplt_epi32(s, zero);
454 u = _mm_unpacklo_epi32(s, t);
455 c = _mm_unpacklo_epi32(t, t);
457 v_m_sh = _mm_sub_epi64(sh, u);
458 v_m_sh = _mm_and_si128(c, v_m_sh);
459 u = _mm_andnot_si128(c, u);
460 u = _mm_or_si128(u, v_m_sh);
462 _mm_storeu_si128((__m128i*)dp, u);
463 u = _mm_unpackhi_epi32(s, t);
464 c = _mm_unpackhi_epi32(t, t);
466 v_m_sh = _mm_sub_epi64(sh, u);
467 v_m_sh = _mm_and_si128(c, v_m_sh);
468 u = _mm_andnot_si128(c, u);
469 u = _mm_or_si128(u, v_m_sh);
471 _mm_storeu_si128((__m128i*)dp + 1, u);
479 const si64 *sp = src_line->i64 + src_line_offset;
480 si32 *dp = dst_line->i32 + dst_line_offset;
481 __m128i sh = _mm_set1_epi64x(-shift);
482 __m128i zero = _mm_setzero_si128();
483 __m128i half_mask = _mm_set_epi64x(0, (
si64)ULLONG_MAX);
484 for (
int i = (width + 3) >> 2; i > 0; --i, sp += 4, dp += 4)
488 __m128i s, t, p, n, m, tm;
489 s = _mm_loadu_si128((__m128i*)sp);
491 tm = _mm_cmplt_epi32(s, zero);
492 m = _mm_shuffle_epi32(tm, _MM_SHUFFLE(3, 3, 1, 1));
493 tm = _mm_sub_epi64(sh, s);
494 n = _mm_and_si128(m, tm);
495 p = _mm_andnot_si128(m, s);
496 tm = _mm_or_si128(n, p);
497 tm = _mm_shuffle_epi32(tm, _MM_SHUFFLE(0, 0, 2, 0));
498 t = _mm_and_si128(half_mask, tm);
500 s = _mm_loadu_si128((__m128i*)sp + 1);
501 tm = _mm_cmplt_epi32(s, zero);
502 m = _mm_shuffle_epi32(tm, _MM_SHUFFLE(3, 3, 1, 1));
503 tm = _mm_sub_epi64(sh, s);
504 n = _mm_and_si128(m, tm);
505 p = _mm_andnot_si128(m, s);
506 tm = _mm_or_si128(n, p);
507 tm = _mm_shuffle_epi32(tm, _MM_SHUFFLE(2, 0, 0, 0));
508 tm = _mm_andnot_si128(half_mask, tm);
510 t = _mm_or_si128(t, tm);
511 _mm_storeu_si128((__m128i*)dp, t);
517 template<
bool NLT_TYPE3>
519 void local_sse2_irv_convert_to_float(
const line_buf *src_line,
520 ui32 src_line_offset, line_buf *dst_line,
521 ui32 bit_depth,
bool is_signed,
ui32 width)
528 assert(bit_depth <= 32);
529 __m128 mul = _mm_set1_ps((
float)(1.0 / (
double)(1ULL << bit_depth)));
531 const si32* sp = src_line->i32 + src_line_offset;
532 float* dp = dst_line->f32;
535 __m128i zero = _mm_setzero_si128();
536 __m128i bias = _mm_set1_epi32(-(
si32)((1ULL << (bit_depth - 1)) + 1));
537 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
538 __m128i t = _mm_loadu_si128((__m128i*)sp);
541 __m128i c = _mm_cmplt_epi32(t, zero);
542 __m128i neg = _mm_sub_epi32(bias, t);
543 neg = _mm_and_si128(c, neg);
544 c = _mm_andnot_si128(c, t);
545 t = _mm_or_si128(neg, c);
547 __m128 v = _mm_cvtepi32_ps(t);
548 v = _mm_mul_ps(v, mul);
549 _mm_storeu_ps(dp, v);
554 __m128i half = _mm_set1_epi32((
si32)(1ULL << (bit_depth - 1)));
555 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
556 __m128i t = _mm_loadu_si128((__m128i*)sp);
557 t = _mm_sub_epi32(t, half);
558 __m128 v = _mm_cvtepi32_ps(t);
559 v = _mm_mul_ps(v, mul);
560 _mm_storeu_ps(dp, v);
567 ui32 src_line_offset, line_buf *dst_line,
568 ui32 bit_depth,
bool is_signed,
ui32 width)
570 local_sse2_irv_convert_to_float<false>(src_line, src_line_offset,
571 dst_line, bit_depth, is_signed, width);
576 ui32 src_line_offset, line_buf *dst_line,
577 ui32 bit_depth,
bool is_signed,
ui32 width)
579 local_sse2_irv_convert_to_float<true>(src_line, src_line_offset,
580 dst_line, bit_depth, is_signed, width);
584 template<
int NLT_TYPE>
586 void local_sse2_irv_convert_to_float_nlt2or4(
const line_buf *src_line,
587 ui32 src_line_offset, line_buf *dst_line,
598 assert(bit_depth <= 32);
599 __m128 mul = _mm_set1_ps(rec->multiplier);
600 __m128 ft_min = _mm_set1_ps(rec->ft_min);
601 __m128 ft_max = _mm_set1_ps(rec->ft_max);
602 __m128 delta = _mm_set1_ps(rec->delta);
603 __m128 inv_delta = _mm_set1_ps(rec->inv_delta);
604 const float* lut = rec->approx_enc_points;
606 __m128 half_ps = _mm_set1_ps(0.5f);
608 const si32* sp = src_line->i32 + src_line_offset;
609 float* dp = dst_line->f32;
610 if (rec->is_signed())
613 _mm_set1_epi32(-(
si32)((1ULL << (rec->get_bit_depth() - 1)) + 1));
614 __m128i zero = _mm_setzero_si128();
615 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
616 __m128i v = _mm_loadu_si128((__m128i*)sp);
619 __m128i c = _mm_cmpgt_epi32(zero, v);
620 __m128i neg = _mm_sub_epi32(bias, v);
621 neg = _mm_and_si128(c, neg);
622 v = _mm_andnot_si128(c, v);
623 v = _mm_or_si128(neg, v);
625 __m128 t = _mm_add_ps(
626 _mm_mul_ps(_mm_cvtepi32_ps(v), mul), half_ps);
627 t = _mm_max_ps(t, ft_min);
628 t = _mm_min_ps(t, ft_max);
629 __m128i k = _mm_cvttps_epi32(
630 _mm_mul_ps(_mm_sub_ps(t, ft_min), inv_delta));
631 __m128 d_k = _mm_add_ps(ft_min,
632 _mm_mul_ps(_mm_cvtepi32_ps(k), delta));
636 _mm_storeu_si128((__m128i*)kk, k);
637 __m128 t_k = _mm_set_ps(lut[kk[3]], lut[kk[2]],
638 lut[kk[1]], lut[kk[0]]);
639 __m128 t_kp1 = _mm_set_ps(lut[kk[3] + 1], lut[kk[2] + 1],
640 lut[kk[1] + 1], lut[kk[0] + 1]);
641 __m128 y = _mm_add_ps(t_k,
642 _mm_mul_ps(_mm_mul_ps(_mm_sub_ps(t, d_k), inv_delta),
643 _mm_sub_ps(t_kp1, t_k)));
644 _mm_storeu_ps(dp, _mm_sub_ps(y, half_ps));
649 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
650 __m128i v = _mm_loadu_si128((__m128i*)sp);
651 __m128 t = _mm_mul_ps(_mm_cvtepi32_ps(v), mul);
652 t = _mm_max_ps(t, ft_min);
653 t = _mm_min_ps(t, ft_max);
654 __m128i k = _mm_cvttps_epi32(
655 _mm_mul_ps(_mm_sub_ps(t, ft_min), inv_delta));
656 __m128 d_k = _mm_add_ps(ft_min,
657 _mm_mul_ps(_mm_cvtepi32_ps(k), delta));
661 _mm_storeu_si128((__m128i*)kk, k);
662 __m128 t_k = _mm_set_ps(lut[kk[3]], lut[kk[2]],
663 lut[kk[1]], lut[kk[0]]);
664 __m128 t_kp1 = _mm_set_ps(lut[kk[3] + 1], lut[kk[2] + 1],
665 lut[kk[1] + 1], lut[kk[0] + 1]);
666 __m128 y = _mm_add_ps(t_k,
667 _mm_mul_ps(_mm_mul_ps(_mm_sub_ps(t, d_k), inv_delta),
668 _mm_sub_ps(t_kp1, t_k)));
669 _mm_storeu_ps(dp, _mm_sub_ps(y, half_ps));
682 template<
int NLT_TYPE>
684 void local_sse2_irv_convert_to_float_nlt2or4_precise_1step(
685 const line_buf *src_line,
ui32 src_line_offset, line_buf *dst_line,
696 assert(bit_depth <= 32);
697 __m128 mul = _mm_set1_ps(rec->multiplier);
698 __m128 ft_min = _mm_set1_ps(rec->ft_min);
699 __m128 ft_max = _mm_set1_ps(rec->ft_max);
700 __m128 fd_min = _mm_set1_ps(rec->fd_min);
701 __m128 delta = _mm_set1_ps(rec->delta);
702 __m128 inv_delta = _mm_set1_ps(rec->inv_delta);
703 const float* lut = rec->precise_dec_lut;
704 const ui16* indices = rec->precise_enc_dec_indices;
706 __m128 half_ps = _mm_set1_ps(0.5f);
707 __m128 one_ps = _mm_set1_ps(1.0f);
708 __m128 zero_ps = _mm_setzero_ps();
709 __m128i one = _mm_set1_epi32(1);
711 const si32* sp = src_line->i32 + src_line_offset;
712 float* dp = dst_line->f32;
713 if (rec->is_signed())
716 _mm_set1_epi32(-(
si32)((1ULL << (rec->get_bit_depth() - 1)) + 1));
717 __m128i zero = _mm_setzero_si128();
718 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
719 __m128i v = _mm_loadu_si128((__m128i*)sp);
722 __m128i c = _mm_cmpgt_epi32(zero, v);
723 __m128i neg = _mm_sub_epi32(bias, v);
724 neg = _mm_and_si128(c, neg);
725 v = _mm_andnot_si128(c, v);
726 v = _mm_or_si128(neg, v);
728 __m128 t = _mm_add_ps(
729 _mm_mul_ps(_mm_cvtepi32_ps(v), mul), half_ps);
730 t = _mm_max_ps(t, ft_min);
731 t = _mm_min_ps(t, ft_max);
732 __m128i kk = _mm_cvttps_epi32(
733 _mm_mul_ps(_mm_sub_ps(t, ft_min), inv_delta));
739 _mm_storeu_si128((__m128i*)e, kk);
740 for (
int j = 0; j < 4; ++j)
741 k[j] = (
si32)indices[e[j]];
742 __m128i kv = _mm_setr_epi32(k[0], k[1], k[2], k[3]);
743 __m128 y0 = _mm_set_ps(lut[k[3]], lut[k[2]], lut[k[1]], lut[k[0]]);
744 __m128 y1 = _mm_set_ps(lut[k[3] + 1], lut[k[2] + 1],
745 lut[k[1] + 1], lut[k[0] + 1]);
746 __m128 y2 = _mm_set_ps(lut[k[3] + 2], lut[k[2] + 2],
747 lut[k[1] + 2], lut[k[0] + 2]);
751 __m128 adv = _mm_cmpgt_ps(t, y1);
752 y0 = _mm_or_ps(_mm_and_ps(adv, y1), _mm_andnot_ps(adv, y0));
753 y1 = _mm_or_ps(_mm_and_ps(adv, y2), _mm_andnot_ps(adv, y1));
754 kv = _mm_add_epi32(kv,
755 _mm_and_si128(_mm_castps_si128(adv), one));
759 __m128 den = _mm_sub_ps(y1, y0);
760 __m128 has = _mm_cmpgt_ps(den, zero_ps);
761 den = _mm_or_ps(_mm_and_ps(has, den), _mm_andnot_ps(has, one_ps));
762 __m128 y = _mm_add_ps(
763 _mm_add_ps(fd_min, _mm_mul_ps(_mm_cvtepi32_ps(kv), delta)),
764 _mm_and_ps(has, _mm_div_ps(
765 _mm_mul_ps(_mm_sub_ps(t, y0), delta), den)));
766 _mm_storeu_ps(dp, _mm_sub_ps(y, half_ps));
771 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
772 __m128i v = _mm_loadu_si128((__m128i*)sp);
773 __m128 t = _mm_mul_ps(_mm_cvtepi32_ps(v), mul);
774 t = _mm_max_ps(t, ft_min);
775 t = _mm_min_ps(t, ft_max);
776 __m128i kk = _mm_cvttps_epi32(
777 _mm_mul_ps(_mm_sub_ps(t, ft_min), inv_delta));
783 _mm_storeu_si128((__m128i*)e, kk);
784 for (
int j = 0; j < 4; ++j)
785 k[j] = (
si32)indices[e[j]];
786 __m128i kv = _mm_setr_epi32(k[0], k[1], k[2], k[3]);
787 __m128 y0 = _mm_set_ps(lut[k[3]], lut[k[2]], lut[k[1]], lut[k[0]]);
788 __m128 y1 = _mm_set_ps(lut[k[3] + 1], lut[k[2] + 1],
789 lut[k[1] + 1], lut[k[0] + 1]);
790 __m128 y2 = _mm_set_ps(lut[k[3] + 2], lut[k[2] + 2],
791 lut[k[1] + 2], lut[k[0] + 2]);
795 __m128 adv = _mm_cmpgt_ps(t, y1);
796 y0 = _mm_or_ps(_mm_and_ps(adv, y1), _mm_andnot_ps(adv, y0));
797 y1 = _mm_or_ps(_mm_and_ps(adv, y2), _mm_andnot_ps(adv, y1));
798 kv = _mm_add_epi32(kv,
799 _mm_and_si128(_mm_castps_si128(adv), one));
803 __m128 den = _mm_sub_ps(y1, y0);
804 __m128 has = _mm_cmpgt_ps(den, zero_ps);
805 den = _mm_or_ps(_mm_and_ps(has, den), _mm_andnot_ps(has, one_ps));
806 __m128 y = _mm_add_ps(
807 _mm_add_ps(fd_min, _mm_mul_ps(_mm_cvtepi32_ps(kv), delta)),
808 _mm_and_ps(has, _mm_div_ps(
809 _mm_mul_ps(_mm_sub_ps(t, y0), delta), den)));
810 _mm_storeu_ps(dp, _mm_sub_ps(y, half_ps));
826 template<
int NLT_TYPE>
828 void local_sse2_irv_convert_to_float_nlt2or4_precise_search(
829 const line_buf *src_line,
ui32 src_line_offset, line_buf *dst_line,
840 assert(bit_depth <= 32);
841 assert(rec->precise_max_steps > 1);
842 __m128 mul = _mm_set1_ps(rec->multiplier);
843 __m128 ft_min = _mm_set1_ps(rec->ft_min);
844 __m128 ft_max = _mm_set1_ps(rec->ft_max);
845 __m128 fd_min = _mm_set1_ps(rec->fd_min);
846 __m128 delta = _mm_set1_ps(rec->delta);
847 __m128 inv_delta = _mm_set1_ps(rec->inv_delta);
848 const float* lut = rec->precise_dec_lut;
849 const ui16* indices = rec->precise_enc_dec_indices;
850 ui32 num_points = rec->num_points;
855 ui32 span = rec->precise_max_steps + 1;
856 int steps = 32 - (int)count_leading_zeros(rec->precise_max_steps);
858 __m128 half_ps = _mm_set1_ps(0.5f);
859 __m128 one_ps = _mm_set1_ps(1.0f);
860 __m128 zero_ps = _mm_setzero_ps();
861 __m128i span_epi32 = _mm_set1_epi32((
si32)span);
862 __m128i num_epi32 = _mm_set1_epi32((
si32)num_points);
864 const si32* sp = src_line->i32 + src_line_offset;
865 float* dp = dst_line->f32;
866 if (rec->is_signed())
869 _mm_set1_epi32(-(
si32)((1ULL << (rec->get_bit_depth() - 1)) + 1));
870 __m128i zero = _mm_setzero_si128();
871 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
872 __m128i v = _mm_loadu_si128((__m128i*)sp);
875 __m128i c = _mm_cmpgt_epi32(zero, v);
876 __m128i neg = _mm_sub_epi32(bias, v);
877 neg = _mm_and_si128(c, neg);
878 v = _mm_andnot_si128(c, v);
879 v = _mm_or_si128(neg, v);
881 __m128 t = _mm_add_ps(
882 _mm_mul_ps(_mm_cvtepi32_ps(v), mul), half_ps);
883 t = _mm_max_ps(t, ft_min);
884 t = _mm_min_ps(t, ft_max);
885 __m128i kk = _mm_cvttps_epi32(
886 _mm_mul_ps(_mm_sub_ps(t, ft_min), inv_delta));
889 _mm_storeu_si128((__m128i*)e, kk);
890 for (
int j = 0; j < 4; ++j)
891 k[j] = (
si32)indices[e[j]];
892 __m128i lo = _mm_setr_epi32(k[0], k[1], k[2], k[3]);
895 __m128i kspan = _mm_add_epi32(lo, span_epi32);
896 __m128i m = _mm_cmpgt_epi32(kspan, num_epi32);
897 __m128i hi = _mm_or_si128(_mm_and_si128(m, num_epi32),
898 _mm_andnot_si128(m, kspan));
900 for (
int step = 0; step < steps; ++step)
902 __m128i mid = _mm_srli_epi32(_mm_add_epi32(lo, hi), 1);
904 _mm_storeu_si128((__m128i*)m4, mid);
905 __m128 lmid = _mm_set_ps(lut[m4[3]], lut[m4[2]],
906 lut[m4[1]], lut[m4[0]]);
907 __m128 ge = _mm_cmpge_ps(t, lmid);
908 __m128i g = _mm_castps_si128(ge);
909 lo = _mm_or_si128(_mm_and_si128(g, mid),
910 _mm_andnot_si128(g, lo));
911 hi = _mm_or_si128(_mm_and_si128(g, hi),
912 _mm_andnot_si128(g, mid));
916 _mm_storeu_si128((__m128i*)l4, lo);
917 _mm_storeu_si128((__m128i*)h4, hi);
918 __m128 y0 = _mm_set_ps(lut[l4[3]], lut[l4[2]], lut[l4[1]], lut[l4[0]]);
919 __m128 y1 = _mm_set_ps(lut[h4[3]], lut[h4[2]], lut[h4[1]], lut[h4[0]]);
923 __m128 den = _mm_sub_ps(y1, y0);
924 __m128 has = _mm_cmpgt_ps(den, zero_ps);
925 den = _mm_or_ps(_mm_and_ps(has, den), _mm_andnot_ps(has, one_ps));
926 __m128 y = _mm_add_ps(
927 _mm_add_ps(fd_min, _mm_mul_ps(_mm_cvtepi32_ps(lo), delta)),
928 _mm_and_ps(has, _mm_div_ps(
929 _mm_mul_ps(_mm_sub_ps(t, y0), delta), den)));
930 _mm_storeu_ps(dp, _mm_sub_ps(y, half_ps));
935 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
936 __m128i v = _mm_loadu_si128((__m128i*)sp);
937 __m128 t = _mm_mul_ps(_mm_cvtepi32_ps(v), mul);
938 t = _mm_max_ps(t, ft_min);
939 t = _mm_min_ps(t, ft_max);
940 __m128i kk = _mm_cvttps_epi32(
941 _mm_mul_ps(_mm_sub_ps(t, ft_min), inv_delta));
944 _mm_storeu_si128((__m128i*)e, kk);
945 for (
int j = 0; j < 4; ++j)
946 k[j] = (
si32)indices[e[j]];
947 __m128i lo = _mm_setr_epi32(k[0], k[1], k[2], k[3]);
948 __m128i kspan = _mm_add_epi32(lo, span_epi32);
949 __m128i m = _mm_cmpgt_epi32(kspan, num_epi32);
950 __m128i hi = _mm_or_si128(_mm_and_si128(m, num_epi32),
951 _mm_andnot_si128(m, kspan));
953 for (
int step = 0; step < steps; ++step)
955 __m128i mid = _mm_srli_epi32(_mm_add_epi32(lo, hi), 1);
957 _mm_storeu_si128((__m128i*)m4, mid);
958 __m128 lmid = _mm_set_ps(lut[m4[3]], lut[m4[2]],
959 lut[m4[1]], lut[m4[0]]);
960 __m128 ge = _mm_cmpge_ps(t, lmid);
961 __m128i g = _mm_castps_si128(ge);
962 lo = _mm_or_si128(_mm_and_si128(g, mid),
963 _mm_andnot_si128(g, lo));
964 hi = _mm_or_si128(_mm_and_si128(g, hi),
965 _mm_andnot_si128(g, mid));
969 _mm_storeu_si128((__m128i*)l4, lo);
970 _mm_storeu_si128((__m128i*)h4, hi);
971 __m128 y0 = _mm_set_ps(lut[l4[3]], lut[l4[2]], lut[l4[1]], lut[l4[0]]);
972 __m128 y1 = _mm_set_ps(lut[h4[3]], lut[h4[2]], lut[h4[1]], lut[h4[0]]);
973 __m128 den = _mm_sub_ps(y1, y0);
974 __m128 has = _mm_cmpgt_ps(den, zero_ps);
975 den = _mm_or_ps(_mm_and_ps(has, den), _mm_andnot_ps(has, one_ps));
976 __m128 y = _mm_add_ps(
977 _mm_add_ps(fd_min, _mm_mul_ps(_mm_cvtepi32_ps(lo), delta)),
978 _mm_and_ps(has, _mm_div_ps(
979 _mm_mul_ps(_mm_sub_ps(t, y0), delta), den)));
980 _mm_storeu_ps(dp, _mm_sub_ps(y, half_ps));
987 ui32 src_line_offset, line_buf *dst_line,
991 if (rec->get_type() == nl::OJPH_NLT_LUT_STYLE_NLT)
993 if (rec->approx_encoding_nlt)
994 local_sse2_irv_convert_to_float_nlt2or4<2>(src_line,
995 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
996 else if (rec->precise_max_steps == 1)
997 local_sse2_irv_convert_to_float_nlt2or4_precise_1step<2>(src_line,
998 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
1000 local_sse2_irv_convert_to_float_nlt2or4_precise_search<2>(src_line,
1001 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
1003 else if (rec->get_type() == nl::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
1005 if (rec->approx_encoding_nlt)
1006 local_sse2_irv_convert_to_float_nlt2or4<4>(src_line,
1007 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
1008 else if (rec->precise_max_steps == 1)
1009 local_sse2_irv_convert_to_float_nlt2or4_precise_1step<4>(src_line,
1010 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
1012 local_sse2_irv_convert_to_float_nlt2or4_precise_search<4>(src_line,
1013 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
1023 line_buf *y, line_buf *cb, line_buf *cr,
1041 const si32 *rp = r->i32, * gp = g->i32, * bp = b->i32;
1042 si32 *yp = y->i32, * cbp = cb->i32, * crp = cr->i32;
1043 for (
int i = (repeat + 3) >> 2; i > 0; --i)
1045 __m128i mr = _mm_load_si128((__m128i*)rp);
1046 __m128i mg = _mm_load_si128((__m128i*)gp);
1047 __m128i mb = _mm_load_si128((__m128i*)bp);
1048 __m128i t = _mm_add_epi32(mr, mb);
1049 t = _mm_add_epi32(t, _mm_slli_epi32(mg, 1));
1050 _mm_store_si128((__m128i*)yp, _mm_srai_epi32(t, 2));
1051 t = _mm_sub_epi32(mb, mg);
1052 _mm_store_si128((__m128i*)cbp, t);
1053 t = _mm_sub_epi32(mr, mg);
1054 _mm_store_si128((__m128i*)crp, t);
1056 rp += 4; gp += 4; bp += 4;
1057 yp += 4; cbp += 4; crp += 4;
1068 __m128i zero = _mm_setzero_si128();
1069 __m128i v2 = _mm_set1_epi64x(1ULL << (63 - 2));
1070 const si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
1071 si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64;
1072 for (
int i = (repeat + 3) >> 2; i > 0; --i)
1074 __m128i mr32 = _mm_load_si128((__m128i*)rp);
1075 __m128i mg32 = _mm_load_si128((__m128i*)gp);
1076 __m128i mb32 = _mm_load_si128((__m128i*)bp);
1077 __m128i mr, mg, mb, t;
1078 mr = sse2_cvtlo_epi32_epi64(mr32, zero);
1079 mg = sse2_cvtlo_epi32_epi64(mg32, zero);
1080 mb = sse2_cvtlo_epi32_epi64(mb32, zero);
1082 t = _mm_add_epi64(mr, mb);
1083 t = _mm_add_epi64(t, _mm_slli_epi64(mg, 1));
1084 _mm_store_si128((__m128i*)yp, sse2_mm_srai_epi64(t, 2, v2));
1085 t = _mm_sub_epi64(mb, mg);
1086 _mm_store_si128((__m128i*)cbp, t);
1087 t = _mm_sub_epi64(mr, mg);
1088 _mm_store_si128((__m128i*)crp, t);
1090 yp += 2; cbp += 2; crp += 2;
1092 mr = sse2_cvthi_epi32_epi64(mr32, zero);
1093 mg = sse2_cvthi_epi32_epi64(mg32, zero);
1094 mb = sse2_cvthi_epi32_epi64(mb32, zero);
1096 t = _mm_add_epi64(mr, mb);
1097 t = _mm_add_epi64(t, _mm_slli_epi64(mg, 1));
1098 _mm_store_si128((__m128i*)yp, sse2_mm_srai_epi64(t, 2, v2));
1099 t = _mm_sub_epi64(mb, mg);
1100 _mm_store_si128((__m128i*)cbp, t);
1101 t = _mm_sub_epi64(mr, mg);
1102 _mm_store_si128((__m128i*)crp, t);
1104 rp += 4; gp += 4; bp += 4;
1105 yp += 2; cbp += 2; crp += 2;
1114 line_buf *r, line_buf *g, line_buf *b,
1132 const si32 *yp = y->i32, *cbp = cb->i32, *crp = cr->i32;
1133 si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
1134 for (
int i = (repeat + 3) >> 2; i > 0; --i)
1136 __m128i my = _mm_load_si128((__m128i*)yp);
1137 __m128i mcb = _mm_load_si128((__m128i*)cbp);
1138 __m128i mcr = _mm_load_si128((__m128i*)crp);
1140 __m128i t = _mm_add_epi32(mcb, mcr);
1141 t = _mm_sub_epi32(my, _mm_srai_epi32(t, 2));
1142 _mm_store_si128((__m128i*)gp, t);
1143 __m128i u = _mm_add_epi32(mcb, t);
1144 _mm_store_si128((__m128i*)bp, u);
1145 u = _mm_add_epi32(mcr, t);
1146 _mm_store_si128((__m128i*)rp, u);
1148 yp += 4; cbp += 4; crp += 4;
1149 rp += 4; gp += 4; bp += 4;
1160 __m128i v2 = _mm_set1_epi64x(1ULL << (63 - 2));
1161 __m128i low_bits = _mm_set_epi64x(0, (
si64)ULLONG_MAX);
1162 const si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64;
1163 si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
1164 for (
int i = (repeat + 3) >> 2; i > 0; --i)
1166 __m128i my, mcb, mcr, tr, tg, tb;
1167 my = _mm_load_si128((__m128i*)yp);
1168 mcb = _mm_load_si128((__m128i*)cbp);
1169 mcr = _mm_load_si128((__m128i*)crp);
1171 tg = _mm_add_epi64(mcb, mcr);
1172 tg = _mm_sub_epi64(my, sse2_mm_srai_epi64(tg, 2, v2));
1173 tb = _mm_add_epi64(mcb, tg);
1174 tr = _mm_add_epi64(mcr, tg);
1177 mr = _mm_shuffle_epi32(tr, _MM_SHUFFLE(0, 0, 2, 0));
1178 mr = _mm_and_si128(low_bits, mr);
1179 mg = _mm_shuffle_epi32(tg, _MM_SHUFFLE(0, 0, 2, 0));
1180 mg = _mm_and_si128(low_bits, mg);
1181 mb = _mm_shuffle_epi32(tb, _MM_SHUFFLE(0, 0, 2, 0));
1182 mb = _mm_and_si128(low_bits, mb);
1184 yp += 2; cbp += 2; crp += 2;
1186 my = _mm_load_si128((__m128i*)yp);
1187 mcb = _mm_load_si128((__m128i*)cbp);
1188 mcr = _mm_load_si128((__m128i*)crp);
1190 tg = _mm_add_epi64(mcb, mcr);
1191 tg = _mm_sub_epi64(my, sse2_mm_srai_epi64(tg, 2, v2));
1192 tb = _mm_add_epi64(mcb, tg);
1193 tr = _mm_add_epi64(mcr, tg);
1195 tr = _mm_shuffle_epi32(tr, _MM_SHUFFLE(2, 0, 0, 0));
1196 tr = _mm_andnot_si128(low_bits, tr);
1197 mr = _mm_or_si128(mr, tr);
1198 tg = _mm_shuffle_epi32(tg, _MM_SHUFFLE(2, 0, 0, 0));
1199 tg = _mm_andnot_si128(low_bits, tg);
1200 mg = _mm_or_si128(mg, tg);
1201 tb = _mm_shuffle_epi32(tb, _MM_SHUFFLE(2, 0, 0, 0));
1202 tb = _mm_andnot_si128(low_bits, tb);
1203 mb = _mm_or_si128(mb, tb);
1205 _mm_store_si128((__m128i*)rp, mr);
1206 _mm_store_si128((__m128i*)gp, mg);
1207 _mm_store_si128((__m128i*)bp, mb);
1209 yp += 2; cbp += 2; crp += 2;
1210 rp += 4; gp += 4; bp += 4;
void sse2_rct_backward(const line_buf *y, const line_buf *cb, const line_buf *cr, line_buf *r, line_buf *g, line_buf *b, ui32 repeat)
void sse2_irv_convert_to_integer(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void sse2_irv_convert_to_float_nlt_type3(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void sse2_irv_convert_to_integer_nlt_type3(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void sse2_rev_convert(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void sse2_rev_convert_nlt_type3(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void sse2_irv_convert_to_integer_nlt(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void sse2_rct_forward(const line_buf *r, const line_buf *g, const line_buf *b, line_buf *y, line_buf *cb, line_buf *cr, ui32 repeat)
void sse2_irv_convert_to_float_nlt(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void sse2_irv_convert_to_float(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
ojph::param_nlt::nonlinearity nonlinearity