thumbnail and calib

This commit is contained in:
sunsets
2024-01-08 11:04:52 +08:00
parent 6382f4e052
commit 632fb9e06e
9 changed files with 537 additions and 16 deletions

View File

@@ -0,0 +1,144 @@
#ifndef _DATA_TYPE_H_
#define _DATA_TYPE_H_
//#include "framework.h"
#include <stdlib.h>
#ifndef null
#define null 0
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef U8
typedef unsigned char U8;
#endif
#ifndef S8
typedef signed char S8;
#endif
#ifndef U16
typedef unsigned short U16;
#endif
#ifndef S16
typedef signed short S16;
#endif
#ifndef U32
typedef unsigned int U32;
#endif
#ifndef S32
typedef signed int S32;
#endif
#ifndef S64
typedef signed long long S64;
#endif
#ifndef U64
typedef unsigned long long U64;
#endif
#ifndef FP32
typedef float FP32;
#endif
#ifndef FP64
typedef double FP64;
#endif
#ifndef Pixel_t
typedef unsigned short Pixel_t;
#endif
#ifndef UINT32
typedef unsigned int UINT32;
#endif
#ifndef INT
typedef int INT;
#endif
// #ifndef INT32
// typedef int INT32;
// #endif
typedef unsigned char INT8U; /* Unsigned 8 bit quantity */
typedef signed char INT8S; /* Signed 8 bit quantity */
typedef unsigned short INT16U; /* Unsigned 16 bit quantity */
typedef signed short INT16S; /* Signed 16 bit quantity */
typedef unsigned int INT32U; /* Unsigned 32 bit quantity */
typedef signed int INT32S; /* Signed 32 bit quantity */
typedef unsigned long long INT64U;
typedef signed long long INT64S;
typedef float FP32; /* Single precision floating point */
typedef double FP64; /* Double precision floating point */
typedef struct
{
U16 star;
U16 end;
}PosLaction;
typedef struct
{
int a0;
int a1;
int a2;
int a3;
int a4;
int a5;
int a6;
int a7;
int a8;
int a9;
int a10;
int a11;
int a12;
int a13;
int a14;
int a15;
}bytes_64Bytes;
typedef struct
{
bytes_64Bytes a0;
bytes_64Bytes a1;
bytes_64Bytes a2;
bytes_64Bytes a3;
}bytes_256Bytes;
typedef struct
{
bytes_64Bytes a0;
bytes_64Bytes a1;
bytes_64Bytes a2;
bytes_64Bytes a3;
bytes_64Bytes a4;
bytes_64Bytes a5;
bytes_64Bytes a6;
bytes_64Bytes a7;
bytes_64Bytes a8;
bytes_64Bytes a9;
bytes_64Bytes a10;
bytes_64Bytes a11;
bytes_64Bytes a12;
bytes_64Bytes a13;
bytes_64Bytes a14;
bytes_64Bytes a15;
}bytes_1024Bytes;
#endif

View File

@@ -86,6 +86,65 @@ std::unique_ptr<CompressedImageBuffer> compress_thumbnail_jpg(const ThumbnailDat
return out;
}
//B3
std::string compress_thumbnail_qidi(const ThumbnailData &data)
{
auto out = std::make_unique<CompressedPNG>();
// BOOST_LOG_TRIVIAL(error) << data.width;
int width = int(data.width);
int height = int(data.height);
if (data.width * data.height > 500 * 500) {
width = 500;
height = 500;
}
U16 color16[500 * 500];
// U16 *color16 = new U16[data.width * data.height];
// for (int i = 0; i < 200*200; i++) color16[i] = 522240;
unsigned char outputdata[500 * 500 * 10];
// unsigned char *outputdata = new unsigned char[data.width * data.height * 10];
std::vector<uint8_t> rgba_pixels(data.pixels.size() * 4);
size_t row_size = width * 4;
for (size_t y = 0; y < height; ++y)
memcpy(rgba_pixels.data() + y * row_size, data.pixels.data() + y * row_size, row_size);
const unsigned char *pixels;
pixels = (const unsigned char *) rgba_pixels.data();
int rrrr = 0, gggg = 0, bbbb = 0, aaaa = 0, rgb = 0;
int time = width * height - 1; // 200*200-1;
for (unsigned int r = 0; r < height; ++r) {
unsigned int rr = r * width;
for (unsigned int c = 0; c < width; ++c) {
unsigned int cc = width - c - 1;
rrrr = int(pixels[4 * (rr + cc) + 0]) >> 3;
gggg = int(pixels[4 * (rr + cc) + 1]) >> 2;
bbbb = int(pixels[4 * (rr + cc) + 2]) >> 3;
aaaa = int(pixels[4 * (rr + cc) + 3]);
if (aaaa == 0) {
rrrr = 239 >> 3;
gggg = 243 >> 2;
bbbb = 247 >> 3;
}
rgb = (rrrr << 11) | (gggg << 5) | bbbb;
color16[time--] = rgb;
}
}
int res = ColPic_EncodeStr(color16, width, height, outputdata, height * width * 10, 1024);
std::string temp;
// for (unsigned char i : outputdata) { temp += i; }
for (unsigned int i = 0; i < sizeof(outputdata); ++i) {
temp += outputdata[i];
// unsigned char strr = outputdata[i];
// temp += strr;
}
// 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 temp;
}
std::unique_ptr<CompressedImageBuffer> compress_thumbnail_qoi(const ThumbnailData &data)
{
qoi_desc desc;
@@ -120,6 +179,8 @@ std::unique_ptr<CompressedImageBuffer> compress_thumbnail(const ThumbnailData &d
}
}
//B3
std::string compress_qidi_thumbnail(const ThumbnailData &data, GCodeThumbnailsFormat format) { return compress_thumbnail_qidi(data); }
std::pair<GCodeThumbnailDefinitionsList, ThumbnailErrors> make_and_check_thumbnail_list(const std::string& thumbnails_string, const std::string_view def_ext /*= "PNG"sv*/)
{
@@ -198,6 +259,246 @@ std::string get_error_string(const ThumbnailErrors& errors)
return error_str;
}
//B3
static void colmemmove(U8 *dec, U8 *src, int lenth)
{
if (src < dec) {
dec += lenth - 1;
src += lenth - 1;
while (lenth > 0) {
*(dec--) = *(src--);
lenth--;
}
} else {
while (lenth > 0) {
*(dec++) = *(src++);
lenth--;
}
}
}
static void colmemcpy(U8 *dec, U8 *src, int lenth)
{
while (lenth > 0) {
*(dec++) = *(src++);
lenth--;
}
}
static void colmemset(U8 *dec, U8 val, int lenth)
{
while (lenth > 0) {
*(dec++) = val;
lenth--;
}
}
static void ADList0(U16 val, U16HEAD *listu16, int *listqty, int maxqty)
{
U8 A0;
U8 A1;
U8 A2;
int qty = *listqty;
if (qty >= maxqty)
return;
for (int i = 0; i < qty; i++) {
if (listu16[i].colo16 == val) {
listu16[i].qty++;
return;
}
}
A0 = (U8) (val >> 11);
A1 = (U8) ((val << 5) >> 10);
A2 = (U8) ((val << 11) >> 11);
U16HEAD *a = &listu16[qty];
a->colo16 = val;
a->A0 = A0;
a->A1 = A1;
a->A2 = A2;
a->qty = 1;
*listqty = qty + 1;
}
static int Byte8bitEncode(U16 *fromcolor16, U16 *listu16, int listqty, int dotsqty, U8 *outputdata, int decMaxBytesize)
{
U8 tid, sid;
int dots = 0;
int srcindex = 0;
int decindex = 0;
int lastid = 0;
int temp = 0;
while (dotsqty > 0) {
dots = 1;
for (int i = 0; i < (dotsqty - 1); i++) {
if (fromcolor16[srcindex + i] != fromcolor16[srcindex + i + 1])
break;
dots++;
if (dots == 255)
break;
}
temp = 0;
for (int i = 0; i < listqty; i++) {
if (listu16[i] == fromcolor16[srcindex]) {
temp = i;
break;
}
}
tid = (U8) (temp % 32);
sid = (U8) (temp / 32);
if (lastid != sid) {
if (decindex >= decMaxBytesize)
goto IL_END;
outputdata[decindex] = 7;
outputdata[decindex] <<= 5;
outputdata[decindex] += sid;
decindex++;
lastid = sid;
}
if (dots <= 6) {
if (decindex >= decMaxBytesize)
goto IL_END;
outputdata[decindex] = (U8) dots;
outputdata[decindex] <<= 5;
outputdata[decindex] += tid;
decindex++;
} else {
if (decindex >= decMaxBytesize)
goto IL_END;
outputdata[decindex] = 0;
outputdata[decindex] += tid;
decindex++;
if (decindex >= decMaxBytesize)
goto IL_END;
outputdata[decindex] = (U8) dots;
decindex++;
}
srcindex += dots;
dotsqty -= dots;
}
IL_END:
return decindex;
}
static int ColPicEncode(U16 *fromcolor16, int picw, int pich, U8 *outputdata, int outputmaxtsize, int colorsmax)
{
U16HEAD l0;
int cha0, cha1, cha2, fid, minval;
ColPicHead3 *Head0 = null;
U16HEAD Listu16[1024];
int ListQty = 0;
int enqty = 0;
int dotsqty = picw * pich;
if (colorsmax > 1024)
colorsmax = 1024;
for (int i = 0; i < dotsqty; i++) {
int ch = (int) fromcolor16[i];
ADList0(ch, Listu16, &ListQty, 1024);
}
for (int index = 1; index < ListQty; index++) {
l0 = Listu16[index];
for (int i = 0; i < index; i++) {
if (l0.qty >= Listu16[i].qty) {
colmemmove((U8 *) &Listu16[i + 1], (U8 *) &Listu16[i], (index - i) * sizeof(U16HEAD));
colmemcpy((U8 *) &Listu16[i], (U8 *) &l0, sizeof(U16HEAD));
break;
}
}
}
while (ListQty > colorsmax) {
l0 = Listu16[ListQty - 1];
minval = 255;
fid = -1;
for (int i = 0; i < colorsmax; i++) {
cha0 = Listu16[i].A0 - l0.A0;
if (cha0 < 0)
cha0 = 0 - cha0;
cha1 = Listu16[i].A1 - l0.A1;
if (cha1 < 0)
cha1 = 0 - cha1;
cha2 = Listu16[i].A2 - l0.A2;
if (cha2 < 0)
cha2 = 0 - cha2;
int chall = cha0 + cha1 + cha2;
if (chall < minval) {
minval = chall;
fid = i;
}
}
for (int i = 0; i < dotsqty; i++) {
if (fromcolor16[i] == l0.colo16)
fromcolor16[i] = Listu16[fid].colo16;
}
ListQty = ListQty - 1;
}
Head0 = ((ColPicHead3 *) outputdata);
colmemset(outputdata, 0, sizeof(ColPicHead3));
Head0->encodever = 3;
Head0->oncelistqty = 0;
Head0->mark = 0x05DDC33C;
Head0->ListDataSize = ListQty * 2;
for (int i = 0; i < ListQty; i++) {
U16 *l0 = (U16 *) &outputdata[sizeof(ColPicHead3)];
l0[i] = Listu16[i].colo16;
}
enqty = Byte8bitEncode(fromcolor16, (U16 *) &outputdata[sizeof(ColPicHead3)], Head0->ListDataSize >> 1, dotsqty,
&outputdata[sizeof(ColPicHead3) + Head0->ListDataSize],
outputmaxtsize - sizeof(ColPicHead3) - Head0->ListDataSize);
Head0->ColorDataSize = enqty;
Head0->PicW = picw;
Head0->PicH = pich;
return sizeof(ColPicHead3) + Head0->ListDataSize + Head0->ColorDataSize;
}
int ColPic_EncodeStr(U16 *fromcolor16, int picw, int pich, U8 *outputdata, int outputmaxtsize, int colorsmax)
{
int qty = 0;
int temp = 0;
int strindex = 0;
int hexindex = 0;
U8 TempBytes[4];
qty = ColPicEncode(fromcolor16, picw, pich, outputdata, outputmaxtsize, colorsmax);
if (qty == 0)
return 0;
temp = 3 - (qty % 3);
while (temp > 0) {
outputdata[qty] = 0;
qty++;
temp--;
}
if ((qty * 4 / 3) >= outputmaxtsize)
return 0;
hexindex = qty;
strindex = (qty * 4 / 3);
while (hexindex > 0) {
hexindex -= 3;
strindex -= 4;
TempBytes[0] = (U8) (outputdata[hexindex] >> 2);
TempBytes[1] = (U8) (outputdata[hexindex] & 3);
TempBytes[1] <<= 4;
TempBytes[1] += ((U8) (outputdata[hexindex + 1] >> 4));
TempBytes[2] = (U8) (outputdata[hexindex + 1] & 15);
TempBytes[2] <<= 2;
TempBytes[2] += ((U8) (outputdata[hexindex + 2] >> 6));
TempBytes[3] = (U8) (outputdata[hexindex + 2] & 63);
TempBytes[0] += 48;
if (TempBytes[0] == (U8) '\\')
TempBytes[0] = 126;
TempBytes[0 + 1] += 48;
if (TempBytes[0 + 1] == (U8) '\\')
TempBytes[0 + 1] = 126;
TempBytes[0 + 2] += 48;
if (TempBytes[0 + 2] == (U8) '\\')
TempBytes[0 + 2] = 126;
TempBytes[0 + 3] += 48;
if (TempBytes[0 + 3] == (U8) '\\')
TempBytes[0 + 3] = 126;
outputdata[strindex] = TempBytes[0];
outputdata[strindex + 1] = TempBytes[1];
outputdata[strindex + 2] = TempBytes[2];
outputdata[strindex + 3] = TempBytes[3];
}
qty = qty * 4 / 3;
outputdata[qty] = 0;
return qty;
}
} // namespace Slic3r::GCodeThumbnails

View File

@@ -13,6 +13,8 @@
#include <boost/beast/core/detail/base64.hpp>
#include "../libslic3r/enum_bitmask.hpp"
//B3
#include "DataType.h"
namespace Slic3r {
enum class ThumbnailError : int { InvalidVal, OutOfRange, InvalidExt };
@@ -21,6 +23,30 @@ namespace Slic3r {
}
//B3
typedef struct
{
U16 colo16;
U8 A0;
U8 A1;
U8 A2;
U8 res0;
U16 res1;
U32 qty;
} U16HEAD;
typedef struct
{
U8 encodever;
U8 res0;
U16 oncelistqty;
U32 PicW;
U32 PicH;
U32 mark;
U32 ListDataSize;
U32 ColorDataSize;
U32 res1;
U32 res2;
} ColPicHead3;
namespace Slic3r::GCodeThumbnails {
@@ -43,23 +69,46 @@ std::pair<GCodeThumbnailDefinitionsList, ThumbnailErrors> make_and_check_thumbna
std::string get_error_string(const ThumbnailErrors& errors);
//B3
std::string compress_qidi_thumbnail(const ThumbnailData &data, GCodeThumbnailsFormat format);
int ColPic_EncodeStr(U16 *fromcolor16, int picw, int pich, U8 *outputdata, int outputmaxtsize, int colorsmax);
template<typename WriteToOutput, typename ThrowIfCanceledCallback>
inline void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb, const std::vector<std::pair<GCodeThumbnailsFormat, Vec2d>>& thumbnails_list, WriteToOutput output, ThrowIfCanceledCallback throw_if_canceled)
{
// Write thumbnails using base64 encoding
if (thumbnail_cb != nullptr) {
//B3
int count = 0;
for (const auto& [format, size] : thumbnails_list) {
static constexpr const size_t max_row_length = 78;
ThumbnailsList thumbnails = thumbnail_cb(ThumbnailsParams{ {size}, true, true, true, true });
ThumbnailsList thumbnails = thumbnail_cb(ThumbnailsParams{{size}, true, false, false, true});
for (const ThumbnailData& data : thumbnails)
if (data.is_valid()) {
switch (format) {
case GCodeThumbnailsFormat::QIDI: {
auto compressed = compress_qidi_thumbnail(data, format);
if (count == 0) {
output((boost::format("\n\n;gimage:%s\n\n") % compressed).str().c_str());
count++;
break;
} else {
output((boost::format("\n\n;simage:%s\n\n") % compressed).str().c_str());
count++;
break;
}
}
default: {
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));
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());
@@ -71,8 +120,10 @@ inline void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb,
output((boost::format("; %s end\n;\n") % compressed->tag()).str().c_str());
}
}
}
throw_if_canceled();
}
}