Squash is an open source library for compressing data, and comes with a range of compression algorithms. ofxSquash is a C++ wrapper for that libary for use with openFrameworks and supports both simple and stream API's.
Squash ships with plugin implementations for the following algorithms:
- brieflz
- brotli
- bsc
- bzip2
- copy (no compression)
- crush
- csc
- density
- doboz
- fari
- fastlz
- gipfeli
- heatshrink
- libdeflate
- lz4
- lzf
- lzg
- lzham
- lzjb
- lzma
- lzo
- miniz
- ms-compress
- ncompress
- pithy
- quicklz
- snappy
- wflz
- yalz77
- zlib-ng
- zlib
- zling
- zpaq
- zstd
There's a really helpful system at https://quixdb.github.io/squash-benchmark/ which can help you choose which algorithm to pick for your data.
The following plugins do not work on these platforms:
- csc
- ncompress
- quicklz
### Windows
- csc
- doboz
- pithy
To get a list of available algorithms:
auto codecs = ofxSquash::getCodecList();
cout << "Squash found " << codecs.size() << " codecs." << endl;
for(auto & codec : codecs) {
cout << "* " << codec.getName() << endl;
}
Generally we use the class ofxSquash::Codec
for most of our work, e.g.:
// create a Density codec object
auto codec = ofxSquash::Codec("density");
//make something to compress
string text = "Something to compress";
// compress the text using our codec
auto compressedText = codec.compress(text);
// uncompress the text again, resulting in our original string
auto uncompressedText = codec.uncompress(compressedText);
Often whilst we're compressing, we might not want to pass the entire data to the codec at once, for example:
- We're compressing from one file to another, and don't want to keep the entire contents in memory
- Latency is an issue, and we want the next process to begin before compression is completed (e.g. transmit to the network whilst compression is still ongoing).
Check exampleStreamSimple for help on how to use this (note you need to provide a lambda function to ofxSquash::Stream
. This function is called whenever there is data available to write).
//initialise the codec
auto codec = ofxSquash::Codec("density");
//initialise the stream
ofxSquash::Stream compressStream(codec, ofxSquash::Direction::Compress);
// Setup a WriteFunction for compression.
// This function is called whenever the stream wants
// to write to an output (e.g. a file or a network
// stream). This function will be called periodically
// as the stream compresses the data.
compressStream.setWriteFunction([&decompressStream](const ofxSquash::WriteFunctionArguments & args) {
// In this example, our 'write' code for the compressor just dumps the output to console
auto compressedPacketString = string((const char*)args.data, args.size);
cout << compressedPacketString << endl;
});
// Stream something into the compressor.
string text = " \n\
....XXXXXXXX \n\
..XXX..ooooXXX \n\
..X....oooo..X \n\
.X....oooooo..X \n\
XX...oo....oo.XX \n\
Xooooo......oooX \n\
Xo..oo......oooX \n\
X....o......oo.X \n\
X....oo....oo..X \n\
Xo..ooooooooo..X \n\
XoooXXXXXXXXoo.X \n\
.XXX..X..X..XXX \n\
..X...X..X...X \n\
..X..........X \n\
...X........X \n\
....XXXXXXXX \n\
";
compressStream << text;
// Important!!
// We also need to send Finish to the stream
compressStream << ofxSquash::Stream::Finish();
// The stream is now closed. It will reopen if you stream any more data into it
### ofxSquash doesn't find any plugins
Try:
- Make sure you have a
data/
folder which can be found byofToDataPath
(we use this function when navigating to theplugins
folder, so thebin/data
path must exist even if it is empty). - Make sure that the plugins are copied so that the directory structure is
bin/plugins/squash/[codec name]/
.
This addon is tested and working with :
- openFrameworks 0.9.0+
- Visual Studio 2015 x64 (Windows 10)
- XCode 7.2 x64 (OSX 10.11)
Note : On OSX, the ncompress
plugin crashes, so remove it from the plugins folder.
Copyright (c) 2015, Kimchi and Chips
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Squash is licensed under the MIT License, which is highly permissive and allows Squash to be integrated into any application virtually without restriction. That said, please keep in mind that some plugins use libraries which are subject to more restrictive terms (such as the GNU GPL), and using Squash as an intermediary does not release you from the obligations of those licenses if you choose to actually use plugins which use those libraries. Squash includes an API for programmatically determining the license of a plugin, and it is possible to use it to avoid any GPL'd plugins even if they are installed. Each plugin's page in the C documentation lists the license of the library, or libraries, it uses.
Several of the GPL libraries used by Squash plugins are also available for integration with proprietary software under commercial licenses.