MCPcopy Create free account
hub / github.com/creatale/node-dv / transform_8u

Function transform_8u

deps/opencv/modules/core/src/matmul.cpp:1373–1492  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1371#endif
1372
1373static void
1374transform_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

Callers

nothing calls this directly

Calls 2

transform_Function · 0.85
absFunction · 0.70

Tested by

no test coverage detected