LCOV - code coverage report
Current view: top level - lunchbox/compressor - compressorTurboJPEG.cpp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 13 102 12.7 %
Date: 2014-10-01 Functions: 26 34 76.5 %

          Line data    Source code
       1             : 
       2             : /*
       3             :  * Copyright (c) 2010, Eyescale Software GmbH <info@eyescale.ch>
       4             :  *               2013, Stefan.Eilemann@epfl.ch
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or modify it under
       7             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       8             :  * by the Free Software Foundation.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      11             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      12             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      13             :  * details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      17             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             :  */
      19             : 
      20             : #include "compressorTurboJPEG.h"
      21             : 
      22             : #include <iostream>
      23             : #include <math.h>
      24             : 
      25             : #define QUOTE( string ) STRINGIFY( string )
      26             : #define STRINGIFY( foo ) #foo
      27             : 
      28             : namespace lunchbox
      29             : {
      30             : namespace plugin
      31             : {
      32             : namespace
      33             : {
      34             :     static int _version; // Eq plugin API version
      35             :     typedef const char* ( *GetKey_t ) ();
      36             : 
      37             : #define REGISTER_ENGINE( token_, name_, quality_, ratio_, speed_, alpha )    \
      38             :     static void _getInfoTurbo ## token_ ## name_ ## alpha( EqCompressorInfo* const info ) \
      39             :     {                                                                        \
      40             :         _version = info->version;                                            \
      41             :         info->version = EQ_COMPRESSOR_VERSION;                               \
      42             :         info->capabilities = EQ_COMPRESSOR_DATA_2D;                          \
      43             :         if( alpha )                                                          \
      44             :             info->capabilities |= EQ_COMPRESSOR_IGNORE_ALPHA;                \
      45             :         info->quality = quality_ ## f;                                       \
      46             :         info->ratio   = ratio_ ## f;                                         \
      47             :         info->speed   = speed_ ## f;                                         \
      48             :         info->name = EQ_COMPRESSOR_CH_EYESCALE_JPEG_## token_ ## name_;      \
      49             :         info->tokenType = EQ_COMPRESSOR_DATATYPE_ ## token_;                 \
      50             :         if( alpha )                                                          \
      51             :         {                                                                    \
      52             :             if( _version > 2 )                                               \
      53             :             {                                                                \
      54             :                 info->outputTokenType = EQ_COMPRESSOR_DATATYPE_ ## token_;   \
      55             :                 info->outputTokenSize = 3;                                   \
      56             :             }                                                                \
      57             :         }                                                                    \
      58             :         else if( _version < 3 )                                              \
      59             :             info->tokenType = EQ_COMPRESSOR_DATATYPE_INVALID;                \
      60             :     }                                                                        \
      61             :                                                                              \
      62             :     static bool _registerTurbo ## token_ ## name_ ## alpha()                 \
      63             :     {                                                                        \
      64             :         Compressor::registerEngine(                                          \
      65             :             Compressor::Functions(                                           \
      66             :                 EQ_COMPRESSOR_CH_EYESCALE_JPEG_ ## token_ ## name_,          \
      67             :                _getInfoTurbo ## token_ ## name_ ## alpha,                    \
      68             :                CompressorTurboJPEG::getNewCompressor,                        \
      69             :                CompressorTurboJPEG::getNewCompressor,                        \
      70             :                CompressorTurboJPEG::decompress, 0 ));                        \
      71             :         return true;                                                         \
      72             :     }                                                                        \
      73             :                                                                              \
      74             :     static bool _initialized ## token_ ## name_ ## alpha =                   \
      75             :         _registerTurbo ## token_ ## name_ ## alpha();
      76             : 
      77          61 : REGISTER_ENGINE( RGBA, 100, 0.95, 0.33, 0.34, true );
      78          61 : REGISTER_ENGINE( BGRA, 100, 0.95, 0.33, 0.34, true );
      79             : 
      80          61 : REGISTER_ENGINE( RGBA, 90, 0.9, 0.09, 0.65, true );
      81          61 : REGISTER_ENGINE( BGRA, 90, 0.9, 0.09, 0.65, true );
      82             : 
      83          61 : REGISTER_ENGINE( RGBA, 80, 0.8, 0.07, 0.75, true );
      84          61 : REGISTER_ENGINE( BGRA, 80, 0.8, 0.07, 0.75, true );
      85             : 
      86          61 : REGISTER_ENGINE( RGB, 100, 0.95, 0.3, 1.2, false );
      87          61 : REGISTER_ENGINE( RGB, 90, 0.9, 0.3, 1.2, false );
      88          61 : REGISTER_ENGINE( RGB, 80, 0.8, 0.3, 1.2, false );
      89          61 : REGISTER_ENGINE( BGR, 100, 0.95, 0.3, 1.2, false );
      90          61 : REGISTER_ENGINE( BGR, 90, 0.9, 0.3, 1.2, false );
      91          61 : REGISTER_ENGINE( BGR, 80, 0.8, 0.3, 1.2, false );
      92             : }
      93             : 
      94           0 : CompressorTurboJPEG::CompressorTurboJPEG( const unsigned name )
      95             :      : Compressor()
      96             :      , _quality( 100 )
      97             :      , _tokenSize( 4 )
      98             :      , _flags( 0 )
      99             :      , _encoder( 0 )
     100           0 :      , _decoder( 0 )
     101             : {
     102           0 :     switch( name )
     103             :     {
     104             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_BGRA80:
     105           0 :             _flags = TJ_BGR;
     106             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_RGBA80:
     107           0 :             _quality = 80;
     108           0 :             break;
     109             : 
     110             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_BGRA90:
     111           0 :             _flags = TJ_BGR;
     112             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_RGBA90:
     113           0 :             _quality = 90;
     114           0 :             break;
     115             : 
     116             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_BGRA100:
     117           0 :             _flags = TJ_BGR;
     118             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_RGBA100:
     119           0 :             break;
     120             : 
     121             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_BGR80:
     122           0 :             _flags = TJ_BGR;
     123             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_RGB80:
     124           0 :             _quality = 80;
     125           0 :             _tokenSize = 3;
     126           0 :             break;
     127             : 
     128             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_BGR90:
     129           0 :             _flags = TJ_BGR;
     130             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_RGB90:
     131           0 :             _quality = 90;
     132           0 :             _tokenSize = 3;
     133           0 :             break;
     134             : 
     135             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_BGR100:
     136           0 :             _flags = TJ_BGR;
     137             :         case EQ_COMPRESSOR_CH_EYESCALE_JPEG_RGB100:
     138           0 :             _tokenSize = 3;
     139           0 :             break;
     140             : 
     141             :         default:
     142           0 :             assert( false );
     143             :     }
     144             : 
     145           0 :     _flags = _flags | TJ_FASTUPSAMPLE;
     146           0 :     _results.push_back( new Result ); // RGB jpeg
     147           0 :     _results.push_back( new Result ); // Alpha uncompressed TODO RLE
     148           0 : }
     149             : 
     150           0 : CompressorTurboJPEG::~CompressorTurboJPEG()
     151             : {
     152           0 :     if( _decoder )
     153           0 :         tjDestroy( _decoder );
     154           0 :     _decoder = 0;
     155             : 
     156           0 :     if( _encoder )
     157           0 :         tjDestroy( _encoder );
     158           0 :     _encoder = 0;
     159             : 
     160           0 : }
     161             : 
     162           0 : void CompressorTurboJPEG::compress( const void* const inData,
     163             :                                     const eq_uint64_t* inDims,
     164             :                                     const eq_uint64_t flags )
     165             : {
     166           0 :     assert( !_decoder );
     167           0 :     assert( flags & EQ_COMPRESSOR_DATA_2D );
     168             : 
     169           0 :     if( !_encoder )
     170           0 :         _encoder = tjInitCompress();
     171             : 
     172           0 :     const bool useAlpha = !(flags & EQ_COMPRESSOR_IGNORE_ALPHA);
     173           0 :     if( useAlpha && _tokenSize == 4 )
     174             :     {
     175           0 :         const eq_uint64_t size = inDims[3] * inDims[1];
     176           0 :         _extractAlpha( reinterpret_cast< const unsigned char* >(inData), size );
     177           0 :         _nResults = 2;
     178             :     }
     179             :     else
     180           0 :         _nResults = 1;
     181             : 
     182           0 :     _results[0]->resize( TJBUFSIZE( inDims[1], inDims[3] ) );
     183           0 :     unsigned long size = 0;
     184             : 
     185           0 :     void* const data = const_cast< void* const  >(inData);
     186           0 :     if( tjCompress( _encoder, reinterpret_cast< unsigned char*>( data ),
     187           0 :                     inDims[1], inDims[1] * _tokenSize, inDims[3],
     188           0 :                     _tokenSize, _results[0]->getData(), &size,
     189           0 :                     TJ_444, _quality, _flags ))
     190             :     {
     191           0 :         assert( false );
     192             :         size = 0;
     193             :     }
     194           0 :     _results[0]->resize( size );
     195           0 : }
     196             : 
     197           0 : void CompressorTurboJPEG::decompress( const void* const* inData,
     198             :                                       const eq_uint64_t* const inSizes,
     199             :                                       const unsigned nInputs,
     200             :                                       void* const outData,
     201             :                                       eq_uint64_t* const outDims,
     202             :                                       const eq_uint64_t flags,
     203             :                                       void* const instance )
     204             : {
     205           0 :     const bool useAlpha = !(flags & EQ_COMPRESSOR_IGNORE_ALPHA);
     206             :     static_cast< CompressorTurboJPEG* >( instance )->
     207           0 :         _decompress( inData, inSizes[0], nInputs, outData, outDims, useAlpha );
     208           0 : }
     209             : 
     210           0 : void CompressorTurboJPEG::_decompress( const void* const* inData,
     211             :                                        const eq_uint64_t inSize,
     212             :                                        const unsigned nInputs LB_UNUSED,
     213             :                                        void* const outData,
     214             :                                        eq_uint64_t* const outDims,
     215             :                                        const bool useAlpha )
     216             : {
     217           0 :     assert( !_encoder );
     218           0 :     if( !_decoder )
     219           0 :         _decoder = tjInitDecompress();
     220           0 :     void* const data = const_cast< void* const >( inData[0] );
     221             : 
     222           0 :     if( tjDecompress( _decoder, reinterpret_cast< unsigned char* >(data),
     223             :                       inSize, reinterpret_cast< unsigned char*>(outData),
     224           0 :                       outDims[1], outDims[1] * _tokenSize, outDims[3],
     225           0 :                       _tokenSize, _flags ))
     226             :     {
     227           0 :         assert( false );
     228             :     }
     229           0 :     else if( useAlpha && _tokenSize == 4 )
     230             :     {
     231           0 :         assert( nInputs == 2 );
     232           0 :         const eq_uint64_t size = outDims[3] * outDims[1];
     233           0 :         _addAlpha( inData[1], reinterpret_cast< unsigned* >( outData ), size);
     234             :     }
     235             : 
     236           0 : }
     237             : 
     238           0 : void CompressorTurboJPEG::_extractAlpha( const unsigned char* inData,
     239             :                                          const eq_uint64_t nPixels )
     240             : {
     241           0 :     _results[1]->resize( nPixels );
     242             : 
     243           0 :     const unsigned char* end = inData + nPixels * 4;
     244           0 :     unsigned char* dst = _results[1]->getData();
     245           0 :     for( const unsigned char* src = ( inData + 3 ); src < end; src += 4 )
     246             :     {
     247           0 :         *dst = *src;
     248           0 :         ++dst;
     249             :     }
     250           0 : }
     251             : 
     252           0 : void CompressorTurboJPEG::_addAlpha( const void* const in, unsigned* out,
     253             :                                      const eq_uint64_t nPixels ) const
     254             : {
     255           0 :     assert( _tokenSize == 4 );
     256             : 
     257           0 :     const unsigned char* alpha = reinterpret_cast<const unsigned char* >( in );
     258           0 :     const unsigned* end = out + nPixels;
     259           0 :     for(unsigned* i = out; i < end; ++i, ++alpha )
     260           0 :         *i = ((*i) & 0xffffffu) + ((*alpha)<<24);
     261           0 : }
     262             : 
     263             : }
     264          90 : }

Generated by: LCOV version 1.10