Pression  2.0.0
Compressor, decompressor, uploader and downloader plugins
cppPlugins.md
1 C++ Plugin API for CPU compressors {#data}
2 ============
3 
4 This document specifies a modern API for the in-memory C plugin API for
5 lossless byte data compressors. It will not replace the 2D image
6 compressors and CPU-GPU transfer plugins.
7 
8 ## Requirements
9 
10 * Support all features used by current lossless byte compressors:
11  * Lossless compression of binary blobs
12  * Unified API for all compression engines
13  * Other components can add compression engines
14 * Information provided for each compressor:
15  * Compression speed (relative to RLE compressor)
16  * Compression ratio (relative to uncompressed data)
17 * Compressors may produce multiple output chunks
18 * Compressor engines are instantiated to allow reuse of internal state
19  and memory allocations
20 * Easy to use API for plugin implementers
21 
22 ## Dependency Changes
23 
24 * New: Using Lunchbox plugin API for loading plugins
25 
26 ## API
27 
28  class CompressorInfo
29  {
30  public:
31  std::string name;
32  float ratio; //!< Normalized 0..1 size after compression
33  float speed; //!< Relative speed compared to RLE compressor
34 
35  typedef std::function< Compressor* ()> Constructor;
36  Constructor create;
37  };
38  typedef std::vector< CompressorInfo > CompressorInfos;
39 
40  class Registry
41  {
42  public:
43  static Registry& getInstance();
44  template< class P > bool registerEngine( CompressorInfo info )
45 
46  const CompressorInfos& getInfos() const;
47  CompressorInfo choose();
48  CompressorInfo find( const std::string& name );
49  };
50 
51  class Compressor
52  {
53  public:
54  typedef lunchbox::Bufferb Result;
55  typedef std::vector< Result > Results;
56 
57  virtual const Results& compress( const uint8_t* data, size_t size ) = 0;
58 
59  // data points to pre-allocated memory of size decompressed result
60  virtual void decompress( const Results& input, uint8_t* data,
61  size_t size ) = 0;
62  protected:
63  Results compressed;
64  };
65 
66 
67 ## Examples
68 
69  CompressorInfo Registry::choose()
70  {
71  CompressorInfo candidate;
72  float rating = powf( 1.0f, .3f );
73 
74  for( const CompressorInfo& info : _impl->compressorInfos )
75  {
76  float newRating = powf( info.speed, .3f ) / info.ratio;
77  if( newRating > rating )
78  {
79  candidate = info;
80  rating = newRating;
81  }
82  }
83  return candidate;
84  }
85 
86 
87 Compressor implementation:
88 
89  #include "zstd/lib/zstd.h"
90 
91  namespace pression
92  {
93  namespace data
94  {
95  namespace
96  {
97  static const bool LB_UNUSED _initialized = []()
98  {
99  Registry::registerEngine( { "pression::CompressorZSTD",
100  .47f, .25f },
101  CompressorZSTD::newInstance );
102  return true;
103  }();
104  }
105 
106  const Results& CompressorZSTD::compress( const void* const data,
107  const size_t inSize )
108  {
109  if( _results.empty( ))
110  _results.push_back( new pression::plugin::Compressor::Result );
111  _results[0]->reserve( ZSTD_compressBound( inSize ));
112 
113  const size_t size = ZSTD_compress( _results[0]->getData(),
114  _results[0]->getSize(), inData,
115  inSize, 2 /* level */ );
116  _results[0]->setSize( size );
117  return _results;
118  }
119 
120  void CompressorZSTD::decompress( const Results& input, uint8_t* data,
121  size_t size );
122  {
123  if( input.empty( ))
124  return;
125 
126  ZSTD_decompress( data, size,
127  input[0].getData(), input[0].getSize( ));
128  }
129  }
130  }
131 
132 ## Issues