00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "compressorRLEB.h"
00020
00021 namespace
00022 {
00023 static const uint8_t _rleMarker = 0x42;
00024 }
00025
00026 #include "compressorRLE.ipp"
00027
00028 namespace eq
00029 {
00030 namespace plugin
00031 {
00032 namespace
00033 {
00034 REGISTER_ENGINE( CompressorRLEB, BYTE, BYTE, 1., 0.7, 1., false );
00035 }
00036
00037 static inline void _compress( const void* const input, const uint64_t nPixels,
00038 eq::plugin::Compressor::Result** results )
00039 {
00040 if( nPixels == 0 )
00041 {
00042 results[0]->setSize( 0 );
00043 return;
00044 }
00045
00046 const uint8_t* pixel = reinterpret_cast< const uint8_t* >( input );
00047 uint8_t* oneOut( reinterpret_cast< uint8_t* >(
00048 results[ 0 ]->getData( )));
00049
00050 uint8_t oneLast(pixel[0]);
00051 uint8_t oneSame( 1 );
00052 uint8_t one(0);
00053
00054 for( uint64_t i = 1; i < nPixels; ++i )
00055 {
00056 one = pixel[i];
00057 if( one == oneLast && oneSame != 255 )
00058 ++oneSame;
00059 else
00060 {
00061 WRITE_OUTPUT( one );
00062 oneLast = one;
00063 oneSame = 1;
00064 }
00065 }
00066
00067 WRITE_OUTPUT( one );
00068
00069 results[0]->setSize( reinterpret_cast< uint8_t* > ( oneOut ) -
00070 results[0]->getData( ));
00071 }
00072
00073 void CompressorRLEB::compress( const void* const inData,
00074 const eq_uint64_t nPixels, const bool useAlpha,
00075 const bool swizzle )
00076 {
00077 const uint64_t size = nPixels;
00078 const ssize_t nChunks = _setupResults( 1, size, _results );
00079
00080 const uint64_t nElems = nPixels;
00081 const float width = static_cast< float >( nElems ) /
00082 static_cast< float >( nChunks );
00083
00084 const uint8_t* const data =
00085 reinterpret_cast< const uint8_t* >( inData );
00086
00087 #ifdef EQ_USE_OPENMP
00088 #pragma omp parallel for
00089 #endif
00090 for( ssize_t i = 0; i < static_cast< ssize_t >( nChunks ) ; i++ )
00091 {
00092 const uint64_t startIndex = static_cast< uint64_t >( i * width );
00093
00094 uint64_t nextIndex;
00095 if ( i == nChunks -1 )
00096 nextIndex = nPixels;
00097 else
00098 nextIndex = static_cast< uint64_t >(( i + 1 ) * width );
00099 const uint64_t chunkSize = ( nextIndex - startIndex );
00100
00101 _compress( &data[ startIndex ], chunkSize, &_results[i] );
00102 }
00103 _nResults = nChunks;
00104 }
00105
00106 void CompressorRLEB::decompress( const void* const* inData,
00107 const eq_uint64_t* const inSizes,
00108 const unsigned nInputs,
00109 void* const outData,
00110 const eq_uint64_t nPixels,
00111 const bool useAlpha )
00112 {
00113 assert( (inSizes[0] % sizeof( uint8_t )) == 0 );
00114 assert( (inSizes[1] % sizeof( uint8_t )) == 0 );
00115 assert( (inSizes[2] % sizeof( uint8_t )) == 0 );
00116
00117 const uint64_t nElems = nPixels;
00118 const float width = static_cast< float >( nElems ) /
00119 static_cast< float >( nInputs );
00120
00121 const uint8_t* const* in =
00122 reinterpret_cast< const uint8_t* const* >( inData );
00123
00124 #ifdef EQ_USE_OPENMP
00125 #pragma omp parallel for
00126 #endif
00127 for( ssize_t i = 0; i < static_cast< ssize_t >( nInputs ) ; i++ )
00128 {
00129 const uint64_t startIndex = static_cast<uint64_t>( i * width );
00130
00131 uint64_t nextIndex;
00132 if ( i == static_cast<ssize_t>( nInputs -1 ) )
00133 nextIndex = nPixels;
00134 else
00135 nextIndex = static_cast< uint64_t >(( i + 1 ) * width );
00136
00137 const uint64_t chunkSize = ( nextIndex - startIndex );
00138 uint8_t* out = reinterpret_cast< uint8_t* >( outData ) +
00139 startIndex;
00140
00141 const uint8_t* oneIn = in[ i + 0 ];
00142
00143 uint8_t one(0);
00144 uint8_t oneLeft(0);
00145
00146 for( uint64_t j = 0; j < chunkSize ; ++j )
00147 {
00148
00149 if( oneLeft == 0 )
00150 {
00151 one = *oneIn; ++oneIn;
00152 if( one == _rleMarker )
00153 {
00154 one = *oneIn; ++oneIn;
00155 oneLeft = *oneIn; ++oneIn;
00156 }
00157 else
00158 oneLeft = 1;
00159 }
00160 --oneLeft;
00161
00162
00163 out[j] = one;
00164 }
00165
00166 }
00167 }
00168
00169 }
00170 }