OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GCodeThumbnails Namespace Reference

Classes

struct  CompressedPNG
struct  CompressedJPG
struct  CompressedQOI
struct  CompressedBIQU
struct  CompressedColPic
struct  U16HEAD
struct  ColPicHead3
struct  CompressedImageBuffer

Typedefs

typedef std::vector< std::pair< GCodeThumbnailsFormat, Vec2d > > GCodeThumbnailDefinitionsList

Functions

std::unique_ptr< CompressedImageBuffer > compress_thumbnail_png (const ThumbnailData &data)
std::unique_ptr< CompressedImageBuffer > compress_thumbnail_jpg (const ThumbnailData &data)
std::unique_ptr< CompressedImageBuffer > compress_thumbnail_qoi (const ThumbnailData &data)
int ColPic_EncodeStr (unsigned short *fromcolor16, int picw, int pich, unsigned char *outputdata, int outputmaxtsize, int colorsmax)
std::unique_ptr< CompressedImageBuffer > compress_thumbnail_colpic (const ThumbnailData &data)
std::unique_ptr< CompressedImageBuffer > compress_thumbnail_btt_tft (const ThumbnailData &data)
std::string get_hex (const unsigned int input)
std::string rjust (std::string input, unsigned int width, char fill_char)
std::unique_ptr< CompressedImageBuffer > compress_thumbnail (const ThumbnailData &data, GCodeThumbnailsFormat format)
static void colmemmove (unsigned char *dec, unsigned char *src, int lenth)
static void colmemcpy (unsigned char *dec, unsigned char *src, int lenth)
static void colmemset (unsigned char *dec, unsigned char val, int lenth)
static void ADList0 (unsigned short val, U16HEAD *listu16, int *listqty, int maxqty)
static int Byte8bitEncode (unsigned short *fromcolor16, unsigned short *listu16, int listqty, int dotsqty, unsigned char *outputdata, int decMaxBytesize)
static int ColPicEncode (unsigned short *fromcolor16, int picw, int pich, unsigned char *outputdata, int outputmaxtsize, int colorsmax)
std::pair< GCodeThumbnailDefinitionsList, ThumbnailErrors > make_and_check_thumbnail_list (const std::string &thumbnails_string, const std::string_view def_ext)
std::pair< GCodeThumbnailDefinitionsList, ThumbnailErrors > make_and_check_thumbnail_list (const ConfigBase &config)
std::string get_error_string (const ThumbnailErrors &errors)
template<typename WriteToOutput, typename ThrowIfCanceledCallback>
void export_thumbnails_to_file (ThumbnailsGeneratorCallback &thumbnail_cb, int plate_id, const std::vector< std::pair< GCodeThumbnailsFormat, Vec2d > > &thumbnails_list, WriteToOutput output, ThrowIfCanceledCallback throw_if_canceled)

Class Documentation

◆ Slic3r::GCodeThumbnails::U16HEAD

struct Slic3r::GCodeThumbnails::U16HEAD
Class Members
unsigned char A0
unsigned char A1
unsigned char A2
unsigned short colo16
unsigned int qty
unsigned char res0
unsigned short res1

◆ Slic3r::GCodeThumbnails::ColPicHead3

struct Slic3r::GCodeThumbnails::ColPicHead3
Class Members
unsigned int ColorDataSize
unsigned char encodever
unsigned int ListDataSize
unsigned int mark
unsigned short oncelistqty
unsigned int PicH
unsigned int PicW
unsigned char res0
unsigned int res1
unsigned int res2

Typedef Documentation

◆ GCodeThumbnailDefinitionsList

Function Documentation

◆ ADList0()

void Slic3r::GCodeThumbnails::ADList0 ( unsigned short val,
U16HEAD * listu16,
int * listqty,
int maxqty )
static
334{
335 unsigned char A0;
336 unsigned char A1;
337 unsigned char A2;
338 int qty = *listqty;
339 if (qty >= maxqty)
340 return;
341 for (int i = 0; i < qty; i++) {
342 if (listu16[i].colo16 == val) {
343 listu16[i].qty++;
344 return;
345 }
346 }
347 A0 = (unsigned char) (val >> 11);
348 A1 = (unsigned char) ((val << 5) >> 10);
349 A2 = (unsigned char) ((val << 11) >> 11);
350 U16HEAD* a = &listu16[qty];
351 a->colo16 = val;
352 a->A0 = A0;
353 a->A1 = A1;
354 a->A2 = A2;
355 a->qty = 1;
356 *listqty = qty + 1;
357}
unsigned short colo16
Definition Thumbnails.cpp:280
unsigned int qty
Definition Thumbnails.cpp:286

References Slic3r::GCodeThumbnails::U16HEAD::A0, Slic3r::GCodeThumbnails::U16HEAD::A1, Slic3r::GCodeThumbnails::U16HEAD::A2, Slic3r::GCodeThumbnails::U16HEAD::colo16, and Slic3r::GCodeThumbnails::U16HEAD::qty.

