diff --git a/src/libslic3r/GCode/GCodeBinarizer.cpp b/src/libslic3r/GCode/GCodeBinarizer.cpp index cd46324174..e8bd9bffed 100644 --- a/src/libslic3r/GCode/GCodeBinarizer.cpp +++ b/src/libslic3r/GCode/GCodeBinarizer.cpp @@ -14,6 +14,7 @@ extern "C" { #include #include } +#include #include #include @@ -601,6 +602,56 @@ static bool compress(const std::vector& src, std::vector& dst, { switch (compression_type) { + case ECompressionType::Deflate: + { + dst.clear(); + + const size_t BUFSIZE = 2048; + std::vector temp_buffer(BUFSIZE); + + z_stream strm{}; + strm.next_in = const_cast(src.data()); + strm.avail_in = (uInt)src.size(); + strm.next_out = temp_buffer.data(); + strm.avail_out = BUFSIZE; + + const int level = Z_DEFAULT_COMPRESSION; + int res = deflateInit(&strm, level); + if (res != Z_OK) + return false; + + while (strm.avail_in > 0) { + res = deflate(&strm, Z_NO_FLUSH); + if (res != Z_OK) { + deflateEnd(&strm); + return false; + } + if (strm.avail_out == 0) { + dst.insert(dst.end(), temp_buffer.data(), temp_buffer.data() + BUFSIZE); + strm.next_out = temp_buffer.data(); + strm.avail_out = BUFSIZE; + } + } + + int deflate_res = Z_OK; + while (deflate_res == Z_OK) { + if (strm.avail_out == 0) { + dst.insert(dst.end(), temp_buffer.data(), temp_buffer.data() + BUFSIZE); + strm.next_out = temp_buffer.data(); + strm.avail_out = BUFSIZE; + } + deflate_res = deflate(&strm, Z_FINISH); + } + + if (deflate_res != Z_STREAM_END) { + deflateEnd(&strm); + return false; + } + + dst.insert(dst.end(), temp_buffer.data(), temp_buffer.data() + BUFSIZE - strm.avail_out); + deflateEnd(&strm); + break; + } case ECompressionType::Heatshrink_11_4: case ECompressionType::Heatshrink_12_4: { @@ -676,6 +727,55 @@ static bool uncompress(const std::vector& src, std::vector& ds { switch (compression_type) { + case ECompressionType::Deflate: + { + dst.clear(); + dst.reserve(uncompressed_size); + + const size_t BUFSIZE = 2048; + std::vector temp_buffer(BUFSIZE); + + z_stream strm{}; + strm.next_in = const_cast(src.data()); + strm.avail_in = (uInt)src.size(); + strm.next_out = temp_buffer.data(); + strm.avail_out = BUFSIZE; + int res = inflateInit(&strm); + if (res != Z_OK) + return false; + + while (strm.avail_in > 0) { + res = inflate(&strm, Z_NO_FLUSH); + if (res != Z_OK && res != Z_STREAM_END) { + inflateEnd(&strm); + return false; + } + if (strm.avail_out == 0) { + dst.insert(dst.end(), temp_buffer.data(), temp_buffer.data() + BUFSIZE); + strm.next_out = temp_buffer.data(); + strm.avail_out = BUFSIZE; + } + } + + int inflate_res = Z_OK; + while (inflate_res == Z_OK) { + if (strm.avail_out == 0) { + dst.insert(dst.end(), temp_buffer.data(), temp_buffer.data() + BUFSIZE); + strm.next_out = temp_buffer.data(); + strm.avail_out = BUFSIZE; + } + inflate_res = inflate(&strm, Z_FINISH); + } + + if (inflate_res != Z_STREAM_END) { + inflateEnd(&strm); + return false; + } + + dst.insert(dst.end(), temp_buffer.data(), temp_buffer.data() + BUFSIZE - strm.avail_out); + inflateEnd(&strm); + break; + } case ECompressionType::Heatshrink_11_4: case ECompressionType::Heatshrink_12_4: { diff --git a/src/libslic3r/GCode/GCodeBinarizer.hpp b/src/libslic3r/GCode/GCodeBinarizer.hpp index 236aee1c5f..05733cd51a 100644 --- a/src/libslic3r/GCode/GCodeBinarizer.hpp +++ b/src/libslic3r/GCode/GCodeBinarizer.hpp @@ -108,6 +108,7 @@ enum class EBlockType : uint16_t enum class ECompressionType : uint16_t { None, + Deflate, Heatshrink_11_4, Heatshrink_12_4, }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d075aeda3e..fccacd2c09 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -7885,7 +7885,7 @@ void GLCanvas3D::show_binary_gcode_debug_window() ImGui::TableSetColumnIndex(0); imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "File metadata compression"); ImGui::TableSetColumnIndex(1); - std::vector options = { "None", "heatshrink 11,4", "heatshrink 12,4" }; + std::vector options = { "None", "Deflate", "heatshrink 11,4", "heatshrink 12,4" }; int option_id = (int)binarizer_config.compression.file_metadata; if (imgui.combo(std::string("##file_metadata_compression"), options, option_id, ImGuiComboFlags_HeightLargest, 0.0f, 175.0f)) binarizer_config.compression.file_metadata = (BinaryGCode::ECompressionType)option_id; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2878e28a5a..355ff79f6a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5431,17 +5431,6 @@ void Plater::reload_gcode_from_disk() } #if ENABLE_BINARIZED_GCODE -static bool is_valid_binary_gcode(const wxString& filename) -{ - FILE* file = boost::nowide::fopen(into_u8(filename).c_str(), "rb"); - if (file == nullptr) - return false; - - const bool ret = BinaryGCode::is_valid_binary_gcode(*file); - fclose(file); - return ret; -} - void Plater::convert_gcode_to_ascii() { // Ask user for a gcode file name.