Lunchbox  1.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
lunchbox::Compressor Class Reference

A C++ class to handle one compressor plugin instance. More...

#include <compressor.h>

+ Inheritance diagram for lunchbox::Compressor:
+ Collaboration diagram for lunchbox::Compressor:

Public Member Functions

LUNCHBOX_API Compressor ()
 Construct a new, invalid compressor instance. More...
 
LUNCHBOX_API Compressor (PluginRegistry &from, const uint32_t name)
 Construct a new, named compressor instance. More...
 
virtual LUNCHBOX_API ~Compressor ()
 Destruct the compressor. More...
 
LUNCHBOX_API bool isGood () const
 
 operator bool_t () const
 
bool operator! () const
 
LUNCHBOX_API bool uses (const uint32_t name) const
 
LUNCHBOX_API const
EqCompressorInfo
getInfo () const
 
LUNCHBOX_API bool setup (PluginRegistry &from, const uint32_t name)
 Set up a new, named compressor instance. More...
 
LUNCHBOX_API bool setup (PluginRegistry &registry, const uint32_t tokenType, const float minQuality, const bool ignoreMSE)
 Set up a new, auto-selected compressor instance. More...
 
LUNCHBOX_API bool realloc ()
 Reallocate the current instance. More...
 
LUNCHBOX_API void clear ()
 Reset to EQ_COMPRESSOR_NONE. More...
 
LUNCHBOX_API void compress (void *const in, const uint64_t inDims[2])
 Compress one-dimensional data. More...
 
LUNCHBOX_API void compress (void *const in, const uint64_t pvp[4], const uint64_t flags)
 Compress two-dimensional data. More...
 
LUNCHBOX_API unsigned getNumResults () const LB_DEPRECATED
 
LUNCHBOX_API CompressorResult getResult () const
 
LUNCHBOX_API void getResult (const unsigned i, void **const out, uint64_t *const outSize) const LB_DEPRECATED
 

Static Public Member Functions

static LUNCHBOX_API uint32_t choose (const PluginRegistry &registry, const uint32_t tokenType, const float minQuality, const bool ignoreMSE)
 Find the best compressor in all plugins for the given parameters. More...
 

Detailed Description

A C++ class to handle one compressor plugin instance.

Example:

/* Copyright (c) 2010, Cedric Stalder <cedric.stalder@gmail.com>
* 2010-2014, Stefan Eilemann <eile@eyescale.ch>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 2.1 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define TEST_RUNTIME 600 // seconds
#include <test.h>
#include <lunchbox/buffer.h>
#include <lunchbox/clock.h>
#include <lunchbox/compressor.h>
#include <lunchbox/compressorInfo.h>
#include <lunchbox/compressorResult.h>
#include <lunchbox/decompressor.h>
#include <lunchbox/file.h>
#include <lunchbox/memoryMap.h>
#include <lunchbox/plugin.h>
#include <lunchbox/pluginRegistry.h>
#include <lunchbox/rng.h>
#include <algorithm>
using namespace lunchbox;
void _testFile();
void _testRandom();
void _testData( const uint32_t nameCompressor, const std::string& name,
const uint8_t* data, const uint64_t size );
std::vector< uint32_t > getCompressorNames( const uint32_t tokenType );
Strings getFiles( const std::string& path, Strings& files,
const std::string& ext );
PluginRegistry registry;
uint64_t _result = 0;
uint64_t _size = 0;
float _compressionTime = 0;
float _decompressionTime = 0;
float _baseTime = 0.f;
int main( int, char** )
{
registry.addDirectory( std::string( LUNCHBOX_BUILD_DIR ) + "/lib" );
TEST( registry.addLunchboxPlugins( ));
registry.init();
_testFile();
_testRandom();
registry.exit();
Compressor compressor;
TEST( !compressor.isGood( ));
TEST( !compressor );
Decompressor decompressor;
TEST( !decompressor.isGood( ));
TEST( !decompressor );
return EXIT_SUCCESS;
}
std::vector< uint32_t > getCompressorNames( const uint32_t tokenType )
{
const Plugins& plugins = registry.getPlugins();
std::vector< uint32_t > names;
for( PluginsCIter i = plugins.begin(); i != plugins.end(); ++i )
{
const CompressorInfos& infos = (*i)->getInfos();
for( CompressorInfosCIter j = infos.begin(); j != infos.end(); ++j )
{
if ( (*j).tokenType == tokenType )
names.push_back( (*j).name );
}
}
std::sort( names.begin(), names.end( ));
return names;
}
void _testData( const uint32_t compressorName, const std::string& name,
const uint8_t* data, const uint64_t size )
{
Compressor compressor( registry, compressorName );
Decompressor decompressor( registry, compressorName );
TEST( compressor.isGood( ));
TEST( compressor );
TESTINFO( decompressor.isGood(), compressorName );
TESTINFO( decompressor, compressorName );
const uint64_t flags = EQ_COMPRESSOR_DATA_1D;
uint64_t inDims[2] = { 0, size };
compressor.compress( const_cast<uint8_t*>(data), inDims, flags );
Clock clock;
compressor.compress( const_cast<uint8_t*>(data), inDims, flags );
const float compressTime = clock.getTimef();
const CompressorResult& compressed = compressor.getResult();
const uint64_t compressedSize = compressed.getSize();
std::vector< void * > chunks;
std::vector< uint64_t > chunkSizes;
chunks.resize( compressed.chunks.size( ));
chunkSizes.resize( chunks.size( ));
for( unsigned i = 0; i < chunks.size(); ++i )
{
chunks[ i ] = compressed.chunks[i].data;
chunkSizes[ i ] = compressed.chunks[i].getNumBytes();
}
Bufferb result;
result.resize( size );
uint8_t* outData = result.getData();
decompressor.decompress( &chunks.front(), &chunkSizes.front(),
unsigned( chunks.size( )), outData, inDims );
clock.reset();
decompressor.decompress( &chunks.front(), &chunkSizes.front(),
unsigned(chunks.size()), outData, inDims);
const float decompressTime = clock.getTimef();
TEST( memcmp( outData, data, size ) == 0 );
std::cout << std::setw(20) << name << ", 0x" << std::setw(8)
<< std::setfill( '0' ) << std::hex << compressorName << std::dec
<< std::setfill(' ') << ", " << std::setw(10) << size << ", "
<< std::setw(10) << compressedSize << ", " << std::setw(10)
<< compressTime << ", " << std::setw(10) << decompressTime
<< std::endl;
_size += size;
_result += compressedSize;
_compressionTime += compressTime;
_decompressionTime += decompressTime;
}
void _testFile()
{
std::vector< uint32_t >compressorNames =
getCompressorNames( EQ_COMPRESSOR_DATATYPE_BYTE );
std::vector< std::string > files;
getFiles( "", files, ".*\\.dll" );
getFiles( "", files, ".*\\.exe" );
getFiles( "", files, ".*\\.so" );
getFiles( "../bin", files, ".*\\.dll" );
getFiles( "../lib", files, ".*\\.so" );
getFiles( "../../install/bin", files, ".*\\.dll" );
getFiles( "../../install/lib", files, ".*\\.so" );
getFiles( "images", files, ".*\\.rgb" );
getFiles( "", files, ".*\\.a" );
getFiles( "", files, ".*\\.dylib" );
getFiles( "/Users/eile/Library/Models/mediumPly/", files, ".*\\.bin" );
getFiles( "/Users/eile/Library/Models/mediumPly/", files, ".*\\.ply" );
getFiles( "/home/eilemann/Software/Models/mediumPly/", files, ".*\\.bin" );
getFiles( "/home/eilemann/Software/Models/mediumPly/", files, ".*\\.ply" );
// Limit to 30 files using a pseudo-random selection for reproducability
const size_t maxFiles = 30;
if( files.size() > maxFiles )
{
const size_t cut = files.size() - maxFiles;
for( size_t i = 0; i < cut; ++i )
files.erase( files.begin() + (i * 997 /*prime*/) % files.size( ));
}
std::cout.setf( std::ios::right, std::ios::adjustfield );
std::cout.precision( 5 );
std::cout << " File, Compressor, Uncompress, "
<< "Compressed, t_comp, t_decomp" << std::endl;
for( std::vector< uint32_t >::const_iterator i = compressorNames.begin();
i != compressorNames.end(); ++i )
{
_result = 0;
_size = 0;
_compressionTime = 0;
_decompressionTime = 0;
for( StringsCIter j = files.begin(); j != files.end(); ++j )
{
MemoryMap file;
const uint8_t* data = static_cast<const uint8_t*>( file.map( *j ));
if( !data )
{
LBERROR << "Can't mmap " << *j << std::endl;
continue;
}
const size_t size = file.getSize();
const std::string name = getFilename( *j );
_testData( *i, name, data, size );
}
if( _baseTime == 0.f )
_baseTime = _compressionTime + _decompressionTime;
std::cout << std::setw(24) << "Total, 0x" << std::setw(8)
<< std::setfill( '0' ) << std::hex << *i << std::dec
<< std::setfill(' ') << ", " << std::setw(10) << _size << ", "
<< std::setw(10) << _result << ", " << std::setw(10)
<< _compressionTime << ", " << std::setw(10)
<< _decompressionTime << std::endl
<< " info->ratio = " << float(_result) / float(_size)
<< "f;" << std::endl
<< " info->speed = " << float(_baseTime) /
float(_compressionTime + _decompressionTime)
<< "f;" << std::endl << std::endl;
}
}
void _testRandom()
{
ssize_t size = LB_10MB;
uint8_t* data = new uint8_t[size];
RNG rng;
#pragma omp parallel for
for( ssize_t i = 0; i < size; ++i )
data[i] = rng.get< uint8_t >();
std::vector< uint32_t >compressorNames =
getCompressorNames( EQ_COMPRESSOR_DATATYPE_BYTE );
_result = 0;
_size = 0;
_compressionTime = 0;
_decompressionTime = 0;
for( std::vector<uint32_t>::const_iterator i = compressorNames.begin();
i != compressorNames.end(); ++i )
{
size = LB_10MB;
for( size_t j = 0; j<8; ++j ) // test all granularities between mod 8..1
{
_testData( *i, "Random data", data, size );
--size;
}
std::cout << std::setw(24) << "Total, 0x" << std::setw(8)
<< std::setfill( '0' ) << std::hex << *i << std::dec
<< std::setfill(' ') << ", " << std::setw(10) << _size << ", "
<< std::setw(10) << _result << ", " << std::setw(10)
<< _compressionTime << ", " << std::setw(10)
<< _decompressionTime << std::endl << std::endl;
}
delete [] data;
}
Strings getFiles( const std::string& path, Strings& files,
const std::string& ext )
{
Strings paths = registry.getDirectories();
if( !path.empty( ))
paths.push_back( path );
for( uint64_t j = 0; j < paths.size(); ++j )
{
const Strings& candidates = searchDirectory( paths[j], ext );
for( StringsCIter i = candidates.begin(); i != candidates.end(); ++i )
{
const std::string& filename = *i;
files.push_back( paths[j] + '/' + filename );
}
}
return files;
}

