TuttleOFX  1
DPXWriterAlgorithm.hpp
Go to the documentation of this file.
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