diff options
-rw-r--r-- | src/libslic3r/GCode/Thumbnails.cpp | 48 | ||||
-rw-r--r-- | src/libslic3r/GCode/Thumbnails.hpp | 35 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.cpp | 8 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.hpp | 2 |
4 files changed, 78 insertions, 15 deletions
diff --git a/src/libslic3r/GCode/Thumbnails.cpp b/src/libslic3r/GCode/Thumbnails.cpp index 855c32e69..59a224384 100644 --- a/src/libslic3r/GCode/Thumbnails.cpp +++ b/src/libslic3r/GCode/Thumbnails.cpp @@ -20,19 +20,61 @@ struct CompressedJPG : CompressedImageBuffer std::string_view tag() const override { return "thumbnail_JPG"sv; } }; -struct CompressedQOI : CompressedImageBuffer +struct CompressedQOI : CompressedImageBuffer { ~CompressedQOI() override { free(data); } std::string_view tag() const override { return "thumbnail_QOI"sv; } }; -std::unique_ptr<CompressedImageBuffer> compress_thumbnail_png(const ThumbnailData &data) +struct CompressedBIQU : CompressedImageBuffer +{ + ~CompressedBIQU() override { free(data); } + std::string_view tag() const override { return "thumbnail_BIQU"sv; } +}; + +std::unique_ptr<CompressedImageBuffer> compress_thumbnail_png(const ThumbnailData& data) { auto out = std::make_unique<CompressedPNG>(); out->data = tdefl_write_image_to_png_file_in_memory_ex((const void*)data.pixels.data(), data.width, data.height, 4, &out->size, MZ_DEFAULT_LEVEL, 1); return out; } +std::unique_ptr<CompressedImageBuffer> compress_thumbnail_biqu(const ThumbnailData& data) +{ + // Take vector of RGBA pixels and flip the image vertically + std::vector<uint8_t> rgba_pixels(data.pixels.size()); + const size_t row_size = data.width * 4; + for (size_t y = 0; y < data.height; ++y) + ::memcpy(rgba_pixels.data() + (data.height - y - 1) * row_size, data.pixels.data() + y * row_size, row_size); + + auto out = std::make_unique<CompressedBIQU>(); + //size: height is number of lines. Add 2 byte to each line for the ';' and '\n'. Each pixel is 4 byte, +1 for the 0 of the c_str + out->size = data.height * (2 + data.width * 4) + 1; + out->data = malloc(out->size); + + int idx = 0; + std::stringstream tohex; + tohex << std::setfill('0') << std::hex; + for (size_t y = 0; y < data.height; ++y) { + tohex << ";"; + for (size_t x = 0; x < data.width; ++x) { + uint16_t pixel = 0; + //r + pixel |= uint16_t((rgba_pixels[y * row_size + x * 4 + 0 ] & 0x000000F8) >> 3); + //g + pixel |= uint16_t((rgba_pixels[y * row_size + x * 4 + 1 ] & 0x000000FC) << 3); + //b + pixel |= uint16_t((rgba_pixels[y * row_size + x * 4 + 2 ] & 0x000000F8) << 8); + tohex << std::setw(4) << pixel; + } + tohex << "\n"; + } + std::string str = tohex.str(); + assert(str.size() + 1 == out->size); + ::memcpy(out->data, (const void*)str.c_str(), out->size); + return out; +} + std::unique_ptr<CompressedImageBuffer> compress_thumbnail_jpg(const ThumbnailData& data) { // Take vector of RGBA pixels and flip the image vertically @@ -91,6 +133,8 @@ std::unique_ptr<CompressedImageBuffer> compress_thumbnail(const ThumbnailData &d return compress_thumbnail_jpg(data); case GCodeThumbnailsFormat::QOI: return compress_thumbnail_qoi(data); + case GCodeThumbnailsFormat::BIQU: + return compress_thumbnail_biqu(data); } } diff --git a/src/libslic3r/GCode/Thumbnails.hpp b/src/libslic3r/GCode/Thumbnails.hpp index 7c49422b2..1a98b6223 100644 --- a/src/libslic3r/GCode/Thumbnails.hpp +++ b/src/libslic3r/GCode/Thumbnails.hpp @@ -41,20 +41,33 @@ inline void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb, if (data.is_valid()) { auto compressed = compress_thumbnail(data, format); if (compressed->data && compressed->size) { - std::string encoded; - encoded.resize(boost::beast::detail::base64::encoded_size(compressed->size)); - encoded.resize(boost::beast::detail::base64::encode((void*)encoded.data(), (const void*)compressed->data, compressed->size)); + if (format == GCodeThumbnailsFormat::BIQU) { + output((boost::format("\n;\n; %s begin %dx%d %d\n") % compressed->tag() % data.width % data.height % (compressed->size - 1)).str().c_str()); + //print size in hex + std::stringstream ss; + ss << std::setfill('0') << std::hex; + //biqu header + ss << ";" << std::setw(4) << data.width << std::setw(4) << data.height << "\n"; + output(ss.str().c_str()); + if (((char*)compressed->data)[compressed->size -1] == '\0') + output((char*)(compressed->data)); + else + assert(false); + output("; bigtree thumbnail end\n"); + } else { + std::string encoded; + encoded.resize(boost::beast::detail::base64::encoded_size(compressed->size)); + encoded.resize(boost::beast::detail::base64::encode((void*)encoded.data(), (const void*)compressed->data, compressed->size)); - output((boost::format("\n;\n; %s begin %dx%d %d\n") % compressed->tag() % data.width % data.height % encoded.size()).str().c_str()); + output((boost::format("\n;\n; %s begin %dx%d %d\n") % compressed->tag() % data.width % data.height % encoded.size()).str().c_str()); + while (encoded.size() > max_row_length) { + output((boost::format("; %s\n") % encoded.substr(0, max_row_length)).str().c_str()); + encoded = encoded.substr(max_row_length); + } - while (encoded.size() > max_row_length) { - output((boost::format("; %s\n") % encoded.substr(0, max_row_length)).str().c_str()); - encoded = encoded.substr(max_row_length); + if (encoded.size() > 0) + output((boost::format("; %s\n") % encoded).str().c_str()); } - - if (encoded.size() > 0) - output((boost::format("; %s\n") % encoded).str().c_str()); - output((boost::format("; %s end\n;\n") % compressed->tag()).str().c_str()); } throw_if_canceled(); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d52c00c20..57b43ec4f 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -286,7 +286,8 @@ CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(DraftShield) static const t_config_enum_values s_keys_map_GCodeThumbnailsFormat = { { "PNG", int(GCodeThumbnailsFormat::PNG) }, { "JPG", int(GCodeThumbnailsFormat::JPG) }, - { "QOI", int(GCodeThumbnailsFormat::QOI) } + { "QOI", int(GCodeThumbnailsFormat::QOI) }, + { "BIQU", int(GCodeThumbnailsFormat::BIQU) } }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(GCodeThumbnailsFormat) @@ -405,6 +406,11 @@ void PrintConfigDef::init_common_params() def->enum_values.push_back("PNG"); def->enum_values.push_back("JPG"); def->enum_values.push_back("QOI"); + def->enum_values.push_back("BIQU"); + def->enum_labels.push_back("PNG"); + def->enum_labels.push_back("JPG"); + def->enum_labels.push_back("QOI"); + def->enum_labels.push_back("Biqu"); def->set_default_value(new ConfigOptionEnum<GCodeThumbnailsFormat>(GCodeThumbnailsFormat::PNG)); def = this->add("thumbnails_with_support", coBool); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 04624a731..106c852fe 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -232,7 +232,7 @@ enum DraftShield { }; enum class GCodeThumbnailsFormat { - PNG, JPG, QOI + PNG, JPG, QOI, BIQU }; enum ZLiftTop { |