Referenced by ColPicEncode().

Here is the caller graph for this function:

◆ Byte8bitEncode()

int Slic3r::GCodeThumbnails::Byte8bitEncode ( unsigned short * fromcolor16,
unsigned short * listu16,
int listqty,
int dotsqty,
unsigned char * outputdata,
int decMaxBytesize )
static
361{
362 unsigned char tid, sid;
363 int dots = 0;
364 int srcindex = 0;
365 int decindex = 0;
366 int lastid = 0;
367 int temp = 0;
368 while (dotsqty > 0) {
369 dots = 1;
370 for (int i = 0; i < (dotsqty - 1); i++) {
371 if (fromcolor16[srcindex + i] != fromcolor16[srcindex + i + 1])
372 break;
373 dots++;
374 if (dots == 255)
375 break;
376 }
377 temp = 0;
378 for (int i = 0; i < listqty; i++) {
379 if (listu16[i] == fromcolor16[srcindex]) {
380 temp = i;
381 break;
382 }
383 }
384 tid = (unsigned char) (temp % 32);
385 sid = (unsigned char) (temp / 32);
386 if (lastid != sid) {
387 if (decindex >= decMaxBytesize)
388 goto IL_END;
389 outputdata[decindex] = 7;
390 outputdata[decindex] <<= 5;
391 outputdata[decindex] += sid;
392 decindex++;
393 lastid = sid;
394 }
395 if (dots <= 6) {
396 if (decindex >= decMaxBytesize)
397 goto IL_END;
398 outputdata[decindex] = (unsigned char) dots;
399 outputdata[decindex] <<= 5;
400 outputdata[decindex] += tid;
401 decindex++;
402 } else {
403 if (decindex >= decMaxBytesize)
404 goto IL_END;
405 outputdata[decindex] = 0;
406 outputdata[decindex] += tid;
407 decindex++;
408 if (decindex >= decMaxBytesize)
409 goto IL_END;
410 outputdata[decindex] = (unsigned char) dots;
411 decindex++;
412 }
413 srcindex += dots;
414 dotsqty -= dots;
415 }
416IL_END:
417 return decindex;
418}

Referenced by ColPicEncode().

Here is the caller graph for this function:

◆ colmemcpy()

void Slic3r::GCodeThumbnails::colmemcpy ( unsigned char * dec,
unsigned char * src,
int lenth )
static
319{
320 while (lenth > 0) {
321 *(dec++) = *(src++);
322 lenth--;
323 }
324}

Referenced by ColPicEncode().

Here is the caller graph for this function:

◆ colmemmove()

void Slic3r::GCodeThumbnails::colmemmove ( unsigned char * dec,
unsigned char * src,
int lenth )
static
303{
304 if (src < dec) {
305 dec += lenth - 1;
306 src += lenth - 1;
307 while (lenth > 0) {
308 *(dec--) = *(src--);
309 lenth--;
310 }
311 } else {
312 while (lenth > 0) {
313 *(dec++) = *(src++);
314 lenth--;
315 }
316 }
317}

Referenced by ColPicEncode().

Here is the caller graph for this function:

◆ colmemset()

void Slic3r::GCodeThumbnails::colmemset ( unsigned char * dec,
unsigned char val,
int lenth )
static
326{
327 while (lenth > 0) {
328 *(dec++) = val;
329 lenth--;
330 }
331}

Referenced by ColPicEncode().

Here is the caller graph for this function:

◆ ColPic_EncodeStr()

