TuttleOFX
1
|
00001 #ifndef _TUTTLE_PLUGIN_DPXWRITER_ALGORITHM_HPP_ 00002 #define _TUTTLE_PLUGIN_DPXWRITER_ALGORITHM_HPP_ 00003 00004 #include <boost/gil/gil_all.hpp> 00005 00006 #ifndef __SSSE3__ 00007 #include <emmintrin.h> 00008 #else 00009 // SSSE3 00010 #include <tmmintrin.h> 00011 #endif 00012 00013 #include <tuttle/plugin/memory/OfxAllocator.hpp> 00014 #include <vector> 00015 00016 using namespace boost::gil; 00017 00018 typedef std::vector<char, tuttle::plugin::OfxAllocator<char> > DataVector; 00019 00020 void convertGrayToRGB( DataVector& dataVec, size_t width, size_t height, int pixelSize ) 00021 { 00022 size_t size = width * height; 00023 switch( pixelSize ) 00024 { 00025 case 1 : 00026 { 00027 char* ptrS = (char*) &dataVec.front(); 00028 char* ptrD = (char*) &dataVec.front(); 00029 // go to end of image 00030 ptrS += size - 1; 00031 ptrD += (3 * size) - 1; 00032 // process from back to begin 00033 for(size_t i = 0; i< size; i++) 00034 { 00035 *ptrD = *ptrS; ptrD--; // red 00036 *ptrD = *ptrS; ptrD--; // green 00037 *ptrD = *ptrS; ptrD--; ptrS--; // blue 00038 } 00039 break; 00040 } 00041 case 2: 00042 { 00043 short* ptrS = (short*) &dataVec.front(); 00044 short* ptrD = (short*) &dataVec.front(); 00045 // go to end of image 00046 ptrS += size - 1; 00047 ptrD += (3 * size) - 1; 00048 // process from back to begin 00049 for(size_t i = 0; i< size; i++) 00050 { 00051 *ptrD = *ptrS; ptrD--; // red 00052 *ptrD = *ptrS; ptrD--; // green 00053 *ptrD = *ptrS; ptrD--; ptrS--; // blue 00054 } 00055 break; 00056 } 00057 case 4 : 00058 { 00059 float* ptrS = (float*) &dataVec.front(); 00060 float* ptrD = (float*) &dataVec.front(); 00061 // go to end of image 00062 ptrS += size - 1; 00063 ptrD += (3 * size) - 1; 00064 // process from back to begin 00065 for(size_t i = 0; i< size; i++) 00066 { 00067 *ptrD = *ptrS; ptrD--; // red 00068 *ptrD = *ptrS; ptrD--; // green 00069 *ptrD = *ptrS; ptrD--; ptrS--; // blue 00070 } 00071 break; 00072 } 00073 } 00074 } 00075 00076 void convertRGBToRGBA() 00077 { 00078 00079 } 00080 00081 void convertRGBToABGR() 00082 { 00083 00084 } 00085 00086 void convertRGBAToRGB( DataVector& dataVec, size_t width, size_t height, int pixelSize ) 00087 { 00088 size_t size = width * height; 00089 00090 switch( pixelSize ) 00091 { 00092 case 4 : 00093 { 00094 char* ptrS = (char*) &dataVec.front(); 00095 char* ptrD = ptrS; 00096 for(size_t i = 0; i< size; i++) 00097 { 00098 *ptrD = *ptrS; ptrS++; ptrD++; // red 00099 *ptrD = *ptrS; ptrS++; ptrD++; // green 00100 *ptrD = *ptrS; ptrS+=2;/*skip alpha*/ ptrD++; // blue 00101 } 00102 break; 00103 } 00104 case 8: 00105 { 00106 short* ptrS = (short*) &dataVec.front(); 00107 short* ptrD = ptrS; 00108 for(size_t i = 0; i< size; i++) 00109 { 00110 *ptrD = *ptrS; ptrS++; ptrD++; // red 00111 *ptrD = *ptrS; ptrS++; ptrD++; // green 00112 *ptrD = *ptrS; ptrS+=2;/*skip alpha*/ ptrD++; // blue 00113 } 00114 break; 00115 } 00116 case 16 : 00117 { 00118 float* ptrS = (float*) &dataVec.front(); 00119 float* ptrD = ptrS; 00120 for(size_t i = 0; i< size; i++) 00121 { 00122 *ptrD = *ptrS; ptrS++; ptrD++; // red 00123 *ptrD = *ptrS; ptrS++; ptrD++; // green 00124 *ptrD = *ptrS; ptrS+=2;/*skip alpha*/ ptrD++; // blue 00125 } 00126 } 00127 } 00128 } 00129 00130 void convertRGBAToABGR( DataVector& dataVec, size_t width, size_t height, int pixelSize ) 00131 { 00132 float* dataPtrIt = (float*)&dataVec.front(); 00133 __m128i* dataCharIt = NULL; 00134 __m128i data, mask; 00135 00136 char* charPtr = NULL; 00137 // define flipping data 00138 char charMask [16] = {0x03, 0x02, 0x01, 0x00, // pixel 1 00139 0x07, 0x06, 0x05, 0x04, // pixel 2 00140 0x0B, 0x0A, 0x09, 0x08, // pixel 3 00141 0x0F, 0x0E, 0x0D, 0x0C // pixel 4 00142 }; 00143 char shortMask [16] = {0x06, 0x07, 0x04, 0x05, 0x02, 0x03, 0x00, 0x01, // pixel 1 00144 0x0E, 0x0F, 0x0C, 0x0D, 0x0A, 0x0B, 0x08, 0x09 // pixel 2 00145 }; 00146 00147 size_t size = width * height; 00148 00149 size_t i = 0; 00150 00151 switch( pixelSize ) 00152 { 00153 case 4 : 00154 { 00155 // loading mask to flip with char data 00156 mask = _mm_loadu_si128( (__m128i*)charMask ); 00157 #ifndef __SSSE3__ 00158 __m128i maskA = _mm_set_epi32 ( 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff); 00159 __m128i maskB = _mm_sll_epi32 ( maskA, _mm_set_epi32( 8, 8, 8, 8 ) ); 00160 __m128i maskC = _mm_sll_epi32 ( maskB, _mm_set_epi32( 8, 8, 8, 8 ) ); 00161 __m128i maskD = _mm_sll_epi32 ( maskC, _mm_set_epi32( 8, 8, 8, 8 ) ); 00162 #endif 00163 for(; i< size - 3; i+=4) 00164 { 00165 dataCharIt = (__m128i*) dataPtrIt; 00166 data = _mm_loadu_si128( dataCharIt ); 00167 #ifdef __SSSE3__ 00168 data = _mm_shuffle_epi8( data, mask ); 00169 #else 00170 00171 __m128i result = _mm_srl_epi32 ( _mm_and_si128( data, maskD ), _mm_set_epi32( 24, 24, 24, 24 ) ); 00172 result = _mm_or_si128( _mm_srl_epi32( _mm_and_si128( data, maskC ), _mm_set_epi32( 8, 8, 8, 8 ) ), result ); 00173 result = _mm_or_si128( _mm_sll_epi32( _mm_and_si128( data, maskB ), _mm_set_epi32( 8, 8, 8, 8 ) ), result ); 00174 result = _mm_or_si128( _mm_sll_epi32( _mm_and_si128( data, maskA ), _mm_set_epi32( 24, 24, 24, 24 ) ), result ); 00175 00176 data = result; 00177 #endif 00178 _mm_store_si128( dataCharIt , data ); 00179 dataPtrIt += 4; 00180 } 00181 charPtr = (char*)dataPtrIt; 00182 for( size_t lastPixel =0; lastPixel < size-i; i++ ) 00183 { 00184 char pixel[4]; 00185 for( size_t c=0; c<4; c++) 00186 { 00187 pixel[c]= *charPtr; 00188 charPtr++; 00189 } 00190 charPtr -=4; 00191 for( int c=3; c>-1; c--) 00192 { 00193 *charPtr = pixel[c]; 00194 charPtr++; 00195 } 00196 } 00197 break; 00198 } 00199 case 8: 00200 { 00201 // loading mask to flip with short data 00202 mask = _mm_loadu_si128( (__m128i*)shortMask ); 00203 #ifndef __SSSE3__ 00204 __m128i maskA = _mm_set_epi32 ( 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff ); 00205 __m128i maskB = _mm_sll_epi32 ( maskA, _mm_set_epi32( 16, 16, 16, 16 ) ); 00206 __m128i maskC = _mm_set_epi32 ( 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000 ); 00207 __m128i maskD = _mm_sll_epi32 ( maskC, _mm_set_epi32( 16, 16, 16, 16 ) ); 00208 #endif 00209 for( ; i < size - 1; i+=2 ) 00210 { 00211 dataCharIt = (__m128i*) dataPtrIt; 00212 data = _mm_loadu_si128( dataCharIt ); 00213 #ifdef __SSSE3__ 00214 data = _mm_shuffle_epi8( data, mask ); 00215 #else 00216 __m128i result = _mm_srl_epi32 ( _mm_and_si128( data, maskD ), _mm_set_epi32( 48, 48, 48, 48 ) ); 00217 result = _mm_or_si128( _mm_srl_epi32( _mm_and_si128( data, maskC ), _mm_set_epi32( 16, 16, 16, 16 ) ), result ); 00218 result = _mm_or_si128( _mm_sll_epi32( _mm_and_si128( data, maskB ), _mm_set_epi32( 16, 16, 16, 16 ) ), result ); 00219 result = _mm_or_si128( _mm_sll_epi32( _mm_and_si128( data, maskA ), _mm_set_epi32( 48, 48, 48, 48 ) ), result ); 00220 00221 data = result; 00222 #endif 00223 _mm_store_si128( dataCharIt , data ); 00224 dataPtrIt += 4; 00225 } 00226 if( i != size ) 00227 { 00228 short* shortPtr = (short*)dataPtrIt; 00229 short pixel[4]; 00230 for( size_t c=0; c<4; c++) 00231 { 00232 pixel[c]= *shortPtr; 00233 shortPtr++; 00234 } 00235 shortPtr -=4; 00236 for( int c=3; c>-1; c--) 00237 { 00238 *shortPtr = pixel[c]; 00239 shortPtr++; 00240 } 00241 } 00242 break; 00243 } 00244 case 16 : 00245 { 00246 float* dataFloatIt; 00247 dataFloatIt = dataPtrIt; 00248 00249 /*for(char c=0; c<4; c++) 00250 TUTTLE_LOG_INFO( *(dataFloatIt+c) ); 00251 TUTTLE_LOG_INFO( "" );*/ 00252 00253 __m128 floatData; 00254 // only interate on 1 dimension: 128 bits is one pixel 00255 for(; i< size; i++) 00256 { 00257 // load 4 float into floatData ( R, G, B, A ) 00258 floatData = _mm_loadu_ps(dataPtrIt); 00259 // store reversed ( A, B, G, R ) 00260 _mm_storer_ps( dataPtrIt , floatData ); 00261 // increase pointer from 4 float 00262 dataPtrIt += 4; 00263 } 00264 00265 /*for(char i=0; i<4; i++) 00266 TUTTLE_LOG_INFO( *(dataFloatIt+i) );*/ 00267 break; 00268 } 00269 } 00270 } 00271 00272 void selectChannelInRGB() 00273 { 00274 00275 } 00276 00277 void selectChannelInRGBA( void* dataSrcPtr ) 00278 { 00279 // boost::gil::rgb32f_view_t vw = boost::gil::interleaved_view ( size.x, size.y, Iterator pixels, std::ptrdiff_t rowsize_in_bytes); 00280 } 00281 00282 #endif