Definition at line 37 of file compressor.h.

Constructor & Destructor Documentation

LUNCHBOX_API lunchbox::Compressor::Compressor ( )

Construct a new, invalid compressor instance.

Version
1.7.1
LUNCHBOX_API lunchbox::Compressor::Compressor ( PluginRegistry from,
const uint32_t  name 
)

Construct a new, named compressor instance.

Parameters
fromthe plugin registry
namethe name of the compressor
Version
1.7.1
virtual LUNCHBOX_API lunchbox::Compressor::~Compressor ( )
virtual

Destruct the compressor.

Version
1.7.1

Member Function Documentation

static LUNCHBOX_API uint32_t lunchbox::Compressor::choose ( const PluginRegistry registry,
const uint32_t  tokenType,
const float  minQuality,
const bool  ignoreMSE 
)
static

Find the best compressor in all plugins for the given parameters.

This convenience method searches all compressors in all plugins to find the compressor which matches best the given parameters.

Parameters
registrythe plugin registry to choose from.
tokenTypethe structure of the data to compress.
minQualityminimal quality of the compressed data, with 0 = no quality and 1 = full quality, no loss.
ignoreMSEthe most-significant element of a four-element token can be ignored, typically the alpha channel of an image.
Returns
the name of the chosen compressor.
Version
1.7.1
LUNCHBOX_API void lunchbox::Compressor::clear ( )

