LCOV - code coverage report
Current view: top level - pression/compressor - compressorRLEB.cpp (source / functions) Hit Total Coverage
Test: Pression Lines: 76 78 97.4 %
Date: 2016-12-06 05:44:58 Functions: 30 30 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2010-2016, Cedric Stalder <cedric.stalder@gmail.com>
       3             :  *                          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 pression
      30             : {
      31             : namespace plugin
      32             : {
      33             : namespace
      34             : {
      35           3 : REGISTER_ENGINE( CompressorRLEB, BYTE, BYTE, 1., 0.97, 1., false );
      36             : }
      37             : 
      38             : template< typename T >
      39         278 : inline void _compressChunk( const T* const in, const eq_uint64_t nPixels,
      40             :                             Compressor::Result* result )
      41             : {
      42         278 :     if( nPixels == 0 )
      43             :     {
      44           0 :         result->setSize( 0 );
      45           0 :         return;
      46             :     }
      47             : 
      48         278 :     T* tokenOut = reinterpret_cast< T* >( result->getData( ));
      49       18750 :     T tokenLast( in[0] );
      50       18750 :     T tokenSame( 1 );
      51       18750 :     T token(0);
      52             : 
      53    29445902 :     for( eq_uint64_t i = 1; i < nPixels; ++i )
      54             :     {
      55    29445465 :         token = in[i];
      56    29445465 :         COMPRESS( token );
      57             :     }
      58             : 
      59         437 :     WRITE_OUTPUT( token );
      60         437 :     result->setSize( (tokenOut - reinterpret_cast< T* >( result->getData( ))) *
      61             :                      sizeof( T ));
      62             : #ifndef PRESSION_AGGRESSIVE_CACHING
      63         437 :     result->pack();
      64             : #endif
      65             : }
      66             : 
      67             : template< typename T >
      68          74 : ssize_t _compress( const void* const inData, const eq_uint64_t nPixels,
      69             :                    Compressor::ResultVector& results )
      70             : {
      71          74 :     const eq_uint64_t size = nPixels * sizeof( T );
      72          74 :     const ssize_t nChunks = _setupResults( 1, size, results );
      73          74 :     const float width = static_cast< float >( nPixels ) /
      74          74 :                         static_cast< float >( nChunks );
      75             : 
      76          74 :     const T* const data = reinterpret_cast< const T* >( inData );
      77             : 
      78         316 : #pragma omp parallel for
      79         242 :     for( ssize_t i = 0; i < static_cast< ssize_t >( nChunks ) ; ++i )
      80             :     {
      81         332 :         const eq_uint64_t startIndex = static_cast< eq_uint64_t >( i * width );
      82             : 
      83             :         eq_uint64_t nextIndex;
      84         332 :         if ( i == nChunks - 1 )
      85          74 :             nextIndex = nPixels;
      86             :         else
      87         258 :             nextIndex = static_cast< eq_uint64_t >(( i + 1 ) * width );
      88         332 :         const eq_uint64_t chunkSize = ( nextIndex - startIndex );
      89             : 
      90         332 :         _compressChunk< T >( &data[ startIndex ], chunkSize, results[i] );
      91             :     }
      92          74 :     return nChunks;
      93             : }
      94             : 
      95             : 
      96          74 : void CompressorRLEB::compress( const void* const inData,
      97             :                                const eq_uint64_t nPixels, const bool /*alpha*/ )
      98             : {
      99          74 :     if( (nPixels & 0x7) == 0 )
     100          36 :         _nResults = _compress< eq_uint64_t >( inData, nPixels>>3, _results );
     101          38 :     else if( (nPixels & 0x3) == 0 )
     102          12 :         _nResults = _compress< uint32_t >( inData, nPixels>>2, _results );
     103          26 :     else if( (nPixels & 0x1) == 0 )
     104          14 :         _nResults = _compress< uint16_t >( inData, nPixels>>1, _results );
     105             :     else
     106          12 :         _nResults = _compress< uint8_t >( inData, nPixels, _results );
     107          74 : }
     108             : 
     109             : //----------------------------------------------------------------------
     110             : template< typename T >
     111         439 : inline void _decompressChunk( const T* in, T* out, const eq_uint64_t nPixels )
     112             : {
     113         439 :     T token(0);
     114         439 :     T tokenLeft(0);
     115             : 
     116    30486260 :     for( eq_uint64_t i = 0; i < nPixels ; ++i )
     117             :     {
     118    30485821 :         if( tokenLeft == 0 )
     119             :         {
     120    29932927 :             token = *in; ++in;
     121    29932927 :             if( token == _rleMarker )
     122             :             {
     123      181776 :                 token     = *in; ++in;
     124      181776 :                 tokenLeft = *in; ++in;
     125             :             }
     126             :             else // single symbol
     127    29751151 :                 tokenLeft = 1;
     128             :         }
     129             : 
     130    30485821 :         --tokenLeft;
     131    30485821 :         out[i] = token;
     132             :     }
     133         439 : }
     134             : 
     135             : 
     136             : template< typename T >
     137          74 : void _decompress( const void* const* inData, const unsigned nInputs,
     138             :                   void* const outData, const eq_uint64_t nPixels )
     139             : {
     140          74 :     const float width = static_cast< float >( nPixels ) /
     141          74 :                         static_cast< float >( nInputs );
     142             : 
     143          74 :     const T* const* in = reinterpret_cast< const T* const* >( inData );
     144             : 
     145         310 : #pragma omp parallel for
     146         236 :     for( ssize_t i = 0; i < static_cast< ssize_t >( nInputs ) ; ++i )
     147             :     {
     148         334 :         const eq_uint64_t startIndex = static_cast<uint64_t>( i * width );
     149             : 
     150             :         eq_uint64_t nextIndex;
     151         334 :         if ( i == static_cast<ssize_t>( nInputs -1 ) )
     152          74 :             nextIndex = nPixels;
     153             :         else
     154         260 :             nextIndex = static_cast< eq_uint64_t >(( i + 1 ) * width );
     155             : 
     156         334 :         const eq_uint64_t chunkSize = ( nextIndex - startIndex );
     157         334 :         T* out = reinterpret_cast< T* >( outData ) + startIndex;
     158             : 
     159         334 :         _decompressChunk< T >( in[i], out, chunkSize );
     160             :     }
     161          74 : }
     162             : 
     163          74 : 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          74 :     const eq_uint64_t nPixels = ( flags & EQ_COMPRESSOR_DATA_1D) ?
     170          74 :                                     outDims[1] : outDims[1] * outDims[3];
     171          74 :     if( (nPixels & 0x7) == 0 )
     172          36 :         _decompress< uint64_t >( inData, nInputs, outData, nPixels>>3 );
     173          38 :     else if( (nPixels & 0x3) == 0 )
     174          12 :         _decompress< uint32_t >( inData, nInputs, outData, nPixels>>2 );
     175          26 :     else if( (nPixels & 0x1) == 0 )
     176          14 :         _decompress< uint16_t >( inData, nInputs, outData, nPixels>>1 );
     177             :     else
     178          12 :         _decompress< uint8_t >( inData, nInputs, outData, nPixels );
     179          74 : }
     180             : 
     181             : }
     182           3 : }

Generated by: LCOV version 1.11