compressorRLEB.cpp

00001 
00002 /* Copyright (c) 2010, Cedric Stalder <cedric.stalder@gmail.com>
00003  *               2010, Stefan Eilemann <eile@eyescale.ch>
00004  *
00005  * This library is free software; you can redistribute it and/or modify it under
00006  * the terms of the GNU Lesser General Public License version 2.1 as published
00007  * by the Free Software Foundation.
00008  *  
00009  * This library is distributed in the hope that it will be useful, but WITHOUT
00010  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00012  * details.
00013  * 
00014  * You should have received a copy of the GNU Lesser General Public License
00015  * along with this library; if not, write to the Free Software Foundation, Inc.,
00016  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00017  */
00018 
00019 #include "compressorRLEB.h"
00020 
00021 namespace
00022 {
00023 static const uint8_t _rleMarker = 0x42; // just a random number
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 // single symbol
00158                         oneLeft = 1;
00159            }
00160            --oneLeft;
00161 
00162            
00163            out[j] = one;
00164         }
00165 
00166     }
00167 }
00168 
00169 }
00170 }
Generated on Sun Aug 29 2010 13:53:09 for Equalizer 0.9.1 by  doxygen 1.7.1