| 1492 | } |
| 1493 | |
| 1494 | static void |
| 1495 | transform_16u( const ushort* src, ushort* dst, const float* m, int len, int scn, int dcn ) |
| 1496 | { |
| 1497 | #if CV_SSE2 |
| 1498 | if( USE_SSE2 && scn == 3 && dcn == 3 ) |
| 1499 | { |
| 1500 | __m128 m0, m1, m2, m3; |
| 1501 | __m128i delta = _mm_setr_epi16(0,-32768,-32768,-32768,-32768,-32768,-32768,0); |
| 1502 | load3x3Matrix(m, m0, m1, m2, m3); |
| 1503 | m3 = _mm_sub_ps(m3, _mm_setr_ps(32768.f, 32768.f, 32768.f, 0.f)); |
| 1504 | |
| 1505 | int x = 0; |
| 1506 | for( ; x <= (len - 4)*3; x += 4*3 ) |
| 1507 | { |
| 1508 | __m128i z = _mm_setzero_si128(); |
| 1509 | __m128i v0 = _mm_loadu_si128((const __m128i*)(src + x)), v1; |
| 1510 | __m128i v2 = _mm_loadl_epi64((const __m128i*)(src + x + 8)), v3; |
| 1511 | v1 = _mm_unpacklo_epi16(_mm_srli_si128(v0, 6), z); // b1 g1 r1 |
| 1512 | v3 = _mm_unpacklo_epi16(_mm_srli_si128(v2, 2), z); // b3 g3 r3 |
| 1513 | v2 = _mm_or_si128(_mm_srli_si128(v0, 12), _mm_slli_si128(v2, 4)); |
| 1514 | v0 = _mm_unpacklo_epi16(v0, z); // b0 g0 r0 |
| 1515 | v2 = _mm_unpacklo_epi16(v2, z); // b2 g2 r2 |
| 1516 | __m128 x0 = _mm_cvtepi32_ps(v0), x1 = _mm_cvtepi32_ps(v1); |
| 1517 | __m128 x2 = _mm_cvtepi32_ps(v2), x3 = _mm_cvtepi32_ps(v3); |
| 1518 | __m128 y0 = _mm_add_ps(_mm_add_ps(_mm_add_ps( |
| 1519 | _mm_mul_ps(m0, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(0,0,0,0))), |
| 1520 | _mm_mul_ps(m1, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(1,1,1,1)))), |
| 1521 | _mm_mul_ps(m2, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(2,2,2,2)))), m3); |
| 1522 | __m128 y1 = _mm_add_ps(_mm_add_ps(_mm_add_ps( |
| 1523 | _mm_mul_ps(m0, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(0,0,0,0))), |
| 1524 | _mm_mul_ps(m1, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(1,1,1,1)))), |
| 1525 | _mm_mul_ps(m2, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(2,2,2,2)))), m3); |
| 1526 | __m128 y2 = _mm_add_ps(_mm_add_ps(_mm_add_ps( |
| 1527 | _mm_mul_ps(m0, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(0,0,0,0))), |
| 1528 | _mm_mul_ps(m1, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(1,1,1,1)))), |
| 1529 | _mm_mul_ps(m2, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(2,2,2,2)))), m3); |
| 1530 | __m128 y3 = _mm_add_ps(_mm_add_ps(_mm_add_ps( |
| 1531 | _mm_mul_ps(m0, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(0,0,0,0))), |
| 1532 | _mm_mul_ps(m1, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(1,1,1,1)))), |
| 1533 | _mm_mul_ps(m2, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(2,2,2,2)))), m3); |
| 1534 | v0 = _mm_cvtps_epi32(y0); v1 = _mm_cvtps_epi32(y1); |
| 1535 | v2 = _mm_cvtps_epi32(y2); v3 = _mm_cvtps_epi32(y3); |
| 1536 | |
| 1537 | v0 = _mm_add_epi16(_mm_packs_epi32(_mm_slli_si128(v0,4), v1), delta); // 0 b0 g0 r0 b1 g1 r1 0 |
| 1538 | v2 = _mm_add_epi16(_mm_packs_epi32(_mm_slli_si128(v2,4), v3), delta); // 0 b2 g2 r2 b3 g3 r3 0 |
| 1539 | v1 = _mm_or_si128(_mm_srli_si128(v0,2), _mm_slli_si128(v2,10)); // b0 g0 r0 b1 g1 r1 b2 g2 |
| 1540 | v2 = _mm_srli_si128(v2, 6); // r2 b3 g3 r3 0 0 0 0 |
| 1541 | _mm_storeu_si128((__m128i*)(dst + x), v1); |
| 1542 | _mm_storel_epi64((__m128i*)(dst + x + 8), v2); |
| 1543 | } |
| 1544 | |
| 1545 | for( ; x < len*3; x += 3 ) |
| 1546 | { |
| 1547 | float v0 = src[x], v1 = src[x+1], v2 = src[x+2]; |
| 1548 | ushort t0 = saturate_cast<ushort>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]); |
| 1549 | ushort t1 = saturate_cast<ushort>(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]); |
| 1550 | ushort t2 = saturate_cast<ushort>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]); |
| 1551 | dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2; |
nothing calls this directly
no test coverage detected