int Slic3r::GCodeThumbnails::ColPic_EncodeStr ( unsigned short * fromcolor16,
int picw,
int pich,
unsigned char * outputdata,
int outputmaxtsize,
int colorsmax )
492{
493 int qty = 0;
494 int temp = 0;
495 int strindex = 0;
496 int hexindex = 0;
497 unsigned char TempBytes[4];
498 qty = ColPicEncode(fromcolor16, picw, pich, outputdata, outputmaxtsize, colorsmax);
499 if (qty == 0)
500 return 0;
501 temp = 3 - (qty % 3);
502 while (temp > 0) {
503 outputdata[qty] = 0;
504 qty++;
505 temp--;
506 }
507 if ((qty * 4 / 3) >= outputmaxtsize)
508 return 0;
509 hexindex = qty;
510 strindex = (qty * 4 / 3);
511 while (hexindex > 0) {
512 hexindex -= 3;
513 strindex -= 4;
514
515 TempBytes[0] = (unsigned char) (outputdata[hexindex] >> 2);
516 TempBytes[1] = (unsigned char) (outputdata[hexindex] & 3);
517 TempBytes[1] <<= 4;
518 TempBytes[1] += ((unsigned char) (outputdata[hexindex + 1] >> 4));
519 TempBytes[2] = (unsigned char) (outputdata[hexindex + 1] & 15);
520 TempBytes[2] <<= 2;
521 TempBytes[2] += ((unsigned char) (outputdata[hexindex + 2] >> 6));
522 TempBytes[3] = (unsigned char) (outputdata[hexindex + 2] & 63);
523
524 TempBytes[0] += 48;
525 if (TempBytes[0] == (unsigned char) '\\')
526 TempBytes[0] = 126;
527 TempBytes[0 + 1] += 48;
528 if (TempBytes[0 + 1] == (unsigned char) '\\')
529 TempBytes[0 + 1] = 126;
530 TempBytes[0 + 2] += 48;
531 if (TempBytes[0 + 2] == (unsigned char) '\\')
532 TempBytes[0 + 2] = 126;
533 TempBytes[0 + 3] += 48;
534 if (TempBytes[0 + 3] == (unsigned char) '\\')
535 TempBytes[0 + 3] = 126;
536
537 outputdata[strindex] = TempBytes[0];
538 outputdata[strindex + 1] = TempBytes[1];
539 outputdata[strindex + 2] = TempBytes[2];
540 outputdata[strindex + 3] = TempBytes[3];
541 }
542 qty = qty * 4 / 3;
543 outputdata[qty] = 0;
544 return qty;
545}
static int ColPicEncode(unsigned short *fromcolor16, int picw, int pich, unsigned char *outputdata, int outputmaxtsize, int colorsmax)
Definition Thumbnails.cpp:420

References ColPicEncode().

Referenced by compress_thumbnail_colpic().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ColPicEncode()

int Slic3r::GCodeThumbnails::ColPicEncode ( unsigned short * fromcolor16,
int picw,
int pich,
unsigned char * outputdata,
int outputmaxtsize,
int colorsmax )
static
421{
422 U16HEAD l0;
423 int cha0, cha1, cha2, fid, minval;
424 ColPicHead3* Head0 = nullptr;
425 U16HEAD Listu16[1024];
426 int ListQty = 0;
427 int enqty = 0;
428 int dotsqty = picw * pich;
429 if (colorsmax > 1024)
430 colorsmax = 1024;
431 for (int i = 0; i < dotsqty; i++) {
432 int ch = (int) fromcolor16[i];
433 ADList0(ch, Listu16, &ListQty, 1024);
434 }
435
436 for (int index = 1; index < ListQty; index++) {
437 l0 = Listu16[index];
438 for (int i = 0; i < index; i++) {
439 if (l0.qty >= Listu16[i].qty) {
440 colmemmove((unsigned char*) &Listu16[i + 1], (unsigned char*) &Listu16[i], (index - i) * sizeof(U16HEAD));
441 colmemcpy((unsigned char*) &Listu16[i], (unsigned char*) &l0, sizeof(U16HEAD));
442 break;
443 }
444 }
445 }
446 while (ListQty > colorsmax) {
447 l0 = Listu16[ListQty - 1];
448 minval = 255;
449 fid = -1;
450 for (int i = 0; i < colorsmax; i++) {
451 cha0 = Listu16[i].A0 - l0.A0;
452 if (cha0 < 0)
453 cha0 = 0 - cha0;
454 cha1 = Listu16[i].A1 - l0.A1;
455 if (cha1 < 0)
456 cha1 = 0 - cha1;
457 cha2 = Listu16[i].A2 - l0.A2;
458 if (cha2 < 0)
459 cha2 = 0 - cha2;
460 int chall = cha0 + cha1 + cha2;
461 if (chall < minval) {
462 minval = chall;
463 fid = i;
464 }
465 }
466 for (int i = 0; i < dotsqty; i++) {
467 if (fromcolor16[i] == l0.colo16)
468 fromcolor16[i] = Listu16[fid].colo16;
469 }
470 ListQty = ListQty - 1;
471 }
472 Head0 = ((ColPicHead3*) outputdata);
473 colmemset(outputdata, 0, sizeof(ColPicHead3));
474 Head0->encodever = 3;
475 Head0->oncelistqty = 0;
476 Head0->mark = 0x05DDC33C;
477 Head0->ListDataSize = ListQty * 2;
478 for (int i = 0; i < ListQty; i++) {
479 unsigned short* l0 = (unsigned short*) &outputdata[sizeof(ColPicHead3)];
480 l0[i] = Listu16[i].colo16;
481 }
482 enqty = Byte8bitEncode(fromcolor16, (unsigned short*) &outputdata[sizeof(ColPicHead3)], Head0->ListDataSize >> 1, dotsqty,
483 &outputdata[sizeof(ColPicHead3) + Head0->ListDataSize],
484 outputmaxtsize - sizeof(ColPicHead3) - Head0->ListDataSize);
485 Head0->ColorDataSize = enqty;
486 Head0->PicW = picw;
487 Head0->PicH = pich;
488 return sizeof(ColPicHead3) + Head0->ListDataSize + Head0->ColorDataSize;
489}
unsigned int PicH
Definition Thumbnails.cpp:294
static void colmemmove(unsigned char *dec, unsigned char *src, int lenth)
Definition Thumbnails.cpp:302
unsigned char A1
Definition Thumbnails.cpp:282
unsigned char A2
Definition Thumbnails.cpp:283
unsigned short oncelistqty
Definition Thumbnails.cpp:292
static void ADList0(unsigned short val, U16HEAD *listu16, int *listqty, int maxqty)
Definition Thumbnails.cpp:333
unsigned char A0
Definition Thumbnails.cpp:281
static int Byte8bitEncode(unsigned short *fromcolor16, unsigned short *listu16, int listqty, int dotsqty, unsigned char *outputdata, int decMaxBytesize)
Definition Thumbnails.cpp:359
unsigned int mark
Definition Thumbnails.cpp:295
unsigned char encodever
Definition Thumbnails.cpp:290
static void colmemset(unsigned char *dec, unsigned char val, int lenth)
Definition Thumbnails.cpp:325
unsigned int ListDataSize
Definition Thumbnails.cpp:296
static void colmemcpy(unsigned char *dec, unsigned char *src, int lenth)
Definition Thumbnails.cpp:318
unsigned int ColorDataSize
Definition Thumbnails.cpp:297
unsigned int PicW
Definition Thumbnails.cpp:293
Definition Thumbnails.cpp:289
Definition Thumbnails.cpp:279

References Slic3r::GCodeThumbnails::U16HEAD::A0, Slic3r::GCodeThumbnails::U16HEAD::A1, Slic3r::GCodeThumbnails::U16HEAD::A2, ADList0(), Byte8bitEncode(), colmemcpy(), colmemmove(), colmemset(), Slic3r::GCodeThumbnails::U16HEAD::colo16, Slic3r::GCodeThumbnails::ColPicHead3::ColorDataSize, Slic3r::GCodeThumbnails::ColPicHead3::encodever, Slic3r::GCodeThumbnails::ColPicHead3::ListDataSize, Slic3r::GCodeThumbnails::ColPicHead3::mark, Slic3r::GCodeThumbnails::ColPicHead3::oncelistqty, Slic3r::GCodeThumbnails::ColPicHead3::PicH, Slic3r::GCodeThumbnails::ColPicHead3::PicW, and Slic3r::GCodeThumbnails::U16HEAD::qty.

Referenced by ColPic_EncodeStr().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compress_thumbnail()

std::unique_ptr< CompressedImageBuffer > Slic3r::GCodeThumbnails::compress_thumbnail ( const ThumbnailData & data,
GCodeThumbnailsFormat format )
262{
263 switch (format) {
265 default:
266 return compress_thumbnail_png(data);
268 return compress_thumbnail_jpg(data);
270 return compress_thumbnail_qoi(data);
272 return compress_thumbnail_btt_tft(data);
274 return compress_thumbnail_colpic(data);
275 }
276}
std::unique_ptr< CompressedImageBuffer > compress_thumbnail_colpic(const ThumbnailData &data)
Definition Thumbnails.cpp:140
std::unique_ptr< CompressedImageBuffer > compress_thumbnail_qoi(const ThumbnailData &data)
Definition Thumbnails.cpp:117
std::unique_ptr< CompressedImageBuffer > compress_thumbnail_jpg(const ThumbnailData &data)
Definition Thumbnails.cpp:69
std::unique_ptr< CompressedImageBuffer > compress_thumbnail_png(const ThumbnailData &data)
Definition Thumbnails.cpp:62
std::unique_ptr< CompressedImageBuffer > compress_thumbnail_btt_tft(const ThumbnailData &data)
Definition Thumbnails.cpp:196
@ BTT_TFT
Definition PrintConfig.hpp:598
@ PNG
Definition PrintConfig.hpp:598
@ QOI
Definition PrintConfig.hpp:598
@ ColPic
Definition PrintConfig.hpp:598
@ JPG
Definition PrintConfig.hpp:598
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:45

References Slic3r::BTT_TFT, Slic3r::ColPic, compress_thumbnail_btt_tft(), compress_thumbnail_colpic(), compress_thumbnail_jpg(), compress_thumbnail_png(), compress_thumbnail_qoi(), Slic3r::format(), Slic3r::JPG, Slic3r::PNG, and Slic3r::QOI.

Referenced by export_thumbnails_to_file().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compress_thumbnail_btt_tft()

std::unique_ptr< CompressedImageBuffer > Slic3r::GCodeThumbnails::compress_thumbnail_btt_tft ( const ThumbnailData & data)
196 {
197
198 // Take vector of RGBA pixels and flip the image vertically
199 std::vector<unsigned char> rgba_pixels(data.pixels.size());
200 const unsigned int row_size = data.width * 4;
201 for (unsigned int y = 0; y < data.height; ++y) {
202 ::memcpy(rgba_pixels.data() + (data.height - y - 1) * row_size, data.pixels.data() + y * row_size, row_size);
203 }
204
205 auto out = std::make_unique<CompressedBIQU>();
206
207 // get the output size of the data
208 // add 4 bytes to the row_size to account for end of line (\r\n)
209 // add 1 byte for the 0 of the c_str
210 out->size = data.height * (row_size + 4) + 1;
211 out->data = malloc(out->size);
212
213 std::stringstream out_data;
214 typedef struct {unsigned char r, g, b, a;} pixel;
215 pixel px;
216 for (unsigned int ypos = 0; ypos < data.height; ypos++) {
217 std::stringstream line;
218 line << ";";
219 for (unsigned int xpos = 0; xpos < row_size; xpos+=4) {
220 px.r = rgba_pixels[ypos * row_size + xpos];
221 px.g = rgba_pixels[ypos * row_size + xpos + 1];
222 px.b = rgba_pixels[ypos * row_size + xpos + 2];
223 px.a = rgba_pixels[ypos * row_size + xpos + 3];
224
225 // calculate values for RGB with alpha
226 const uint8_t rv = ((px.a * px.r) / 255);
227 const uint8_t gv = ((px.a * px.g) / 255);
228 const uint8_t bv = ((px.a * px.b) / 255);
229
230 // convert the RGB values to RGB565 hex that is right justified (same algorithm BTT firmware uses)
231 auto color_565 = rjust(get_hex(((rv >> 3) << 11) | ((gv >> 2) << 5) | (bv >> 3)), 4, '0');
232
233 //BTT original converter specifies these values should be '0000'
234 if (color_565 == "0020" || color_565 == "0841" || color_565 == "0861")
235 color_565 = "0000";
236 //add the color to the line
237 line << color_565;
238 }
239 // output line and end line (\r\n is important. BTT firmware requires it)
240 out_data << line.str() << "\r\n";
241 line.clear();
242 }
243 ::memcpy(out->data, (const void*) out_data.str().c_str(), out->size);
244 return out;
245}
std::string get_hex(const unsigned int input)
Definition Thumbnails.cpp:247
std::string rjust(std::string input, unsigned int width, char fill_char)
Definition Thumbnails.cpp:253
unsigned int height
Definition ThumbnailData.hpp:19
std::vector< unsigned char > pixels
Definition ThumbnailData.hpp:20
unsigned int width
Definition ThumbnailData.hpp:18

References get_hex(), Slic3r::ThumbnailData::height, Slic3r::ThumbnailData::pixels, rjust(), and Slic3r::ThumbnailData::width.

Referenced by compress_thumbnail().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compress_thumbnail_colpic()

std::unique_ptr< CompressedImageBuffer > Slic3r::GCodeThumbnails::compress_thumbnail_colpic ( const ThumbnailData & data)
141{
142 const int MAX_SIZE = 512;
143 int width = int(data.width);
144 int height = int(data.height);
145
146 // Orca: cap data size to MAX_SIZE while maintaining aspect ratio
147 if (width > MAX_SIZE || height > MAX_SIZE) {
148 double aspectRatio = static_cast<double>(width) / height;
149 if (aspectRatio > 1.0) {
150 width = MAX_SIZE;
151 height = static_cast<int>(MAX_SIZE / aspectRatio);
152 } else {
153 height = MAX_SIZE;
154 width = static_cast<int>(MAX_SIZE * aspectRatio);
155 }
156 }
157
158 std::vector<unsigned short> color16_buf(width * height);
159 std::vector<unsigned char> output_buf(height * width * 10);
160
161 std::vector<uint8_t> rgba_pixels(data.pixels.size() * 4);
162 size_t row_size = width * 4;
163 for (size_t y = 0; y < height; ++y)
164 memcpy(rgba_pixels.data() + y * row_size, data.pixels.data() + y * row_size, row_size);
165 const unsigned char* pixels;
166 pixels = (const unsigned char*) rgba_pixels.data();
167 int r = 0, g = 0, b = 0, a = 0, rgb = 0;
168 int time = width * height - 1;
169 for (int row = 0; row < height; ++row) {
170 int rr = row * width;
171 for (int col = 0; col < width; ++col) {
172 const int pix_idx = 4 * (rr + width - col - 1);
173 r = int(pixels[pix_idx]) >> 3;
174 g = int(pixels[pix_idx + 1]) >> 2;
175 b = int(pixels[pix_idx + 2]) >> 3;
176 a = int(pixels[pix_idx + 3]);
177 if (a == 0) {
178 r = 46 >> 3;
179 g = 51 >> 2;
180 b = 72 >> 3;
181 }
182 rgb = (r << 11) | (g << 5) | b;
183 color16_buf[time--] = rgb;
184 }
185 }
186
187 ColPic_EncodeStr(color16_buf.data(), width, height, output_buf.data(), output_buf.size(), 1024);
188
189 auto out = std::make_unique<CompressedColPic>();
190 out->size = output_buf.size();
191 out->data = malloc(out->size);
192 ::memcpy(out->data, output_buf.data(), out->size);
193 return out;
194}
#define MAX_SIZE
Definition GizmoObjectManipulation.cpp:46
int ColPic_EncodeStr(unsigned short *fromcolor16, int picw, int pich, unsigned char *outputdata, int outputmaxtsize, int colorsmax)
Definition Thumbnails.cpp:491
coord_t width(const BoundingBox &box)
Definition Arrange.cpp:1184
coord_t height(const BoundingBox &box)
Definition Arrange.cpp:1185

References ColPic_EncodeStr(), Slic3r::ThumbnailData::height, MAX_SIZE, Slic3r::ThumbnailData::pixels, and Slic3r::ThumbnailData::width.

Referenced by compress_thumbnail().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compress_thumbnail_jpg()

std::unique_ptr< CompressedImageBuffer > Slic3r::GCodeThumbnails::compress_thumbnail_jpg ( const ThumbnailData & data)
70{
71 // Take vector of RGBA pixels and flip the image vertically
72 std::vector<unsigned char> rgba_pixels(data.pixels.size());
73 const unsigned int row_size = data.width * 4;
74 for (unsigned int y = 0; y < data.height; ++y) {
75 ::memcpy(rgba_pixels.data() + (data.height - y - 1) * row_size, data.pixels.data() + y * row_size, row_size);
76 }
77
78 // Store pointers to scanlines start for later use
79 std::vector<unsigned char*> rows_ptrs;
80 rows_ptrs.reserve(data.height);
81 for (unsigned int y = 0; y < data.height; ++y) {
82 rows_ptrs.emplace_back(&rgba_pixels[y * row_size]);
83 }
84
85 std::vector<unsigned char> compressed_data(data.pixels.size());
86 unsigned char* compressed_data_ptr = compressed_data.data();
87 unsigned long compressed_data_size = data.pixels.size();
88
89 jpeg_error_mgr err;
90 jpeg_compress_struct info;
91 info.err = jpeg_std_error(&err);
92 jpeg_create_compress(&info);
93 jpeg_mem_dest(&info, &compressed_data_ptr, &compressed_data_size);
94
95 info.image_width = data.width;
96 info.image_height = data.height;
97 info.input_components = 4;
98 info.in_color_space = JCS_EXT_RGBA;
99
100 jpeg_set_defaults(&info);
101 jpeg_set_quality(&info, 85, TRUE);
102 jpeg_start_compress(&info, TRUE);
103
104 jpeg_write_scanlines(&info, rows_ptrs.data(), data.height);
105 jpeg_finish_compress(&info);
106 jpeg_destroy_compress(&info);
107
108 // FIXME -> Add error checking
109
110 auto out = std::make_unique<CompressedJPG>();
111 out->data = malloc(compressed_data_size);
112 out->size = size_t(compressed_data_size);
113 ::memcpy(out->data, (const void*)compressed_data.data(), out->size);
114 return out;
115}

References Slic3r::ThumbnailData::height, Slic3r::ThumbnailData::pixels, and Slic3r::ThumbnailData::width.

Referenced by compress_thumbnail().

Here is the caller graph for this function:

◆ compress_thumbnail_png()

std::unique_ptr< CompressedImageBuffer > Slic3r::GCodeThumbnails::compress_thumbnail_png ( const ThumbnailData & data)
63{
64 auto out = std::make_unique<CompressedPNG>();
65 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);
66 return out;
67}

References Slic3r::ThumbnailData::height, Slic3r::ThumbnailData::pixels, and Slic3r::ThumbnailData::width.

Referenced by compress_thumbnail().

Here is the caller graph for this function:

◆ compress_thumbnail_qoi()

std::unique_ptr< CompressedImageBuffer > Slic3r::GCodeThumbnails::compress_thumbnail_qoi ( const ThumbnailData & data)
118{
119 qoi_desc desc;
120 desc.width = data.width;
121 desc.height = data.height;
122 desc.channels = 4;
123 desc.colorspace = QOI_SRGB;
124
125 // Take vector of RGBA pixels and flip the image vertically
126 std::vector<uint8_t> rgba_pixels(data.pixels.size() * 4);
127 size_t row_size = data.width * 4;
128 for (size_t y = 0; y < data.height; ++ y)
129 memcpy(rgba_pixels.data() + (data.height - y - 1) * row_size, data.pixels.data() + y * row_size, row_size);
130
131 auto out = std::make_unique<CompressedQOI>();
132 int size;
133 out->data = qoi_encode((const void*)rgba_pixels.data(), &desc, &size);
134 out->size = size;
135 return out;
136}

References Slic3r::ThumbnailData::height, Slic3r::ThumbnailData::pixels, and Slic3r::ThumbnailData::width.

Referenced by compress_thumbnail().

Here is the caller graph for this function:

◆ export_thumbnails_to_file()

template<typename WriteToOutput, typename ThrowIfCanceledCallback>
void Slic3r::GCodeThumbnails::export_thumbnails_to_file ( ThumbnailsGeneratorCallback & thumbnail_cb,
int plate_id,
const std::vector< std::pair< GCodeThumbnailsFormat, Vec2d > > & thumbnails_list,
WriteToOutput output,
ThrowIfCanceledCallback throw_if_canceled )
inline
53{
54 // Write thumbnails using base64 encoding
55 if (thumbnail_cb == nullptr)
56 return;
57 short i = 0;
58 bool first_ColPic = true;
59 for (const auto& [format, size] : thumbnails_list) {
60 static constexpr const size_t max_row_length = 78;
61 ThumbnailsList thumbnails = thumbnail_cb(ThumbnailsParams{{size}, true, true, true, true, plate_id});
62 for (const ThumbnailData &data : thumbnails) {
63 if (data.is_valid()) {
64 auto compressed = compress_thumbnail(data, format);
65 if (compressed->data && compressed->size) {
67 // write BTT_TFT header
68 output((";" + rjust(get_hex(data.width), 4, '0') + rjust(get_hex(data.height), 4, '0') + "\r\n").c_str());
69 output((char *) compressed->data);
70 if (i == (thumbnails_list.size() - 1))
71 output("; bigtree thumbnail end\r\n\r\n");
72 }
74 if (first_ColPic) {
75 output((boost::format("\n\n;gimage:%s\n\n") % reinterpret_cast<char*>(compressed->data)).str().c_str());
76 } else {
77 output((boost::format("\n\n;simage:%s\n\n") % reinterpret_cast<char*>(compressed->data)).str().c_str());
78 }
79 first_ColPic = false;
80 }
81 else {
82 output("; THUMBNAIL_BLOCK_START\n");
83 std::string encoded;
84 encoded.resize(boost::beast::detail::base64::encoded_size(compressed->size));
85 encoded.resize(boost::beast::detail::base64::encode((void *) encoded.data(), (const void *) compressed->data,
86 compressed->size));
87 output((boost::format("\n;\n; %s begin %dx%d %d\n") % compressed->tag() % data.width % data.height % encoded.size())
88 .str()
89 .c_str());
90 while (encoded.size() > max_row_length) {
91 output((boost::format("; %s\n") % encoded.substr(0, max_row_length)).str().c_str());
92 encoded = encoded.substr(max_row_length);
93 }
94
95 // Orca write remaining ecoded data
96 if (encoded.size() > 0)
97 output((boost::format("; %s\n") % encoded).str().c_str());
98
99 output((boost::format("; %s end\n") % compressed->tag()).str().c_str());
100 output("; THUMBNAIL_BLOCK_END\n\n");
101 }
102 throw_if_canceled();
103 }
104 }
105 }
106 i++;
107 }
108}
std::unique_ptr< CompressedImageBuffer > compress_thumbnail(const ThumbnailData &data, GCodeThumbnailsFormat format)
Definition Thumbnails.cpp:261
std::vector< ThumbnailData > ThumbnailsList
Definition ThumbnailData.hpp:34
Definition ThumbnailData.hpp:37

References Slic3r::BTT_TFT, Slic3r::ColPic, compress_thumbnail(), Slic3r::format(), get_hex(), and rjust().

Referenced by Slic3r::GCode::_do_export().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_error_string()

std::string Slic3r::GCodeThumbnails::get_error_string ( const ThumbnailErrors & errors)
610{
611 std::string error_str;
612
614 error_str += "\n - " + Slic3r::format(_u8L("Invalid input format. Expected vector of dimensions in the following format: \"%1%\""), "XxY/EXT, XxY/EXT, ...");
616 error_str += "\n - " + _u8L("Input value is out of range");
618 error_str += "\n - " + _u8L("Some extension in the input is invalid");
619
620 return error_str;
621}
constexpr bool has(option_type t) const
Definition enum_bitmask.hpp:47
@ OutOfRange
Definition Thumbnails.hpp:21
@ InvalidVal
Definition Thumbnails.hpp:21
@ InvalidExt
Definition Thumbnails.hpp:21
#define _u8L(s)
Definition I18N.hpp:11

References _u8L, Slic3r::format(), Slic3r::enum_bitmask< option_type, typename >::has(), Slic3r::InvalidExt, Slic3r::InvalidVal, and Slic3r::OutOfRange.

Referenced by Slic3r::GCode::_do_export(), Slic3r::GUI::TabPrinter::build_fff(), and Slic3r::PrintConfigDef::handle_legacy_composite().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_hex()

std::string Slic3r::GCodeThumbnails::get_hex ( const unsigned int input)
247 {
248 std::stringstream stream;
249 stream << std::hex << input;
250 return stream.str();
251}

Referenced by compress_thumbnail_btt_tft(), and export_thumbnails_to_file().

Here is the caller graph for this function:

◆ make_and_check_thumbnail_list() [1/2]

std::pair< GCodeThumbnailDefinitionsList, ThumbnailErrors > Slic3r::GCodeThumbnails::make_and_check_thumbnail_list ( const ConfigBase & config)
597{
598 // ??? Unit tests or command line slicing may not define "thumbnails" or "thumbnails_format".
599 // ??? If "thumbnails_format" is not defined, export to PNG.
600
601 // generate thumbnails data to process it
602
603 if (const auto thumbnails_value = config.option<ConfigOptionString>("thumbnails"))
604 return make_and_check_thumbnail_list(thumbnails_value->value);
605
606 return {};
607}
ConfigOption * option(const t_config_option_key &opt_key, bool create=false)
Definition Config.hpp:2768
Definition Config.hpp:1158
std::pair< GCodeThumbnailDefinitionsList, ThumbnailErrors > make_and_check_thumbnail_list(const std::string &thumbnails_string, const std::string_view def_ext)
Definition Thumbnails.cpp:546

References make_and_check_thumbnail_list(), and Slic3r::ConfigBase::option().

Here is the call graph for this function:

◆ make_and_check_thumbnail_list() [2/2]

std::pair< GCodeThumbnailDefinitionsList, ThumbnailErrors > Slic3r::GCodeThumbnails::make_and_check_thumbnail_list ( const std::string & thumbnails_string,
const std::string_view def_ext )
547{
548 if (thumbnails_string.empty())
549 return {};
550
551 std::istringstream is(thumbnails_string);
552 std::string point_str;
553
554 ThumbnailErrors errors;
555
556 // generate thumbnails data to process it
557
558 GCodeThumbnailDefinitionsList thumbnails_list;
559 while (std::getline(is, point_str, ',')) {
560 Vec2d point(Vec2d::Zero());
562 std::istringstream iss(point_str);
563 std::string coord_str;
564 if (std::getline(iss, coord_str, 'x') && !coord_str.empty()) {
565 std::istringstream(coord_str) >> point(0);
566 if (std::getline(iss, coord_str, '/') && !coord_str.empty()) {
567 std::istringstream(coord_str) >> point(1);
568
569 if (0 < point(0) && point(0) < 1000 && 0 < point(1) && point(1) < 1000) {
570 std::string ext_str;
571 std::getline(iss, ext_str, '/');
572
573 if (ext_str.empty())
574 ext_str = def_ext.empty() ? "PNG"sv : def_ext;
575
576 // check validity of extention
577 boost::to_upper(ext_str);
580 errors = enum_bitmask(errors | ThumbnailError::InvalidExt);
581 }
582
583 thumbnails_list.emplace_back(std::make_pair(format, point));
584 }
585 else
586 errors = enum_bitmask(errors | ThumbnailError::OutOfRange);
587 continue;
588 }
589 }
590 errors = enum_bitmask(errors | ThumbnailError::InvalidVal);
591 }
592
593 return std::make_pair(std::move(thumbnails_list), errors);
594}
static bool from_string(const std::string &str, T &value)
Definition Config.hpp:2132
Definition enum_bitmask.hpp:14
std::vector< std::pair< GCodeThumbnailsFormat, Vec2d > > GCodeThumbnailDefinitionsList
Definition Thumbnails.hpp:42
enum_bitmask< ThumbnailError > ThumbnailErrors
Definition Thumbnails.hpp:22
GCodeThumbnailsFormat
Definition PrintConfig.hpp:597
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:67

References Slic3r::format(), Slic3r::ConfigOptionEnum< T >::from_string(), Slic3r::InvalidExt, Slic3r::InvalidVal, Slic3r::OutOfRange, and Slic3r::PNG.

Referenced by Slic3r::GCode::_do_export(), Slic3r::GUI::TabPrinter::build_fff(), Slic3r::deep_diff(), Slic3r::PrintConfigDef::handle_legacy_composite(), make_and_check_thumbnail_list(), and Slic3r::GUI::validate_thumbnails_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rjust()

std::string Slic3r::GCodeThumbnails::rjust ( std::string input,
unsigned int width,
char fill_char )
253 {
254 std::stringstream stream;
255 stream.fill(fill_char);
256 stream.width(width);
257 stream << input;
258 return stream.str();
259}

Referenced by compress_thumbnail_btt_tft(), and export_thumbnails_to_file().

Here is the caller graph for this function: