| 1371 | #endif |
| 1372 | |
| 1373 | static void |
| 1374 | transform_8u( const uchar* src, uchar* dst, const float* m, int len, int scn, int dcn ) |
| 1375 | { |
| 1376 | #if CV_SSE2 |
| 1377 | const int BITS = 10, SCALE = 1 << BITS; |
| 1378 | const float MAX_M = (float)(1 << (15 - BITS)); |
| 1379 | |
| 1380 | if( USE_SSE2 && scn == 3 && dcn == 3 && |
| 1381 | std::abs(m[0]) < MAX_M && std::abs(m[1]) < MAX_M && std::abs(m[2]) < MAX_M && std::abs(m[3]) < MAX_M*256 && |
| 1382 | std::abs(m[4]) < MAX_M && std::abs(m[5]) < MAX_M && std::abs(m[6]) < MAX_M && std::abs(m[7]) < MAX_M*256 && |
| 1383 | std::abs(m[8]) < MAX_M && std::abs(m[9]) < MAX_M && std::abs(m[10]) < MAX_M && std::abs(m[11]) < MAX_M*256 ) |
| 1384 | { |
| 1385 | // faster fixed-point transformation |
| 1386 | short m00 = saturate_cast<short>(m[0]*SCALE), m01 = saturate_cast<short>(m[1]*SCALE), |
| 1387 | m02 = saturate_cast<short>(m[2]*SCALE), m10 = saturate_cast<short>(m[4]*SCALE), |
| 1388 | m11 = saturate_cast<short>(m[5]*SCALE), m12 = saturate_cast<short>(m[6]*SCALE), |
| 1389 | m20 = saturate_cast<short>(m[8]*SCALE), m21 = saturate_cast<short>(m[9]*SCALE), |
| 1390 | m22 = saturate_cast<short>(m[10]*SCALE); |
| 1391 | int m03 = saturate_cast<int>((m[3]+0.5f)*SCALE), m13 = saturate_cast<int>((m[7]+0.5f)*SCALE ), |
| 1392 | m23 = saturate_cast<int>((m[11]+0.5f)*SCALE); |
| 1393 | |
| 1394 | __m128i m0 = _mm_setr_epi16(0, m00, m01, m02, m00, m01, m02, 0); |
| 1395 | __m128i m1 = _mm_setr_epi16(0, m10, m11, m12, m10, m11, m12, 0); |
| 1396 | __m128i m2 = _mm_setr_epi16(0, m20, m21, m22, m20, m21, m22, 0); |
| 1397 | __m128i m3 = _mm_setr_epi32(m03, m13, m23, 0); |
| 1398 | int x = 0; |
| 1399 | |
| 1400 | for( ; x <= (len - 8)*3; x += 8*3 ) |
| 1401 | { |
| 1402 | __m128i z = _mm_setzero_si128(), t0, t1, t2, r0, r1; |
| 1403 | __m128i v0 = _mm_loadl_epi64((const __m128i*)(src + x)); |
| 1404 | __m128i v1 = _mm_loadl_epi64((const __m128i*)(src + x + 8)); |
| 1405 | __m128i v2 = _mm_loadl_epi64((const __m128i*)(src + x + 16)), v3; |
| 1406 | v0 = _mm_unpacklo_epi8(v0, z); // b0 g0 r0 b1 g1 r1 b2 g2 |
| 1407 | v1 = _mm_unpacklo_epi8(v1, z); // r2 b3 g3 r3 b4 g4 r4 b5 |
| 1408 | v2 = _mm_unpacklo_epi8(v2, z); // g5 r5 b6 g6 r6 b7 g7 r7 |
| 1409 | |
| 1410 | v3 = _mm_srli_si128(v2, 2); // ? b6 g6 r6 b7 g7 r7 0 |
| 1411 | v2 = _mm_or_si128(_mm_slli_si128(v2, 10), _mm_srli_si128(v1, 6)); // ? b4 g4 r4 b5 g5 r5 ? |
| 1412 | v1 = _mm_or_si128(_mm_slli_si128(v1, 6), _mm_srli_si128(v0, 10)); // ? b2 g2 r2 b3 g3 r3 ? |
| 1413 | v0 = _mm_slli_si128(v0, 2); // 0 b0 g0 r0 b1 g1 r1 ? |
| 1414 | |
| 1415 | // process pixels 0 & 1 |
| 1416 | t0 = _mm_madd_epi16(v0, m0); // a0 b0 a1 b1 |
| 1417 | t1 = _mm_madd_epi16(v0, m1); // c0 d0 c1 d1 |
| 1418 | t2 = _mm_madd_epi16(v0, m2); // e0 f0 e1 f1 |
| 1419 | v0 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0 |
| 1420 | t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1 |
| 1421 | t1 = _mm_unpacklo_epi32(t2, z); // e0 0 f0 0 |
| 1422 | t2 = _mm_unpackhi_epi32(t2, z); // e1 0 f1 0 |
| 1423 | r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v0, t1), _mm_unpackhi_epi64(v0,t1)), m3); // B0 G0 R0 0 |
| 1424 | r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B1 G1 R1 0 |
| 1425 | r0 = _mm_srai_epi32(r0, BITS); |
| 1426 | r1 = _mm_srai_epi32(r1, BITS); |
| 1427 | v0 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B0 G0 R0 B1 G1 R1 0 |
| 1428 | |
| 1429 | // process pixels 2 & 3 |
| 1430 | t0 = _mm_madd_epi16(v1, m0); // a0 b0 a1 b1 |
nothing calls this directly
no test coverage detected