Reset to EQ_COMPRESSOR_NONE.

Version
1.7.1
LUNCHBOX_API void lunchbox::Compressor::compress ( void *const  in,
const uint64_t  inDims[2] 
)

Compress one-dimensional data.

Parameters
inthe pointer to the input data.
inDimsthe dimensions of the input data
Version
1.7.1
LUNCHBOX_API void lunchbox::Compressor::compress ( void *const  in,
const uint64_t  pvp[4],
const uint64_t  flags 
)

Compress two-dimensional data.

Parameters
inthe pointer to the input data.
pvpthe dimensions of the input data
flagscapability flags for the compression
Version
1.7.1
LUNCHBOX_API const EqCompressorInfo& lunchbox::Compressor::getInfo ( ) const
Returns
the information about the allocated instance.
Version
1.7.1
LUNCHBOX_API unsigned lunchbox::Compressor::getNumResults ( ) const
Deprecated:
use new getResult()
Returns
the number of compressed chunks of the last compression.
Version
1.7.1
LUNCHBOX_API CompressorResult lunchbox::Compressor::getResult ( ) const
Returns
the result of the last compression.
Version
1.9.1
LUNCHBOX_API void lunchbox::Compressor::getResult ( const unsigned  i,
void **const  out,
uint64_t *const  outSize 
) const
LUNCHBOX_API bool lunchbox::Compressor::isGood ( ) const
Returns
true if the instance is usable.
Version
1.7.1

Referenced by operator bool_t(), and operator!().

+ Here is the caller graph for this function:

lunchbox::Compressor::operator bool_t ( ) const
inline
Returns
true if the instance is usable, false otherwise.
Version
1.9.1

Definition at line 64 of file compressor.h.

References isGood().

+ Here is the call graph for this function:

bool lunchbox::Compressor::operator! ( ) const
inline
Returns
true if the instance is not usable.
Version
1.9.1

Definition at line 67 of file compressor.h.

References isGood().

+ Here is the call graph for this function:

LUNCHBOX_API bool lunchbox::Compressor::realloc ( )

Reallocate the current instance.

Version
1.7.1
LUNCHBOX_API bool lunchbox::Compressor::setup ( PluginRegistry from,
const uint32_t  name 
)

Set up a new, named compressor instance.

Parameters
fromthe plugin registry.
namethe name of the compressor.
Returns
true on success, false otherwise.
Version
1.7.1
LUNCHBOX_API bool lunchbox::Compressor::setup ( PluginRegistry registry,
const uint32_t  tokenType,
const float  minQuality,
const bool  ignoreMSE 
)

Set up a new, auto-selected compressor instance.

See Also
choose() for parameters.
Version
1.7.1
LUNCHBOX_API bool lunchbox::Compressor::uses ( const uint32_t  name) const
Returns
true if the instance is usable for the given name.
Version
1.7.1

The documentation for this class was generated from the following file: