From ed3cc51a46c2b4c5691101526dfacf6fe0df6621 Mon Sep 17 00:00:00 2001 From: gitlost Date: Fri, 26 Feb 2021 20:45:08 +0000 Subject: [PATCH] png.c: Use palette for file size savings --- backend/png.c | 236 +++++++++++++----- backend/tests/data/png/codablockf_3rows.png | Bin 365 -> 178 bytes .../tests/data/png/code128_egrave_bold.png | Bin 520 -> 220 bytes .../data/png/code128_egrave_bold_box3.png | Bin 549 -> 235 bytes backend/tests/data/png/code39_small.png | Bin 366 -> 151 bytes .../data/png/ean13_2addon_ggs_5.2.2.5.1-2.png | Bin 901 -> 434 bytes .../data/png/ean13_5addon_ggs_5.2.2.5.2-2.png | Bin 1002 -> 488 bytes .../data/png/ean13_cc_2addon_cca_4x4.png | Bin 1132 -> 545 bytes .../data/png/ean13_cc_5addon_ccb_3x4.png | Bin 1263 -> 584 bytes .../png/ean13_cc_5addon_ccb_3x4_notext.png | Bin 647 -> 236 bytes backend/tests/data/png/ean2.png | Bin 299 -> 155 bytes backend/tests/data/png/ean5.png | Bin 454 -> 219 bytes backend/tests/data/png/ean8_2addon.png | Bin 745 -> 344 bytes backend/tests/data/png/ean8_5addon.png | Bin 865 -> 392 bytes .../tests/data/png/ean8_cc_2addon_cca_4x3.png | Bin 934 -> 411 bytes .../tests/data/png/ean8_cc_5addon_ccb_8x3.png | Bin 1073 -> 470 bytes backend/tests/data/png/gs1_128_cc_fig12.png | Bin 1164 -> 518 bytes backend/tests/data/png/pdf417_bgalpha.png | Bin 392 -> 193 bytes backend/tests/data/png/pdf417_bgfgalpha.png | Bin 0 -> 194 bytes backend/tests/data/png/pdf417_fgalpha.png | Bin 395 -> 192 bytes backend/tests/data/png/postnet_zip.png | Bin 350 -> 150 bytes backend/tests/data/png/ultra_alpha.png | Bin 305 -> 0 bytes backend/tests/data/png/ultra_bgalpha.png | Bin 0 -> 223 bytes backend/tests/data/png/ultra_bgfgalpha.png | Bin 0 -> 231 bytes backend/tests/data/png/ultra_fgalpha.png | Bin 0 -> 230 bytes backend/tests/data/png/ultra_fgalpha_nobg.png | Bin 0 -> 220 bytes .../data/png/upca_2addon_ggs_5.2.6.6-5.png | Bin 941 -> 442 bytes backend/tests/data/png/upca_5addon.png | Bin 910 -> 460 bytes backend/tests/data/png/upca_5addon_bind3.png | Bin 904 -> 460 bytes backend/tests/data/png/upca_5addon_notext.png | Bin 424 -> 167 bytes .../tests/data/png/upca_cc_2addon_cca_3x4.png | Bin 1062 -> 515 bytes .../tests/data/png/upca_cc_5addon_ccb_4x4.png | Bin 1179 -> 579 bytes .../data/png/upca_cc_5addon_ccb_4x4_bind3.png | Bin 1169 -> 581 bytes .../png/upca_cc_5addon_ccb_4x4_notext.png | Bin 657 -> 239 bytes backend/tests/data/png/upce_2addon.png | Bin 710 -> 342 bytes backend/tests/data/png/upce_5addon.png | Bin 828 -> 357 bytes .../tests/data/png/upce_cc_2addon_cca_5x2.png | Bin 882 -> 410 bytes .../tests/data/png/upce_cc_5addon_ccb_8x2.png | Bin 1060 -> 481 bytes .../png/upce_cc_5addon_ccb_8x2_notext.png | Bin 596 -> 230 bytes backend/tests/data/print/png/code128_aim.png | Bin 367 -> 147 bytes .../tests/data/print/png/dotcode_aim_fig7.png | Bin 682 -> 348 bytes .../tests/data/print/png/maxicode_fig_2.png | Bin 3845 -> 1994 bytes backend/tests/data/print/png/qr_v1_m.png | Bin 288 -> 192 bytes backend/tests/data/print/png/ultracode_a.png | Bin 249 -> 186 bytes backend/tests/test_png.c | 10 +- backend/tests/test_print.c | 2 + 46 files changed, 185 insertions(+), 63 deletions(-) create mode 100644 backend/tests/data/png/pdf417_bgfgalpha.png delete mode 100644 backend/tests/data/png/ultra_alpha.png create mode 100644 backend/tests/data/png/ultra_bgalpha.png create mode 100644 backend/tests/data/png/ultra_bgfgalpha.png create mode 100644 backend/tests/data/png/ultra_fgalpha.png create mode 100644 backend/tests/data/png/ultra_fgalpha_nobg.png diff --git a/backend/png.c b/backend/png.c index 0552cfca..187459b9 100644 --- a/backend/png.c +++ b/backend/png.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2009-2017 Robin Stuart + Copyright (C) 2009-2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,8 +37,6 @@ #include #include #endif -#include -#include #include "common.h" #ifndef NO_PNG @@ -72,37 +70,47 @@ static void writepng_error_handler(png_structp png_ptr, png_const_charp msg) { longjmp(graphic->jmpbuf, 1); } +/* Guestimate best compression strategy */ +static int guess_compression_strategy(struct zint_symbol *symbol, unsigned char *pixelbuf) { + (void)pixelbuf; + + /* TODO: Do properly */ + + /* It seems the best choice for typical barcode pngs is one of Z_DEFAULT_STRATEGY and Z_FILTERED */ + + /* Some guesses */ + if (symbol->symbology == BARCODE_MAXICODE) { + return Z_DEFAULT_STRATEGY; + } + if (symbol->symbology == BARCODE_AZTEC && symbol->bitmap_width <= 30) { + return Z_DEFAULT_STRATEGY; + } + + /* Z_FILTERED seems to work better for slightly more barcodes+data so default to that */ + return Z_FILTERED; +} + INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { struct mainprog_info_type wpng_info; struct mainprog_info_type *graphic; png_structp png_ptr; png_infop info_ptr; + int i; int row, column; - unsigned char fg[4], bg[4]; - unsigned char white[4] = { 0xff, 0xff, 0xff, 0xff }; - unsigned char cyan[4] = { 0, 0xff, 0xff, 0xff }; - unsigned char blue[4] = { 0, 0, 0xff, 0xff }; - unsigned char magenta[4] = { 0xff, 0, 0xff, 0xff }; - unsigned char red[4] = { 0xff, 0, 0, 0xff }; - unsigned char yellow[4] = { 0xff, 0xff, 0, 0xff }; - unsigned char green[4] = { 0, 0xff, 0, 0xff }; - unsigned char black[4] = { 0, 0, 0, 0xff }; - unsigned char *map[91] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x00-0F */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x10-1F */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x20-2F */ - bg, fg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0-9 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* :;<=>?@ */ - NULL, blue, cyan, NULL, NULL, NULL, green, NULL, NULL, NULL, black, NULL, magenta, /* A-M */ - NULL, NULL, NULL, NULL, red, NULL, NULL, NULL, NULL, white, NULL, yellow, NULL /* N-Z */ - }; - int use_alpha, incr; - unsigned char *image_data; + png_color bg, fg; + unsigned char bg_alpha, fg_alpha; + unsigned char map[128]; + png_color palette[32]; + int num_palette = 0; + unsigned char trans_alpha[32]; + int num_trans = 0; + int bit_depth; + int compression_strategy; #ifndef _MSC_VER - unsigned char outdata[symbol->bitmap_width * 4]; + unsigned char outdata[symbol->bitmap_width]; #else - unsigned char* outdata = (unsigned char*) _alloca(symbol->bitmap_width * 4); + unsigned char* outdata = (unsigned char*) _alloca(symbol->bitmap_width); #endif graphic = &wpng_info; @@ -110,28 +118,101 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) graphic->width = symbol->bitmap_width; graphic->height = symbol->bitmap_height; - fg[0] = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); - fg[1] = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); - fg[2] = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); - bg[0] = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); - bg[1] = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); - bg[2] = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + fg.red = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fg.green = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fg.blue = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bg.red = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bg.green = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bg.blue = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); - use_alpha = 0; - if (strlen(symbol->fgcolour) > 6) { - fg[3] = (16 * ctoi(symbol->fgcolour[6])) + ctoi(symbol->fgcolour[7]); - white[3] = cyan[3] = blue[3] = magenta[3] = red[3] = yellow[3] = green[3] = black[3] = fg[3]; - if (fg[3] != 0xff) use_alpha = 1; + fg_alpha = (16 * ctoi(symbol->fgcolour[6])) + ctoi(symbol->fgcolour[7]); } else { - fg[3] = 0xff; + fg_alpha = 0xff; } - + if (strlen(symbol->bgcolour) > 6) { - bg[3] = (16 * ctoi(symbol->bgcolour[6])) + ctoi(symbol->bgcolour[7]); - if (bg[3] != 0xff) use_alpha = 1; + bg_alpha = (16 * ctoi(symbol->bgcolour[6])) + ctoi(symbol->bgcolour[7]); } else { - bg[3] = 0xff; + bg_alpha = 0xff; + } + + if (symbol->symbology == BARCODE_ULTRA) { + static const int ultra_chars[8] = { 'W', 'C', 'B', 'M', 'R', 'Y', 'G', 'K' }; + static png_color ultra_colours[8] = { + { 0xff, 0xff, 0xff, }, /* White */ + { 0, 0xff, 0xff, }, /* Cyan */ + { 0, 0, 0xff, }, /* Blue */ + { 0xff, 0, 0xff, }, /* Magenta */ + { 0xff, 0, 0, }, /* Red */ + { 0xff, 0xff, 0, }, /* Yellow */ + { 0, 0xff, 0, }, /* Green */ + { 0, 0, 0, }, /* Black */ + }; + for (i = 0; i < 8; i++) { + map[ultra_chars[i]] = i; + palette[i] = ultra_colours[i]; + if (fg_alpha != 0xff) { + trans_alpha[i] = fg_alpha; + } + } + num_palette = 8; + if (fg_alpha != 0xff) { + num_trans = 8; + } + + /* For Ultracode, have background only if have whitespace/quiet zones */ + if (pixelbuf[0] == '0' || pixelbuf[symbol->bitmap_width - 1] == '0' + || pixelbuf[symbol->bitmap_height * (symbol->bitmap_width - 1)] == '0' + || pixelbuf[symbol->bitmap_height * symbol->bitmap_width - 1] == '0') { + /* Check whether can re-use white */ + if (bg.red == 0xff && bg.green == 0xff && bg.blue == 0xff && bg_alpha == fg_alpha) { + map['0'] = 0; /* Re-use white */ + } else { + if (bg_alpha == 0xff || fg_alpha != 0xff) { + /* No alpha or have foreground alpha - add to end */ + map['0'] = num_palette; + palette[num_palette++] = bg; + } else { + /* Alpha and no foreground alpha - add to front & move white to end */ + map['0'] = 0; + palette[0] = bg; + map['W'] = num_palette; + palette[num_palette++] = ultra_colours[0]; + } + if (bg_alpha != 0xff) { + trans_alpha[num_trans++] = bg_alpha; + } + } + } + } else { + int bg_idx = 0, fg_idx = 1; + /* Do alphas first so can swop indexes if background not alpha */ + if (bg_alpha != 0xff) { + trans_alpha[num_trans++] = bg_alpha; + } + if (fg_alpha != 0xff) { + trans_alpha[num_trans++] = fg_alpha; + if (num_trans == 1) { + /* Only foreground has alpha so swop indexes - saves a byte! */ + bg_idx = 1; + fg_idx = 0; + } + } + + map['0'] = bg_idx; + palette[bg_idx] = bg; + map['1'] = fg_idx; + palette[fg_idx] = fg; + num_palette = 2; + } + + if (num_palette <= 2) { + bit_depth = 1; + } else if (num_palette <= 16) { + bit_depth = 4; + } else { + bit_depth = 8; } /* Open output file in binary mode */ @@ -177,32 +258,64 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) /* set compression */ png_set_compression_level(png_ptr, 9); + /* Compression strategy can make a difference */ + compression_strategy = guess_compression_strategy(symbol, pixelbuf); + if (compression_strategy != Z_DEFAULT_STRATEGY) { + png_set_compression_strategy(png_ptr, compression_strategy); + } + /* set Header block */ - if (use_alpha) - png_set_IHDR(png_ptr, info_ptr, graphic->width, graphic->height, - 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - else - png_set_IHDR(png_ptr, info_ptr, graphic->width, graphic->height, - 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_set_IHDR(png_ptr, info_ptr, graphic->width, graphic->height, + bit_depth, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + png_set_PLTE(png_ptr, info_ptr, palette, num_palette); + if (num_trans) { + png_set_tRNS(png_ptr, info_ptr, trans_alpha, num_trans, NULL); + } + /* write all chunks up to (but not including) first IDAT */ png_write_info(png_ptr, info_ptr); - /* set up the transformations: for now, just pack low-bit-depth pixels - into bytes (one, two or four pixels per byte) */ - png_set_packing(png_ptr); - /* Pixel Plotting */ - incr = use_alpha ? 4 : 3; - for (row = 0; row < symbol->bitmap_height; row++) { - unsigned char *pb = pixelbuf + symbol->bitmap_width * row; - image_data = outdata; - for (column = 0; column < symbol->bitmap_width; column++, pb++, image_data += incr) { - memcpy(image_data, map[*pb], incr); + if (bit_depth == 1) { + for (row = 0; row < symbol->bitmap_height; row++) { + unsigned char *pb = pixelbuf + symbol->bitmap_width * row; + unsigned char *image_data = outdata; + for (column = 0; column < symbol->bitmap_width; column += 8, image_data++) { + unsigned char byte = 0; + for (i = 0; i < 8 && column + i < symbol->bitmap_width; i++, pb++) { + byte |= map[*pb] << (7 - i); + } + *image_data = byte; + } + /* write row contents to file */ + png_write_row(png_ptr, outdata); + } + } else if (bit_depth == 4) { + for (row = 0; row < symbol->bitmap_height; row++) { + unsigned char *pb = pixelbuf + symbol->bitmap_width * row; + unsigned char *image_data = outdata; + for (column = 0; column < symbol->bitmap_width; column += 2, image_data++) { + unsigned char byte = 0; + for (i = 0; i < 2 && column + i < symbol->bitmap_width; i++, pb++) { + byte |= map[*pb] << (i * 4); + } + *image_data = byte; + } + /* write row contents to file */ + png_write_row(png_ptr, outdata); + } + } else { /* Bit depth 8 */ + for (row = 0; row < symbol->bitmap_height; row++) { + unsigned char *pb = pixelbuf + symbol->bitmap_width * row; + unsigned char *image_data = outdata; + for (column = 0; column < symbol->bitmap_width; column++, pb++, image_data++) { + *image_data = map[*pb]; + } + /* write row contents to file */ + png_write_row(png_ptr, outdata); } - /* write row contents to file */ - png_write_row(png_ptr, outdata); } /* End the file */ @@ -215,6 +328,7 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) } else { fclose(wpng_info.outfile); } + return 0; } #endif /* NO_PNG */ diff --git a/backend/tests/data/png/codablockf_3rows.png b/backend/tests/data/png/codablockf_3rows.png index 90ef5c07eed64318750ab41bb0f8fcee82ec242f..dc71eb9768a2bd82652b4f9b5f26be6f4d144d1b 100644 GIT binary patch delta 162 zcmV;T0A2s>0(G QD*ylh07*qoM6N<$g68E&*8l(j literal 365 zcmeAS@N?(olHy`uVBq!ia0vp^pMcndg9%7FN83MOU|=-yba4!+xb^n#!F5dr0uF&$ zKmNzB<2Ij>HtU!lugP;AMaP4`E1Zmiveq77@1@DU#xVHV>4(Yoo7}D`WKS@CVo|(4 z+Wx!SqU;-GZ%aK(;#H%h_a<#QJF#4J@Be>gWw)G4&fHeE*|#TFy0$6u`?Wc1KdQ2% z@NQy@Y+f_b^n?_cshr);0OUJ@P2AM>Tr1MP-q`rd(Yj~t`~Ljlt+9OndAhCfqTBY) zF3fx03MudU``G@|u6@xUEl?v+m=J^OQ>IN+J!9mw$u~{%xO~6l+Ou<&=iJ==kJ%<& zj?rqb^}#84PyQ2$uSfQ@7EZ1`R5;uRIKK}e10ha0000c&grgrtSCRw(mZNJ~+tI<>0u0 zLxhEk$#sE30FYvBR0-Zc?0zVhmGQv0>A zBCWeIxBRtB;xj*So6GE<9r^wGzn@o@eYcCeX$N`4#7ZG0foU>gTe~DWM4f DpYX@z diff --git a/backend/tests/data/png/code128_egrave_bold_box3.png b/backend/tests/data/png/code128_egrave_bold_box3.png index 6edfb65b13bb82255a12a2777a60d86fb2f09791..ac9fb05d1137d9890825740945f3479e6ab733ae 100644 GIT binary patch delta 219 zcmV<103`pV1nU8i7=Hl+0000oD;IVE000J1OjJex|Nj6009C@%egFUfph-kQR7l6| z*E5rnI~@? VCFWQAAKU-{002ovPDHLkV1iF`UzY#? literal 549 zcmeAS@N?(olHy`uVBq!ia0vp^Z-BUgg9%8sw+kgPFfhLHba4!+xb^nt#k?j1k%ou! zQs4hSb(eM7O%2;JMzidF?@#ftuGzol3P>}M8(jno(qr@htoFrffWcC0>6o5>i$e@#C1_r=^>dvUufeD${It4%8 z{=d4bgX6KnqgHOcr85d=3jgMlcvxL4)wE>4tYue)t@>)wy&d7Z{J!tq_B?0yr|CW0 z-l?fPQ_p*&H}B=P8GNgymR^gyap-M%hxSL^@H^gI)w?D~troQv+<#$?#O2QEdb|H} zd`e%q+o}73T9}9AC>`i;b?H}{%w&q)>1E9F{boFyt=akR{ E0CuqEdjJ3c diff --git a/backend/tests/data/png/code39_small.png b/backend/tests/data/png/code39_small.png index 09985dc49a12eef8a5bd024f50ee4fc9e60c582e..45d9813ffb7a3c9d295e8b595d12ab8878050852 100644 GIT binary patch delta 134 zcmaFIG@WsRL_H%j0|UdGq*oJx6kC8#i0l9V|AEZVLznA-l#i#2V~EA+WQ&~7H=k|z zIFmo!ZvJ!2;v3J553e|YfC_>N@&$9;pBkSHx#A$0@FYMONWLrB;t+hXb5&F3J7eBW bvMda#4a`}-FFyi}Wnl1h^>bP0l+XkKvgtSk literal 366 zcmeAS@N?(olHy`uVBq!ia0vp^4M1GL!2~2D&%JMDU|=-$ba4!+xb^n>X|84i0f&o{ zFaQ7lR3ezwEaWM#&{!Ovb@h^raHgA!OGxORQ)m8q+=xbg8~Bs3&=kxC#7An~x*6@d)VZlE2vhEc(5}Z4l Qfj(yNboFyt=akR{0NHbI=Kufz diff --git a/backend/tests/data/png/ean13_2addon_ggs_5.2.2.5.1-2.png b/backend/tests/data/png/ean13_2addon_ggs_5.2.2.5.1-2.png index b9493972e837de2ccce1377fb21a1cb0a36459b6..3d8a4377b8e5a8f1bd978f2f05534a8d2f27c3c1 100644 GIT binary patch delta 420 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 Un-1QK2j*c0Pgg&ebxsLQ0OxH8U;qFB diff --git a/backend/tests/data/png/ean13_cc_2addon_cca_4x4.png b/backend/tests/data/png/ean13_cc_2addon_cca_4x4.png index 3fb571c084a8667e318744313947c2879d335f63..fe5fd5f8c972126e1c39b6936a99e8907553387a 100644 GIT binary patch delta 532 zcmV+v0_*+k2%!X!7=Hl+0001O>K`Bg000J1OjJex|Nj6009C@%egFUg)=5M`R9M69 z*0GA)KoADte{O=5V(=De1QBtUdV?Ui5bUe0$qV=a47WyY$n&IJBe-h8FOWiyu%JeT zuu@!dr@Kq=rila5)E~po?i4=&4%)QA$T$j%s`}^^bl>-_#((4dbren2LaE;L!gV!9 zB?eV{T{N0%(rQwss@e3W4Rss&bX_#*x@KX+ysc9T5lV+ zIKG;r_Yj}M7vwVJ2wdoGb7Sf0rVQd&sYh)wb8`TA5rrzoMU`dqcExV=y8ejDQ=r~+?(0?Bw=D*T~(P%5aSXi z57r02=4fpylRtmqk?Hq)lCRHpe@mV8@&2~rJ>TXoJ>j7|Gu?XsskyupxfoV51Thw^ zdi!Vj_sm@$^916*Z-4K&_Nx4O;YUC3-I}}TM{wChqqjfv?=#Q&o^E6Q@7nGNB~b^h zhL8hmHQd)^@2@`EQ*4wAHK+W{%9P-Oe;pwZQ?;~{Pb_l*ss(aeEMD%dfBV0@YtQoC z|I9w=ecf9Ay?2lL-tTi?X4^{Ezpr^W`{`qMm4A6(e*B4om@)>307(S7y*mH*|Q zvd)rwCR=WnB{<7Vb7@arXLrbtw8c_YK9@@_oSGc+BkJ4U;CUeqn*tv{><)2Q7Py3I zQm>Mz#MB&-l?PU&EcRe^duo5lQR~hu<-E|!MNE%EH>D|w9$CSA)O-~Ra?taG?P0Rsw2u=9f$6~Mj*#|MbX0Fs&j3BDyvpa21Sasn5M zDy#;;RADs$WX*^2iaGb6nD|=T-3+h$SD8QeW0lg{=Y6W#-`rlEdDZX1s-PJ(HRzJQ z<#{XV>ziF0PfT5Z_xyIzZR}ga9!A{{O3N%x>(khl&$n4>Z|st+IS!G}&pNJMQvPX@ z+x;@-?Kj@#2ZJQ6&aF6lb@h}Wugvv7l-p}QFOt}kweMC{^uM?5oyA{Q?T>xF=tdG# zb@pw;yo0DHI{#>RdjF(bX|BPX3o+}XA`@TjTxRuC zi7T#F5Jn;4& z@6S3)FFp$v2btUce|1zoCh|`4`b8zVt+FNaSFOIaOFjQ^h|RmJw<8bo_n&@xZ(iTT zy%!E{bm8ieD4o3F+m18O-gL&zNetILdFk@(^twxWWw#O@yX#u8oVM5gw11MXWtP&_ zZ%1>UsJx54$0BYyzvz_-+oxNt-aVN;zb*%{1~)yP6>Xgv=dV7e-stM=ixXMYDp)O_ zulUM$@YDMn5?d?f-dBq(4!oUkvREzs$ciHykGxm9_h-NTKgMX;rBAGmSV#j)5e83J KKbLh*2~7Z*hawID diff --git a/backend/tests/data/png/ean13_cc_5addon_ccb_3x4.png b/backend/tests/data/png/ean13_cc_5addon_ccb_3x4.png index 2bcf13cbf0968189aa04cbecff9d1b3871e5f06d..c2bf3d938e2db15b250263491d7d0bbaa6cba791 100644 GIT binary patch delta 571 zcmV-B0>u6A3CIMH7=Hl+0002(nJ6;=000J1OjJex|Nj6009C@%egFUg{YgYYR9M69 z*0GA)KoADte{X`6V(_+Gn7B*5K@eOR_Epy81ze^u+#0n<>O4xyF$z~Ls7;YVkFelI zg|Jdw2nQ#@9)aM1rv6y|8MgQVP;}N^bnAw;(d|xLt9c-b)_>x~+=ks%jTRnTR65$R zxx_}sCZ?OUY*P~6B}cqg`~BNW~l*y69%NyEM!KU?WDS4NSImVVh$OEUcH$xz2PyV%A4GyANx#b>qc?`#22QSKpr5cSuv~R2)SzSx zk@}5X(YezwVc&tzH7u(@L4`=hbdRd@=Z6XV5iA7HDt{0N@$RkN*W_`2GhyF@rGyw2 z3Y3Us?7qJ9YVzFzEGs2OB^?SxmF&KTr_j&Xwdy{oUU!VB(sp0Nmzc9#*b2Np7)1KE zIoI$j^>fk!2bfP_V+~NQ^|^*$)0c?`UI6G|?&ZlAtWGujmWpYs|xdhSb|wU zS;8Z{pER{sorrqfS%CTiSNQwWFq3yIg;XlV0xB_%@J{*{@)vNVV(J}~jWz%P002ov JPDHLkV1mnU6{G+F literal 1263 zcmaJ>eNfT|7{;tfC#RdUUAaK7GfzuN%_tSDsaqdLYAcy0rul^=Q5b%pl6hseo2)Y} zwB(dajS@o-emVqJYHEU%3p745^Mh3)8Vf_n-*C6J<9Y9`h{1jb zbKK|%fk0sU_eI7*Aa=Ha8TY&Qs9jh zF~3G_aF1vjEzG`MAw*w|*r%vh)3IMz8$)=AsfW8`dCy zXI-Be??HelaM`ND5JaK(lR%!u?r(*lLg7a7?FhaZ#6f$kq>hIGsE8gjTV>0?jGot0 zXhAzZkyS~{1s17+HBD!8btqFHt4CfGujxw89kSjcv}T@ursN2s^_SD?En~^uYBc}C zxpl_^ja%39FFFHDBe&S99@uEDHNLMXonH<;aO`R4)D}r~7H~E0fX{7$OM|K>;^5L; zUJZX4H>Pk!@XGBR!gyrezFrRm7Aq)EyGOvm^U%7r&DjhqBHoa8-}x(dT34*z(~C~@ zL(IHacxLH6neqCDyhgE%P7Vik8(5(+de5U%v^ie5uaSe63X8&Y#)};ETI0}!6>Of) zRFS%)kS6kW66<-wO#eFAyOeIJyo4&KF{D1MBOj&hVj5ri3@RT{IVyV&T0*F)H~XK@ zS&-5fA5eGH(~oIJO%kR!d+1rh5xpG`x>EN_6*lf_LjGZ1sz301)Jqxs0&PLfj+l~eY^{#DF3pSS5qWeeXb zHr{Jh|18Sw%;e%`HJGmzK8(Aj2R@iLQgO@miLC_(n}v4+sJ!36O(QGJX!_FtzZhk0&`F-A-EK%e+>5jaLW`Y+~0)n2%kdW=iGrl)byceERWUCM3EiK2f&HwpF*%kT^iN zv(&E4I>!I4G}tGq!fIv5^C>somEv}N;m0-rS~;vy(3(ba6D^IS`np;zcaU^P z&e$XXnyQ@fd52R_+nJ-mA%IuMp2IURnD`_KjAHjPoHW7naEz=(RyEnzlyhpi#S2xM zykh{&^aqoR&jhgI^{2T6bO3Qv@0RlR@v~>4?(f8G4EeZ+F*W=w4*%KwIjsWwb}{tD z3~Nq(T^#88dMcPS981)$E*bIw|Ind^MIvNYD`jwZXtTG`9`FLWjx14eCuj$AK)xi5 Tbf?=M8DxJHHj?|zi3@)Mc=41& diff --git a/backend/tests/data/png/ean13_cc_5addon_ccb_3x4_notext.png b/backend/tests/data/png/ean13_cc_5addon_ccb_3x4_notext.png index 89fc6b000f7a1f5eb09d71961a5a25b4ae14eaa0..cfef27910f5467186a3cf49fc937b1cab4670a64 100644 GIT binary patch delta 220 zcmZo?eZx3GqMnhNfq}vQ3g#TMWb;`;ype;_mT(B(QHwb0YWF(l&f+iM%SnhiNx z0~J?4Sk1AHF+R3Hv}UTqHHTgQE|lqt?fE?O-516K9I1DwR9(_so+&iXuu1Y>*kQjy zqdlBX2d|g!i0u!(rnElQLY&{}n6u?U6~9Ptrt8TsiPH&fNVkAn{5eWCwk+&4-6%{N>hz4hPUnKH4BPa;KQ z-ZFx8-7DM{KXdix>x<6M^|a^wE}Ua`S#IwC-`B66Kl||Ny-&tAzohDno>x!3cU5kJ ztwQw!xy`jk7oSd!Guo|Ioc}ee>{HFbUoo@(^Va{r{OA4W)uxue-W;g;cYPi6x^E3{ zfHoXwTb+I;WSOZ=8q~sfR<~zg`0%4}D|-t63Ar8LbMl=ICm(~Festcy|KCnNpZ|1z z;Py|F)hGWyRDUm8{!aMrr1g{cu3h6+8g|v}s_mpZ*VOOryajYU$Ow?L93Yl$Vh4E% zBKYB%+_VPkSNBaHys+jAc^_ktXa9cx{?Ph0KbN1}xGHzmUa$cO^+<*wOvNe)_7}t& zgi0hqgoB#j=rW=?@ZVWrEZzD3_elAHBJFYG@5RdL_{t$b(J*RXGuSARapLh({F eC=BJ_u&ZskHT~7ud-s6}jKR~@&t;ucLK6TA5luk= diff --git a/backend/tests/data/png/ean2.png b/backend/tests/data/png/ean2.png index 2a2602a5612a33885b566a606e2ceb21bfbefc06..13e686305d5d2725b15205f6cdc98ba10b602b53 100644 GIT binary patch delta 139 zcmZ3@G@EgPL_H%j0|NuU&oVV2#TMWb;`;ype;_mT(B(QH72xUO7-DfcIU!-&M#Ei6q&|7NIEGZ*dV9x_tJy$+^@7ib zf8pD@8$6aynssr@hcs2SQ}tmULum5XORX0ER>Zj+d zKvSp!Cd6L+-><7(;H|q|=k>$&smCv_Ws6>LZ_2*adAIgh-B`JZ{e`5Qeb`ZY0i<~J!{PkY`8Q|tH?4F9q?lWmC}v7~ z-bq}{ky(-KA9Sm|1>N73`#%RTlx$D(3_Y2i-!8j%11002ovPDHLk FV1mh#Pn!S$ literal 454 zcmeAS@N?(olHy`uVBq!ia0vp^Wk6iQ!2~4l^9K4dFfjIdx;TbZ+ zeE~!_io04fet zAP5nMY6OZyHG;%RFz~x>(K!*HkJZ~_%J;b}nUbY`_ScK@r<=|;&7E5NzT!vLX8%Io z72jU`s|vpJc(>&Ij*cH2{kNPiJf-hd>;~j zz-aCJmAS9Ji*GEve>|ps%Ur7mv%aRaNbjFiDE;PB*}n5-vvog;+p%DF|JVO^%zyv*^PU7l84@;OXk;vd$@?2>{VE)>!}m diff --git a/backend/tests/data/png/ean8_2addon.png b/backend/tests/data/png/ean8_2addon.png index 18e27169c7cd4796f6e2a8c3fbe896f37ddc425f..d1ac393e984b842b0e19bdd109bbf28a06e08326 100644 GIT binary patch delta 329 zcmV-P0k;0>1=s?R7=Hl+0002pFm5{l000J1OjJex|Nj6009C@%egFUg4M{{nR7l6| z)-h_sKoEuDf0?jqgw?7r*)H`MLvR&cMZSR#5by@KIn)>h()bWQf+39xW2do`NRC9( z?`sC;;}z2lh#s1v+S$jv*qQ2au7EuO{A$kDgC@3(L*~s5+JBwNpkW!qHW{($h%H8J zHDdb_vk^Ow*n0T(Oa5u|rqRZdB}(T1)~q`la* zXsb=f?tPA_Xvu$R2TP{or_^-PX|90Jcm b_}+g4^M}XuVW`S*00000NkvXXu0mjfzb2qv literal 745 zcmeAS@N?(olHy`uVBq!ia0vp^H-NZ=g9%7x%*obgU|`zd>EaktaqI1^vy-v|L>dB@ zYrp@0YB{^wsq-5*wr;rgV%ig>m*?Fk1!ccY^3sgG{`I{4zv>?u`MYd3rTnOG_ikGj zJ%8QWz2{CyEsO5YFMnz37FYfIZg>9QjuWqE-M!lU&nm)B>sJ4^`TI{E-|fHW&_xcN zrBi}}o-OJ;@k?@N{fi!LM#W2}>wNqD0~9}9<=T8~iNMWz)0gXJx`%4GPfddzR| zJLC6H^XZ#D^H=-l844ODC%d+HkdvLz=1*h2q-*Y->GRKp`LEQxy=rUUI+yqx@17r0+&JrsY}uNLe$)T5ew=Ne@#ovh%J1hD pzSXK0*L>epcVX(*yUTyEM000J1OjJex|Nj6009C@%egFUgJxN4CR7l6| z*0E~CFc1ddUpaXsqbP6Su|sH7y!N3kxX{IrSI8q6x_B^Ym!?oE zD-b&BUv9XMf4J!Y;-M>DFCTT;3-eSn0C-E23OfM63^}^?0)J6QFNWX~ggm55lN+yu zb&|kSXf(D-QsBuvJ}1cn#t0?J61uuT*3foHljbtL%6|ogljy6gbG=7t1Il4ARZnc3h zafLOiRg~PrsB*x>6&UQh7`ele;E5}EG;yM_F5rnRM)*0>6yc57h7)9t93ee1_U|gh z2%wc<^9o?!s^A5YXbRYTrb&S_A2Ya`hnp>$00000NkvXXu0mjfI^U$V literal 865 zcmeAS@N?(olHy`uVBq!ia0y~yVB`a`OE{Q-A z?K-*V_t{4MoiR~4=e(SK{!2OK?{WWM9zAd8@nl;0`$Z+om)f46yRmW$|KHgPcRc@G z{q@iPOS-^?rIWATuJqDey5)|<{B)(@Q{u}6H*?v}-~DX5U(a>#d5TL9MYywkquOskUj=|6Kn+ z@kjrkTYf!Wb?UMOi|4b<2zAg>5S_r~!McPgh!KQWHiSTg5W+wq2DmUtB}6q;2-$#@ z3`hoeu)@p*tAv?LidA*T;@2}jozr~#e6HqRDf|3Cr<9NP#3!z|KDvf!zsc$~OQvY$ zcYR(x_4~Q2d=txW{*vsE`?;|E`=yoM<$^bF)_fA)?3LQ_W?$6(|Ic>C{5f5xmNqqS z?wWf>!NA!2<@Ml5qPxysukfwA|GztSB4qL8@8`A7D$XvpGhDEH`i1a6hrHg4?4B>l z@$4yo0x&|09ZaluYAsp(-1LiWL+J~ZAB+dShbx@rwwCJox+`+&|AHQq%~C7xUgnZ3 zh|9D6E;)&N+Sgj^NV5%5zxZc0&62l#6ZdD&(vnuI%0`nH|KmSYPjybeFIQad^|IRi zU~9$SHxuW({mJ-qYE99)$v;w(CVXt$>h;}E&Y;ly`kG7GwgpuOdh0SW?JPmdKI;Vst0C@+Lf&c&j diff --git a/backend/tests/data/png/ean8_cc_2addon_cca_4x3.png b/backend/tests/data/png/ean8_cc_2addon_cca_4x3.png index 8f5247066400025e4bcafe9347bcad95dcba4b10..044be6dbf1027fe57ec439599eb1dd7152fd4d00 100644 GIT binary patch delta 397 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 E0C%|!WB>pF diff --git a/backend/tests/data/png/gs1_128_cc_fig12.png b/backend/tests/data/png/gs1_128_cc_fig12.png index 38a44e0f02ec5eb505fae6c8ac5ea7235d859578..222284f510bfde65ce84c3ebc9adadb6c3ee2134 100644 GIT binary patch delta 504 zcmVuFw3N&N-|UtuRCaoia}al@pv}pnnpBLe9A}CHR6xX~9@O za1IbSB<^#}MQMg)GJ!!q9YE$fh~je5WLUyb1k+BJkOP!nVe}aii%A!x zq<|Su7z!lra$?yd>k~#z0672`Jd4bbBr-21A!{8xZ;W{uDIfgE3UZW z{}BIs8L&&gj~jJ*{^nz2^7ZdA-r19h9OE{Q-q}w0aDGUrO!JaOTAr-gY-o03~$UuTE z;O57_@i+Ir@M)L&_d~TIs`}hfKXJne4D%-}(3$SI{r20UojRvKeR#ih{mbH|q3^TS zKKJ*!y?@G*Isa@zcZcfUT<2MDyE=E`mA$hz$DZGu9Xr(^>i)lblimjwyC0t?c6$1a z``0|P|L;B~}e^UGY=PuQyYp37-cQ^j{Rw{`up$aHvL^!-xvG6TjYPrCoXro=`Y*vRbN+4TX{`4((BTyt7U6$?X<6(_(t*X z*Ejdi-`7{XZ*}rl&%3L|w@=K3m<4v?{v%&y!xq^q8Qi)bcXnpK!WVb#RYvabSFe9| za(Za(=Eo~`f1fN?@h@&-kNy|$*Y%edN?D(Hy8qWxAI5^8Fi-vn@RzOisQPrhIL!9U z&;0jWmWI}!|EuL^x32KbWbRLfQ*6(Nt;m{n=eGT?>d2E7r(TGyzozojb!AQD-=*Pi z_b;zO_2KKlzw?XFf0M1vEB(Eu(QE(y?f+L>pPVedDtz+Rv&UuK<}2HLU-I~3?yNI2 zd*pkkUA`Yw?7t~*d*IgmC+=RG)+~8a)06pSx7J^wIhqXi=SAG?&E4!LKAU&q%Kx^Q zdaq9>?Y~D(nIHV*^|b4G_0dn~*PRreJn7f7@@0FrsXjk<`d9AN_-l8*q{yFmFR;?9 zU>U<7aKOXk6A>4uFC%5d*-Yt<%yX{_oFFUnI`{Bb&^3!hW?Va^wj?`Ci zm#3>Zzo{Jhp0~@6?N(>J_0z-K^V__apV@sldGnuDXU_i5le5g7lRIta&M)nucDvoK zHWmCV$aAQ9`}gXRKX3WJKl?gIxVo~m<5~X98H($FKQujM&hGTE;c^S-&$^j9tLG;E zzqotNo0WHCqUQ!G$Jo_){Cac$vAO?gbN%8~%^&ifJ$d!lT71>%35TnT<*soo{J?qc z#_7pMt6%IoY8ux~J*)Gp z?o&1&ZyfNc1}Gd*IG}J~Yul%4t9qecs_9KP^?JX4G|z0l**MjGs;;xTZ`~ffZn}Av zG|d|a6b>jHP&lA)fQZ;IRm)POYLC;Z-n3D#ST!}u(zWjWkM?wRQ^?tU8tqs1T=lAf zPc=Z{fWiTV19GRZU8=UKC++A-&~ExOd*ZWt!n3+xqkS5UJDcu}#>rB^?)9Qap% Xg&TG$@M3TP00000NkvXXu0mjfIOx3T diff --git a/backend/tests/data/png/pdf417_bgfgalpha.png b/backend/tests/data/png/pdf417_bgfgalpha.png new file mode 100644 index 0000000000000000000000000000000000000000..08d39756756407a5f66ce9ab7e202487d305075d GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^=YUv+kr_z-=9``jq}T#{LR`Nc%?j&{?^4|@Cfdemn! z&-hiVx>n&O=Ztpe-t$^qQ`MIJin$o}`$WwQrRbxtkHy!q&wO6cd8y-S>lLeCaT|Kv s{4dR%zOnC*(^KDPA5$du`F>#*EV}UHtJD#p#T5? literal 0 HcmV?d00001 diff --git a/backend/tests/data/png/pdf417_fgalpha.png b/backend/tests/data/png/pdf417_fgalpha.png index aa1ebed129be6fec76b0d4cf2b98246d3bd7e2ba..c2710c68bb00fca6dfbf6fade8781a09d3466ce4 100644 GIT binary patch delta 176 zcmV;h08jsm1Hb{07=Hl+0002{4wqv9000J1OjJcMF*5)E|7XBCYybcN0d!JMQ#1cI zxo`jg0BA`>K~yNu&Can2L_r7zzz3#+tt@OR*t)Q(U@L;D@Grg&j3*fYk$#U9C#IMT z;pWIFtRl5=CN4%tWH)MLt7F4z9@J1AVKrE;i3E=tzXJ1N#hX-qmF9kq4j7g>i? eKi5X!ZK5BQ8`Bg5D2OTm0000GKB*Q2NVt{9C#%kuePAobg28jQGY5ErAV`RN9)U`an;l_ zJHPBcMf35-0iSAs!U2T?3J12feX7>g3-ypqZ>p)+^YycNM)Qrv$?j8jo!Nb>_UKj9 z&9kIw-Z-FeK;eMG0fhsMF*Z!qq7*6Hr0v->sMr`fox>E3LdCjH*wVHqKvz#ZM%Q)qcpdGz>Po%3d%&vm&!(T*=aXHxHxBqz1BC-998fs$ aul@j@XLa#C&5(uw0000vhBL>(hD0|SGq`R!&P#TMWb;`;ype;_mT(B(QH7!q;#?dgr242C=h z92(hAc*LDuoW>LWY_`7Bt}m-tnvxk37BRA2V_WoJrkG(Hn(>R-9Hxop|l_dnllGqJr~ui6mClz~btn92~v fiAGSWYITf^aO^71iMh7GaAWXv^>bP0l+XkKu{?FY diff --git a/backend/tests/data/png/ultra_alpha.png b/backend/tests/data/png/ultra_alpha.png deleted file mode 100644 index 8fbefaf22112dccb97e411dcf5a23aeff0cd79ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 305 zcmV-10nYx3P)Q2!=dA&gzAAtm49E1qsp6J@2pbE9w}l zf;^WpF1ijD_w~GTK*p6@**mxU+$r2^`9~bfdsj!QJAiwHtc{B)zwcwE@*4sy+*Iz7 z#h$nBK8BJ@K9$P*TZ!;8I(9IQfrIlj!9%|Qr$y`y!WwjuQwfKD00000NkvXXu0mjf DVfTeZ diff --git a/backend/tests/data/png/ultra_bgalpha.png b/backend/tests/data/png/ultra_bgalpha.png new file mode 100644 index 0000000000000000000000000000000000000000..ffa7bbb03c6caad0ba010ee20e092b305e41ce45 GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^YCtT-!VDxeR~vf+Dd_;85ZC`e#(y9I#88R>Bn0IA zFN$wx0kRlNg8YJw|C{YB0CI{vT^vI+&i7tC$;<4(<8(3e;dLk7Ee_mU9Bx{s1sZkj z+}o`BxY+Oh^EsanKhqQ7iCOb%NrY$7#*0T!u*I%lA zV0f3OoegAhmIV0)*F%Bv$++h?fr3SzE{-7@=X)isun#3XOGn_nx_r-rd->+XJvTF6wCr8RbuJd&D Kb6Mw<&;$TcLR&5X literal 0 HcmV?d00001 diff --git a/backend/tests/data/png/ultra_fgalpha.png b/backend/tests/data/png/ultra_fgalpha.png new file mode 100644 index 0000000000000000000000000000000000000000..37bcf2275235cb1a75fe8af9ebcf5dbb5e5f25b3 GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^YCtT-!VDxeR~vf+Dd_;85ZC|z|1$s)2tz3bAP>lA zV0f3OoegAhlmz(&*F!<cXJx4`+4vL7C_1|54 zYyGk9mM&e3U*9TT=WXvZlS}o$!DlD)?rdWh4sI6yaPXQYZ|lcZvT7C4%k#dmZJYD@< J);T3K0RU!^S+W2C literal 0 HcmV?d00001 diff --git a/backend/tests/data/png/ultra_fgalpha_nobg.png b/backend/tests/data/png/ultra_fgalpha_nobg.png new file mode 100644 index 0000000000000000000000000000000000000000..00074fa3d15c2bc9ef6cb753fb6cb6b349dbc394 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^azHG_!VDyX`aiYVb!qo20kDO*AyMV3dzrZn8zQ{b{E~=j6ke7q?&S-16b`|Mufg zq;`KzEah7AKxUr$oJ)V+ecUo5YQyh+|37^H8^6M(ID4C-(>IWlJYD@<);T3K0RZ0v BT!a7s literal 0 HcmV?d00001 diff --git a/backend/tests/data/png/upca_2addon_ggs_5.2.6.6-5.png b/backend/tests/data/png/upca_2addon_ggs_5.2.6.6-5.png index 6a2373c9184a37f2879339fa1039caf999be5e24..6d4637accdf0ced9099103e40ab3f699d9fca0fa 100644 GIT binary patch delta 428 zcmV;d0aO012f7207=Hl+0001fJzvxS000J1OjJex|Nj6009C@%egFUgZ%IT!R9M69 z*Re_jF%Smee;7#+;;m&0abIC1%@qgxDvQF^_W+_feb zXAS#h)@VFs%?vxAGZ#k~3zeN!$GoXh-W=+0#`TrsP)sq!6jMww#S~LaF~$6A^B(P4 z-cROR=0C=ezpav@Eemx!jx{zDvw-7){p;Rvx6`TVwi9y)$Aj+H5JR3tgOyx8KA6U# z_ItC0yV1N>iFpImq1DOI766)$eI)@Pzte#!0hMn#T5JFu-u?#J WC`|iJdp5cN0000~)y?wW6wSov+ zz{@9p<8KyEoOzA8>-PSJ!nLdYvN%@Em-d)_tWai~wl8$)~=( zUO(mS^i%%#Z$01C{`IrK&z*H)uh+ZBX}XK-7yGI$RG(k-hCNkwMg6Hr+nYd!{ybV-EReHMz1aXs{Fn7QC4<(Z+WJ| z#OCt(dwttKhF4y4x&7ow{p}5_L zxrZMke~6|(-k!X<_xwHyP4}-K)7o`oUnFG9?-t&*w$A>t-nLgyU-|A?pZ|A#z~kE0 zJxl-nm{I$F*tqG&Rv^PXKYh-IHA1A zO!tfatfaSjx!En#PWf#M+Il44Ab0m&E9;`^I!iTn7d9vEezbGnF3;ky);)oNS^LUM zm!B%GDq6NOVs6v1@2&m*8K?hUzy9vv$>;f;vvRY3t*$=XH|tGo?u)oex!timZ)V%+ z*2>PiyYHh_nT<`V+T-pY9wO~GjwLUV&NYvXZ3Cu l^E~J3e9v~yx#esAGl;unt66TG(g4hc44$rjF6*2UngAd7$_000J1OjJex|Nj6009C@%egFUgfk{L`R9M69 z*D-1%K@bJd-!5ojC|hX<0{IAKDw$wFK1#t}z@Y+TwQ=eL_&656{vlK-;;pgOclT_amcz-Vzh6 zfRZ7FGJ0k%i7%osinktjMRbNW-`p3`OE4!Yq6_#?NE`U&p^V;^Qv)OUBD#4Tkj5gq z+8&UKcAefop}L<-w@WJRo+_=h(n>3>w9-l|t+digEB(*u+nY%8miW{g`3>q~fO!Ox z`NN3h5l&Ky0e`(mL$chCNFL2G%1|94MTGR6xDj9p~B z9HRo&;XK-z1w50W4}^ecW(AH>7Y!B=NL*?NA=h$oO7AlL3A;uhq1gJX>rClgtufOb zOc6+C@ZL02|Bn6w0Qc|&`+)#lf;cC9pk1cFVVe|y1vhB^x=A7L_$h6^q>*8S00{iw o^pW0A>1sQkr0tY0``1(S4-zTl=TqYnsQ>@~07*qoM6N<$f?STwBme*a literal 910 zcmeAS@N?(olHy`uVBq!ia0y~yVDtjAOE{Q-WRA}pYX%19P)`@fkcwMx?_8WTTS0;? z;N_d&`;GSA$W)u!(V-x5e&?wjY_2~)HTy~>^_(tLY)Or*yFa^rZk7F`-*zv*Z8`fz z=2=ehYpa}G&uHtav!BCv)SRF6_UG#IFSFv8J^56(he^Kt#GA>mw0{6_PUH?4k(%qFYtMAzu-kvFPR6^UxtY)p^y?|iF^7LoB zZ_ZQsqxSs7x92(XRVrn54=+64?C`bi)P~%rHKDt>?fI%~&IIp$7_ses@$RZWWg1&{ z^M4M>moW4E_anDyrQFVy_b${i+IT(-%}?3=_^|F(>0{Yn{qMi*+O_1P-_zJV4-c1A zX|MRpmtMqo{p#Dh@-wg0-qpQ4>!jtD`E}xMtCbp`^RKF6US(b$Cvp96o!wpI|I)wz z>^}ELZU2-1;wQeBypC99ZqrxMT*3T^x5HfFUIU1M#OyGKi-H(X1#mH{t3-7OKHCo$ zw@M_Rz3mh+?dkWuKd-OcrF`!}P+m;?`*)djzl+y(zT%B}^;|6V;S0OPQPx+^o+(+D z^eDKZ%K2CKtG$-X_OIExW#zWzRu8WxcfGRxz`VP_Ms`)8`1Y{cBLYqw|7}?`*FU%Q z`hFnC{%z&i(yP@!d~-{=)AMwXMO?fxRetxgC-D(`+wWi5w))`f=-1}CH*L>9Tm5cj zTVv{>x7Y9G9>08MZEo+~wTolycPw9ZdzldLqrXzl`@0WV`j?b0_n()3`YjP8(#oZ*p4Qrj zY>%&A#(!h>`d$8h4=%r*dyM(`qrFmY+cj>fyXOK8J$q8REG49V>bry4`OjkVogcrl zUH+w7AzkRwwykZGZ!czDyFvNz@6#J9_KTIOAD6#+`Q=&`r{UqX9%8I2Fzy+p00i_>zopr0CWk_>Hq)$ diff --git a/backend/tests/data/png/upca_5addon_bind3.png b/backend/tests/data/png/upca_5addon_bind3.png index 11da1cf6a244130c5fb7879ba8d41c55fa003701..b6b976ffb9114a7aed99e78a5c457f607f1f7689 100644 GIT binary patch delta 446 zcmV;v0YUzV2h0PI7=Hl+00012vgV-a0#52T{Kp60*Mu%G*WmxAy1QfZ}?R$6JLl~!75rIl7%>Bpt@HwQvEz8=cr zUz?per2m07(SM-^Cw_iEk_>K=N^}f{R{U~1k__#8)B?<+ZwAX6yqYFj)&Q$?N*4f^ z(TiGs0BW0<+Zpu$pQ2u<;~OwIAvbuBHc?TBgC@0t!{zBIz0Je#=rs-`cINYSrt;=l zW2QSa;9!O^xq*2@p8%TsNAxQWt`M8sIqfrjK{v_40ymjIZ<71H$7$OBl}3vS4m{>p oJEwQ2bhRBPX?IGO!}ApV2@N95*_cya{Qv*}07*qoM6N<$f@;vtE&u=k literal 904 zcmeAS@N?(olHy`uVBq!ia0y~yVDtjA8#tJNCJYSB{+=$5Ar-gY-nlq!kpe?Q z;*HC{_ZwATyeX?LEaz!CK$HU6|f6iy0c8|H2 z_V@SK8LyukJf9K$JMp#o>x+HwKL3%^+n;*!{pafUFYNZei_pKZH~;&A+tMj{k>5LZ zFAn|jnCE!-nPln0yuaE1zLkIcaA@({uUjOOdp=&jwXMcZf95W0-|K1l`!>Gyan)Sf zb*wEu`-F5>+KIbUf9Bnud?dfHZ`=LtwJ&rxeirAmJ;$1szoI91_2=m;cYi3k@c69F zW^YHy*-_CDebhp;{{2SiGVkh(MeGRTg=cVOm)HB+6eoo8Za`)p|-Oc7b*I)VH zf35v$(m`wA_n+F#PrqCn@Y{CIQOg+f{P%Sym%MwNH}j&-xrKi}?KW83#dO|&#Z760 z>f-0zk9WO4zdnEF|GwIPaq0Ue$A9|I{bYN|>y2mbeJFjx`-$xd?+NJ%<_h@^_dvK| z4`U@WND!yQ32B6mhCPl59jFqFmCZ1tK<2~j0GW?d0%$SBa)@e(tDr6dM{9$CQ-|i# zS-X!)I91#;|NlAauJXNv@Vqze=kHzm^L~H&{4*!-?|qnTn`fviv-j+Zi+s6hX_mno zKWNreId2o+{Qa5X-^9gh+p~U$sNbpfDST`Dp=Gblyr{E*;{9QJZ7lbn%CIgqzjH5a zxoCIC=FQ&^2$$WyeCo{NrBk%pc758C?fb9s`n|*PSGI*WU+=$`FS+Np&FuJ6|5Aw^ zK0E$yEx-LZ^V!91eRuz?`n_*`>(V1X_WYN3HawQ;KTUuAmy^$LmTmFNon8{RL(w>A z{WkU|wcX}LyX_9oyzTdYivHv0cj9vUW9I1dFXrrTn0a6KwQatB{?AXlO!mKecG%`x z`^6`(KZm*J-oChN+uamrx7_tBtN*+?yXCW)$?Uz)Lq1wgIPGTrpJkQ$mP5Rf`}Xpj z{=HM`{$CN3zw3;)aka2@fBrM)0PE*(?_O>NCX||;`wv}6k`S`zeFzFxPgg&ebxsLQ E0GwCV(f|Me diff --git a/backend/tests/data/png/upca_5addon_notext.png b/backend/tests/data/png/upca_5addon_notext.png index faf3b144d08dc9597fcc83e6cd3d8e98a46fae4c..12967b5c3ac1ecef0245acfd1afdd7f11628bb9b 100644 GIT binary patch delta 151 zcmZ3%yqs}@L_H%j0|P_#+7p+66kC8#i0l9V|AEZVLznA-RE(#KV@Sl|x7Q818XS0B zE;`&|T`x4ltX=$)-V-gk1BbG-H-{v;S3j3^P68`1)(p*XcW+o2D1f zSbJr)?A%KGhhL4uul;^0JJ<65XCtNw<_h@^_Zs#vRx*EL1K}sUC!|4wApGFoJ+}jY zV=L?T&AYij`TqM|pZxxv`p^Bv-)i^t{QM7(We~cXAtoT}#%U~E;t4OpK8Jfq4#6XF zLKn_#(wKV?t7Rk#{ cw{_cXy0q@Pa1+NQU<@#Ly85}Sb4q9e0HU_IV*mgE diff --git a/backend/tests/data/png/upca_cc_2addon_cca_3x4.png b/backend/tests/data/png/upca_cc_2addon_cca_3x4.png index 262ec0951236d018e271ea707fd1ca81bf450027..beeb27ad5eb20ec4b1fad85581c9d7661fd8059d 100644 GIT binary patch delta 501 zcmVK`Bg000J1OjJex|Nj6009C@%egFUgxJg7oR9M69 z*0GA)KoADtf4v~37_1`Ah8XS@CS0RpIlYSf23Mvqxixx;JW9$n0#^%auhb(9s8J#8 z6mk?R7`)Xvg{Iv3ieYApAAs$;!Pe3=-t$lw1wnLHSb4@(eSbKrWhjDBRDbD15dyIvYH2bn0f0t- zAEj!zk20OyM_&Yqkqv9il?xABhW;lm$cV7p(KCaOXhYcZ=kmkwdBuL|Kv|-t%NCv0y%=^ zgEI-d^5j)zOnX$Vm4MxZz9U#xjuUw0$m`W7-d4J_5^$W*JA!5HN`luQpK8O~YE@bZ zSWW0Bg5?w~p-(;eL#hwId0m(d~wM-CvWtxr^5x&6#|fh zzPW@9VA4%?s8CL=zvvZIv?EGL?JtPusGSgBp>mEqjB>Odk;ZZC`#CzNz1k0{0Id52 rrx6Wv^j5XX^|}RE31K&)9~bf){o;$=`G(7+00000NkvXXu0mjfZkyzp literal 1062 zcmeAS@N?(olHy`uVBq!ia0y~yV3Yx}OE{Q-ZIIZFUs0`JU-ztdd!DnN#7gMc?+fJcmF0`d!)bWAcyBFSmdE=$-22 ze&g1pRFi36kKI33dNnuk&bAKzq#%E_I7UCx0yes9($Y$Venv`z_nrdt^Ko4t-rFo zx?yd(*|)bxK9w)swrT6SpqZ(sKYwpEI{tsj^6R_bs{}JHVe(*Ah+?=N^*hS*@QjHo z8G?X9Z&t49NlaIT$UfLzt!1q(VQeG{cFFmo6Yp1k+JEolp3tP%(K1Hwr>y=uZ&$5u zXY^K6yVG)0ZwXA-`MM=UtuO9h&-~rRvt1W^9Zu1T`5)!+@3vO{s>%-Qx|=H^v!vP* zCG7U9=mkGK<;Ggo^SI)I)|8MPI?;1iex2qN)EM|*@@wTUCDDM(8bORxdzC~bLT_pS zg(1xUANhhFF1LIXHdS3qAwKk)&$1?&uWrUOxlW|X^=mTLDg-Zly!XPj`?XX5mA}^i zm7?`v^#m>ju=~NmqaX_QrUz?72m{2&Ag=+L5LFDIK$*Y=m4d6nW&m6jHUm(sY0x(4 zc^vWF;c&t3yYt*<|Fix3?c}G=QMnm?%LTIhg#c5WPUY2gsmlyjzG4<$CrCF^1N@Dm~H z^J;SIqUQ3=XPjF%<9zJww3{jB+HI*{Ic9zl{azlHBer*~yY<}_FYmuyeyTcqq0I3@ z_bYypGi5?zFHEn9iu`-u_h{3cvTFf#SN};#ynVj9`ZxEB?T$6Kuk5O|G%@vuef1%#SWvygQ{oO?}C$>0(tj zw!drUsb1n+4uk67$i@RSw zzKQqjf4qu&Tki50wum_Y^EqCVFT3jtyXbq*cs8wm_xyi%zH1zN9v-%@tnYJZdXLpc hW%+Nr{&qf)zb9+(!T#jV2w?ta@O1TaS?83{1OSb6{5b#s diff --git a/backend/tests/data/png/upca_cc_5addon_ccb_4x4.png b/backend/tests/data/png/upca_cc_5addon_ccb_4x4.png index cb914998380185ab6a54c0084b4382b0e7deb516..d7d4b432e10e7b512b17505f9059869f996ea2fb 100644 GIT binary patch delta 566 zcmV-60?GZG3Bv@C7=Hl+0002(nJ6;=000J1OjJex|Nj6009C@%egFUg_(?=TR9M69 z*RhJ*KoADtf4v|jFtOSV82kzw+^AUMS6RP-%PUN7jb7p&CFK}_s|B@J>Jb*ys93BN zx|qb)!Cn&_(3CS@Gs6@!08HJR2~Jp<_Le zX&%;c9Xf=-6m+PIE^;h9nWlbN+i}AbyTCehgWT{SiA~czs0Cv(=s~TVrjz+cu>ae9 z;f=1FPMfgVdQX~T9h$-f4*Y-jrq?e+h-{w43$hgA!xo7I!Hy;}W;wUd^igrntXCC($` zNjv1dI4{OL09y7LE~AZ;_PJ_>>tzdQ5eSFT{`gz|0=E%yf=m>&c>n+a07*qoM6N<$ Ef;ch}vH$=8 literal 1179 zcma)6Z7|yh9R91Ro;B$7rlo?ms`N@nP?bcLdYJ|b7OKjOOqF_1v=Om(le#WmR+GiN z%&GUQjMB7-uredsP%n{Wq~4km5t2$o{usA!yIpS|elK^=@1EzL=ff{Iz|RY!W26HB z0K~`J0}TKgy9J~j*tgq59L`z-z(-L&9&SMye908Msp_1*R`IrO=j8=K%3bY`n!A(nkZ7Fbi04|j59hfyM4U?x;*{!>UDd&bsJY$@@m#CxhqA-Rb z1%9Tbm2D*tzY{&c;Gojgg*WxRxCh3e`h<(i-zF2(nT(^)ImZ^O1Lx-HhaPPTBrw6+ z93mlla0ABnL$1g2TE>m+r$rsUbiQVk-hD(;{xtISNcEl0v9kFLf2efzgw&fp{=jqk zg{jbPjbk)VHQ&z7uEIE_Z8RXv6xoxSh>{gt_?h$Apj}0cX6=;`fp|CxtlNX4^#1B# za4Tni{z9^g^g^EnJmd&OuE9_h5(HCEu=X47FqvTDp9xfJS*Q~Hv507UvCA}%WO^OM zY|XM74Ta_I>vD2d+N#)2c?{J?mJRirA}$a+M)p5etY#0h1XTFy0u|rX57cs$WBHGJ$$g zF>%hF$M~d(nCix3VD=2(+p~QCpIH8T`5?F#=l`H!qJV#qcgNJ+E*Bq!q3B#Of-jRU zR3!>_xL0##9B<)%fhVG(W|IaR6wRA4q1#xop_b3Vr`RDht|S8 znZ@!<%u{pufOz{kq5y_-((Xk7Y5d& zSxbrPWiuajWgO|jke7@#_|0m}ab##8x9qB|g&q=u%Mo_+g~#P=IEguJzzTcn!p9ZL z42PDmSJkumBeJOuOEGpWYm%)ZdFAK+%zcEWlF>B?J^2}fP!JIT$dc45LR|E`bMZKOvA zggX%q9xpt7-;z!%1f$%s@ixyV>}$x3@Z_F&g3=}>`Q*kvJeB&JDI5a+^bnloP>PsL sTYLV1l}kL$p2kYL?AO#r$PjI5hFOj;D|sr+?$ZH$F8g^jU5dQ>H*9usX8-^I diff --git a/backend/tests/data/png/upca_cc_5addon_ccb_4x4_bind3.png b/backend/tests/data/png/upca_cc_5addon_ccb_4x4_bind3.png index 6783d1679475861311136934ee75c5254ef5f030..83a4ed6300ced49e540e759bf06e7f329406b596 100644 GIT binary patch delta 568 zcmV-80>}N43B?4E7=Hl+0001EnsYn=000J1OjJex|Nj6009C@%egFUg`bk7VR9M69 z*s+S^Fc1ddUlG`Mpp9D{1o8?x(zp$^y<>Pep zeG2xo^%u2Pu4$DHn{8bSMbU+((4htZW)CoH$P~-%1%7MG6q}za<_$fi*ayqG0llW! zuQp#8M$c)rEq`ISm1%YblOxfVFw0cChgqds4^t-E6T$3Lt%WhE_5yQE?O6}Ar6l{2 zKbdZuLbzh%YTXuMwzHk>Y-c;$+0J&h|HRIBqwC!WwN|%1?6#l1Khu81KIR?A1x8SR z3WYtuyl;<#^@94UThj$zhZ^O*ECJxf$_&H^V3m~q%zr!p9PaJYFz%}i#4NxUU(~MR z1^~|Y_H|eljR0`~IhSfzEerrG?(H)GNjgfEkQCXmV@Ou z4~#}_pD}mr6!QQm-etH9Hjdh3<(cic2NVkehr#~%Q~m-AFId3i-!0n!0000h70QxWsXl;&U^U%`}Z98|NFSl z_M1H4$h7v!&YwG%{1cw z1f&0vtP0;6ZZMz!bUn>%Vx8$dV}JRx-&-cGtFt;=w6C=K;)%^l-qv%C?k{zpR`c^t z$aeWk{-pQXPFvZJ$O%+0xPQ;?ey-a(WB00;S1f*h=Lq`ywrJMVA0OwL8Ku_D%2c0U zwI%0fRe}I+FaPpIkZs&6ucAHb{pCLQwN#c)rG3EU2=k}p;KkfefDOTRkCjNi#-aq*#bf;^5iv0d((v(_#hkf#W_409l z!v8+nzgj$ge(cxJyX#5{if2amExYAh`RsB3ySe}NT(nyI?L)(v^IC5Wcn)uhD>Zvh$k>mJ$r+^93z*e-0m|JRXhcj0P_kFgC}jccrD-Dp13 zZF^!5nA&6bIf>u1H2Bul=iPUgvP*~V@+x@^vTU(ceA(@syB9;MEnXkly+FiV+IK5^ zNcFud74QGXHC!n^z3=0~H_@D@_U&Bo=C(G-!;T;?gF+tccWex7VkpXqFyfvT1DY-1 z^u~~I)SxeUZe!cS&p&J2XaBRU{gVCjf7Iyb~`7o^QT*-l=R;)GNPh zC)FhWO}rtt_iw(dx%IL2)24XL?G*X^sJQXiYSm3bLEL++B0pxVyta3Buzgn8Z*RVJ zk1fP|F(IYlUMGGPup|9IQ`<2u#?xmd0z{z+Vu2sZu;fAPjW{#_j9;c zJA7++)A;(_x361f)|{Jj=F;Y`SKbSrd3L*SX5rtTKC^XZ>RFVdQ&MBb@00rkv{Qv*} diff --git a/backend/tests/data/png/upce_2addon.png b/backend/tests/data/png/upce_2addon.png index 0dba7cb98c8026e746e1239f87a5406cbbf75fcd..586796822b559a7f6dd62d7f8ff810a682ea0ace 100644 GIT binary patch delta 327 zcmV-N0l5Cg1=a$P7=Hl+0000C*J?`u000J1OjJex|Nj6009C@%egFUg3rR#lR7l6| z)-h_sPz=WLzY)B*h-CE;+O4xeP%@bM0zHJYcSvvG1M~nrj-VX_y@HS6(L+hPIBDEI zL)XI7_#1?z3_<8!PE0-;c1sH?UA&v z7F-v6JuLJelYXwhxzx33ojrT@?Afzt|L6W4^)k!-B`=1?%Q%P}=PqO8WgMa$#TX`C zVL|aKup)>R8c;z z;|Ho|Z)Z;7>_A?qT5sXnrDJzWcw};)djMD3y*pgy4-m)3b=^0e!)4z9@_CC!zs2Ev ZpD&azT)&o~?Ii#J002ovPDHLkV1n_zoC5#= literal 710 zcmeAS@N?(olHy`uVBq!ia0vp^JAk-^g9%9Ptj>>TU|{O?ba4!+xb^nd?RBdaL>vNd ze*9lQ^Yeu#M>Lqaf>tHlnTi#1PCmMn*YMa&3&obqS$5y`?DO}>#{Jx|C;RlabGf-+ zOP?*ys$Bdh*7W1{;LmO+msuRV-*P`Cf63e0+4}J**B<$AO_}QC#G%-7xzg3`XQ;PP ztX%S*nq|tT{EMzMAFFKFc)w|h>RExOx~nC3%iYQ242*CRnHG}{re`nq?hl%C#?F3y z%%Z-YPm5wM6}?egY*SoR*wX)AVKL9HZ8!cMR{Q^d-rnl|fBqhBjVsw*7y}(d1Xx`d zJD3(VXee-jDF&z*n1YIdDF(Q5pcGs=ND5>GOcw*fBn2*r=};*mENQwfoYa$^$DKH9 z+4;Sv&#%urHP@`t?e__d6-n<5PW;;}8@ifl=A@I2(KSgMxB0YIZ`^BKd+x5z<(I zoyKNg_!Cn8KTEmrR#3e?lOyrzsfC3x_V>e&&9A@z$b^0wKM^HcXe-}GdU#?QIlr_HpE?Rb0F zdRNw0uD8Ya<7V3&-thDF&LyeFnG3$hE$+!bxqU%$zv-#YZ@y(dMH2(p?5Vi%|L(hZ z-%ZWZH@|M5w^#3dS;*$7i6Zq~uV!wEv-%n`Z+cGmQ3?O@h)vs$O|mt9cS87%{o(Bs V7;cC?p94&v44$rjF6*2UngHt&JDUIi diff --git a/backend/tests/data/png/upce_5addon.png b/backend/tests/data/png/upce_5addon.png index 9ecbcebfbc57bf7ec2318cf190a9cc86e556ac70..a136d3d733fbba0deb310c846186f8715541bce9 100644 GIT binary patch delta 342 zcmV-c0jd7H2IT^f7=Hl+0002E-JC=K000J1OjJex|Nj6009C@%egFUg8c9S!R7l6| z*D-1XF%Uq}zYIu?a9S6}?p!Ynm=q>^75N6v4fX&zK#ntzlnc3nkFbzti(sdSAgm)f zq>j`+1e&Sz0S)_$%G(P=s|w(nv9qNg0W!Rh=@zeDz*jT}SRfW}Po0Ik;>+b@LnzKYKYwD`kMChWh{`aw zl`B`ST)A@P%9Z~+e}5Y#_m%vGQ%H!Mvz$W0%UP6hjtew}!~!SUOmkkNDI@|xw0WNM z4oxAkWF;zL&QDu3g~S8PpX|^S5?$Zs`70zIE#{aM644@LIE6%sQ%FR!ET@n-n!)wl o4pK;Ty}|X?9HfxgU~skbPl?Rn%{s?6VgLXD07*qoM6N<$f~44+{r~^~ literal 828 zcmeAS@N?(olHy`uVBq!ia0vp^?|`_3g9#*3I5U8OftlIU#WAGf*4tZ-d8-XX90LDb z{hNQYUSOrujT`(tEr%=@YpFV1o*nKyx#-;GGR>u#v+T~#t&goM|99f}pU9;}^Pk>( z^gCz%)f4_#>cXD<@fZD>xO#n1Y4fpZzx!_7z0LPuO)g#c$kzAUw*S|z`|~LN#>XU? zWmAH@KC?eAwlbRJFLij?r_a`TB9n{nUA!EA%_FF8_u7M{;o^7u@`ZM>w)HJvJ3aex z_k81B=2O?Ma!y=px>w@l!7t}`TrinhI!8Hq-yV}YA{pPEE{8l@WdG%=_4n<&WPma? zH~9A7-oA3p<936o_g}1tKK+!-V$y!~ySn4B*r z(W9r>B>8ql?w*pLzFGNrl=Q=i+OEMf+b0+W zv1v9>aXjTAxr7JER8E~>1ZKLOQUEi-k_xF{NlbM;Q}(i;>g)lUg-z!~h_P@RVCtaO z!)<`5TO4$*^8DqXS<7C2zVq|?`Z~?smjqhs>vS07%>ZQQ;6 z7~l1CXFFd8(Mn);f=|6c5Oc#96hID z0srh%*Gu-iEPC5?IG6Vp(}Q=xKX=Qz&x$h<_p#r1Q!%?_UL|{S@bS-XyTk22-cGr? zck1#ll__s`Sk)Dsdb?XddAm!|xzzgfBU^q59t*d~Uf=os!2J2A*zet1&6j+5(y6GQ z|77dC&3jhv+59-m>gv(F^5=K!3+v4<91S{E{p_0NbnXjVwKq)WyPlE3RpavH)WP$< y;t~gcAAg!=`TVYD=y$UnPp8&z?Rg^jpYfs|tKcKo>S|!FVDNPHb6Mw<&;$U31eSpS diff --git a/backend/tests/data/png/upce_cc_2addon_cca_5x2.png b/backend/tests/data/png/upce_cc_2addon_cca_5x2.png index 5508fbed999b7f0dd5109e867b8a88c1575f6e9b..4b97eef645f82975a0b803247f77cdc78c92d815 100644 GIT binary patch delta 396 zcmV;70dxNH2ATtq7=Hl+0002#Nv|gW000J1OjJex|Nj6009C@%egFUgPf0{UR7l6| z)-h_sFcb#hUwL465Ov24hF(FCC4)g%dA&gn5L!Vmk)w1}@cO`4@DT)FGKi!@Nh23) zD8yZAO%fjxdjFs&08JQT?4sx@SZQ$^_k>{>ylLXb!s^+e^?zNA7o&}BW&^6aHbyJa znz^8*wuO#S@Tvo&!B}vIz?;u)qTU7LwjIek}9g-@w-I z!6^iY`hqk11b@^CLXP2ad{@1eDqP_JAuzmhM4SL=NC8%kP_9@DOahhLD_7zXtOcAx z|4L7#tHD~nTQX@#y(2R4TdKDV~^(%AONM`!#v}X!Y3p(=RQm>191QV002ovP6b4+LSTZ%1FvcT literal 882 zcmeAS@N?(olHy`uVBq!ia0vp^2Y|SQg9%8+JY8kXz`$(j>EaktaqI2fi+zg?cpNTn zdiDRm(eHpx$0a-XSfUQ?^j~bkC6JffZe-B&_{WNLiME&TuXCh&FMB>`tN-)2A2|yD zfAVp~vATE2$I=&Dbh{Iyk+w{q#6znU#2 z2$XMJz?O9~D%BugfAxeK*2(KnUR$+#$E8(!(=TIr}rxU6dJ(ijObN`n!n`^$=cxwFn zzkZYd&hWzOf0C}e>NYd>uF6xoAnW~UhwA;e>PiCV(z(=U9^Y=8R-W*#$5|;L{M#DU zWk!wLyq2-N((Ru6C;w+q1ph-|NL6qqN%lLR%4K@!-@Tx3UcJdhl`z2-+SNvUoenGF zT7BjBW~>kay7)@^-Z06tM*Fs#*36kV>%WRRQ)wu}+?;-nD{GyrcXc{g@C&|3O3i=P zxAf2CY2Ws%yRbBgurYzW3i2&5Fd4uc4i+%SL7@RE?7#pH4i+Ym8cfwpj1XZCh#_#* zVmxc_J&E2|`?;f>B|fJp{MnM_KLr~%bU)XxvA$ooMd8Q3YkX7R{4sRm*fP=K>FFi2 zZ+~unnRfBh#V8x&&BFdqp9PEd&%Bc)!*=T1cJ+U66%HG$k^SNLE#&BF?kf(DE#$Vp zj-NTj^!BR0kY~RH8pVW7`jS7y=0yCGvAxxHPW|@$p6TCp7cGBzV$SK5W!8&cb(z;j zz1iuq;`cM7f1)?c=KntWM@{tSjkRlc)ZQ-6V$t$HvwEpd-_Ino^+#(KAIy03bC$#B z#k_qr7jujI?%N!7^t^s&-d4+(D;etJs@|VI%{$xweE*Sor`LY^Gv#CSw=X~!IPUv- zXm{3%2dB<%%g?e7=Hl+0001tq+M75000J1OjJex|Nj6009C@%egFUgmPtfGR7l6| z)v=1)Fc1ddUs15G7@}5%Veb(J)LbFZtN0PNOsQ~f9w3jBat>c9aGTPPAaLWtptQ%X zwOi#3VO5RzV3^T>20&oH)W||w2llu+|Joz_thZ7o;dqD#zkiH&lS(><13UyjE+V;3 zTR6lwUny*3%^_?@c=cnUZOpoadW1*MtT8P$gm{3*=;Ih=DqQ0c4*3w%=eurRKF5#l zA9*PvK9DTP8Gza#^+&O(=}PMBdXknWoz$yybK9Z6Jn_)<4o17S7n?d&+P>PERC#GR zs6RXXyIDWTv41nYz3CmPbi?_UyPmlt-Fkn$+L`s*HRn@|uqxE@d-J{Rv`C&7qABtu z4}bW>AO3&)hxNGoKi+dAHStNDE&Fcgn$9hML8d{a*@3~7&3xhCk)NJ5#DOvF_#b2% zj7kmzg!0$R{J)Tmbb3BvPjgVeX>0Ql~O}h4PvrIERB!ej%xpMSp*Ad=+!T}hr z-LdNkZxs%}^PclPH>47Q_w(DC^%@h|0@$7UjIb&vkP+abzrPBW7hAIyjEn#P002ov JPDHLkV1mdz=X(GE literal 1060 zcmeAS@N?(olHy`uVBq!ia0vp^-+;J;g9%7lazywrFfhONba4!+xb^n##Yu}51l%4L zX5afib+h$fv&PraRKymD^nzstA&FMV(ICAR*_&*wr7j~I?NmOm}87p^u+RhxRx{;l_inLTl* zFK^A?npVC7D9hNz?4J73cBP5&u^8`TuSNFR<;|J>_?z+0KRe>MLJC0!D0b&>R?mKR zd`7nN<=@X29dSQ1fAg8OUCbiv8hmHYJt{29{Tp__X407%Rj(z}ihizm%@8WHz`~*M z#3SXCJ#NR1{oR(nx>cB+F7e;*O9w(S`BHAY)VY4=?fcqQ=0(o458GFsSP~-&G&DeF z#>AuF`+q-6UzJj~{^s@W6FZ?>&Ya0dRlTo! zK}>n^;KSCsYwuk%Yx@(`_Fua;t^fY1Ns$xxmHn$tH?pkX|A#a4{_Y#i@r(1`&50>| zxuAP-m-5q(^W5UhX5V@1yV~MjS4wG(#J8gV)1{4<+J0_op8rUe{c!e9t-g7`75n05 zzjk^yy?=?tvGV!f+-H5dd^uiIc|}d&p?hz>ZS9KFet3G*5!t^pS3IhktY3Co(aBU>SotX=e;&d%l_4C&J~Yd?3ZlYBlP^G?bO9_*Zc}&UbgN0Te#wj zhyEYfcoqs>℘njTYZ@_CLSz_*|#$ zsvqT%`-;y8mjxeX4E@tw)%Eeu?>}>XoXK+EI`iF3%fGezB|G}Bn(tWG_4x2Y3s6Xd zA_^4Aj9tx;)BuWAkT9wwFtR~O1t#fGh^!MN*?2xxa%)p=?%AX3_wDF3)nC}fynDvp zs!x}hc5D@`h!>i&cY)r%oPvblR~xnDG=(_!E{{}*J}Uo>M<=9z*{83j6D%s*PJZqW zF1l=-e&y{e!NLSl`$bmM>NhCfn){+L?(x>uKOVm~5BriD`AF+t$?V>#YgTT3{HN^v z8E&n^>%abO(_HH-r{t$EdHa}}-pl{OO{c7{OuDvd*Yk}ZO4ckn;=W_wpM&QPZ~ozU zO3k(u?q~3H^>bP0l+XkK Din17) diff --git a/backend/tests/data/png/upce_cc_5addon_ccb_8x2_notext.png b/backend/tests/data/png/upce_cc_5addon_ccb_8x2_notext.png index 8874016f6b85e523d4b4b315ee5fd64319e2db50..1fec2e4b33e3469c33b6a0f229ba3b3ba0b3067f 100644 GIT binary patch delta 214 zcmV;{04e{}1m*#d7=Hl+0000k>3pRC000J1OjJex|Nj6009C@%egFUfn@L1LR7l6| z)iDYKK?nsyrU(=H@iCPFe+eqLqs1psBqGIl~#7I>LYyRiiB zwWhPRxJr)4_98TGa8()U9yPbN_?9Bwqe69ec*$6_N8r-xa8DCvgqfvk4Q?hj%;(~= z4hO&N^nJ(M@Ez~IA0n5#D0xD}@jrJ;kC{Z%c>3|<$B+NEU*6-}ems8bPfnV}N+-}L Qp#T5?07*qoM6N<$g2Z@VssI20 literal 596 zcmeAS@N?(olHy`uVBq!ia0vp^-+(xeg9%8^cCFmVz`!K!>EaktaqI2fi&?83MA|M! zefqaPN1w@6;@g+`l3O_=U%#3#Z^hL9#BiTG-)jF$ZO^^^et&;-#lCxapMU)Nxc9j3 zmi6lYpZ};TQn?!V)P8N<^qrp#%Kx3LwPy8@QQ=$vYU94nsWXjcdd;_=JNv<8$-T3d zuP*OB_b%e7<0FN_9a&=WGrcBfpShZH$M50Wy5Ggc^}kQX)ZLBOgeW-ks6Kk8>1UvV zsV~1)2mY!)(|_|!t|)tF^O1+|BKO$u?Aw?9u5QwkS-)Ngsull?e9pMq0%&hv_tDf$A^=jQ}OEu5rpIfW8)%=f+oTPp!{J4F&%Cmg1Bl(2f!4`tT zNr=5u8E7|%xxLbYb-n)n|91P;?J92tmM*U@^8bG)o$c4}S=Bq{pcB*rC=cC5r_P?I6o!@gr3)vAs_c*^`kCCjs VeP+S3!@$(S;OXk;vd$@?2>_VN7C`_2 diff --git a/backend/tests/data/print/png/code128_aim.png b/backend/tests/data/print/png/code128_aim.png index e961266df44489e76acc475f73e5a4961ddb0060..252dcade15ecf2108390202cca104c4517230bda 100644 GIT binary patch delta 130 zcmaFQG?{UNL^UHb0|P^f%8Ozk#TMWb;`;ype;_mT(B(QH<>Be#7~*j}`Nx^VISGf) zpUL_2^T5x~XW0MENtY0nL_kZW5H_1K-3%osne+=TA{#q$6g860Uu;^~rX$EB{)m~u XH2hz-^v)I^pqUJwu6{1-oD!M<00b^R literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^9Y9>d!2~2PcDzkzU|=-!ba4!+xb^nNMXn|X0f&o{ zFaOt9Rz*y3G+c8d*qZATqVt4}|M33joc#ZvH}kV{=_~0T+l(3w qlfxu!p5LFh+HPX~^xV{{#p+pa^Ph$#Tkik{B!j1`pUXO@geCx5xQXuo diff --git a/backend/tests/data/print/png/dotcode_aim_fig7.png b/backend/tests/data/print/png/dotcode_aim_fig7.png index d30531230fe613a35a880921218dcaacfb382cbc..3ef99708fe8feb286c887e8ed76cb60ece0e1e59 100644 GIT binary patch delta 333 zcmV-T0kZz81>6FV7=Hl+0000~PQtnX000J1OjJex|Nj6009C@%egFUg5lKWrR5;7s zlsyW=FcgDj8t_=(z(+|AR!EQLqx1+KJCvk@Bgd|spLXmU%tIjbB0d7hbie=rL)tpP z!$bfkrp*KW{qh8Gd8VzuHVVv-FWH400MDIL_t(|+U=anvcf5Zy0!NBvqp4BB^buy-Gc-zR3|>Uw8zyWx+`kK>NBs?J-(#5o`3W=qB|l{XI`gEb`tAi z|GTUIPd%bLH!Sv?d690ryw_TL{5y{54%Up2Gtbp+U~Ey0t%-yy$c~tZLg2)N1Omqs zh@>Z?5ICMtLEv}-5%xqB0;h|WL*RG<8Ou(NTy&IOMIPG`fhXj#9T7M@HuAMjIC9ZZ zc6E7dM+6R!jem4>v5s7HlwAWJ+Yy1oVvbsoD8 ze=f~qm*UUqVtwjFwMp`*Gwbr$)%bI=lT{a6ZIV3X%pN>;1^yh2t(u+Kiw=Vw*8A9* zIB?^A>|`7`U93`_U@uzX`?~I9=i|W1PGVgwd(q+FH^V-54h|fQt%|Wh!clg2@Yqa) zPm2kVFn{~l)CrLAcDrkNY^K4Ei-3QrBVS6t<(0oh5ci{)N%?iDw-%e~??Ft#Qlt$^OudF(pqU7E)(h2H66 zed+{U^d7sqJa#qoPIj{DV&S4U*!AGCE1-8Uwik;00f*5W@y$^cX#fBK07*qoM6N<$ Ef@5qCVz#MH~F(^Whv+?z|qlX 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 XJmgoRvmDU?015yANkvXXu0mjfkobcD diff --git a/backend/tests/data/print/png/ultracode_a.png b/backend/tests/data/print/png/ultracode_a.png index f32580c37d1920fe7369b6bf82890d771ca255bd..6345d36984773bac6097f55f8edcbd7044b1c858 100644 GIT binary patch delta 170 zcmey#xQlUuL_G^L0|P^JO5k50B@y5g;`;ype+D1|VJO7_%=JH6d0B;&6-<#1Jmp1KSx&RJC$-tZ8`tK{Zxp;$BQg N(bLt>Wt~$(69AfyOh^C# delta 233 zcmV%t7=H)?0000cDBGC;006*AL_t(Y$IX>X62mYEL#0mde`R%nDS}LQ zrHwb47=M(9Ai$jm<00w&O4bZP0HWqT(T)&u+havt-dXn?y(}$9h3TbfjFn$j_jGm~ zV(WeZkVONgE}yx{&d~K-XS`P0{NV^Lvr8G%QvonIW=>7*31aVMmRGN3z@QpH7VOxI z#mqL}wVIt}>Q3w@{jFxb68Pz$b>FobC`GNsT{@lcBi}Vs72Go`t62l-eQ>wmO>zF0 jP#SO4Z)#j%ckl56LBC}*+WbWy00000NkvXXu0mjfIznpo diff --git a/backend/tests/test_png.c b/backend/tests/test_png.c index 66ee1570..6fee4d0b 100644 --- a/backend/tests/test_png.c +++ b/backend/tests/test_png.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020 Robin Stuart + Copyright (C) 2020 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -164,7 +164,11 @@ static void test_print(int index, int generate, int debug) { /* 29*/ { BARCODE_POSTNET, -1, -1, -1, -1, -1, -1, 0, 3.5, "", "", "12345", "", "../data/png/postnet_zip.png", "300 dpi, using 1/43in X, 300 / 43 / 2 = ~3.5 scale" }, /* 30*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, 0, 0, "", "CFCECDCC", "12345", "", "../data/png/pdf417_bgalpha.png", "" }, /* 31*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, 0, 0, "30313233", "", "12345", "", "../data/png/pdf417_fgalpha.png", "" }, - /* 32*/ { BARCODE_ULTRA, -1, -1, 2, -1, -1, -1, 0, 0, "0000007F", "FF000033", "12345", "", "../data/png/ultra_alpha.png", "" }, + /* 32*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, 0, 0, "20212244", "CFCECDCC", "12345", "", "../data/png/pdf417_bgfgalpha.png", "" }, + /* 33*/ { BARCODE_ULTRA, -1, -1, 2, -1, -1, -1, 0, 0, "0000007F", "FF000033", "12345", "", "../data/png/ultra_bgfgalpha.png", "" }, + /* 34*/ { BARCODE_ULTRA, -1, -1, 2, -1, -1, -1, 0, 0, "", "FF000033", "12345", "", "../data/png/ultra_bgalpha.png", "" }, + /* 35*/ { BARCODE_ULTRA, -1, -1, 2, -1, -1, -1, 0, 0, "0000007F", "FF0000", "12345", "", "../data/png/ultra_fgalpha.png", "" }, + /* 36*/ { BARCODE_ULTRA, -1, -1, -1, -1, -1, -1, 0, 0, "0000007F", "", "12345", "", "../data/png/ultra_fgalpha_nobg.png", "" }, }; int data_size = ARRAY_SIZE(data); @@ -242,6 +246,8 @@ static void test_print(int index, int generate, int debug) { ret = testUtilCmpPngs(symbol->outfile, data[i].expected_file); assert_zero(ret, "i:%d %s testUtilCmpPngs(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, data[i].expected_file, ret); + ret = testUtilCmpBins(symbol->outfile, data[i].expected_file); + assert_zero(ret, "i:%d %s testUtilCmpBins(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, data[i].expected_file, ret); assert_zero(remove(symbol->outfile), "i:%d remove(%s) != 0\n", i, symbol->outfile); } diff --git a/backend/tests/test_print.c b/backend/tests/test_print.c index c0d269d9..ca20bc18 100644 --- a/backend/tests/test_print.c +++ b/backend/tests/test_print.c @@ -166,6 +166,8 @@ static void test_print(int index, int generate, int debug) { } else if (strcmp(exts[j], "png") == 0) { ret = testUtilCmpPngs(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpPngs(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); + ret = testUtilCmpBins(symbol->outfile, expected_file); + assert_zero(ret, "i:%d %s testUtilCmpBins(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); } else if (strcmp(exts[j], "svg") == 0) { ret = testUtilCmpSvgs(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpSvgs(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret);