diff --git a/README.md b/README.md index f72e8f3f0f656ef6d4b088dd7e9372b0145355cb..7f5cdff72f74bb29a42ae13e4e33ccb49f5fce12 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ - [x] gZip (zLib, huffman deflate combination) - [ ] Save all different results at different settings, use different `Compression strategy` - [ ] bzip2 + - [ ] LZMA (7-zip) + - [ ] Different presets and `extreme` preset http://www.manpagez.com/man/1/lzma/ - [ ] deflate - [ ] *B3D cuda library* - [ ] Look at *Image difference* @@ -60,4 +62,4 @@ Later on, we can extend our program to handle more things from the file, like: ## Image difference - Find difference between included images. - Plot those differences and find out if certain images aren't same, just positioned little bit differently -- *Pattern matching* - Find if there are some patterns in image sets. \ No newline at end of file +- *Pattern matching* - Find if there are some patterns in image sets. diff --git a/czi-format/czi-parser/CMakeLists.txt b/czi-format/czi-parser/CMakeLists.txt index d3d9d45051d2a7587b57226aa8584fc4fdbb8e0c..d7f9c1f18f85fda19a2e51c970f030d3411f7e8d 100644 --- a/czi-format/czi-parser/CMakeLists.txt +++ b/czi-format/czi-parser/CMakeLists.txt @@ -15,13 +15,27 @@ find_package(Boost REQUIRED COMPONENTS filesystem locale) if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) target_link_libraries(czi-parser ${Boost_LIBRARIES}) + message("LINKED BOOST") endif() find_package (Threads) target_link_libraries (czi-parser ${CMAKE_THREAD_LIBS_INIT}) find_package(ZLIB) +if(ZLIB_FOUND) target_link_libraries(czi-parser ${ZLIB_LIBRARIES}) +message("LINKED ZLIB") +endif(ZLIB_FOUND) + + + + +find_package(LibLZMA) +if (LIBLZMA_FOUND) + include_directories(${LIBLZMA_INCLUDE_DIRS}) + target_link_libraries(czi-parser ${LIBLZMA_LIBRARIES}) + message("LINKED LIBLZMA") +endif() set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) diff --git a/czi-format/czi-parser/compression/compressors.h b/czi-format/czi-parser/compression/compressors.h index cb4488dd26313f3b69975da35221a17a5e4230cb..bcc57924ec745936e817853b063fe82ae7f9adf1 100644 --- a/czi-format/czi-parser/compression/compressors.h +++ b/czi-format/czi-parser/compression/compressors.h @@ -8,11 +8,23 @@ namespace library_zlib #include <zlib.h> }; +namespace library_lzma +{ +#include <lzma.h> +}; + enum CompressionMethod { CompressionMethod_RLE, CompressionMethod_LZ, - CompressionMethod_GZIP + CompressionMethod_GZIP, + CompressionMethod_LZMA, +}; + +struct CompressionSettings +{ + size_t lzmaPreset = LZMA_PRESET_DEFAULT; //LZMA_PRESET_EXTREME; + bool lzmaExtreme = false; }; struct CompressionResult @@ -48,7 +60,7 @@ inline float compression_ratio(float uncompressedSize, float compressedSize) return (uncompressedSize / compressedSize); } -ByteArray gzip_encode(const std::vector<byte> &data) +ByteArray gzip_encode(const std::vector<byte> &data, CompressionSettings settings) { size_t compressedSize = library_zlib::compressBound(data.size()); ByteArray compressedBuffer; @@ -80,6 +92,48 @@ ByteArray gzip_encode(const std::vector<byte> &data) return actualCompressedData; } +ByteArray lzma_encode(const std::vector<byte> &data, CompressionSettings settings) +{ + size_t maximumSize = library_lzma::lzma_stream_buffer_bound(data.size()); + ByteArray buffer; + buffer.resize(maximumSize); + size_t finalSize = 0; + auto compressionResult = library_lzma::lzma_easy_buffer_encode(settings.lzmaPreset, library_lzma::LZMA_CHECK_NONE, + nullptr, data.data(), data.size(), + buffer.data(), &finalSize, maximumSize); + switch (compressionResult) + { + case library_lzma::LZMA_MEM_ERROR: + printf(RED "Unable to allocate memory!\n" RESET); + break; + case library_lzma::LZMA_MEMLIMIT_ERROR: + printf(RED "Memory limit was reached!\n" RESET); + break; + case library_lzma::LZMA_BUF_ERROR: + printf(RED "Cannot consume input buffer!\n" RESET); + break; + case library_lzma::LZMA_PROG_ERROR: + printf(RED "Wrong arguments!\n" RESET); + break; + // To make GCC with -Wall happy. + case library_lzma::LZMA_OK: + case library_lzma::LZMA_STREAM_END: + case library_lzma::LZMA_NO_CHECK: + case library_lzma::LZMA_UNSUPPORTED_CHECK: + case library_lzma::LZMA_GET_CHECK: + case library_lzma::LZMA_FORMAT_ERROR: + case library_lzma::LZMA_OPTIONS_ERROR: + case library_lzma::LZMA_DATA_ERROR: + break; + } + always_assert(compressionResult == library_lzma::LZMA_OK); + + ByteArray result(buffer.begin(), buffer.begin() + finalSize); + always_assert(result.size() == finalSize); + + return result; +} + // Run-Length encode bytes and return compressed bytes. std::vector<byte> rle_encode(const std::vector<byte> &bytes) { @@ -328,7 +382,7 @@ void comp_test() always_assert(same && "Error in compression!"); } -CompressionResult test_compression_method(const ByteArray &data, CompressionMethod method) +CompressionResult test_compression_method(const ByteArray &data, CompressionMethod method, CompressionSettings settings) { ByteArray compressedData; switch (method) @@ -340,7 +394,10 @@ CompressionResult test_compression_method(const ByteArray &data, CompressionMeth compressedData = lz_encode(data); break; case CompressionMethod_GZIP: - compressedData = gzip_encode(data); + compressedData = gzip_encode(data, settings); + break; + case CompressionMethod_LZMA: + compressedData = lzma_encode(data, settings); break; default: INVALID_CASE; diff --git a/czi-format/czi-parser/czi_file.cpp b/czi-format/czi-parser/czi_file.cpp index 40e95c07425c305eec2a6009b88dc1ba03a8cede..8380d9fed614c5e92bc1a9a22fdd770972d10dbb 100644 --- a/czi-format/czi-parser/czi_file.cpp +++ b/czi-format/czi-parser/czi_file.cpp @@ -423,6 +423,9 @@ void CziFile::test_compression(CompressionMethod method, bool verbose) const case CompressionMethod_GZIP: printf("Selected compression: GZIP (zlib)\n"); break; + case CompressionMethod_LZMA: + printf("Selected compression: LZMA (2?)\n"); + break; default: INVALID_CASE; return; @@ -431,13 +434,15 @@ void CziFile::test_compression(CompressionMethod method, bool verbose) const CompressionResult overallN; CompressionResult overallZ; + //TODO: Use settings. + CompressionSettings settings; for (size_t i = 0; i < subBlockDirectory.entries.size(); i++) { auto data = get_image_data(i, false); auto dataZ = get_image_data(i, true); - CompressionResult nResult = test_compression_method(data, method); - CompressionResult zResult = test_compression_method(dataZ, method); + CompressionResult nResult = test_compression_method(data, method, settings); + CompressionResult zResult = test_compression_method(dataZ, method, settings); overallN.compressionRatio += nResult.compressionRatio; overallZ.compressionRatio += zResult.compressionRatio; diff --git a/czi-format/czi-parser/main.cpp b/czi-format/czi-parser/main.cpp index e40c3368a177d2fed85fb9c2d72f9ffaf5b27509..3f1907161522da9218ee3ea23f88276e29f65755 100644 --- a/czi-format/czi-parser/main.cpp +++ b/czi-format/czi-parser/main.cpp @@ -24,6 +24,7 @@ int main(int argc, char **argv) args::Flag rleCompressionOption(compressionGroup, "RLE", "RLE compression", {"rle"}); args::Flag lzCompressionOption(compressionGroup, "LZ", "LZ compression", {"lz"}); args::Flag gzipCompressionOption(compressionGroup, "GZIP", "GZIP (zlib) compression", {"gzip"}); + args::Flag lzmaCompressionOption(compressionGroup, "LZMA", "LZMA (2?) compression", {"lzma"}); try { @@ -58,6 +59,8 @@ int main(int argc, char **argv) cm = CompressionMethod_LZ; else if (gzipCompressionOption) cm = CompressionMethod_GZIP; + else if (lzmaCompressionOption) + cm = CompressionMethod_LZMA; parsedFile.test_compression(cm, verboseOption.Matched()); }