SPE-1784: New compressed (binary) gcode format integration

Added Deflate compression using zlib
This commit is contained in:
enricoturri1966 2023-07-26 13:21:50 +02:00
parent fba2406ace
commit a8d8914071
4 changed files with 102 additions and 12 deletions

View File

@ -14,6 +14,7 @@ extern "C" {
#include <heatshrink/heatshrink_encoder.h> #include <heatshrink/heatshrink_encoder.h>
#include <heatshrink/heatshrink_decoder.h> #include <heatshrink/heatshrink_decoder.h>
} }
#include <zlib.h>
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
@ -601,6 +602,56 @@ static bool compress(const std::vector<uint8_t>& src, std::vector<uint8_t>& dst,
{ {
switch (compression_type) switch (compression_type)
{ {
case ECompressionType::Deflate:
{
dst.clear();
const size_t BUFSIZE = 2048;
std::vector<uint8_t> temp_buffer(BUFSIZE);
z_stream strm{};
strm.next_in = const_cast<uint8_t*>(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_11_4:
case ECompressionType::Heatshrink_12_4: case ECompressionType::Heatshrink_12_4:
{ {
@ -676,6 +727,55 @@ static bool uncompress(const std::vector<uint8_t>& src, std::vector<uint8_t>& ds
{ {
switch (compression_type) switch (compression_type)
{ {
case ECompressionType::Deflate:
{
dst.clear();
dst.reserve(uncompressed_size);
const size_t BUFSIZE = 2048;
std::vector<uint8_t> temp_buffer(BUFSIZE);
z_stream strm{};
strm.next_in = const_cast<uint8_t*>(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_11_4:
case ECompressionType::Heatshrink_12_4: case ECompressionType::Heatshrink_12_4:
{ {

View File

@ -108,6 +108,7 @@ enum class EBlockType : uint16_t
enum class ECompressionType : uint16_t enum class ECompressionType : uint16_t
{ {
None, None,
Deflate,
Heatshrink_11_4, Heatshrink_11_4,
Heatshrink_12_4, Heatshrink_12_4,
}; };

View File

@ -7885,7 +7885,7 @@ void GLCanvas3D::show_binary_gcode_debug_window()
ImGui::TableSetColumnIndex(0); ImGui::TableSetColumnIndex(0);
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "File metadata compression"); imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "File metadata compression");
ImGui::TableSetColumnIndex(1); ImGui::TableSetColumnIndex(1);
std::vector<std::string> options = { "None", "heatshrink 11,4", "heatshrink 12,4" }; std::vector<std::string> options = { "None", "Deflate", "heatshrink 11,4", "heatshrink 12,4" };
int option_id = (int)binarizer_config.compression.file_metadata; 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)) 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; binarizer_config.compression.file_metadata = (BinaryGCode::ECompressionType)option_id;

View File

@ -5431,17 +5431,6 @@ void Plater::reload_gcode_from_disk()
} }
#if ENABLE_BINARIZED_GCODE #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() void Plater::convert_gcode_to_ascii()
{ {
// Ask user for a gcode file name. // Ask user for a gcode file name.