LCOV - code coverage report
Current view: top level - lunchbox/compressor - compressorRLEB.cpp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 73 76 96.1 %
Date: 2014-10-01 Functions: 30 30 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2010, Cedric Stalder <cedric.stalder@gmail.com>
       3             :  *               2010-2013, Stefan Eilemann <eile@eyescale.ch>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #include "compressorRLEB.h"
      20             : #include <limits>
      21             : 
      22             : namespace
      23             : {
      24             : static const uint8_t _rleMarker = 0x42; // just a random number
      25             : }
      26             : 
      27             : #include "compressorRLE.ipp"
      28             : 
      29             : namespace lunchbox
      30             : {
      31             : namespace plugin
      32             : {
      33             : namespace
      34             : {
      35          61 : REGISTER_ENGINE( CompressorRLEB, BYTE, BYTE, 1., 0.93, 1., false );
      36             : }
      37             : 
      38             : template< typename T >
      39         513 : inline void _compressChunk( const T* const in, const eq_uint64_t nPixels,
      40             :                             Compressor::Result* result )
      41             : {
      42         513 :     if( nPixels == 0 )
      43             :     {
      44           0 :         result->setSize( 0 );
      45         902 :         return;
      46             :     }
      47             : 
      48         513 :     T* tokenOut = reinterpret_cast< T* >( result->getData( ));
      49     5668654 :     T tokenLast( in[0] );
      50     5668654 :     T tokenSame( 1 );
      51     5668654 :     T token(0);
      52             : 
      53    39446936 :     for( eq_uint64_t i = 1; i < nPixels; ++i )
      54             :     {
      55    39446037 :         token = in[i];
      56    39446037 :         COMPRESS( token );
      57             :     }
      58             : 
      59         899 :     WRITE_OUTPUT( token );
      60         898 :     result->setSize( (tokenOut - reinterpret_cast< T* >( result->getData( ))) *
      61             :                      sizeof( T ));
      62             : #ifndef LUNCHBOX_AGGRESSIVE_CACHING
      63         899 :     result->pack();
      64             : #endif
      65             : }
      66             : 
      67             : template< typename T >
      68          76 : ssize_t _compress( const void* const inData, const eq_uint64_t nPixels,
      69             :                    Compressor::ResultVector& results )
      70             : {
      71          76 :     const eq_uint64_t size = nPixels * sizeof( T );
      72          76 :     const ssize_t nChunks = _setupResults( 1, size, results );
      73             :     const float width = static_cast< float >( nPixels ) /
      74          76 :                         static_cast< float >( nChunks );
      75             : 
      76          76 :     const T* const data = reinterpret_cast< const T* >( inData );
      77             : 
      78         658 : #pragma omp parallel for
      79         582 :     for( ssize_t i = 0; i < static_cast< ssize_t >( nChunks ) ; ++i )
      80             :     {
      81         609 :         const eq_uint64_t startIndex = static_cast< eq_uint64_t >( i * width );
      82             : 
      83             :         eq_uint64_t nextIndex;
      84         609 :         if ( i == nChunks - 1 )
      85          76 :             nextIndex = nPixels;
      86             :         else
      87         533 :             nextIndex = static_cast< eq_uint64_t >(( i + 1 ) * width );
      88         609 :         const eq_uint64_t chunkSize = ( nextIndex - startIndex );
      89             : 
      90         609 :         _compressChunk< T >( &data[ startIndex ], chunkSize, results[i] );
      91             :     }
      92          76 :     return nChunks;
      93             : }
      94             : 
      95             : 
      96          76 : void CompressorRLEB::compress( const void* const inData,
      97             :                                const eq_uint64_t nPixels, const bool /*alpha*/ )
      98             : {
      99          76 :     if( (nPixels & 0x7) == 0 )
     100          14 :         _nResults = _compress< eq_uint64_t >( inData, nPixels>>3, _results );
     101          62 :     else if( (nPixels & 0x3) == 0 )
     102          14 :         _nResults = _compress< uint32_t >( inData, nPixels>>2, _results );
     103          48 :     else if( (nPixels & 0x1) == 0 )
     104          18 :         _nResults = _compress< uint16_t >( inData, nPixels>>1, _results );
     105             :     else
     106          30 :         _nResults = _compress< uint8_t >( inData, nPixels, _results );
     107          76 : }
     108             : 
     109             : //----------------------------------------------------------------------
     110             : template< typename T >
     111         900 : inline void _decompressChunk( const T* in, T* out, const eq_uint64_t nPixels )
     112             : {
     113         900 :     T token(0);
     114         900 :     T tokenLeft(0);
     115             : 
     116    40315444 :     for( eq_uint64_t i = 0; i < nPixels ; ++i )
     117             :     {
     118    40314544 :         if( tokenLeft == 0 )
     119             :         {
     120    41590014 :             token = *in; ++in;
     121    41590014 :             if( token == _rleMarker )
     122             :             {
     123           0 :                 token     = *in; ++in;
     124           0 :                 tokenLeft = *in; ++in;
     125             :             }
     126             :             else // single symbol
     127    42737998 :                 tokenLeft = 1;
     128             :         }
     129             : 
     130    40314544 :         --tokenLeft;
     131    40314544 :         out[i] = token;
     132             :     }
     133         900 : }
     134             : 
     135             : 
     136             : template< typename T >
     137          76 : void _decompress( const void* const* inData, const unsigned nInputs,
     138             :                   void* const outData, const eq_uint64_t nPixels )
     139             : {
     140             :     const float width = static_cast< float >( nPixels ) /
     141          76 :                         static_cast< float >( nInputs );
     142             : 
     143          76 :     const T* const* in = reinterpret_cast< const T* const* >( inData );
     144             : 
     145         611 : #pragma omp parallel for
     146         535 :     for( ssize_t i = 0; i < static_cast< ssize_t >( nInputs ) ; ++i )
     147             :     {
     148         658 :         const eq_uint64_t startIndex = static_cast<uint64_t>( i * width );
     149             : 
     150             :         eq_uint64_t nextIndex;
     151         658 :         if ( i == static_cast<ssize_t>( nInputs -1 ) )
     152          76 :             nextIndex = nPixels;
     153             :         else
     154         582 :             nextIndex = static_cast< eq_uint64_t >(( i + 1 ) * width );
     155             : 
     156         658 :         const eq_uint64_t chunkSize = ( nextIndex - startIndex );
     157         658 :         T* out = reinterpret_cast< T* >( outData ) + startIndex;
     158             : 
     159         658 :         _decompressChunk< T >( in[i], out, chunkSize );
     160             :     }
     161          76 : }
     162             : 
     163          76 : void CompressorRLEB::decompress( const void* const* inData,
     164             :                                  const eq_uint64_t* const /*inSizes*/,
     165             :                                  const unsigned nInputs, void* const outData,
     166             :                                  eq_uint64_t* const outDims,
     167             :                                  const eq_uint64_t flags, void* const )
     168             : {
     169          76 :     const eq_uint64_t nPixels = ( flags & EQ_COMPRESSOR_DATA_1D) ?
     170          76 :                                     outDims[1] : outDims[1] * outDims[3];
     171          76 :     if( (nPixels & 0x7) == 0 )
     172          14 :         _decompress< uint64_t >( inData, nInputs, outData, nPixels>>3 );
     173          62 :     else if( (nPixels & 0x3) == 0 )
     174          14 :         _decompress< uint32_t >( inData, nInputs, outData, nPixels>>2 );
     175          48 :     else if( (nPixels & 0x1) == 0 )
     176          18 :         _decompress< uint16_t >( inData, nInputs, outData, nPixels>>1 );
     177             :     else
     178          30 :         _decompress< uint8_t >( inData, nInputs, outData, nPixels );
     179          76 : }
     180             : 
     181             : }
     182          90 : }

Generated by: LCOV version 1.10