Is there a way to convert a 16 bit image of interleaved (gray and alpha), to its equivalent planer buffers. The following code snippit is the only way that I could come up with. Any ideas to spead this up using IPP. Im aware of "ippiCopy..." but it has no functions split up interleaved 16 bit images into planer data.
unsigned short gray[] = {};
unsigned char gray1[w*h];
unsigned char gray2[w*h];
for (int n = 0; n < w*h; ++n)
{
unsigned char* a = (unsigned char*)&gray
gray1
gray2
}
Link Copied
that should do it:
[bash]/* Created: ReneGr */ void Copy_16u_C2P2(const unsigned short* pSrc, unsigned short* pDst1, unsigned short* pDst2, int n) { const __m128i* pSrcMM = (__m128i*)pSrc; __m128i* pDstMM1 = (__m128i*)pDst1; __m128i* pDstMM2 = (__m128i*)pDst2; __m128i t1, t2, t3, t4; for( ; n>=16; n-=16, pSrcMM+=2, ++pDstMM1, ++pDstMM2) { t1 = _mm_unpacklo_epi16( pSrcMM[0], pSrcMM[1]); t2 = _mm_unpackhi_epi16( pSrcMM[0], pSrcMM[1]); t3 = _mm_unpacklo_epi16( t1, t2); t4 = _mm_unpackhi_epi16( t1, t2); t1 = _mm_unpacklo_epi16( t3, t4); t2 = _mm_unpackhi_epi16( t3, t4); _mm_store_si128( pDstMM1, t1); _mm_store_si128( pDstMM2, t2); } if (n) { // C++ version for last 15 values } } [/bash]
Attention: the pointers must be 16 byte aligned. If pointers aren't 16 byte aligned, you could use _mm_storeu_si128 for storing and _mm_loadu_si128 for loading. But this will be much slower.
that should do it:
[bash]/* Created: ReneGr */ void Copy_16u_C2P2(const unsigned short* pSrc, unsigned short* pDst1, unsigned short* pDst2, int n) { const __m128i* pSrcMM = (__m128i*)pSrc; __m128i* pDstMM1 = (__m128i*)pDst1; __m128i* pDstMM2 = (__m128i*)pDst2; __m128i t1, t2, t3, t4; for( ; n>=16; n-=16, pSrcMM+=2, ++pDstMM1, ++pDstMM2) { t1 = _mm_unpacklo_epi16( pSrcMM[0], pSrcMM[1]); t2 = _mm_unpackhi_epi16( pSrcMM[0], pSrcMM[1]); t3 = _mm_unpacklo_epi16( t1, t2); t4 = _mm_unpackhi_epi16( t1, t2); t1 = _mm_unpacklo_epi16( t3, t4); t2 = _mm_unpackhi_epi16( t3, t4); _mm_store_si128( pDstMM1, t1); _mm_store_si128( pDstMM2, t2); } if (n) { // C++ version for last 15 values } } [/bash]
Attention: the pointers must be 16 byte aligned. If pointers aren't 16 byte aligned, you could use _mm_storeu_si128 for storing and _mm_loadu_si128 for loading. But this will be much slower.
For more complete information about compiler optimizations, see our Optimization Notice.