LCOV - code coverage report
Current view: top level - co - dataIStream.cpp (source / functions) Hit Total Coverage
Test: Collage Lines: 62 90 68.9 %
Date: 2015-11-03 13:48:53 Functions: 16 18 88.9 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2007-2013, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *               2009-2010, Cedric Stalder <cedric.stalder@gmail.com>
       4             :  *
       5             :  * This file is part of Collage <https://github.com/Eyescale/Collage>
       6             :  *
       7             :  * This library is free software; you can redistribute it and/or modify it under
       8             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       9             :  * by the Free Software Foundation.
      10             :  *
      11             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      12             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      13             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      14             :  * details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public License
      17             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      18             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      19             :  */
      20             : 
      21             : #include "dataIStream.h"
      22             : 
      23             : #include "global.h"
      24             : #include "log.h"
      25             : #include "node.h"
      26             : 
      27             : #include <lunchbox/buffer.h>
      28             : #include <lunchbox/debug.h>
      29             : #include <pression/decompressor.h>
      30             : #include <pression/plugins/compressor.h>
      31             : 
      32             : #include <string.h>
      33             : 
      34             : namespace co
      35             : {
      36             : namespace detail
      37             : {
      38     2786453 : class DataIStream
      39             : {
      40             : public:
      41     2784713 :     explicit DataIStream( const bool swap_ )
      42             :         : input( 0 )
      43             :         , inputSize( 0 )
      44             :         , position( 0 )
      45     2784713 :         , swap( swap_ )
      46     2785905 :     {}
      47             : 
      48             :     /** The current input buffer */
      49             :     const uint8_t* input;
      50             : 
      51             :     /** The size of the input buffer */
      52             :     uint64_t inputSize;
      53             : 
      54             :     /** The current read position in the buffer */
      55             :     uint64_t position;
      56             : 
      57             :     pression::Decompressor decompressor; //!< current decompressor
      58             :     lunchbox::Bufferb data; //!< decompressed buffer
      59             :     bool swap; //!< Invoke endian conversion
      60             : };
      61             : }
      62             : 
      63     1016333 : DataIStream::DataIStream( const bool swap_ )
      64     1016333 :         : _impl( new detail::DataIStream( swap_ ))
      65     1016502 : {}
      66             : 
      67     1770358 : DataIStream::DataIStream( const DataIStream& rhs )
      68     1770358 :         : _impl( new detail::DataIStream( rhs._impl->swap ))
      69     1770359 : {}
      70             : 
      71     2786684 : DataIStream::~DataIStream()
      72             : {
      73     2786684 :     _reset();
      74     2786498 :     delete _impl;
      75     2785461 : }
      76             : 
      77      574892 : DataIStream& DataIStream::operator = ( const DataIStream& rhs )
      78             : {
      79      574892 :     _reset();
      80      574907 :     setSwapping( rhs.isSwapping( ));
      81      574935 :     return *this;
      82             : }
      83             : 
      84      575098 : void DataIStream::setSwapping( const bool onOff )
      85             : {
      86      575098 :     _impl->swap = onOff;
      87      575098 : }
      88             : 
      89     3617502 : bool DataIStream::isSwapping() const
      90             : {
      91     3617502 :     return _impl->swap;
      92             : }
      93             : 
      94     3356586 : void DataIStream::_reset()
      95             : {
      96     3356586 :     _impl->input     = 0;
      97     3356586 :     _impl->inputSize = 0;
      98     3356586 :     _impl->position  = 0;
      99     3356586 :     _impl->swap      = false;
     100     3356586 : }
     101             : 
     102     3042428 : void DataIStream::_read( void* data, uint64_t size )
     103             : {
     104     3042428 :     if( !_checkBuffer( ))
     105             :     {
     106           0 :         LBUNREACHABLE;
     107           0 :         LBERROR << "No more input data" << std::endl;
     108           0 :         return;
     109             :     }
     110             : 
     111     3042438 :     LBASSERT( _impl->input );
     112     3042441 :     if( size > _impl->inputSize - _impl->position )
     113             :     {
     114           0 :         LBERROR << "Not enough data in input buffer: need " << size
     115           0 :                 << " bytes, " << _impl->inputSize - _impl->position << " left "
     116           0 :                 << std::endl;
     117           0 :         LBUNREACHABLE;
     118             :         // TODO: Allow reads which are asymmetric to writes by reading from
     119             :         // multiple blocks here?
     120           0 :         return;
     121             :     }
     122             : 
     123     3042441 :     memcpy( data, _impl->input + _impl->position, size );
     124     3042441 :     _impl->position += size;
     125             : }
     126             : 
     127     2329981 : const void* DataIStream::getRemainingBuffer( const uint64_t size )
     128             : {
     129     2329981 :     if( !_checkBuffer( ))
     130           0 :         return 0;
     131             : 
     132     2331534 :     LBASSERT( _impl->position + size <= _impl->inputSize );
     133     2331055 :     if( _impl->position + size > _impl->inputSize )
     134           0 :         return 0;
     135             : 
     136     2331055 :     _impl->position += size;
     137     2331055 :     return _impl->input + _impl->position - size;
     138             : }
     139             : 
     140     2338036 : uint64_t DataIStream::getRemainingBufferSize()
     141             : {
     142     2338036 :     if( !_checkBuffer( ))
     143         109 :         return 0;
     144             : 
     145     2327443 :     return _impl->inputSize - _impl->position;
     146             : }
     147             : 
     148           0 : bool DataIStream::wasUsed() const
     149             : {
     150           0 :     return _impl->input != 0;
     151             : }
     152             : 
     153     7660110 : bool DataIStream::_checkBuffer()
     154             : {
     155    17750580 :     while( _impl->position >= _impl->inputSize )
     156             :     {
     157     2439479 :         uint32_t compressor = EQ_COMPRESSOR_NONE;
     158     2439479 :         uint32_t nChunks = 0;
     159     2439479 :         const void* data = 0;
     160             : 
     161     2439479 :         _impl->position = 0;
     162     2439479 :         _impl->input = 0;
     163     2439479 :         _impl->inputSize = 0;
     164             : 
     165     2439479 :         if( !getNextBuffer( compressor, nChunks, &data, _impl->inputSize ))
     166         158 :             return false;
     167             : 
     168             :         _impl->input = _decompress( data, compressor, nChunks,
     169     2433633 :                                     _impl->inputSize );
     170             :     }
     171     7650991 :     return true;
     172             : }
     173             : 
     174     2433210 : const uint8_t* DataIStream::_decompress( const void* data, const uint32_t name,
     175             :                                          const uint32_t nChunks,
     176             :                                          const uint64_t dataSize )
     177             : {
     178     2433210 :     const uint8_t* src = reinterpret_cast< const uint8_t* >( data );
     179     2433210 :     if( name == EQ_COMPRESSOR_NONE )
     180     2433210 :         return src;
     181             : 
     182           0 :     LBASSERT( name > EQ_COMPRESSOR_NONE );
     183             : #ifndef CO_AGGRESSIVE_CACHING
     184           0 :     _impl->data.clear();
     185             : #endif
     186           0 :     _impl->data.reset( dataSize );
     187             : 
     188           0 :     _impl->decompressor.setup( Global::getPluginRegistry(), name );
     189           0 :     LBASSERT( _impl->decompressor.uses( name ));
     190             : 
     191           0 :     uint64_t outDim[2] = { 0, dataSize };
     192             :     uint64_t* chunkSizes = static_cast< uint64_t* >(
     193           0 :                                 alloca( nChunks * sizeof( uint64_t )));
     194             :     void** chunks = static_cast< void ** >(
     195           0 :                                 alloca( nChunks * sizeof( void* )));
     196             : 
     197           0 :     for( uint32_t i = 0; i < nChunks; ++i )
     198             :     {
     199           0 :         const uint64_t size = *reinterpret_cast< const uint64_t* >( src );
     200           0 :         chunkSizes[ i ] = size;
     201           0 :         src += sizeof( uint64_t );
     202             : 
     203             :         // The plugin API uses non-const source buffers for in-place operations
     204           0 :         chunks[ i ] = const_cast< uint8_t* >( src );
     205           0 :         src += size;
     206             :     }
     207             : 
     208             :     _impl->decompressor.decompress( chunks, chunkSizes, nChunks,
     209           0 :                                     _impl->data.getData(), outDim );
     210           0 :     return _impl->data.getData();
     211             : }
     212             : 
     213          63 : }

Generated by: LCOV version 1.11