compression.cpp
Go to the documentation of this file.
00001 //=================================================================================================
00002 // Copyright (c) 2013, Johannes Meyer, TU Darmstadt
00003 // All rights reserved.
00004 
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions are met:
00007 //     * Redistributions of source code must retain the above copyright
00008 //       notice, this list of conditions and the following disclaimer.
00009 //     * Redistributions in binary form must reproduce the above copyright
00010 //       notice, this list of conditions and the following disclaimer in the
00011 //       documentation and/or other materials provided with the distribution.
00012 //     * Neither the name of the Flight Systems and Automatic Control group,
00013 //       TU Darmstadt, nor the names of its contributors may be used to
00014 //       endorse or promote products derived from this software without
00015 //       specific prior written permission.
00016 
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00018 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //=================================================================================================
00028 
00029 #include <blob/compression.h>
00030 
00031 #ifndef HAVE_BZIP2
00032   #define HAVE_BZIP2
00033 #endif
00034 
00035 #ifdef HAVE_BZIP2
00036 
00037 #include <bzlib.h>
00038 
00039 namespace blob
00040 {
00041   static const std::size_t CHUNK_SIZE = 10 * 1024; // 10k chunks
00042   static const int VERBOSITY = 1;
00043 
00044   bool compressionAvailable() { return true; }
00045 
00046   bool deflate(const uint8_t *data, uint32_t size, std::vector<uint8_t>& deflated)
00047   {
00048     static int BLOCK_SIZE_100K = 5;
00049     deflated.clear();
00050 
00051     bz_stream stream;
00052     stream.next_in   = reinterpret_cast<char *>(const_cast<uint8_t *>(data));
00053     stream.avail_in  = size;
00054     stream.bzalloc   = NULL;
00055     stream.bzfree    = NULL;
00056     stream.opaque    = NULL;
00057 
00058     if (BZ2_bzCompressInit(&stream, BLOCK_SIZE_100K, 0, 0) != BZ_OK) {
00059       return false;
00060     }
00061 
00062     deflated.resize(CHUNK_SIZE);
00063     stream.next_out  = reinterpret_cast<char *>(deflated.data());
00064     stream.avail_out = deflated.size();
00065 
00066     int result = BZ_RUN_OK;
00067     int state  = BZ_RUN;
00068     while(result == BZ_RUN_OK || result == BZ_FLUSH_OK || result == BZ_FINISH_OK) {
00069       if (stream.avail_in == 0) {
00070         state = BZ_FINISH;
00071       }
00072 
00073       if (stream.avail_out == 0) {
00074         deflated.resize(deflated.size() + CHUNK_SIZE);
00075         stream.next_out  = reinterpret_cast<char *>(deflated.data() + deflated.size() - CHUNK_SIZE);
00076         stream.avail_out = CHUNK_SIZE;
00077       }
00078 
00079       result = BZ2_bzCompress(&stream, state);
00080     }
00081 
00082     if (result != BZ_STREAM_END) {
00083       deflated.clear();
00084       BZ2_bzCompressEnd(&stream);
00085       return false;
00086     }
00087 
00088     deflated.resize(deflated.size() - stream.avail_out);
00089     BZ2_bzCompressEnd(&stream);
00090     return true;
00091   }
00092 
00093   bool inflate(const uint8_t *data, uint32_t size, std::vector<uint8_t>& inflated)
00094   {
00095     static const int SMALL = 1;
00096     inflated.clear();
00097 
00098     bz_stream stream;
00099     stream.next_in   = reinterpret_cast<char *>(const_cast<uint8_t *>(data));
00100     stream.avail_in  = size;
00101     stream.bzalloc   = NULL;
00102     stream.bzfree    = NULL;
00103     stream.opaque    = NULL;
00104 
00105     if (BZ2_bzDecompressInit(&stream, VERBOSITY, SMALL) != BZ_OK) {
00106       return false;
00107     }
00108 
00109     inflated.resize(CHUNK_SIZE);
00110     stream.next_out  = reinterpret_cast<char *>(inflated.data());
00111     stream.avail_out = inflated.size();
00112 
00113     int result = BZ_OK;
00114     while(result == BZ_OK || result == BZ_FLUSH_OK || result == BZ_FINISH_OK) {
00115       if (stream.avail_out == 0) {
00116         inflated.resize(inflated.size() + CHUNK_SIZE);
00117         stream.next_out  = reinterpret_cast<char *>(inflated.data() + inflated.size() - CHUNK_SIZE);
00118         stream.avail_out = CHUNK_SIZE;
00119       }
00120 
00121       result = BZ2_bzDecompress(&stream);
00122     }
00123 
00124     if (result != BZ_STREAM_END) {
00125       inflated.clear();
00126       BZ2_bzDecompressEnd(&stream);
00127       return false;
00128     }
00129 
00130     inflated.resize(inflated.size() - stream.avail_out);
00131     BZ2_bzDecompressEnd(&stream);
00132     return true;
00133   }
00134 
00135 } // namespace blob
00136 
00137 #else // HAVE_BZIP2
00138 
00139 namespace blob
00140 {
00141   bool compressionAvailable() { return false; }
00142   bool deflate(const uint8_t *data, uint32_t size, std::vector<uint8_t>& deflated) { return false; }
00143   bool inflate(const uint8_t *data, uint32_t size, std::vector<uint8_t>& inflated) { return false; }
00144 }
00145 
00146 #endif // HAVE_BZIP2


blob
Author(s): Johannes Meyer
autogenerated on Mon Oct 6 2014 07:55:44