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_decoder.h>
}
#include <zlib.h>
#include <algorithm>
#include <cassert>
@ -601,6 +602,56 @@ static bool compress(const std::vector<uint8_t>& src, std::vector<uint8_t>& dst,
{
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_12_4:
{
@ -676,6 +727,55 @@ static bool uncompress(const std::vector<uint8_t>& src, std::vector<uint8_t>& ds
{
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_12_4:
{

View File

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

View File

@ -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<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;
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;

View File

@ -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.