Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,

GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
  better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
  namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
This commit is contained in:
gitlost 2022-05-09 19:50:50 +01:00
parent 3b9d989894
commit f58c80e290
81 changed files with 12026 additions and 4701 deletions

View File

@ -61,6 +61,10 @@ Changes
- HANXIN: removed alternating filler in function information - HANXIN: removed alternating filler in function information
- GRIDMATRIX/HANXIN/QRCODE/RMQR: warn if auto-conversion (i.e. no ECI given) - GRIDMATRIX/HANXIN/QRCODE/RMQR: warn if auto-conversion (i.e. no ECI given)
occurs to resp. specialized char sets (GB 2312/GB 18030/Shift JIS) occurs to resp. specialized char sets (GB 2312/GB 18030/Shift JIS)
- Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
- MICROQR: check versions M1 and M2 for allowed characters so as to give better
error messages
Bugs Bugs
---- ----
@ -85,6 +89,8 @@ Bugs
- DATAMATRIX: fix mis-encoding of FNC1/GS in EDIFACT in GS1 mode - DATAMATRIX: fix mis-encoding of FNC1/GS in EDIFACT in GS1 mode
- Allow for dot overspill in height of vertical box sides (dotty mode) - Allow for dot overspill in height of vertical box sides (dotty mode)
- HANXIN: fix gate-posts on codeword limits - HANXIN: fix gate-posts on codeword limits
- GUI: cater for HiDPI display, props bitaround (#257)
- RMQR: fix ECI encoding (wrong bit length for indicator)
Version 2.10.0 2021-08-14 Version 2.10.0 2021-08-14

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -29,7 +29,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
@ -100,9 +99,10 @@ static int az_bin_append_posn(const int arg, const int length, char *binary, con
} }
static int aztec_text_process(const unsigned char source[], int src_len, int bp, char binary_string[], const int gs1, static int aztec_text_process(const unsigned char source[], int src_len, int bp, char binary_string[], const int gs1,
const int eci, int *data_length, const int debug_print) { const int eci, char *p_current_mode, int *data_length, const int debug_print) {
int i, j; int i, j;
const char initial_mode = p_current_mode ? *p_current_mode : 'U';
char current_mode; char current_mode;
int count; int count;
char next_mode; char next_mode;
@ -129,7 +129,7 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
// Deal first with letter combinations which can be combined to one codeword // Deal first with letter combinations which can be combined to one codeword
// Combinations are (CR LF) (. SP) (, SP) (: SP) in Punct mode // Combinations are (CR LF) (. SP) (, SP) (: SP) in Punct mode
current_mode = 'U'; current_mode = initial_mode;
for (i = 0; i + 1 < src_len; i++) { for (i = 0; i + 1 < src_len; i++) {
// Combination (CR LF) should always be in Punct mode // Combination (CR LF) should always be in Punct mode
if ((source[i] == 13) && (source[i + 1] == 10)) { if ((source[i] == 13) && (source[i + 1] == 10)) {
@ -230,7 +230,7 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
reduced_length = j; reduced_length = j;
current_mode = 'U'; current_mode = initial_mode;
for (i = 0; i < reduced_length; i++) { for (i = 0; i < reduced_length; i++) {
// Resolve Carriage Return (CR) which can be Punct or Mixed mode // Resolve Carriage Return (CR) which can be Punct or Mixed mode
if (reduced_source[i] == 13) { if (reduced_source[i] == 13) {
@ -386,7 +386,7 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
} }
// Decide when to use P/S instead of P/L and U/S instead of U/L // Decide when to use P/S instead of P/L and U/S instead of U/L
current_mode = 'U'; current_mode = initial_mode;
for (i = 0; i < reduced_length; i++) { for (i = 0; i < reduced_length; i++) {
if (reduced_encode_mode[i] != current_mode) { if (reduced_encode_mode[i] != current_mode) {
@ -459,14 +459,14 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
printf("%.*s\n", reduced_length, reduced_encode_mode); printf("%.*s\n", reduced_length, reduced_encode_mode);
} }
if (gs1) { if (bp == 0 && gs1) {
bp = bin_append_posn(0, 5, binary_string, bp); // P/S bp = bin_append_posn(0, 5, binary_string, bp); // P/S
bp = bin_append_posn(0, 5, binary_string, bp); // FLG(n) bp = bin_append_posn(0, 5, binary_string, bp); // FLG(n)
bp = bin_append_posn(0, 3, binary_string, bp); // FLG(0) bp = bin_append_posn(0, 3, binary_string, bp); // FLG(0)
} }
if (eci != 0) { if (eci != 0) {
bp = bin_append_posn(0, 5, binary_string, bp); // P/S bp = bin_append_posn(0, initial_mode == 'D' ? 4 : 5, binary_string, bp); // P/S
bp = bin_append_posn(0, 5, binary_string, bp); // FLG(n) bp = bin_append_posn(0, 5, binary_string, bp); // FLG(n)
if (eci < 10) { if (eci < 10) {
bp = bin_append_posn(1, 3, binary_string, bp); // FLG(1) bp = bin_append_posn(1, 3, binary_string, bp); // FLG(1)
@ -504,7 +504,7 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
} }
} }
current_mode = 'U'; current_mode = initial_mode;
for (i = 0; i < reduced_length; i++) { for (i = 0; i < reduced_length; i++) {
if (reduced_encode_mode[i] != 'B') { if (reduced_encode_mode[i] != 'B') {
@ -516,124 +516,124 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
if (current_mode == 'U') { if (current_mode == 'U') {
switch (reduced_encode_mode[i]) { switch (reduced_encode_mode[i]) {
case 'L': case 'L':
if (!(bp = az_bin_append_posn(28, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // L/L if (!(bp = az_bin_append_posn(28, 5, binary_string, bp))) return 0; // L/L
break; break;
case 'M': case 'M':
if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // M/L if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return 0; // M/L
break; break;
case 'P': case 'P':
if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // M/L if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return 0; // M/L
if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // P/L if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return 0; // P/L
break; break;
case 'p': case 'p':
if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // P/S if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return 0; // P/S
break; break;
case 'D': case 'D':
if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // D/L if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return 0; // D/L
break; break;
case 'B': case 'B':
if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // B/S if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return 0; // B/S
break; break;
} }
} else if (current_mode == 'L') { } else if (current_mode == 'L') {
switch (reduced_encode_mode[i]) { switch (reduced_encode_mode[i]) {
case 'U': case 'U':
if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // D/L if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return 0; // D/L
if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return 0; // U/L
break; break;
case 'u': case 'u':
if (!(bp = az_bin_append_posn(28, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/S if (!(bp = az_bin_append_posn(28, 5, binary_string, bp))) return 0; // U/S
break; break;
case 'M': case 'M':
if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // M/L if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return 0; // M/L
break; break;
case 'P': case 'P':
if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // M/L if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return 0; // M/L
if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // P/L if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return 0; // P/L
break; break;
case 'p': case 'p':
if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // P/S if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return 0; // P/S
break; break;
case 'D': case 'D':
if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // D/L if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return 0; // D/L
break; break;
case 'B': case 'B':
if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // B/S if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return 0; // B/S
break; break;
} }
} else if (current_mode == 'M') { } else if (current_mode == 'M') {
switch (reduced_encode_mode[i]) { switch (reduced_encode_mode[i]) {
case 'U': case 'U':
if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return 0; // U/L
break; break;
case 'L': case 'L':
if (!(bp = az_bin_append_posn(28, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // L/L if (!(bp = az_bin_append_posn(28, 5, binary_string, bp))) return 0; // L/L
break; break;
case 'P': case 'P':
if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // P/L if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return 0; // P/L
break; break;
case 'p': case 'p':
if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // P/S if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return 0; // P/S
break; break;
case 'D': case 'D':
if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return 0; // U/L
if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // D/L if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return 0; // D/L
break; break;
case 'B': case 'B':
if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // B/S if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return 0; // B/S
break; break;
} }
} else if (current_mode == 'P') { } else if (current_mode == 'P') {
switch (reduced_encode_mode[i]) { switch (reduced_encode_mode[i]) {
case 'U': case 'U':
if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return 0; // U/L
break; break;
case 'L': case 'L':
if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return 0; // U/L
if (!(bp = az_bin_append_posn(28, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // L/L if (!(bp = az_bin_append_posn(28, 5, binary_string, bp))) return 0; // L/L
break; break;
case 'M': case 'M':
if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return 0; // U/L
if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // M/L if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return 0; // M/L
break; break;
case 'D': case 'D':
if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return 0; // U/L
if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // D/L if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return 0; // D/L
break; break;
case 'B': case 'B':
if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return 0; // U/L
current_mode = 'U'; current_mode = 'U';
if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // B/S if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return 0; // B/S
break; break;
} }
} else if (current_mode == 'D') { } else if (current_mode == 'D') {
switch (reduced_encode_mode[i]) { switch (reduced_encode_mode[i]) {
case 'U': case 'U':
if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return 0; // U/L
break; break;
case 'u': case 'u':
if (!(bp = az_bin_append_posn(15, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/S if (!(bp = az_bin_append_posn(15, 4, binary_string, bp))) return 0; // U/S
break; break;
case 'L': case 'L':
if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return 0; // U/L
if (!(bp = az_bin_append_posn(28, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // L/L if (!(bp = az_bin_append_posn(28, 5, binary_string, bp))) return 0; // L/L
break; break;
case 'M': case 'M':
if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return 0; // U/L
if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // M/L if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return 0; // M/L
break; break;
case 'P': case 'P':
if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return 0; // U/L
if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // M/L if (!(bp = az_bin_append_posn(29, 5, binary_string, bp))) return 0; // M/L
if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // P/L if (!(bp = az_bin_append_posn(30, 5, binary_string, bp))) return 0; // P/L
break; break;
case 'p': case 'p':
if (!(bp = az_bin_append_posn(0, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // P/S if (!(bp = az_bin_append_posn(0, 4, binary_string, bp))) return 0; // P/S
break; break;
case 'B': case 'B':
if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // U/L if (!(bp = az_bin_append_posn(14, 4, binary_string, bp))) return 0; // U/L
current_mode = 'U'; current_mode = 'U';
if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // B/S if (!(bp = az_bin_append_posn(31, 5, binary_string, bp))) return 0; // B/S
break; break;
} }
} }
@ -643,16 +643,16 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
for (count = 0; ((i + count) < reduced_length) && (reduced_encode_mode[i + count] == 'B'); count++); for (count = 0; ((i + count) < reduced_length) && (reduced_encode_mode[i + count] == 'B'); count++);
if (count > 2079) { if (count > 2079) {
return ZINT_ERROR_TOO_LONG; return 0;
} }
if (count > 31) { if (count > 31) {
/* Put 00000 followed by 11-bit number of bytes less 31 */ /* Put 00000 followed by 11-bit number of bytes less 31 */
if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return 0;
if (!(bp = az_bin_append_posn(count - 31, 11, binary_string, bp))) return ZINT_ERROR_TOO_LONG; if (!(bp = az_bin_append_posn(count - 31, 11, binary_string, bp))) return 0;
} else { } else {
/* Put 5-bit number of bytes */ /* Put 5-bit number of bytes */
if (!(bp = az_bin_append_posn(count, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; if (!(bp = az_bin_append_posn(count, 5, binary_string, bp))) return 0;
} }
byte_mode = 1; byte_mode = 1;
} }
@ -665,73 +665,94 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
if ((reduced_encode_mode[i] == 'U') || (reduced_encode_mode[i] == 'u')) { if ((reduced_encode_mode[i] == 'U') || (reduced_encode_mode[i] == 'u')) {
if (reduced_source[i] == ' ') { if (reduced_source[i] == ' ') {
if (!(bp = az_bin_append_posn(1, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // SP if (!(bp = az_bin_append_posn(1, 5, binary_string, bp))) return 0; // SP
} else { } else {
if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp))) if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp)))
return ZINT_ERROR_TOO_LONG; return 0;
} }
} else if (reduced_encode_mode[i] == 'L') { } else if (reduced_encode_mode[i] == 'L') {
if (reduced_source[i] == ' ') { if (reduced_source[i] == ' ') {
if (!(bp = az_bin_append_posn(1, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // SP if (!(bp = az_bin_append_posn(1, 5, binary_string, bp))) return 0; // SP
} else { } else {
if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp))) if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp)))
return ZINT_ERROR_TOO_LONG; return 0;
} }
} else if (reduced_encode_mode[i] == 'M') { } else if (reduced_encode_mode[i] == 'M') {
if (reduced_source[i] == ' ') { if (reduced_source[i] == ' ') {
if (!(bp = az_bin_append_posn(1, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // SP if (!(bp = az_bin_append_posn(1, 5, binary_string, bp))) return 0; // SP
} else if (reduced_source[i] == 13) { } else if (reduced_source[i] == 13) {
if (!(bp = az_bin_append_posn(14, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // CR if (!(bp = az_bin_append_posn(14, 5, binary_string, bp))) return 0; // CR
} else { } else {
if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp))) if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp)))
return ZINT_ERROR_TOO_LONG; return 0;
} }
} else if ((reduced_encode_mode[i] == 'P') || (reduced_encode_mode[i] == 'p')) { } else if ((reduced_encode_mode[i] == 'P') || (reduced_encode_mode[i] == 'p')) {
if (gs1 && (reduced_source[i] == '[')) { if (gs1 && (reduced_source[i] == '[')) {
if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // FLG(n) if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return 0; // FLG(n)
if (!(bp = az_bin_append_posn(0, 3, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // FLG(0) = FNC1 if (!(bp = az_bin_append_posn(0, 3, binary_string, bp))) return 0; // FLG(0) = FNC1
} else if (reduced_source[i] == 13) { } else if (reduced_source[i] == 13) {
if (!(bp = az_bin_append_posn(1, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // CR if (!(bp = az_bin_append_posn(1, 5, binary_string, bp))) return 0; // CR
} else if (reduced_source[i] == 'a') { } else if (reduced_source[i] == 'a') {
if (!(bp = az_bin_append_posn(2, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // CR LF if (!(bp = az_bin_append_posn(2, 5, binary_string, bp))) return 0; // CR LF
} else if (reduced_source[i] == 'b') { } else if (reduced_source[i] == 'b') {
if (!(bp = az_bin_append_posn(3, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // . SP if (!(bp = az_bin_append_posn(3, 5, binary_string, bp))) return 0; // . SP
} else if (reduced_source[i] == 'c') { } else if (reduced_source[i] == 'c') {
if (!(bp = az_bin_append_posn(4, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // , SP if (!(bp = az_bin_append_posn(4, 5, binary_string, bp))) return 0; // , SP
} else if (reduced_source[i] == 'd') { } else if (reduced_source[i] == 'd') {
if (!(bp = az_bin_append_posn(5, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // : SP if (!(bp = az_bin_append_posn(5, 5, binary_string, bp))) return 0; // : SP
} else if (reduced_source[i] == ',') { } else if (reduced_source[i] == ',') {
if (!(bp = az_bin_append_posn(17, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // Comma if (!(bp = az_bin_append_posn(17, 5, binary_string, bp))) return 0; // Comma
} else if (reduced_source[i] == '.') { } else if (reduced_source[i] == '.') {
if (!(bp = az_bin_append_posn(19, 5, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // Full stop if (!(bp = az_bin_append_posn(19, 5, binary_string, bp))) return 0; // Full stop
} else { } else {
if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp))) if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp)))
return ZINT_ERROR_TOO_LONG; return 0;
} }
} else if (reduced_encode_mode[i] == 'D') { } else if (reduced_encode_mode[i] == 'D') {
if (reduced_source[i] == ' ') { if (reduced_source[i] == ' ') {
if (!(bp = az_bin_append_posn(1, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // SP if (!(bp = az_bin_append_posn(1, 4, binary_string, bp))) return 0; // SP
} else if (reduced_source[i] == ',') { } else if (reduced_source[i] == ',') {
if (!(bp = az_bin_append_posn(12, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // Comma if (!(bp = az_bin_append_posn(12, 4, binary_string, bp))) return 0; // Comma
} else if (reduced_source[i] == '.') { } else if (reduced_source[i] == '.') {
if (!(bp = az_bin_append_posn(13, 4, binary_string, bp))) return ZINT_ERROR_TOO_LONG; // Full stop if (!(bp = az_bin_append_posn(13, 4, binary_string, bp))) return 0; // Full stop
} else { } else {
if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 4, binary_string, bp))) if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 4, binary_string, bp)))
return ZINT_ERROR_TOO_LONG; return 0;
} }
} else if (reduced_encode_mode[i] == 'B') { } else if (reduced_encode_mode[i] == 'B') {
if (!(bp = az_bin_append_posn(reduced_source[i], 8, binary_string, bp))) return ZINT_ERROR_TOO_LONG; if (!(bp = az_bin_append_posn(reduced_source[i], 8, binary_string, bp))) return 0;
} }
} }
if (debug_print) { if (debug_print) {
printf("Binary String:\n"); printf("Binary String (%d): %.*s\n", bp, bp, binary_string);
printf("%.*s\n", bp, binary_string); }
*data_length = bp;
if (p_current_mode) {
*p_current_mode = current_mode;
}
return 1;
}
/* Call `aztec_text_process()` for each segment */
static int aztec_text_process_segs(struct zint_seg segs[], const int seg_count, int bp, char binary_string[],
const int gs1, int *data_length, const int debug_print) {
int i;
char current_mode = 'U';
for (i = 0; i < seg_count; i++) {
if (!aztec_text_process(segs[i].source, segs[i].length, bp, binary_string, gs1, segs[i].eci, &current_mode,
&bp, debug_print)) {
return 0;
}
} }
*data_length = bp; *data_length = bp;
return 0; return 1;
} }
/* Prevent data from obscuring reference grid */ /* Prevent data from obscuring reference grid */
@ -819,7 +840,7 @@ static void az_populate_map(short AztecMap[], const int layers) {
} }
} }
INTERNAL int aztec(struct zint_symbol *symbol, unsigned char source[], int length) { INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int x, y, i, j, p, data_blocks, ecc_blocks, layers, total_bits; int x, y, i, j, p, data_blocks, ecc_blocks, layers, total_bits;
char bit_pattern[AZTEC_MAP_POSN_MAX + 1]; /* Note AZTEC_MAP_POSN_MAX > AZTEC_BIN_CAPACITY */ char bit_pattern[AZTEC_MAP_POSN_MAX + 1]; /* Note AZTEC_MAP_POSN_MAX > AZTEC_BIN_CAPACITY */
/* To lessen stack usage, share binary_string buffer with bit_pattern, as accessed separately */ /* To lessen stack usage, share binary_string buffer with bit_pattern, as accessed separately */
@ -828,11 +849,13 @@ INTERNAL int aztec(struct zint_symbol *symbol, unsigned char source[], int lengt
char adjusted_string[AZTEC_MAX_CAPACITY]; char adjusted_string[AZTEC_MAX_CAPACITY];
short AztecMap[AZTEC_MAP_SIZE]; short AztecMap[AZTEC_MAP_SIZE];
unsigned char desc_data[4], desc_ecc[6]; unsigned char desc_data[4], desc_ecc[6];
int error_number, compact, data_length, data_maxsize, codeword_size, adjusted_length; int error_number = 0;
int remainder, padbits, count, gs1, adjustment_size; int compact, data_length, data_maxsize, codeword_size, adjusted_length;
int remainder, padbits, count, adjustment_size;
int reader = 0; int reader = 0;
int comp_loop = 4; int comp_loop = 4;
int bp = 0; int bp = 0;
const int gs1 = (symbol->input_mode & 0x07) == GS1_MODE;
const int debug_print = (symbol->debug & ZINT_DEBUG_PRINT); const int debug_print = (symbol->debug & ZINT_DEBUG_PRINT);
rs_t rs; rs_t rs;
rs_uint_t rs_uint; rs_uint_t rs_uint;
@ -842,11 +865,6 @@ INTERNAL int aztec(struct zint_symbol *symbol, unsigned char source[], int lengt
unsigned int *ecc_part; unsigned int *ecc_part;
#endif #endif
if ((symbol->input_mode & 0x07) == GS1_MODE) {
gs1 = 1;
} else {
gs1 = 0;
}
if (symbol->output_options & READER_INIT) { if (symbol->output_options & READER_INIT) {
reader = 1; reader = 1;
comp_loop = 1; comp_loop = 1;
@ -895,16 +913,14 @@ INTERNAL int aztec(struct zint_symbol *symbol, unsigned char source[], int lengt
symbol->structapp.count, symbol->structapp.count, symbol->structapp.id, sa_src); symbol->structapp.count, symbol->structapp.count, symbol->structapp.id, sa_src);
} }
(void) aztec_text_process(sa_src, sa_len, bp, binary_string, 0 /*gs1*/, 0 /*eci*/, &bp, debug_print); (void) aztec_text_process(sa_src, sa_len, bp, binary_string, 0 /*gs1*/, 0 /*eci*/, NULL /*p_current_mode*/,
&bp, debug_print);
/* Will be in U/L due to uppercase A-Z index/count indicators at end */ /* Will be in U/L due to uppercase A-Z index/count indicators at end */
} }
error_number = aztec_text_process(source, length, bp, binary_string, gs1, symbol->eci, &data_length, if (!aztec_text_process_segs(segs, seg_count, bp, binary_string, gs1, &data_length, debug_print)) {
debug_print);
if (error_number != 0) {
strcpy(symbol->errtxt, "502: Input too long or too many extended ASCII characters"); strcpy(symbol->errtxt, "502: Input too long or too many extended ASCII characters");
return error_number; return ZINT_ERROR_TOO_LONG;
} }
assert(data_length > 0); /* Suppress clang-tidy warning: clang-analyzer-core.UndefinedBinaryOperatorResult */ assert(data_length > 0); /* Suppress clang-tidy warning: clang-analyzer-core.UndefinedBinaryOperatorResult */
@ -1409,7 +1425,7 @@ INTERNAL int aztec(struct zint_symbol *symbol, unsigned char source[], int lengt
for (y = offset; y < end_offset; y++) { for (y = offset; y < end_offset; y++) {
int y_map = y * 27; int y_map = y * 27;
for (x = offset; x < end_offset; x++) { for (x = offset; x < end_offset; x++) {
int map = CompactAztecMap[y_map + x]; int map = AztecCompactMap[y_map + x];
if (map == 1) { if (map == 1) {
set_module(symbol, y - offset, x - offset); set_module(symbol, y - offset, x - offset);
} else if (map >= 2 && bit_pattern[map - 2] == '1') { } else if (map >= 2 && bit_pattern[map - 2] == '1') {
@ -1509,9 +1525,9 @@ INTERNAL int azrune(struct zint_symbol *symbol, unsigned char source[], int leng
for (y = 8; y < 19; y++) { for (y = 8; y < 19; y++) {
r = y * 27; r = y * 27;
for (x = 8; x < 19; x++) { for (x = 8; x < 19; x++) {
if (CompactAztecMap[r + x] == 1) { if (AztecCompactMap[r + x] == 1) {
set_module(symbol, y - 8, x - 8); set_module(symbol, y - 8, x - 8);
} else if (CompactAztecMap[r + x] && binary_string[CompactAztecMap[r + x] - 2000] == '1') { } else if (AztecCompactMap[r + x] && binary_string[AztecCompactMap[r + x] - 2000] == '1') {
set_module(symbol, y - 8, x - 8); set_module(symbol, y - 8, x - 8);
} }
} }
@ -1523,3 +1539,5 @@ INTERNAL int azrune(struct zint_symbol *symbol, unsigned char source[], int leng
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -29,11 +29,11 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#ifndef __AZTEC_H
#define __AZTEC_H
static const short CompactAztecMap[] = { #ifndef Z_AZTEC_H
#define Z_AZTEC_H
static const short AztecCompactMap[] = {
/* 27 x 27 data grid */ /* 27 x 27 data grid */
609, 608, 411, 413, 415, 417, 419, 421, 423, 425, 427, 429, 431, 433, 435, 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, 457, 459, // 0 609, 608, 411, 413, 415, 417, 419, 421, 423, 425, 427, 429, 431, 433, 435, 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, 457, 459, // 0
607, 606, 410, 412, 414, 416, 418, 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 454, 456, 458, // 1 607, 606, 410, 412, 414, 416, 418, 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 454, 456, 458, // 1
@ -164,4 +164,5 @@ static const short AztecMapGridYOffsets[] = {
27, 43, 59, 75, 91, 107, 123, 139 27, 43, 59, 75, 91, 107, 123, 139
}; };
#endif /* __AZTEC_H */ /* vim: set ts=4 sw=4 et : */
#endif /* Z_AZTEC_H */

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
Bugfixes thanks to Christian Sakowski and BogDan Vatra Bugfixes thanks to Christian Sakowski and BogDan Vatra
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -30,7 +30,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include <stdio.h> #include <stdio.h>
#ifdef _MSC_VER #ifdef _MSC_VER
@ -103,7 +102,7 @@ INTERNAL int c128_parunmodd(const unsigned char llyth) {
/** /**
* bring together same type blocks * bring together same type blocks
*/ */
static void grwp(int list[2][C128_MAX], int *indexliste) { static void c128_grwp(int list[2][C128_MAX], int *indexliste) {
/* bring together same type blocks */ /* bring together same type blocks */
if (*(indexliste) > 1) { if (*(indexliste) > 1) {
@ -220,7 +219,7 @@ INTERNAL void c128_dxsmooth(int list[2][C128_MAX], int *indexliste) {
} /* Rule 2 is implemented elsewhere, Rule 6 is implied */ } /* Rule 2 is implemented elsewhere, Rule 6 is implied */
} }
grwp(list, indexliste); c128_grwp(list, indexliste);
} }
/** /**
@ -342,11 +341,11 @@ INTERNAL void c128_put_in_set(int list[2][C128_MAX], const int indexliste, char
} }
/* Treats source as ISO 8859-1 and copies into symbol->text, converting to UTF-8. Returns length of symbol->text */ /* Treats source as ISO 8859-1 and copies into symbol->text, converting to UTF-8. Returns length of symbol->text */
STATIC_UNLESS_ZINT_TEST int hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char *source, STATIC_UNLESS_ZINT_TEST int c128_hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char source[],
const int source_len) { const int length) {
int i, j; int i, j;
for (i = 0, j = 0; i < source_len && j < (int) sizeof(symbol->text); i++) { for (i = 0, j = 0; i < length && j < (int) sizeof(symbol->text); i++) {
if (source[i] < 0x80) { if (source[i] < 0x80) {
symbol->text[j++] = source[i] >= ' ' && source[i] != 0x7F ? source[i] : ' '; symbol->text[j++] = source[i] >= ' ' && source[i] != 0x7F ? source[i] : ' ';
} else if (source[i] < 0xC0) { } else if (source[i] < 0xC0) {
@ -724,7 +723,7 @@ INTERNAL int code128(struct zint_symbol *symbol, unsigned char source[], int len
/* ISO/IEC 15417:2007 leaves dimensions/height as application specification */ /* ISO/IEC 15417:2007 leaves dimensions/height as application specification */
hrt_cpy_iso8859_1(symbol, source, length); c128_hrt_cpy_iso8859_1(symbol, source, length);
return error_number; return error_number;
} }
@ -1146,3 +1145,5 @@ INTERNAL int dpd(struct zint_symbol *symbol, unsigned char source[], int length)
return error_number; return error_number;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -29,7 +29,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include <assert.h> #include <assert.h>
#ifdef ZINT_TEST #ifdef ZINT_TEST
#include <stdio.h> #include <stdio.h>
@ -98,36 +97,47 @@ INTERNAL int chr_cnt(const unsigned char string[], const int length, const unsig
return count; return count;
} }
/* Flag table for `is_chr()` and `is_sane()` */
#define IS_CLS_F (IS_CLI_F | IS_SIL_F)
static const unsigned short flgs[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00-1F*/
IS_SPC_F, IS_C82_F, IS_C82_F, IS_HSH_F, /*20-23*/ /* !"# */
IS_CLS_F, IS_SIL_F | IS_C82_F, IS_C82_F, IS_C82_F, /*24-27*/ /* $%&' */
IS_C82_F, IS_C82_F, IS_AST_F, IS_PLS_F, /*28-2B*/ /* ()*+ */
IS_C82_F, IS_MNS_F, IS_CLS_F | IS_C82_F, IS_CLS_F | IS_C82_F, /*2B-2F*/ /* ,-./ */
IS_NUM_F, IS_NUM_F, IS_NUM_F, IS_NUM_F, /*30-33*/ /* 0123 */
IS_NUM_F, IS_NUM_F, IS_NUM_F, IS_NUM_F, /*34-37*/ /* 4567 */
IS_NUM_F, IS_NUM_F, IS_CLI_F | IS_C82_F, IS_C82_F, /*38-3B*/ /* 89:; */
IS_C82_F, IS_C82_F, IS_C82_F, IS_C82_F, /*3B-3F*/ /* <=>? */
0, IS_UHX_F | IS_ARS_F, IS_UHX_F | IS_ARS_F, IS_UHX_F | IS_ARS_F, /*40-43*/ /* @ABC */
IS_UHX_F | IS_ARS_F, IS_UHX_F | IS_ARS_F, IS_UHX_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, /*44-47*/ /* DEFG */
IS_UPO_F | IS_ARS_F, IS_UPO_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, /*48-4B*/ /* HIJK */
IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, IS_UPO_F, /*4B-4F*/ /* LMNO */
IS_UPO_F | IS_ARS_F, IS_UPO_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, /*50-53*/ /* PQRS */
IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, /*53-57*/ /* TUVW */
IS_UX__F | IS_ARS_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, 0, /*58-5B*/ /* XYZ[ */
0, 0, 0, IS_C82_F, /*5B-5F*/ /* \]^_ */
0, IS_LHX_F, IS_LHX_F, IS_LHX_F, /*60-63*/ /* `abc */
IS_LHX_F, IS_LHX_F, IS_LHX_F, IS_LWO_F, /*64-67*/ /* defg */
IS_LWO_F, IS_LWO_F, IS_LWO_F, IS_LWO_F, /*68-6B*/ /* hijk */
IS_LWO_F, IS_LWO_F, IS_LWO_F, IS_LWO_F, /*6B-6F*/ /* lmno */
IS_LWO_F, IS_LWO_F, IS_LWO_F, IS_LWO_F, /*70-73*/ /* pqrs */
IS_LWO_F, IS_LWO_F, IS_LWO_F, IS_LWO_F, /*74-77*/ /* tuvw */
IS_LX__F, IS_LWO_F, IS_LWO_F, 0, /*78-7B*/ /* xyz{ */
0, 0, 0, 0, /*7B-7F*/ /* |}~D */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80-9F*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*A0-BF*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*C0-DF*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*E0-FF*/
};
/* Whether a character matches `flg` */
INTERNAL int is_chr(const unsigned int flg, const unsigned int c) {
return c < 0x80 && (flgs[c] & flg) != 0;
}
/* Verifies that a string only uses valid characters */ /* Verifies that a string only uses valid characters */
INTERNAL int is_sane(const unsigned int flg, const unsigned char source[], const int length) { INTERNAL int is_sane(const unsigned int flg, const unsigned char source[], const int length) {
#define IS_CLS_F (IS_CLI_F | IS_SIL_F)
static const unsigned short flgs[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00-1F*/
IS_SPC_F, IS_C82_F, IS_C82_F, IS_HSH_F, /*20-23*/ /* !"# */
IS_CLS_F, IS_SIL_F | IS_C82_F, IS_C82_F, IS_C82_F, /*24-27*/ /* $%&' */
IS_C82_F, IS_C82_F, IS_C82_F, IS_PLS_F, /*28-2B*/ /* ()*+ */
IS_C82_F, IS_MNS_F, IS_CLS_F | IS_C82_F, IS_CLS_F | IS_C82_F, /*2B-2F*/ /* ,-./ */
IS_NUM_F, IS_NUM_F, IS_NUM_F, IS_NUM_F, /*30-33*/ /* 0123 */
IS_NUM_F, IS_NUM_F, IS_NUM_F, IS_NUM_F, /*34-37*/ /* 4567 */
IS_NUM_F, IS_NUM_F, IS_CLI_F | IS_C82_F, IS_C82_F, /*38-3B*/ /* 89:; */
IS_C82_F, IS_C82_F, IS_C82_F, IS_C82_F, /*3B-3F*/ /* <=>? */
0, IS_UHX_F | IS_ARS_F, IS_UHX_F | IS_ARS_F, IS_UHX_F | IS_ARS_F, /*40-43*/ /* @ABC */
IS_UHX_F | IS_ARS_F, IS_UHX_F | IS_ARS_F, IS_UHX_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, /*44-47*/ /* DEFG */
IS_UPO_F | IS_ARS_F, IS_UPO_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, /*48-4B*/ /* HIJK */
IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, IS_UPO_F, /*4B-4F*/ /* LMNO */
IS_UPO_F | IS_ARS_F, IS_UPO_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, /*50-53*/ /* PQRS */
IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, /*53-57*/ /* TUVW */
IS_UX__F | IS_ARS_F, IS_UPO_F | IS_ARS_F, IS_UPO_F | IS_ARS_F, 0, /*58-5B*/ /* XYZ[ */
0, 0, 0, IS_C82_F, /*5B-5F*/ /* \]^_ */
0, IS_LHX_F, IS_LHX_F, IS_LHX_F, /*60-63*/ /* `abc */
IS_LHX_F, IS_LHX_F, IS_LHX_F, IS_LWO_F, /*64-67*/ /* defg */
IS_LWO_F, IS_LWO_F, IS_LWO_F, IS_LWO_F, /*68-6B*/ /* hijk */
IS_LWO_F, IS_LWO_F, IS_LWO_F, IS_LWO_F, /*6B-6F*/ /* lmno */
IS_LWO_F, IS_LWO_F, IS_LWO_F, IS_LWO_F, /*70-73*/ /* pqrs */
IS_LWO_F, IS_LWO_F, IS_LWO_F, IS_LWO_F, /*74-77*/ /* tuvw */
IS_LX__F, IS_LWO_F, IS_LWO_F, 0, /*78-7B*/ /* xyz{ */
0, 0, 0, 0, /*7B-7F*/ /* |}~D */
};
int i; int i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
@ -189,7 +199,7 @@ INTERNAL int bin_append_posn(const int arg, const int length, char *binary, cons
return bin_posn + length; return bin_posn + length;
} }
#ifndef COMMON_INLINE #ifndef Z_COMMON_INLINE
/* Return true (1) if a module is dark/black, otherwise false (0) */ /* Return true (1) if a module is dark/black, otherwise false (0) */
INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord) { INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord) {
return (symbol->encoded_data[y_coord][x_coord >> 3] >> (x_coord & 0x07)) & 1; return (symbol->encoded_data[y_coord][x_coord >> 3] >> (x_coord & 0x07)) & 1;
@ -505,6 +515,32 @@ INTERNAL float stripf(const float arg) {
return *((volatile const float *) &arg); return *((volatile const float *) &arg);
} }
/* Returns total length of segments */
INTERNAL int segs_length(const struct zint_seg segs[], const int seg_count) {
int total_len = 0;
int i;
for (i = 0; i < seg_count; i++) {
total_len += segs[i].length == -1 ? (int) ustrlen(segs[i].source) : segs[i].length;
}
return total_len;
}
/* Shallow copy segments, adjusting default ECIs */
INTERNAL void segs_cpy(const struct zint_seg segs[], const int seg_count, struct zint_seg local_segs[]) {
int i;
local_segs[0] = segs[0];
for (i = 1; i < seg_count; i++) {
local_segs[i] = segs[i];
/* Ensure default ECI set if follows non-default ECI */
if (local_segs[i].eci == 0 && local_segs[i - 1].eci > 3) {
local_segs[i].eci = 3;
}
}
}
/* Returns red component if any of ultra colour indexing "0CBMRYGKW" */ /* Returns red component if any of ultra colour indexing "0CBMRYGKW" */
INTERNAL int colour_to_red(const int colour) { INTERNAL int colour_to_red(const int colour) {
int return_val = 0; int return_val = 0;
@ -586,3 +622,5 @@ void debug_test_codeword_dump_int(struct zint_symbol *symbol, const int *codewor
symbol->errtxt[strlen(symbol->errtxt) - 1] = '\0'; /* Zap last space */ symbol->errtxt[strlen(symbol->errtxt) - 1] = '\0'; /* Zap last space */
} }
#endif #endif
/* vim: set ts=4 sw=4 et : */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -29,10 +29,9 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#ifndef __COMMON_H #ifndef Z_COMMON_H
#define __COMMON_H #define Z_COMMON_H
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0
@ -49,19 +48,20 @@
/* `is_sane()` flags */ /* `is_sane()` flags */
#define IS_SPC_F 0x0001 /* Space */ #define IS_SPC_F 0x0001 /* Space */
#define IS_HSH_F 0x0002 /* Hash sign # */ #define IS_HSH_F 0x0002 /* Hash sign # */
#define IS_PLS_F 0x0004 /* Plus sign + */ #define IS_AST_F 0x0004 /* Asterisk sign * */
#define IS_MNS_F 0x0008 /* Minus sign - */ #define IS_PLS_F 0x0008 /* Plus sign + */
#define IS_NUM_F 0x0010 /* Number 0-9 */ #define IS_MNS_F 0x0010 /* Minus sign - */
#define IS_UPO_F 0x0020 /* Uppercase letter, apart from A-F and X */ #define IS_NUM_F 0x0020 /* Number 0-9 */
#define IS_UHX_F 0x0040 /* Uppercase hex A-F */ #define IS_UPO_F 0x0040 /* Uppercase letter, apart from A-F and X */
#define IS_UX__F 0x0080 /* Uppercase X */ #define IS_UHX_F 0x0080 /* Uppercase hex A-F */
#define IS_LWO_F 0x0100 /* Lowercase letter, apart from a-f and x */ #define IS_UX__F 0x0100 /* Uppercase X */
#define IS_LHX_F 0x0200 /* Lowercase hex a-f */ #define IS_LWO_F 0x0200 /* Lowercase letter, apart from a-f and x */
#define IS_LX__F 0x0400 /* Lowercase x */ #define IS_LHX_F 0x0400 /* Lowercase hex a-f */
#define IS_C82_F 0x0800 /* CSET82 punctuation (apart from - and +) */ #define IS_LX__F 0x0800 /* Lowercase x */
#define IS_SIL_F 0x1000 /* SILVER/TECHNETIUM punctuation .$/% (apart from space, - and +) */ #define IS_C82_F 0x1000 /* CSET82 punctuation (apart from *, + and -) */
#define IS_CLI_F 0x2000 /* CALCIUM INNER punctuation $:/. (apart from - and +) (Codabar) */ #define IS_SIL_F 0x2000 /* SILVER/TECHNETIUM punctuation .$/% (apart from space, + and -) */
#define IS_ARS_F 0x4000 /* ARSENIC uppercase subset (VIN) */ #define IS_CLI_F 0x4000 /* CALCIUM INNER punctuation $:/. (apart from + and -) (Codabar) */
#define IS_ARS_F 0x8000 /* ARSENIC uppercase subset (VIN) */
#define IS_UPR_F (IS_UPO_F | IS_UHX_F | IS_UX__F) /* Uppercase letters */ #define IS_UPR_F (IS_UPO_F | IS_UHX_F | IS_UX__F) /* Uppercase letters */
#define IS_LWR_F (IS_LWO_F | IS_LHX_F | IS_LX__F) /* Lowercase letters */ #define IS_LWR_F (IS_LWO_F | IS_LHX_F | IS_LX__F) /* Lowercase letters */
@ -121,9 +121,9 @@
#define STATIC_UNLESS_ZINT_TEST static #define STATIC_UNLESS_ZINT_TEST static
#endif #endif
#define COMMON_INLINE 1 #define Z_COMMON_INLINE 1
#ifdef COMMON_INLINE #ifdef Z_COMMON_INLINE
/* Return true (1) if a module is dark/black, otherwise false (0) */ /* Return true (1) if a module is dark/black, otherwise false (0) */
# define module_is_set(s, y, x) (((s)->encoded_data[(y)][(x) >> 3] >> ((x) & 0x07)) & 1) # define module_is_set(s, y, x) (((s)->encoded_data[(y)][(x) >> 3] >> ((x) & 0x07)) & 1)
@ -147,6 +147,7 @@ extern "C" {
INTERNAL void to_upper(unsigned char source[], const int length); INTERNAL void to_upper(unsigned char source[], const int length);
INTERNAL int chr_cnt(const unsigned char string[], const int length, const unsigned char c); INTERNAL int chr_cnt(const unsigned char string[], const int length, const unsigned char c);
INTERNAL int is_chr(const unsigned int flg, const unsigned int c);
INTERNAL int is_sane(const unsigned int flg, const unsigned char source[], const int length); INTERNAL int is_sane(const unsigned int flg, const unsigned char source[], const int length);
INTERNAL int is_sane_lookup(const char test_string[], const int test_length, const unsigned char source[], INTERNAL int is_sane_lookup(const char test_string[], const int test_length, const unsigned char source[],
const int length, int *posns); const int length, int *posns);
@ -154,7 +155,7 @@ extern "C" {
INTERNAL int bin_append_posn(const int arg, const int length, char *binary, const int bin_posn); INTERNAL int bin_append_posn(const int arg, const int length, char *binary, const int bin_posn);
#ifndef COMMON_INLINE #ifndef Z_COMMON_INLINE
INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord); INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord);
INTERNAL void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord); INTERNAL void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord);
INTERNAL int module_colour_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord); INTERNAL int module_colour_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord);
@ -183,6 +184,9 @@ extern "C" {
INTERNAL float stripf(const float arg); INTERNAL float stripf(const float arg);
INTERNAL int segs_length(const struct zint_seg segs[], const int seg_count);
INTERNAL void segs_cpy(const struct zint_seg segs[], const int seg_count, struct zint_seg local_segs[]);
INTERNAL int colour_to_red(const int colour); INTERNAL int colour_to_red(const int colour);
INTERNAL int colour_to_green(const int colour); INTERNAL int colour_to_green(const int colour);
INTERNAL int colour_to_blue(const int colour); INTERNAL int colour_to_blue(const int colour);
@ -197,4 +201,5 @@ extern "C" {
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __COMMON_H */ /* vim: set ts=4 sw=4 et : */
#endif /* Z_COMMON_H */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
developed from and including some functions from: developed from and including some functions from:
IEC16022 bar code generation IEC16022 bar code generation
@ -37,7 +37,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
@ -1485,12 +1484,11 @@ static int dm_isoenc(struct zint_symbol *symbol, const unsigned char source[], c
/* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate /* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate
Supports encoding FNC1 in supporting systems */ Supports encoding FNC1 in supporting systems */
STATIC_UNLESS_ZINT_TEST int dm_encode(struct zint_symbol *symbol, const unsigned char source[], STATIC_UNLESS_ZINT_TEST int dm_encode(struct zint_symbol *symbol, const unsigned char source[],
unsigned char target[], int *p_length, int *p_binlen) { const int length, const int eci, const int gs1, unsigned char target[], int *p_tp) {
int sp = 0; int sp = 0;
int tp = 0; int tp = *p_tp;
int current_mode = DM_ASCII; int current_mode = DM_ASCII;
int i, gs1; int i;
int length = *p_length;
int process_buffer[8]; /* holds remaining data to finalised */ int process_buffer[8]; /* holds remaining data to finalised */
int process_p = 0; /* number of characters left to finalise */ int process_p = 0; /* number of characters left to finalise */
int b256_start = 0; int b256_start = 0;
@ -1498,134 +1496,20 @@ STATIC_UNLESS_ZINT_TEST int dm_encode(struct zint_symbol *symbol, const unsigned
int error_number; int error_number;
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
if (length > 3116) { /* Max is 3166 digits */ if (eci > 0) {
strcpy(symbol->errtxt, "760: Data too long to fit in symbol");
return ZINT_ERROR_TOO_LONG;
}
if (symbol->structapp.count) {
int id1, id2;
if (symbol->structapp.count < 2 || symbol->structapp.count > 16) {
strcpy(symbol->errtxt, "720: Structured Append count out of range (2-16)");
return ZINT_ERROR_INVALID_OPTION;
}
if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
sprintf(symbol->errtxt, "721: Structured Append index out of range (1-%d)", symbol->structapp.count);
return ZINT_ERROR_INVALID_OPTION;
}
if (symbol->structapp.id[0]) {
int id, id_len, id1_err, id2_err;
for (id_len = 0; id_len < 32 && symbol->structapp.id[id_len]; id_len++);
if (id_len > 6) { /* ID1 * 1000 + ID2 */
strcpy(symbol->errtxt, "722: Structured Append ID too long (6 digit maximum)");
return ZINT_ERROR_INVALID_OPTION;
}
id = to_int((const unsigned char *) symbol->structapp.id, id_len);
if (id == -1) {
strcpy(symbol->errtxt, "723: Invalid Structured Append ID (digits only)");
return ZINT_ERROR_INVALID_OPTION;
}
id1 = id / 1000;
id2 = id % 1000;
id1_err = id1 < 1 || id1 > 254;
id2_err = id2 < 1 || id2 > 254;
if (id1_err || id2_err) {
if (id1_err && id2_err) {
sprintf(symbol->errtxt,
"724: Structured Append ID1 '%03d' and ID2 '%03d' out of range (001-254) (ID '%03d%03d')",
id1, id2, id1, id2);
} else if (id1_err) {
sprintf(symbol->errtxt,
"725: Structured Append ID1 '%03d' out of range (001-254) (ID '%03d%03d')",
id1, id1, id2);
} else {
sprintf(symbol->errtxt,
"726: Structured Append ID2 '%03d' out of range (001-254) (ID '%03d%03d')",
id2, id1, id2);
}
return ZINT_ERROR_INVALID_OPTION;
}
} else {
id1 = id2 = 1;
}
target[tp++] = 233;
target[tp++] = (17 - symbol->structapp.count) | ((symbol->structapp.index - 1) << 4);
target[tp++] = id1;
target[tp++] = id2;
}
/* gs1 flag values: 0: no gs1, 1: gs1 with FNC1 serparator, 2: GS separator */
if ((symbol->input_mode & 0x07) == GS1_MODE) {
if (symbol->output_options & GS1_GS_SEPARATOR) {
gs1 = 2;
} else {
gs1 = 1;
}
} else {
gs1 = 0;
}
if (gs1) {
target[tp++] = 232;
if (debug_print) printf("FN1 ");
} /* FNC1 */
if (symbol->output_options & READER_INIT) {
if (gs1) {
strcpy(symbol->errtxt, "521: Cannot encode in GS1 mode and Reader Initialisation at the same time");
return ZINT_ERROR_INVALID_OPTION;
}
if (symbol->structapp.count) {
strcpy(symbol->errtxt, "727: Cannot have Structured Append and Reader Initialisation at the same time");
return ZINT_ERROR_INVALID_OPTION;
}
target[tp++] = 234; /* Reader Programming */
if (debug_print) printf("RP ");
}
if (symbol->eci > 0) {
/* Encode ECI numbers according to Table 6 */ /* Encode ECI numbers according to Table 6 */
target[tp++] = 241; /* ECI Character */ target[tp++] = 241; /* ECI Character */
if (symbol->eci <= 126) { if (eci <= 126) {
target[tp++] = (unsigned char) (symbol->eci + 1); target[tp++] = (unsigned char) (eci + 1);
} else if (symbol->eci <= 16382) { } else if (eci <= 16382) {
target[tp++] = (unsigned char) ((symbol->eci - 127) / 254 + 128); target[tp++] = (unsigned char) ((eci - 127) / 254 + 128);
target[tp++] = (unsigned char) ((symbol->eci - 127) % 254 + 1); target[tp++] = (unsigned char) ((eci - 127) % 254 + 1);
} else { } else {
target[tp++] = (unsigned char) ((symbol->eci - 16383) / 64516 + 192); target[tp++] = (unsigned char) ((eci - 16383) / 64516 + 192);
target[tp++] = (unsigned char) (((symbol->eci - 16383) / 254) % 254 + 1); target[tp++] = (unsigned char) (((eci - 16383) / 254) % 254 + 1);
target[tp++] = (unsigned char) ((symbol->eci - 16383) % 254 + 1); target[tp++] = (unsigned char) ((eci - 16383) % 254 + 1);
} }
if (debug_print) printf("ECI %d ", symbol->eci + 1); if (debug_print) printf("ECI %d ", eci + 1);
}
/* Check for Macro05/Macro06 */
/* "[)>[RS]05[GS]...[RS][EOT]" -> CW 236 */
/* "[)>[RS]06[GS]...[RS][EOT]" -> CW 237 */
if (tp == 0 && sp == 0 && length >= 9
&& source[0] == '[' && source[1] == ')' && source[2] == '>'
&& source[3] == '\x1e' && source[4] == '0'
&& (source[5] == '5' || source[5] == '6')
&& source[6] == '\x1d'
&& source[length - 2] == '\x1e' && source[length - 1] == '\x04') {
/* Output macro Codeword */
if (source[5] == '5') {
target[tp++] = 236;
if (debug_print) printf("Macro05 ");
} else {
target[tp++] = 237;
if (debug_print) printf("Macro06 ");
}
/* Remove macro characters from input string */
sp = 7;
length -= 2;
*p_length -= 2;
} }
if (symbol->input_mode & FAST_MODE) { /* If FAST_MODE, do Annex J-based encodation */ if (symbol->input_mode & FAST_MODE) { /* If FAST_MODE, do Annex J-based encodation */
@ -1769,6 +1653,153 @@ STATIC_UNLESS_ZINT_TEST int dm_encode(struct zint_symbol *symbol, const unsigned
printf("\n"); printf("\n");
} }
*p_tp = tp;
return 0;
}
/* Call `dm_encode()` for each segment, dealing with Structured Append, GS1, READER_INIT and macro headers
beforehand */
static int dm_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count,
unsigned char target[], int *p_binlen) {
int error_number;
int i;
int tp = 0;
int gs1;
int in_macro = 0;
const struct zint_seg *last_seg = &segs[seg_count - 1];
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
if (segs_length(segs, seg_count) > 3116) { /* Max is 3166 digits */
strcpy(symbol->errtxt, "760: Data too long to fit in symbol");
return ZINT_ERROR_TOO_LONG;
}
if (symbol->structapp.count) {
int id1, id2;
if (symbol->structapp.count < 2 || symbol->structapp.count > 16) {
strcpy(symbol->errtxt, "720: Structured Append count out of range (2-16)");
return ZINT_ERROR_INVALID_OPTION;
}
if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
sprintf(symbol->errtxt, "721: Structured Append index out of range (1-%d)", symbol->structapp.count);
return ZINT_ERROR_INVALID_OPTION;
}
if (symbol->structapp.id[0]) {
int id, id_len, id1_err, id2_err;
for (id_len = 0; id_len < 32 && symbol->structapp.id[id_len]; id_len++);
if (id_len > 6) { /* ID1 * 1000 + ID2 */
strcpy(symbol->errtxt, "722: Structured Append ID too long (6 digit maximum)");
return ZINT_ERROR_INVALID_OPTION;
}
id = to_int((const unsigned char *) symbol->structapp.id, id_len);
if (id == -1) {
strcpy(symbol->errtxt, "723: Invalid Structured Append ID (digits only)");
return ZINT_ERROR_INVALID_OPTION;
}
id1 = id / 1000;
id2 = id % 1000;
id1_err = id1 < 1 || id1 > 254;
id2_err = id2 < 1 || id2 > 254;
if (id1_err || id2_err) {
if (id1_err && id2_err) {
sprintf(symbol->errtxt,
"724: Structured Append ID1 '%03d' and ID2 '%03d' out of range (001-254) (ID '%03d%03d')",
id1, id2, id1, id2);
} else if (id1_err) {
sprintf(symbol->errtxt,
"725: Structured Append ID1 '%03d' out of range (001-254) (ID '%03d%03d')",
id1, id1, id2);
} else {
sprintf(symbol->errtxt,
"726: Structured Append ID2 '%03d' out of range (001-254) (ID '%03d%03d')",
id2, id1, id2);
}
return ZINT_ERROR_INVALID_OPTION;
}
} else {
id1 = id2 = 1;
}
target[tp++] = 233;
target[tp++] = (17 - symbol->structapp.count) | ((symbol->structapp.index - 1) << 4);
target[tp++] = id1;
target[tp++] = id2;
}
/* gs1 flag values: 0: no gs1, 1: gs1 with FNC1 serparator, 2: GS separator */
if ((symbol->input_mode & 0x07) == GS1_MODE) {
if (symbol->output_options & GS1_GS_SEPARATOR) {
gs1 = 2;
} else {
gs1 = 1;
}
} else {
gs1 = 0;
}
if (gs1) {
target[tp++] = 232;
if (debug_print) printf("FN1 ");
} /* FNC1 */
if (symbol->output_options & READER_INIT) {
if (gs1) {
strcpy(symbol->errtxt, "521: Cannot encode in GS1 mode and Reader Initialisation at the same time");
return ZINT_ERROR_INVALID_OPTION;
}
if (symbol->structapp.count) {
strcpy(symbol->errtxt, "727: Cannot have Structured Append and Reader Initialisation at the same time");
return ZINT_ERROR_INVALID_OPTION;
}
target[tp++] = 234; /* Reader Programming */
if (debug_print) printf("RP ");
}
/* Check for Macro05/Macro06 */
/* "[)>[RS]05[GS]...[RS][EOT]" -> CW 236 */
/* "[)>[RS]06[GS]...[RS][EOT]" -> CW 237 */
if (tp == 0 && segs[0].length >= 9 && last_seg->length >= 2
&& segs[0].source[0] == '[' && segs[0].source[1] == ')' && segs[0].source[2] == '>'
&& segs[0].source[3] == '\x1e' /*RS*/ && segs[0].source[4] == '0'
&& (segs[0].source[5] == '5' || segs[0].source[5] == '6')
&& segs[0].source[6] == '\x1d' /*GS*/
&& last_seg->source[last_seg->length - 1] == '\x04' /*EOT*/
&& last_seg->source[last_seg->length - 2] == '\x1e' /*RS*/) {
/* Output macro Codeword */
if (segs[0].source[5] == '5') {
target[tp++] = 236;
if (debug_print) printf("Macro05 ");
} else {
target[tp++] = 237;
if (debug_print) printf("Macro06 ");
}
/* Remove macro characters from input string */
in_macro = 1;
}
for (i = 0; i < seg_count; i++) {
int src_inc = 0, len_dec = 0;
if (in_macro) {
if (i == 0) {
src_inc = len_dec = 7; /* Skip over macro characters at beginning */
}
if (i + 1 == seg_count) {
len_dec += 2; /* Remove RS + EOT from end */
}
}
error_number = dm_encode(symbol, segs[i].source + src_inc, segs[i].length - len_dec, segs[i].eci, gs1,
target, &tp);
if (error_number != 0) {
return error_number;
}
}
*p_binlen = tp; *p_binlen = tp;
return 0; return 0;
@ -1791,7 +1822,7 @@ static void dm_add_tail(unsigned char target[], int tp, const int tail_length) {
} }
} }
static int dm_ecc200(struct zint_symbol *symbol, const unsigned char source[], int length) { static int dm_ecc200(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int i, skew = 0; int i, skew = 0;
unsigned char binary[2200]; unsigned char binary[2200];
int binlen; int binlen;
@ -1801,7 +1832,7 @@ static int dm_ecc200(struct zint_symbol *symbol, const unsigned char source[], i
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
/* `length` may be decremented by 2 if macro character is used */ /* `length` may be decremented by 2 if macro character is used */
error_number = dm_encode(symbol, source, binary, &length, &binlen); error_number = dm_encode_segs(symbol, segs, seg_count, binary, &binlen);
if (error_number != 0) { if (error_number != 0) {
return error_number; return error_number;
} }
@ -1906,12 +1937,12 @@ static int dm_ecc200(struct zint_symbol *symbol, const unsigned char source[], i
return error_number; return error_number;
} }
INTERNAL int datamatrix(struct zint_symbol *symbol, unsigned char source[], int length) { INTERNAL int datamatrix(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int error_number; int error_number;
if (symbol->option_1 <= 1) { if (symbol->option_1 <= 1) {
/* ECC 200 */ /* ECC 200 */
error_number = dm_ecc200(symbol, source, length); error_number = dm_ecc200(symbol, segs, seg_count);
} else { } else {
/* ECC 000 - 140 */ /* ECC 000 - 140 */
strcpy(symbol->errtxt, "524: Older Data Matrix standards are no longer supported"); strcpy(symbol->errtxt, "524: Older Data Matrix standards are no longer supported");
@ -1920,3 +1951,5 @@ INTERNAL int datamatrix(struct zint_symbol *symbol, unsigned char source[], int
return error_number; return error_number;
} }
/* vim: set ts=4 sw=4 et : */

File diff suppressed because it is too large Load Diff

View File

@ -197,6 +197,18 @@ INTERNAL int is_eci_convertible(const int eci) {
return 1; return 1;
} }
/* Are any of the ECIs in the segments convertible from UTF-8?
Sets `convertible[]` for each, which must be at least `seg_count` in size */
INTERNAL int is_eci_convertible_segs(const struct zint_seg segs[], const int seg_count, int convertible[]) {
int ret = 0;
int i;
for (i = 0; i < seg_count; i++) {
convertible[i] = is_eci_convertible(segs[i].eci);
ret |= convertible[i];
}
return ret;
}
/* Calculate length required to convert UTF-8 to (double-byte) encoding */ /* Calculate length required to convert UTF-8 to (double-byte) encoding */
INTERNAL int get_eci_length(const int eci, const unsigned char source[], int length) { INTERNAL int get_eci_length(const int eci, const unsigned char source[], int length) {
if (eci == 20) { /* Shift JIS */ if (eci == 20) { /* Shift JIS */
@ -222,6 +234,18 @@ INTERNAL int get_eci_length(const int eci, const unsigned char source[], int len
return length; return length;
} }
/* Call `get_eci_length()` for each segment, returning total */
INTERNAL int get_eci_length_segs(const struct zint_seg segs[], const int seg_count) {
int length = 0;
int i;
for (i = 0; i < seg_count; i++) {
length += get_eci_length(segs[i].eci, segs[i].source, segs[i].length);
}
return length;
}
/* Convert UTF-8 Unicode to other character encodings */ /* Convert UTF-8 Unicode to other character encodings */
INTERNAL int utf8_to_eci(const int eci, const unsigned char source[], unsigned char dest[], int *p_length) { INTERNAL int utf8_to_eci(const int eci, const unsigned char source[], unsigned char dest[], int *p_length) {
@ -325,4 +349,37 @@ INTERNAL int get_best_eci(const unsigned char source[], int length) {
return 26; // If all of these fail, use Unicode! return 26; // If all of these fail, use Unicode!
} }
/* Return 0 on failure, first ECI set on success */
INTERNAL int get_best_eci_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int first_eci_set = 0;
int i;
for (i = 0; i < seg_count; i++) {
if (segs[i].eci == 0) {
int eci = get_best_eci(segs[i].source, segs[i].length);
if (eci == 0) {
return 0;
}
if (eci == 3) {
if (i != 0 && segs[i - 1].eci > 3) {
segs[i].eci = eci;
if (first_eci_set == 0) {
first_eci_set = eci;
}
}
} else {
segs[i].eci = eci;
if (first_eci_set == 0) {
first_eci_set = eci;
if (i == 0) {
symbol->eci = eci;
}
}
}
}
}
return first_eci_set;
}
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */

View File

@ -1,7 +1,7 @@
/* eci.c - Extended Channel Interpretations to Unicode tables /* eci.c - Extended Channel Interpretations to Unicode tables
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -28,22 +28,28 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#ifndef ECI_H #ifndef Z_ECI_H
#define ECI_H #define Z_ECI_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
INTERNAL int is_eci_convertible(const int eci); INTERNAL int is_eci_convertible(const int eci);
INTERNAL int is_eci_convertible_segs(const struct zint_seg segs[], const int seg_count, int convertible[]);
INTERNAL int get_eci_length(const int eci, const unsigned char source[], int length); INTERNAL int get_eci_length(const int eci, const unsigned char source[], int length);
INTERNAL int get_eci_length_segs(const struct zint_seg segs[], const int seg_count);
INTERNAL int utf8_to_eci(const int eci, const unsigned char source[], unsigned char dest[], int *p_length); INTERNAL int utf8_to_eci(const int eci, const unsigned char source[], unsigned char dest[], int *p_length);
INTERNAL int get_best_eci(const unsigned char source[], int length); INTERNAL int get_best_eci(const unsigned char source[], int length);
INTERNAL int get_best_eci_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* ECI_H */ /* vim: set ts=4 sw=4 et : */
#endif /* Z_ECI_H */

View File

@ -2868,7 +2868,7 @@ INTERNAL int gb18030_wctomb_zint(unsigned int *r1, unsigned int *r2, const unsig
/* Convert UTF-8 string to GB 18030 and place in array of ints */ /* Convert UTF-8 string to GB 18030 and place in array of ints */
INTERNAL int gb18030_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length, INTERNAL int gb18030_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length,
unsigned int *gbdata) { unsigned int *ddata) {
int error_number, ret; int error_number, ret;
unsigned int i, j, length; unsigned int i, j, length;
#ifndef _MSC_VER #ifndef _MSC_VER
@ -2884,9 +2884,9 @@ INTERNAL int gb18030_utf8(struct zint_symbol *symbol, const unsigned char source
for (i = 0, j = 0, length = *p_length; i < length; i++, j++) { for (i = 0, j = 0, length = *p_length; i < length; i++, j++) {
if (utfdata[i] < 0x80) { if (utfdata[i] < 0x80) {
gbdata[j] = utfdata[i]; ddata[j] = utfdata[i];
} else { } else {
ret = gb18030_wctomb_zint(gbdata + j, gbdata + j + 1, utfdata[i]); ret = gb18030_wctomb_zint(ddata + j, ddata + j + 1, utfdata[i]);
if (ret == 0) { /* Should never happen, as GB 18030 is a UTF i.e. maps all Unicode codepoints */ if (ret == 0) { /* Should never happen, as GB 18030 is a UTF i.e. maps all Unicode codepoints */
strcpy(symbol->errtxt, "820: Invalid character in input data"); /* Not reached */ strcpy(symbol->errtxt, "820: Invalid character in input data"); /* Not reached */
return ZINT_ERROR_INVALID_DATA; return ZINT_ERROR_INVALID_DATA;
@ -2903,7 +2903,7 @@ INTERNAL int gb18030_utf8(struct zint_symbol *symbol, const unsigned char source
} }
/* Convert UTF-8 string to ECI and place in array of ints */ /* Convert UTF-8 string to ECI and place in array of ints */
INTERNAL int gb18030_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *gbdata, INTERNAL int gb18030_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte) { const int full_multibyte) {
if (is_eci_convertible(eci)) { if (is_eci_convertible(eci)) {
@ -2921,9 +2921,9 @@ INTERNAL int gb18030_utf8_to_eci(const int eci, const unsigned char source[], in
return error_number; return error_number;
} }
gb18030_cpy(converted, p_length, gbdata, full_multibyte); gb18030_cpy(converted, p_length, ddata, full_multibyte);
} else { } else {
gb18030_cpy(source, p_length, gbdata, full_multibyte); gb18030_cpy(source, p_length, ddata, full_multibyte);
} }
return 0; return 0;
@ -2931,7 +2931,7 @@ INTERNAL int gb18030_utf8_to_eci(const int eci, const unsigned char source[], in
/* If `full_multibyte` set, copy byte input stream to array of ints, putting double-bytes that match HANXIN /* If `full_multibyte` set, copy byte input stream to array of ints, putting double-bytes that match HANXIN
* Chinese mode in single entry, and quad-bytes in 2 entries. If `full_multibyte` not set, do a straight copy */ * Chinese mode in single entry, and quad-bytes in 2 entries. If `full_multibyte` not set, do a straight copy */
INTERNAL void gb18030_cpy(const unsigned char source[], int *p_length, unsigned int *gbdata, INTERNAL void gb18030_cpy(const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte) { const int full_multibyte) {
unsigned int i, j, length; unsigned int i, j, length;
int done; int done;
@ -2945,15 +2945,15 @@ INTERNAL void gb18030_cpy(const unsigned char source[], int *p_length, unsigned
if (c1 >= 0x81 && c1 <= 0xFE) { if (c1 >= 0x81 && c1 <= 0xFE) {
c2 = source[i + 1]; c2 = source[i + 1];
if ((c2 >= 0x40 && c2 <= 0x7E) || (c2 >= 0x80 && c2 <= 0xFE)) { if ((c2 >= 0x40 && c2 <= 0x7E) || (c2 >= 0x80 && c2 <= 0xFE)) {
gbdata[j] = (c1 << 8) | c2; ddata[j] = (c1 << 8) | c2;
i++; i++;
done = 1; done = 1;
} else if (length - i >= 4 && (c2 >= 0x30 && c2 <= 0x39)) { } else if (length - i >= 4 && (c2 >= 0x30 && c2 <= 0x39)) {
c3 = source[i + 2]; c3 = source[i + 2];
c4 = source[i + 3]; c4 = source[i + 3];
if ((c3 >= 0x81 && c3 <= 0xFE) && (c4 >= 0x30 && c4 <= 0x39)) { if ((c3 >= 0x81 && c3 <= 0xFE) && (c4 >= 0x30 && c4 <= 0x39)) {
gbdata[j++] = (c1 << 8) | c2; ddata[j++] = (c1 << 8) | c2;
gbdata[j] = (c3 << 8) | c4; ddata[j] = (c3 << 8) | c4;
i += 3; i += 3;
done = 1; done = 1;
} }
@ -2961,16 +2961,28 @@ INTERNAL void gb18030_cpy(const unsigned char source[], int *p_length, unsigned
} }
} }
if (!done) { if (!done) {
gbdata[j] = c1; ddata[j] = c1;
} }
} }
*p_length = j; *p_length = j;
} else { } else {
/* Straight copy */ /* Straight copy */
for (i = 0, length = *p_length; i < length; i++) { for (i = 0, length = *p_length; i < length; i++) {
gbdata[i] = source[i]; ddata[i] = source[i];
} }
} }
} }
/* Call `gb18030_cpy()` for each segment */
INTERNAL void gb18030_cpy_segs(struct zint_seg segs[], const int seg_count, unsigned int *ddata,
const int full_multibyte) {
int i;
unsigned int *dd = ddata;
for (i = 0; i < seg_count; i++) {
gb18030_cpy(segs[i].source, &segs[i].length, dd, full_multibyte);
dd += segs[i].length;
}
}
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */

View File

@ -39,10 +39,13 @@ extern "C" {
INTERNAL int gbk_wctomb_zint(unsigned int *r, const unsigned int wc); INTERNAL int gbk_wctomb_zint(unsigned int *r, const unsigned int wc);
INTERNAL int gb18030_wctomb_zint(unsigned int *r1, unsigned int *r2, const unsigned int wc); INTERNAL int gb18030_wctomb_zint(unsigned int *r1, unsigned int *r2, const unsigned int wc);
INTERNAL int gb18030_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length, INTERNAL int gb18030_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length,
unsigned int *gbdata); unsigned int *ddata);
INTERNAL int gb18030_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *gbdata, INTERNAL int gb18030_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte); const int full_multibyte);
INTERNAL void gb18030_cpy(const unsigned char source[], int *p_length, unsigned int *gbdata,
INTERNAL void gb18030_cpy(const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte);
INTERNAL void gb18030_cpy_segs(struct zint_seg segs[], const int seg_count, unsigned int *ddata,
const int full_multibyte); const int full_multibyte);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
/* /*
* Adapted from GNU LIBICONV library and patched to add 2 duplicate mappings * Adapted from GNU LIBICONV library and patched to add 2 duplicate mappings
* for compatibility with GB 18030 subset: * for compatibility with GB 18030 subset:
@ -1543,7 +1542,7 @@ INTERNAL int gb2312_wctomb_zint(unsigned int *r, const unsigned int wc) {
/* Convert UTF-8 string to GB 2312 (EUC-CN) and place in array of ints */ /* Convert UTF-8 string to GB 2312 (EUC-CN) and place in array of ints */
INTERNAL int gb2312_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length, INTERNAL int gb2312_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length,
unsigned int *gbdata) { unsigned int *ddata) {
int error_number; int error_number;
unsigned int i, length; unsigned int i, length;
#ifndef _MSC_VER #ifndef _MSC_VER
@ -1559,9 +1558,9 @@ INTERNAL int gb2312_utf8(struct zint_symbol *symbol, const unsigned char source[
for (i = 0, length = *p_length; i < length; i++) { for (i = 0, length = *p_length; i < length; i++) {
if (utfdata[i] < 0x80) { if (utfdata[i] < 0x80) {
gbdata[i] = utfdata[i]; ddata[i] = utfdata[i];
} else { } else {
if (!gb2312_wctomb_zint(gbdata + i, utfdata[i])) { if (!gb2312_wctomb_zint(ddata + i, utfdata[i])) {
strcpy(symbol->errtxt, "810: Invalid character in input data"); strcpy(symbol->errtxt, "810: Invalid character in input data");
return ZINT_ERROR_INVALID_DATA; return ZINT_ERROR_INVALID_DATA;
} }
@ -1572,7 +1571,7 @@ INTERNAL int gb2312_utf8(struct zint_symbol *symbol, const unsigned char source[
} }
/* Convert UTF-8 string to ECI and place in array of ints */ /* Convert UTF-8 string to ECI and place in array of ints */
INTERNAL int gb2312_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *gbdata, INTERNAL int gb2312_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte) { const int full_multibyte) {
if (is_eci_convertible(eci)) { if (is_eci_convertible(eci)) {
@ -1590,9 +1589,9 @@ INTERNAL int gb2312_utf8_to_eci(const int eci, const unsigned char source[], int
return error_number; return error_number;
} }
gb2312_cpy(converted, p_length, gbdata, full_multibyte); gb2312_cpy(converted, p_length, ddata, full_multibyte);
} else { } else {
gb2312_cpy(source, p_length, gbdata, full_multibyte); gb2312_cpy(source, p_length, ddata, full_multibyte);
} }
return 0; return 0;
@ -1600,7 +1599,7 @@ INTERNAL int gb2312_utf8_to_eci(const int eci, const unsigned char source[], int
/* If `full_multibyte` set, copy byte input stream to array of ints, putting double-bytes that match GRIDMATRIX /* If `full_multibyte` set, copy byte input stream to array of ints, putting double-bytes that match GRIDMATRIX
* Chinese mode in a single entry. If `full_multibyte` not set, do a straight copy */ * Chinese mode in a single entry. If `full_multibyte` not set, do a straight copy */
INTERNAL void gb2312_cpy(const unsigned char source[], int *p_length, unsigned int *gbdata, INTERNAL void gb2312_cpy(const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte) { const int full_multibyte) {
unsigned int i, j, length; unsigned int i, j, length;
unsigned char c1, c2; unsigned char c1, c2;
@ -1613,20 +1612,34 @@ INTERNAL void gb2312_cpy(const unsigned char source[], int *p_length, unsigned i
if (((c1 >= 0xA1 && c1 <= 0xA9) || (c1 >= 0xB0 && c1 <= 0xF7)) && c2 >= 0xA1 && c2 <= 0xFE) { if (((c1 >= 0xA1 && c1 <= 0xA9) || (c1 >= 0xB0 && c1 <= 0xF7)) && c2 >= 0xA1 && c2 <= 0xFE) {
/* This may or may not be valid GB 2312 (EUC-CN), but don't care as long as it can be encoded in /* This may or may not be valid GB 2312 (EUC-CN), but don't care as long as it can be encoded in
* GRIDMATRIX Chinese mode */ * GRIDMATRIX Chinese mode */
gbdata[j] = (c1 << 8) | c2; ddata[j] = (c1 << 8) | c2;
i++; i++;
} else { } else {
gbdata[j] = c1; ddata[j] = c1;
} }
} else { } else {
gbdata[j] = source[i]; ddata[j] = source[i];
} }
} }
*p_length = j; *p_length = j;
} else { } else {
/* Straight copy */ /* Straight copy */
for (i = 0, length = *p_length; i < length; i++) { for (i = 0, length = *p_length; i < length; i++) {
gbdata[i] = source[i]; ddata[i] = source[i];
} }
} }
} }
/* Call `gb2312_cpy()` for each segment */
INTERNAL void gb2312_cpy_segs(struct zint_seg segs[], const int seg_count, unsigned int *ddata,
const int full_multibyte) {
int i;
unsigned int *dd = ddata;
for (i = 0; i < seg_count; i++) {
gb2312_cpy(segs[i].source, &segs[i].length, dd, full_multibyte);
dd += segs[i].length;
}
}
/* vim: set ts=4 sw=4 et : */

View File

@ -1,7 +1,7 @@
/* gb2312.h - Unicode to GB 2312-1980 (EUC-CN) /* gb2312.h - Unicode to GB 2312-1980 (EUC-CN)
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -28,10 +28,9 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#ifndef GB2312_H #ifndef Z_GB2312_H
#define GB2312_H #define Z_GB2312_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -39,14 +38,18 @@ extern "C" {
INTERNAL int gb2312_wctomb_zint(unsigned int *r, const unsigned int wc); INTERNAL int gb2312_wctomb_zint(unsigned int *r, const unsigned int wc);
INTERNAL int gb2312_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length, INTERNAL int gb2312_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length,
unsigned int *gbdata); unsigned int *ddata);
INTERNAL int gb2312_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *gbdata, INTERNAL int gb2312_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte); const int full_multibyte);
INTERNAL void gb2312_cpy(const unsigned char source[], int *p_length, unsigned int *gbdata,
INTERNAL void gb2312_cpy(const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte);
INTERNAL void gb2312_cpy_segs(struct zint_seg segs[], const int seg_count, unsigned int *ddata,
const int full_multibyte); const int full_multibyte);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* GB2312_H */ /* vim: set ts=4 sw=4 et : */
#endif /* Z_GB2312_H */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -29,14 +29,13 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "common.h" #include "common.h"
#include "general_field.h" #include "general_field.h"
static const char alphanum_puncs[] = "*,-./"; static const char alphanum_puncs[] = "*,-./";
static const char isoiec_puncs[] = "!\"%&'()*+,-./:;<=>?_ "; /* Note contains space, not in cset82 */ static const char isoiec_puncs[] = "!\"%&'()*+,-./:;<=>?_ "; /* Note contains space, not in cset82 */
#define IS_ISOIEC_F (IS_LWR_F | IS_C82_F | IS_PLS_F | IS_MNS_F | IS_SPC_F) #define IS_ISOIEC_F (IS_LWR_F | IS_C82_F | IS_AST_F | IS_PLS_F | IS_MNS_F | IS_SPC_F)
/* Returns type of char at `i`. FNC1 counted as NUMERIC. Returns 0 if invalid char */ /* Returns type of char at `i`. FNC1 counted as NUMERIC. Returns 0 if invalid char */
static int general_field_type(const char *general_field, const int i) { static int general_field_type(const char *general_field, const int i) {
@ -205,3 +204,5 @@ INTERNAL int general_field_encode(const char *general_field, const int general_f
return 1; return 1;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,10 +27,9 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#ifndef __GENERAL_FIELD_H #ifndef Z_GENERAL_FIELD_H
#define __GENERAL_FIELD_H #define Z_GENERAL_FIELD_H
#define NUMERIC 110 #define NUMERIC 110
#define ALPHANUMERIC 97 #define ALPHANUMERIC 97
@ -47,4 +46,5 @@ INTERNAL int general_field_encode(const char *general_field, const int general_f
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __GENERAL_FIELD_H */ /* vim: set ts=4 sw=4 et : */
#endif /* Z_GENERAL_FIELD_H */

View File

@ -46,16 +46,17 @@ static const char EUROPIUM[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkl
static const char EUROPIUM_UPR[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "; static const char EUROPIUM_UPR[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
static const char EUROPIUM_LWR[] = "abcdefghijklmnopqrstuvwxyz "; static const char EUROPIUM_LWR[] = "abcdefghijklmnopqrstuvwxyz ";
/* define_mode() stuff */ /* gm_define_mode() stuff */
/* Bits multiplied by this for costs, so as to be whole integer divisible by 2 and 3 */ /* Bits multiplied by this for costs, so as to be whole integer divisible by 2 and 3 */
#define GM_MULT 6 #define GM_MULT 6
static const char numeral_nondigits[] = " +-.,"; /* Non-digit numeral set, excluding EOL (carriage return/linefeed) */ /* Non-digit numeral set, excluding EOL (carriage return/linefeed) */
static const char gm_numeral_nondigits[] = " +-.,";
/* Whether in numeral or not. If in numeral, *p_numeral_end is set to position after numeral, /* Whether in numeral or not. If in numeral, *p_numeral_end is set to position after numeral,
* and *p_numeral_cost is set to per-numeral cost */ * and *p_numeral_cost is set to per-numeral cost */
static int in_numeral(const unsigned int gbdata[], const int length, const int in_posn, static int gm_in_numeral(const unsigned int ddata[], const int length, const int in_posn,
unsigned int *p_numeral_end, unsigned int *p_numeral_cost) { unsigned int *p_numeral_end, unsigned int *p_numeral_cost) {
int i, digit_cnt, nondigit, nondigit_posn; int i, digit_cnt, nondigit, nondigit_posn;
@ -69,15 +70,15 @@ static int in_numeral(const unsigned int gbdata[], const int length, const int i
block of three numeric characters) */ block of three numeric characters) */
for (i = in_posn, digit_cnt = 0, nondigit = 0, nondigit_posn = 0; i < length && i < in_posn + 4 && digit_cnt < 3; for (i = in_posn, digit_cnt = 0, nondigit = 0, nondigit_posn = 0; i < length && i < in_posn + 4 && digit_cnt < 3;
i++) { i++) {
if (gbdata[i] >= '0' && gbdata[i] <= '9') { if (ddata[i] >= '0' && ddata[i] <= '9') {
digit_cnt++; digit_cnt++;
} else if (posn(numeral_nondigits, (const char) gbdata[i]) != -1) { } else if (posn(gm_numeral_nondigits, (const char) ddata[i]) != -1) {
if (nondigit) { if (nondigit) {
break; break;
} }
nondigit = 1; nondigit = 1;
nondigit_posn = i; nondigit_posn = i;
} else if (i < length - 1 && gbdata[i] == 13 && gbdata[i + 1] == 10) { } else if (i < length - 1 && ddata[i] == 13 && ddata[i + 1] == 10) {
if (nondigit) { if (nondigit) {
break; break;
} }
@ -128,7 +129,7 @@ static int in_numeral(const unsigned int gbdata[], const int length, const int i
/* Calculate optimized encoding modes. Adapted from Project Nayuki */ /* Calculate optimized encoding modes. Adapted from Project Nayuki */
/* Copyright (c) Project Nayuki. (MIT License) See qr.c for detailed notice */ /* Copyright (c) Project Nayuki. (MIT License) See qr.c for detailed notice */
static void define_mode(char *mode, const unsigned int gbdata[], const int length, const int debug) { static void gm_define_mode(char *mode, const unsigned int ddata[], const int length, const int debug_print) {
/* Must be in same order as GM_H etc */ /* Must be in same order as GM_H etc */
static const char mode_types[] = { GM_CHINESE, GM_NUMBER, GM_LOWER, GM_UPPER, GM_MIXED, GM_BYTE, '\0' }; static const char mode_types[] = { GM_CHINESE, GM_NUMBER, GM_LOWER, GM_UPPER, GM_MIXED, GM_BYTE, '\0' };
@ -183,24 +184,24 @@ static void define_mode(char *mode, const unsigned int gbdata[], const int lengt
space = numeric = lower = upper = control = double_digit = eol = 0; space = numeric = lower = upper = control = double_digit = eol = 0;
double_byte = gbdata[i] > 0xFF; double_byte = ddata[i] > 0xFF;
if (!double_byte) { if (!double_byte) {
space = gbdata[i] == ' '; space = ddata[i] == ' ';
if (!space) { if (!space) {
numeric = gbdata[i] >= '0' && gbdata[i] <= '9'; numeric = ddata[i] >= '0' && ddata[i] <= '9';
if (!numeric) { if (!numeric) {
lower = gbdata[i] >= 'a' && gbdata[i] <= 'z'; lower = ddata[i] >= 'a' && ddata[i] <= 'z';
if (!lower) { if (!lower) {
upper = gbdata[i] >= 'A' && gbdata[i] <= 'Z'; upper = ddata[i] >= 'A' && ddata[i] <= 'Z';
if (!upper) { if (!upper) {
control = gbdata[i] < 0x7F; /* Exclude DEL */ control = ddata[i] < 0x7F; /* Exclude DEL */
if (control && i + 1 < length) { if (control && i + 1 < length) {
eol = gbdata[i] == 13 && gbdata[i + 1] == 10; eol = ddata[i] == 13 && ddata[i + 1] == 10;
} }
} }
} }
} else if (i + 1 < length) { } else if (i + 1 < length) {
double_digit = gbdata[i + 1] >= '0' && gbdata[i + 1] <= '9'; double_digit = ddata[i + 1] >= '0' && ddata[i + 1] <= '9';
} }
} }
} }
@ -222,7 +223,7 @@ static void define_mode(char *mode, const unsigned int gbdata[], const int lengt
char_modes[cm_i + GM_B] = GM_BYTE; char_modes[cm_i + GM_B] = GM_BYTE;
byte_count += double_byte ? 2 : 1; byte_count += double_byte ? 2 : 1;
if (in_numeral(gbdata, length, i, &numeral_end, &numeral_cost)) { if (gm_in_numeral(ddata, length, i, &numeral_end, &numeral_cost)) {
cur_costs[GM_N] = prev_costs[GM_N] + numeral_cost; cur_costs[GM_N] = prev_costs[GM_N] + numeral_cost;
char_modes[cm_i + GM_N] = GM_NUMBER; char_modes[cm_i + GM_N] = GM_NUMBER;
} }
@ -290,20 +291,20 @@ static void define_mode(char *mode, const unsigned int gbdata[], const int lengt
mode[i] = cur_mode; mode[i] = cur_mode;
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf(" Mode: %.*s\n", length, mode); printf(" Mode: %.*s\n", length, mode);
} }
} }
/* Add the length indicator for byte encoded blocks */ /* Add the length indicator for byte encoded blocks */
static void add_byte_count(char binary[], const int byte_count_posn, const int byte_count) { static void gm_add_byte_count(char binary[], const int byte_count_posn, const int byte_count) {
/* AIMD014 6.3.7: "Let L be the number of bytes of input data to be encoded in the 8-bit binary data set. /* AIMD014 6.3.7: "Let L be the number of bytes of input data to be encoded in the 8-bit binary data set.
* First output (L-1) as a 9-bit binary prefix to record the number of bytes..." */ * First output (L-1) as a 9-bit binary prefix to record the number of bytes..." */
bin_append_posn(byte_count - 1, 9, binary, byte_count_posn); bin_append_posn(byte_count - 1, 9, binary, byte_count_posn);
} }
/* Add a control character to the data stream */ /* Add a control character to the data stream */
static int add_shift_char(char binary[], int bp, int shifty, int debug) { static int gm_add_shift_char(char binary[], int bp, int shifty, const int debug_print) {
int i; int i;
int glyph = 0; int glyph = 0;
@ -318,7 +319,7 @@ static int add_shift_char(char binary[], int bp, int shifty, int debug) {
} }
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("SHIFT [%d] ", glyph); printf("SHIFT [%d] ", glyph);
} }
@ -327,46 +328,29 @@ static int add_shift_char(char binary[], int bp, int shifty, int debug) {
return bp; return bp;
} }
static int gm_encode(unsigned int gbdata[], const int length, char binary[], const int reader, static int gm_encode(unsigned int ddata[], const int length, char binary[], const int eci, int *p_bp,
const struct zint_structapp *p_structapp, const int eci, int *bin_len, int debug) { const int debug_print) {
/* Create a binary stream representation of the input data. /* Create a binary stream representation of the input data.
7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters, 7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters,
Mixed numerals and latters, Control characters and 8-bit binary data */ Mixed numerals and latters, Control characters and 8-bit binary data */
int sp; int sp = 0;
int current_mode, last_mode; int current_mode = 0;
int last_mode;
unsigned int glyph = 0; unsigned int glyph = 0;
int c1, c2, done; int c1, c2, done;
int p = 0, ppos; int p = 0, ppos;
int numbuf[3], punt = 0; int numbuf[3], punt = 0;
int number_pad_posn, byte_count_posn = 0; int number_pad_posn = 0;
int byte_count_posn = 0;
int byte_count = 0; int byte_count = 0;
int shift; int shift;
int bp; int bp = *p_bp;
#ifndef _MSC_VER #ifndef _MSC_VER
char mode[length]; char mode[length];
#else #else
char *mode = (char *) _alloca(length); char *mode = (char *) _alloca(length);
#endif #endif
*binary = '\0';
bp = 0;
sp = 0;
current_mode = 0;
number_pad_posn = 0;
if (reader && (!p_structapp || p_structapp->index == 1)) { /* Appears only in 1st symbol if Structured Append */
bp = bin_append_posn(10, 4, binary, bp); /* FNC3 - Reader Initialisation */
}
if (p_structapp) {
bp = bin_append_posn(9, 4, binary, bp); /* FNC2 - Structured Append */
bp = bin_append_posn(to_int((const unsigned char *) p_structapp->id, (int) strlen(p_structapp->id)), 8,
binary, bp); /* File signature */
bp = bin_append_posn(p_structapp->count - 1, 4, binary, bp);
bp = bin_append_posn(p_structapp->index - 1, 4, binary, bp);
}
if (eci != 0) { if (eci != 0) {
/* ECI assignment according to Table 8 */ /* ECI assignment according to Table 8 */
bp = bin_append_posn(12, 4, binary, bp); /* ECI */ bp = bin_append_posn(12, 4, binary, bp); /* ECI */
@ -381,7 +365,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} }
} }
define_mode(mode, gbdata, length, debug); gm_define_mode(mode, ddata, length, debug_print);
do { do {
const int next_mode = mode[sp]; const int next_mode = mode[sp];
@ -476,7 +460,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
break; break;
case GM_BYTE: case GM_BYTE:
/* add byte block length indicator */ /* add byte block length indicator */
add_byte_count(binary, byte_count_posn, byte_count); gm_add_byte_count(binary, byte_count_posn, byte_count);
byte_count = 0; byte_count = 0;
switch (next_mode) { switch (next_mode) {
case GM_CHINESE: bp = bin_append_posn(1, 4, binary, bp); case GM_CHINESE: bp = bin_append_posn(1, 4, binary, bp);
@ -492,7 +476,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} }
break; break;
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
switch (next_mode) { switch (next_mode) {
case GM_CHINESE: printf("CHIN "); case GM_CHINESE: printf("CHIN ");
break; break;
@ -515,10 +499,10 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
switch (current_mode) { switch (current_mode) {
case GM_CHINESE: case GM_CHINESE:
done = 0; done = 0;
if (gbdata[sp] > 0xff) { if (ddata[sp] > 0xff) {
/* GB2312 character */ /* GB2312 character */
c1 = (gbdata[sp] & 0xff00) >> 8; c1 = (ddata[sp] & 0xff00) >> 8;
c2 = gbdata[sp] & 0xff; c2 = ddata[sp] & 0xff;
if ((c1 >= 0xa1) && (c1 <= 0xa9)) { if ((c1 >= 0xa1) && (c1 <= 0xa9)) {
glyph = (0x60 * (c1 - 0xa1)) + (c2 - 0xa0); glyph = (0x60 * (c1 - 0xa1)) + (c2 - 0xa0);
@ -529,7 +513,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} }
if (!(done)) { if (!(done)) {
if (sp != (length - 1)) { if (sp != (length - 1)) {
if ((gbdata[sp] == 13) && (gbdata[sp + 1] == 10)) { if ((ddata[sp] == 13) && (ddata[sp + 1] == 10)) {
/* End of Line */ /* End of Line */
glyph = 7776; glyph = 7776;
sp++; sp++;
@ -539,10 +523,10 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} }
if (!(done)) { if (!(done)) {
if (sp != (length - 1)) { if (sp != (length - 1)) {
if (((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) && if (((ddata[sp] >= '0') && (ddata[sp] <= '9')) &&
((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) { ((ddata[sp + 1] >= '0') && (ddata[sp + 1] <= '9'))) {
/* Two digits */ /* Two digits */
glyph = 8033 + (10 * (gbdata[sp] - '0')) + (gbdata[sp + 1] - '0'); glyph = 8033 + (10 * (ddata[sp] - '0')) + (ddata[sp + 1] - '0');
sp++; sp++;
done = 1; done = 1;
} }
@ -550,10 +534,10 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} }
if (!(done)) { if (!(done)) {
/* Byte value */ /* Byte value */
glyph = 7777 + gbdata[sp]; glyph = 7777 + ddata[sp];
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("[%d] ", (int) glyph); printf("[%d] ", (int) glyph);
} }
@ -577,21 +561,21 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
numbuf[1] = '0'; numbuf[1] = '0';
numbuf[2] = '0'; numbuf[2] = '0';
do { do {
if ((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { if ((ddata[sp] >= '0') && (ddata[sp] <= '9')) {
numbuf[p] = gbdata[sp]; numbuf[p] = ddata[sp];
p++; p++;
} else if (posn(numeral_nondigits, (const char) gbdata[sp]) != -1) { } else if (posn(gm_numeral_nondigits, (const char) ddata[sp]) != -1) {
if (ppos != -1) { if (ppos != -1) {
break; break;
} }
punt = gbdata[sp]; punt = ddata[sp];
ppos = p; ppos = p;
} else if (sp < (length - 1) && (gbdata[sp] == 13) && (gbdata[sp + 1] == 10)) { } else if (sp < (length - 1) && (ddata[sp] == 13) && (ddata[sp + 1] == 10)) {
/* <end of line> */ /* <end of line> */
if (ppos != -1) { if (ppos != -1) {
break; break;
} }
punt = gbdata[sp]; punt = ddata[sp];
sp++; sp++;
ppos = p; ppos = p;
} else { } else {
@ -618,7 +602,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
glyph += ppos; glyph += ppos;
glyph += 1000; glyph += 1000;
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("[%d] ", (int) glyph); printf("[%d] ", (int) glyph);
} }
@ -626,7 +610,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} }
glyph = (100 * (numbuf[0] - '0')) + (10 * (numbuf[1] - '0')) + (numbuf[2] - '0'); glyph = (100 * (numbuf[0] - '0')) + (10 * (numbuf[1] - '0')) + (numbuf[2] - '0');
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("[%d] ", (int) glyph); printf("[%d] ", (int) glyph);
} }
@ -639,7 +623,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
byte_count_posn = bp; byte_count_posn = bp;
bp = bin_append_posn(0, 9, binary, bp); bp = bin_append_posn(0, 9, binary, bp);
} }
glyph = gbdata[sp]; glyph = ddata[sp];
if (byte_count == 512 || (glyph > 0xFF && byte_count == 511)) { if (byte_count == 512 || (glyph > 0xFF && byte_count == 511)) {
/* Maximum byte block size is 512 bytes. If longer is needed then start a new block */ /* Maximum byte block size is 512 bytes. If longer is needed then start a new block */
if (glyph > 0xFF && byte_count == 511) { /* Split double-byte */ if (glyph > 0xFF && byte_count == 511) { /* Split double-byte */
@ -647,14 +631,14 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
glyph &= 0xFF; glyph &= 0xFF;
byte_count++; byte_count++;
} }
add_byte_count(binary, byte_count_posn, byte_count); gm_add_byte_count(binary, byte_count_posn, byte_count);
bp = bin_append_posn(7, 4, binary, bp); bp = bin_append_posn(7, 4, binary, bp);
byte_count_posn = bp; byte_count_posn = bp;
bp = bin_append_posn(0, 9, binary, bp); bp = bin_append_posn(0, 9, binary, bp);
byte_count = 0; byte_count = 0;
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("[%d] ", (int) glyph); printf("[%d] ", (int) glyph);
} }
bp = bin_append_posn(glyph, glyph > 0xFF ? 16 : 8, binary, bp); bp = bin_append_posn(glyph, glyph > 0xFF ? 16 : 8, binary, bp);
@ -667,20 +651,20 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
case GM_MIXED: case GM_MIXED:
shift = 1; shift = 1;
if ((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { if ((ddata[sp] >= '0') && (ddata[sp] <= '9')) {
shift = 0; shift = 0;
} else if ((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { } else if ((ddata[sp] >= 'A') && (ddata[sp] <= 'Z')) {
shift = 0; shift = 0;
} else if ((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { } else if ((ddata[sp] >= 'a') && (ddata[sp] <= 'z')) {
shift = 0; shift = 0;
} else if (gbdata[sp] == ' ') { } else if (ddata[sp] == ' ') {
shift = 0; shift = 0;
} }
if (shift == 0) { if (shift == 0) {
/* Mixed Mode character */ /* Mixed Mode character */
glyph = posn(EUROPIUM, (const char) gbdata[sp]); glyph = posn(EUROPIUM, (const char) ddata[sp]);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("[%d] ", (int) glyph); printf("[%d] ", (int) glyph);
} }
@ -688,7 +672,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} else { } else {
/* Shift Mode character */ /* Shift Mode character */
bp = bin_append_posn(1014, 10, binary, bp); /* shift indicator */ bp = bin_append_posn(1014, 10, binary, bp); /* shift indicator */
bp = add_shift_char(binary, bp, gbdata[sp], debug); bp = gm_add_shift_char(binary, bp, ddata[sp], debug_print);
} }
sp++; sp++;
@ -696,16 +680,16 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
case GM_UPPER: case GM_UPPER:
shift = 1; shift = 1;
if ((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { if ((ddata[sp] >= 'A') && (ddata[sp] <= 'Z')) {
shift = 0; shift = 0;
} else if (gbdata[sp] == ' ') { } else if (ddata[sp] == ' ') {
shift = 0; shift = 0;
} }
if (shift == 0) { if (shift == 0) {
/* Upper Case character */ /* Upper Case character */
glyph = posn(EUROPIUM_UPR, (const char) gbdata[sp]); glyph = posn(EUROPIUM_UPR, (const char) ddata[sp]);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("[%d] ", (int) glyph); printf("[%d] ", (int) glyph);
} }
@ -713,7 +697,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} else { } else {
/* Shift Mode character */ /* Shift Mode character */
bp = bin_append_posn(125, 7, binary, bp); /* shift indicator */ bp = bin_append_posn(125, 7, binary, bp); /* shift indicator */
bp = add_shift_char(binary, bp, gbdata[sp], debug); bp = gm_add_shift_char(binary, bp, ddata[sp], debug_print);
} }
sp++; sp++;
@ -721,16 +705,16 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
case GM_LOWER: case GM_LOWER:
shift = 1; shift = 1;
if ((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { if ((ddata[sp] >= 'a') && (ddata[sp] <= 'z')) {
shift = 0; shift = 0;
} else if (gbdata[sp] == ' ') { } else if (ddata[sp] == ' ') {
shift = 0; shift = 0;
} }
if (shift == 0) { if (shift == 0) {
/* Lower Case character */ /* Lower Case character */
glyph = posn(EUROPIUM_LWR, (const char) gbdata[sp]); glyph = posn(EUROPIUM_LWR, (const char) ddata[sp]);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("[%d] ", (int) glyph); printf("[%d] ", (int) glyph);
} }
@ -738,7 +722,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} else { } else {
/* Shift Mode character */ /* Shift Mode character */
bp = bin_append_posn(125, 7, binary, bp); /* shift indicator */ bp = bin_append_posn(125, 7, binary, bp); /* shift indicator */
bp = add_shift_char(binary, bp, gbdata[sp], debug); bp = gm_add_shift_char(binary, bp, ddata[sp], debug_print);
} }
sp++; sp++;
@ -767,7 +751,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
if (current_mode == GM_BYTE) { if (current_mode == GM_BYTE) {
/* Add byte block length indicator */ /* Add byte block length indicator */
add_byte_count(binary, byte_count_posn, byte_count); gm_add_byte_count(binary, byte_count_posn, byte_count);
} }
/* Add "end of data" character */ /* Add "end of data" character */
@ -785,21 +769,58 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
break; break;
} }
if (bp > 9191) {
return ZINT_ERROR_TOO_LONG;
}
*p_bp = bp;
if (debug_print) {
printf("\nBinary (%d): %.*s\n", bp, bp, binary);
}
return 0;
}
static int gm_encode_segs(unsigned int ddata[], const struct zint_seg segs[], const int seg_count, char binary[],
const int reader, const struct zint_structapp *p_structapp, int *p_bin_len, const int debug_print) {
int i;
unsigned int *dd = ddata;
int bp = 0;
int p;
if (reader && (!p_structapp || p_structapp->index == 1)) { /* Appears only in 1st symbol if Structured Append */
bp = bin_append_posn(10, 4, binary, bp); /* FNC3 - Reader Initialisation */
}
if (p_structapp) {
bp = bin_append_posn(9, 4, binary, bp); /* FNC2 - Structured Append */
bp = bin_append_posn(to_int((const unsigned char *) p_structapp->id, (int) strlen(p_structapp->id)), 8,
binary, bp); /* File signature */
bp = bin_append_posn(p_structapp->count - 1, 4, binary, bp);
bp = bin_append_posn(p_structapp->index - 1, 4, binary, bp);
}
for (i = 0; i < seg_count; i++) {
int error_number = gm_encode(dd, segs[i].length, binary, segs[i].eci, &bp, debug_print);
if (error_number != 0) {
return error_number;
}
dd += segs[i].length;
}
/* Add padding bits if required */ /* Add padding bits if required */
p = 7 - (bp % 7); p = 7 - (bp % 7);
if (p % 7) { if (p % 7) {
bp = bin_append_posn(0, p, binary, bp); bp = bin_append_posn(0, p, binary, bp);
} }
/* Note bit-padding can't tip `bp` over max 9191 (1313 * 7) */
if (bp > 9191) { if (debug_print) {
return ZINT_ERROR_TOO_LONG; printf("\nBinary (%d): %.*s\n", bp, bp, binary);
} }
binary[bp] = '\0';
*bin_len = bp;
if (debug & ZINT_DEBUG_PRINT) { *p_bin_len = bp;
printf("\nBinary (%d): %s\n", bp, binary);
}
return 0; return 0;
} }
@ -893,7 +914,7 @@ static void gm_add_ecc(const char binary[], const int data_posn, const int layer
} }
} }
static void place_macromodule(char grid[], int x, int y, int word1, int word2, int size) { static void gm_place_macromodule(char grid[], int x, int y, int word1, int word2, int size) {
int i, j; int i, j;
i = (x * 6) + 1; i = (x * 6) + 1;
@ -943,20 +964,20 @@ static void place_macromodule(char grid[], int x, int y, int word1, int word2, i
} }
} }
static void place_data_in_grid(unsigned char word[], char grid[], int modules, int size) { static void gm_place_data_in_grid(unsigned char word[], char grid[], int modules, int size) {
int x, y, macromodule, offset; int x, y, macromodule, offset;
offset = 13 - ((modules - 1) / 2); offset = 13 - ((modules - 1) / 2);
for (y = 0; y < modules; y++) { for (y = 0; y < modules; y++) {
for (x = 0; x < modules; x++) { for (x = 0; x < modules; x++) {
macromodule = gm_macro_matrix[((y + offset) * 27) + (x + offset)]; macromodule = gm_macro_matrix[((y + offset) * 27) + (x + offset)];
place_macromodule(grid, x, y, word[macromodule * 2], word[(macromodule * 2) + 1], size); gm_place_macromodule(grid, x, y, word[macromodule * 2], word[(macromodule * 2) + 1], size);
} }
} }
} }
/* Place the layer ID into each macromodule */ /* Place the layer ID into each macromodule */
static void place_layer_id(char *grid, int size, int layers, int modules, int ecc_level) { static void gm_place_layer_id(char *grid, int size, int layers, int modules, int ecc_level) {
int i, j, layer, start, stop; int i, j, layer, start, stop;
#ifndef _MSC_VER #ifndef _MSC_VER
@ -1009,7 +1030,7 @@ static void place_layer_id(char *grid, int size, int layers, int modules, int ec
} }
} }
INTERNAL int gridmatrix(struct zint_symbol *symbol, unsigned char source[], int length) { INTERNAL int gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int warn_number = 0; int warn_number = 0;
int size, modules, error_number; int size, modules, error_number;
int auto_layers, min_layers, layers, auto_ecc_level, min_ecc_level, ecc_level; int auto_layers, min_layers, layers, auto_ecc_level, min_ecc_level, ecc_level;
@ -1022,42 +1043,52 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, unsigned char source[], int
const struct zint_structapp *p_structapp = NULL; const struct zint_structapp *p_structapp = NULL;
int size_squared; int size_squared;
int bin_len; int bin_len;
const int eci_length = get_eci_length(symbol->eci, source, length); const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
const int eci_length_segs = get_eci_length_segs(segs, seg_count);
#ifndef _MSC_VER #ifndef _MSC_VER
unsigned int gbdata[eci_length + 1]; struct zint_seg local_segs[seg_count];
unsigned int ddata[eci_length_segs];
#else #else
struct zint_seg *local_segs = (struct zint_seg *) _alloca(sizeof(struct zint_seg) * seg_count);
unsigned int *ddata = (unsigned int *) _alloca(sizeof(unsigned int) * eci_length_segs);
char *grid; char *grid;
unsigned int *gbdata = (unsigned int *) _alloca((eci_length + 1) * sizeof(unsigned int));
#endif #endif
segs_cpy(segs, seg_count, local_segs); /* Shallow copy (needed to set default ECIs & protect lengths) */
/* If ZINT_FULL_MULTIBYTE set use Hanzi mode in DATA_MODE or for non-GB 2312 in UNICODE_MODE */ /* If ZINT_FULL_MULTIBYTE set use Hanzi mode in DATA_MODE or for non-GB 2312 in UNICODE_MODE */
full_multibyte = (symbol->option_3 & 0xFF) == ZINT_FULL_MULTIBYTE; full_multibyte = (symbol->option_3 & 0xFF) == ZINT_FULL_MULTIBYTE;
if ((symbol->input_mode & 0x07) == DATA_MODE) { if ((symbol->input_mode & 0x07) == DATA_MODE) {
gb2312_cpy(source, &length, gbdata, full_multibyte); gb2312_cpy_segs(local_segs, seg_count, ddata, full_multibyte);
} else { } else {
int done = 0; unsigned int *dd = ddata;
if (symbol->eci != 29) { /* Unless ECI 29 (GB 2312) */ for (i = 0; i < seg_count; i++) {
/* Try other conversions (ECI 0 defaults to ISO/IEC 8859-1) */ int done = 0;
error_number = gb2312_utf8_to_eci(symbol->eci, source, &length, gbdata, full_multibyte); if (local_segs[i].eci != 29 || seg_count > 1) { /* Unless ECI 29 (GB 2312) or have multiple segments */
if (error_number == 0) { /* Try other conversions (ECI 0 defaults to ISO/IEC 8859-1) */
done = 1; error_number = gb2312_utf8_to_eci(local_segs[i].eci, local_segs[i].source, &local_segs[i].length,
} else if (symbol->eci) { dd, full_multibyte);
sprintf(symbol->errtxt, "535: Invalid character in input data for ECI %d", symbol->eci); if (error_number == 0) {
return error_number; done = 1;
} else if (local_segs[i].eci || seg_count > 1) {
sprintf(symbol->errtxt, "535: Invalid character in input data for ECI %d", local_segs[i].eci);
return error_number;
}
} }
} if (!done) {
if (!done) { /* Try GB 2312 (EUC-CN) */
/* Try GB 2312 (EUC-CN) */ error_number = gb2312_utf8(symbol, local_segs[i].source, &local_segs[i].length, dd);
error_number = gb2312_utf8(symbol, source, &length, gbdata); if (error_number != 0) {
if (error_number != 0) { return error_number;
return error_number; }
} if (local_segs[i].eci != 29) {
if (symbol->eci != 29) { strcpy(symbol->errtxt, "540: Converted to GB 2312 but no ECI specified");
strcpy(symbol->errtxt, "540: Converted to GB 2312 but no ECI specified"); warn_number = ZINT_WARN_NONCOMPLIANT;
warn_number = ZINT_WARN_NONCOMPLIANT; }
} }
dd += local_segs[i].length;
} }
} }
@ -1100,7 +1131,7 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, unsigned char source[], int
return ZINT_ERROR_INVALID_OPTION; return ZINT_ERROR_INVALID_OPTION;
} }
error_number = gm_encode(gbdata, length, binary, reader, p_structapp, symbol->eci, &bin_len, symbol->debug); error_number = gm_encode_segs(ddata, local_segs, seg_count, binary, reader, p_structapp, &bin_len, debug_print);
if (error_number != 0) { if (error_number != 0) {
strcpy(symbol->errtxt, "531: Input data too long"); strcpy(symbol->errtxt, "531: Input data too long");
return error_number; return error_number;
@ -1205,8 +1236,8 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, unsigned char source[], int
memset(grid, '0', size_squared); memset(grid, '0', size_squared);
place_data_in_grid(word, grid, modules, size); gm_place_data_in_grid(word, grid, modules, size);
place_layer_id(grid, size, layers, modules, ecc_level); gm_place_layer_id(grid, size, layers, modules, ecc_level);
/* Add macromodule frames */ /* Add macromodule frames */
for (x = 0; x < modules; x++) { for (x = 0; x < modules; x++) {

View File

@ -1,7 +1,7 @@
/* gridmtx.h - definitions for Grid Matrix /* gridmtx.h - definitions for Grid Matrix
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -28,7 +28,9 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#ifndef Z_GRIDMTX_H
#define Z_GRIDMTX_H
static const char gm_shift_set[] = { static const char gm_shift_set[] = {
/* From Table 7 - Encoding of control characters */ /* From Table 7 - Encoding of control characters */
@ -38,15 +40,15 @@ static const char gm_shift_set[] = {
';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~'
}; };
static const unsigned short int gm_recommend_cw[] = { static const unsigned short gm_recommend_cw[] = {
9, 30, 59, 114, 170, 237, 315, 405, 506, 618, 741, 875, 1021 9, 30, 59, 114, 170, 237, 315, 405, 506, 618, 741, 875, 1021
}; };
static const unsigned short int gm_max_cw[] = { static const unsigned short gm_max_cw[] = {
11, 40, 79, 146, 218, 305, 405, 521, 650, 794, 953, 1125, 1313 11, 40, 79, 146, 218, 305, 405, 521, 650, 794, 953, 1125, 1313
}; };
static const unsigned short int gm_data_codewords[] = { static const unsigned short gm_data_codewords[] = {
0, 15, 13, 11, 9, 0, 15, 13, 11, 9,
45, 40, 35, 30, 25, 45, 40, 35, 30, 25,
89, 79, 69, 59, 49, 89, 79, 69, 59, 49,
@ -144,7 +146,7 @@ static const char gm_ebeb[] = {
61, 9, 60, 3 61, 9, 60, 3
}; };
static const unsigned short int gm_macro_matrix[] = { static const unsigned short gm_macro_matrix[] = {
728, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 728, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650,
727, 624, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 651, 727, 624, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 651,
726, 623, 528, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 553, 652, 726, 623, 528, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 553, 652,
@ -153,16 +155,16 @@ static const unsigned short int gm_macro_matrix[] = {
723, 620, 525, 438, 359, 288, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 307, 382, 465, 556, 655, 723, 620, 525, 438, 359, 288, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 307, 382, 465, 556, 655,
722, 619, 524, 437, 358, 287, 224, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 241, 308, 383, 466, 557, 656, 722, 619, 524, 437, 358, 287, 224, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 241, 308, 383, 466, 557, 656,
721, 618, 523, 436, 357, 286, 223, 168, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 183, 242, 309, 384, 467, 558, 657, 721, 618, 523, 436, 357, 286, 223, 168, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 183, 242, 309, 384, 467, 558, 657,
720, 617, 522, 435, 356, 285, 222, 167, 120, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 133, 184, 243, 310, 385, 468, 559, 658, 720, 617, 522, 435, 356, 285, 222, 167, 120, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 133, 184, 243, 310, 385, 468, 559, 658,
719, 616, 521, 434, 355, 284, 221, 166, 119, 80, 49, 50, 51, 52, 53, 54, 55, 56, 91, 134, 185, 244, 311, 386, 469, 560, 659, 719, 616, 521, 434, 355, 284, 221, 166, 119, 80, 49, 50, 51, 52, 53, 54, 55, 56, 91, 134, 185, 244, 311, 386, 469, 560, 659,
718, 615, 520, 433, 354, 283, 220, 165, 118, 79, 48, 25, 26, 27, 28, 29, 30, 57, 92, 135, 186, 245, 312, 387, 470, 561, 660, 718, 615, 520, 433, 354, 283, 220, 165, 118, 79, 48, 25, 26, 27, 28, 29, 30, 57, 92, 135, 186, 245, 312, 387, 470, 561, 660,
717, 614, 519, 432, 353, 282, 219, 164, 117, 78, 47, 24, 9, 10, 11, 12, 31, 58, 93, 136, 187, 246, 313, 388, 471, 562, 661, 717, 614, 519, 432, 353, 282, 219, 164, 117, 78, 47, 24, 9, 10, 11, 12, 31, 58, 93, 136, 187, 246, 313, 388, 471, 562, 661,
716, 613, 518, 431, 352, 281, 218, 163, 116, 77, 46, 23, 8, 1, 2, 13, 32, 59, 94, 137, 188, 247, 314, 389, 472, 563, 662, 716, 613, 518, 431, 352, 281, 218, 163, 116, 77, 46, 23, 8, 1, 2, 13, 32, 59, 94, 137, 188, 247, 314, 389, 472, 563, 662,
715, 612, 517, 430, 351, 280, 217, 162, 115, 76, 45, 22, 7, 0, 3, 14, 33, 60, 95, 138, 189, 248, 315, 390, 473, 564, 663, 715, 612, 517, 430, 351, 280, 217, 162, 115, 76, 45, 22, 7, 0, 3, 14, 33, 60, 95, 138, 189, 248, 315, 390, 473, 564, 663,
714, 611, 516, 429, 350, 279, 216, 161, 114, 75, 44, 21, 6, 5, 4, 15, 34, 61, 96, 139, 190, 249, 316, 391, 474, 565, 664, 714, 611, 516, 429, 350, 279, 216, 161, 114, 75, 44, 21, 6, 5, 4, 15, 34, 61, 96, 139, 190, 249, 316, 391, 474, 565, 664,
713, 610, 515, 428, 349, 278, 215, 160, 113, 74, 43, 20, 19, 18, 17, 16, 35, 62, 97, 140, 191, 250, 317, 392, 475, 566, 665, 713, 610, 515, 428, 349, 278, 215, 160, 113, 74, 43, 20, 19, 18, 17, 16, 35, 62, 97, 140, 191, 250, 317, 392, 475, 566, 665,
712, 609, 514, 427, 348, 277, 214, 159, 112, 73, 42, 41, 40, 39, 38, 37, 36, 63, 98, 141, 192, 251, 318, 393, 476, 567, 666, 712, 609, 514, 427, 348, 277, 214, 159, 112, 73, 42, 41, 40, 39, 38, 37, 36, 63, 98, 141, 192, 251, 318, 393, 476, 567, 666,
711, 608, 513, 426, 347, 276, 213, 158, 111, 72, 71, 70, 69, 68, 67, 66, 65, 64, 99, 142, 193, 252, 319, 394, 477, 568, 667, 711, 608, 513, 426, 347, 276, 213, 158, 111, 72, 71, 70, 69, 68, 67, 66, 65, 64, 99, 142, 193, 252, 319, 394, 477, 568, 667,
710, 607, 512, 425, 346, 275, 212, 157, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 143, 194, 253, 320, 395, 478, 569, 668, 710, 607, 512, 425, 346, 275, 212, 157, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 143, 194, 253, 320, 395, 478, 569, 668,
709, 606, 511, 424, 345, 274, 211, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 195, 254, 321, 396, 479, 570, 669, 709, 606, 511, 424, 345, 274, 211, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 195, 254, 321, 396, 479, 570, 669,
708, 605, 510, 423, 344, 273, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, 255, 322, 397, 480, 571, 670, 708, 605, 510, 423, 344, 273, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, 255, 322, 397, 480, 571, 670,
@ -174,3 +176,5 @@ static const unsigned short int gm_macro_matrix[] = {
702, 701, 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, 687, 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, 676, 702, 701, 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, 687, 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, 676,
}; };
/* vim: set ts=4 sw=4 et : */
#endif /* Z_GRIDMTX_H */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -29,9 +29,8 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */ #ifndef Z_GS1_H
#ifndef __GS1_H #define Z_GS1_H
#define __GS1_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -45,4 +44,5 @@ INTERNAL char gs1_check_digit(const unsigned char source[], const int src_len);
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __GS1_H */ /* vim: set ts=4 sw=4 et : */
#endif /* Z_GS1_H */

View File

@ -45,7 +45,7 @@
#include <assert.h> #include <assert.h>
/* Find which submode to use for a text character */ /* Find which submode to use for a text character */
static int getsubmode(const unsigned int input) { static int hx_getsubmode(const unsigned int input) {
if ((input >= '0') && (input <= '9')) { if ((input >= '0') && (input <= '9')) {
return 1; return 1;
@ -63,7 +63,7 @@ static int getsubmode(const unsigned int input) {
} }
/* Return length of terminator for encoding mode */ /* Return length of terminator for encoding mode */
static int terminator_length(const char mode) { static int hx_terminator_length(const char mode) {
int result = 0; int result = 0;
switch (mode) { switch (mode) {
@ -86,7 +86,7 @@ static int terminator_length(const char mode) {
} }
/* Calculate the length of the binary string */ /* Calculate the length of the binary string */
static int calculate_binlength(const char mode[], const unsigned int source[], const int length, const int eci) { static int hx_calc_binlen(const char mode[], const unsigned int ddata[], const int length, const int eci) {
int i; int i;
char lastmode = '\0'; char lastmode = '\0';
int est_binlen = 0; int est_binlen = 0;
@ -108,7 +108,7 @@ static int calculate_binlength(const char mode[], const unsigned int source[], c
do { do {
if (mode[i] != lastmode) { if (mode[i] != lastmode) {
if (i > 0) { if (i > 0) {
est_binlen += terminator_length(lastmode); est_binlen += hx_terminator_length(lastmode);
} }
/* GB 4-byte has indicator for each character (and no terminator) so not included here */ /* GB 4-byte has indicator for each character (and no terminator) so not included here */
/* Region1/Region2 have special terminator to go directly into each other's mode so not included here */ /* Region1/Region2 have special terminator to go directly into each other's mode so not included here */
@ -130,14 +130,14 @@ static int calculate_binlength(const char mode[], const unsigned int source[], c
numeric_run++; numeric_run++;
break; break;
case 't': case 't':
if (getsubmode(source[i]) != submode) { if (hx_getsubmode(ddata[i]) != submode) {
est_binlen += 6; est_binlen += 6;
submode = getsubmode(source[i]); submode = hx_getsubmode(ddata[i]);
} }
est_binlen += 6; est_binlen += 6;
break; break;
case 'b': case 'b':
est_binlen += source[i] > 0xFF ? 16 : 8; est_binlen += ddata[i] > 0xFF ? 16 : 8;
break; break;
case '1': case '1':
case '2': case '2':
@ -154,12 +154,29 @@ static int calculate_binlength(const char mode[], const unsigned int source[], c
i++; i++;
} while (i < length); } while (i < length);
est_binlen += terminator_length(lastmode); est_binlen += hx_terminator_length(lastmode);
return est_binlen; return est_binlen;
} }
static int isRegion1(const unsigned int glyph) { /* Call `hx_calc_binlen()` for each segment */
static int hx_calc_binlen_segs(const char mode[], const unsigned int ddata[], const struct zint_seg segs[],
const int seg_count) {
int i;
int count = 0;
const unsigned int *dd = ddata;
const char *m = mode;
for (i = 0; i < seg_count; i++) {
count += hx_calc_binlen(m, dd, segs[i].length, segs[i].eci);
m += segs[i].length;
dd += segs[i].length;
}
return count;
}
static int hx_isRegion1(const unsigned int glyph) {
unsigned int byte; unsigned int byte;
byte = glyph >> 8; byte = glyph >> 8;
@ -181,7 +198,7 @@ static int isRegion1(const unsigned int glyph) {
return 0; return 0;
} }
static int isRegion2(const unsigned int glyph) { static int hx_isRegion2(const unsigned int glyph) {
unsigned int byte; unsigned int byte;
byte = glyph >> 8; byte = glyph >> 8;
@ -196,7 +213,7 @@ static int isRegion2(const unsigned int glyph) {
return 0; return 0;
} }
static int isDoubleByte(const unsigned int glyph) { static int hx_isDoubleByte(const unsigned int glyph) {
unsigned int byte; unsigned int byte;
byte = glyph >> 8; byte = glyph >> 8;
@ -214,7 +231,7 @@ static int isDoubleByte(const unsigned int glyph) {
return 0; return 0;
} }
static int isFourByte(const unsigned int glyph, const unsigned int glyph2) { static int hx_isFourByte(const unsigned int glyph, const unsigned int glyph2) {
unsigned int byte; unsigned int byte;
byte = glyph >> 8; byte = glyph >> 8;
@ -236,7 +253,7 @@ static int isFourByte(const unsigned int glyph, const unsigned int glyph2) {
} }
/* Convert Text 1 sub-mode character to encoding value, as given in table 3 */ /* Convert Text 1 sub-mode character to encoding value, as given in table 3 */
static int lookup_text1(const unsigned int input) { static int hx_lookup_text1(const unsigned int input) {
if ((input >= '0') && (input <= '9')) { if ((input >= '0') && (input <= '9')) {
return input - '0'; return input - '0';
@ -254,7 +271,7 @@ static int lookup_text1(const unsigned int input) {
} }
/* Convert Text 2 sub-mode character to encoding value, as given in table 4 */ /* Convert Text 2 sub-mode character to encoding value, as given in table 4 */
static int lookup_text2(const unsigned int input) { static int hx_lookup_text2(const unsigned int input) {
if (input <= 27) { if (input <= 27) {
return input; return input;
@ -286,7 +303,7 @@ static int lookup_text2(const unsigned int input) {
/* Whether in numeric or not. If in numeric, *p_end is set to position after numeric, /* Whether in numeric or not. If in numeric, *p_end is set to position after numeric,
* and *p_cost is set to per-numeric cost */ * and *p_cost is set to per-numeric cost */
static int in_numeric(const unsigned int gbdata[], const int length, const int in_posn, static int hx_in_numeric(const unsigned int ddata[], const int length, const int in_posn,
unsigned int *p_end, unsigned int *p_cost) { unsigned int *p_end, unsigned int *p_cost) {
int i, digit_cnt; int i, digit_cnt;
@ -295,7 +312,7 @@ static int in_numeric(const unsigned int gbdata[], const int length, const int i
} }
/* Attempt to calculate the average 'cost' of using numeric mode in number of bits (times HX_MULT) */ /* Attempt to calculate the average 'cost' of using numeric mode in number of bits (times HX_MULT) */
for (i = in_posn; i < length && i < in_posn + 4 && gbdata[i] >= '0' && gbdata[i] <= '9'; i++); for (i = in_posn; i < length && i < in_posn + 4 && ddata[i] >= '0' && ddata[i] <= '9'; i++);
digit_cnt = i - in_posn; digit_cnt = i - in_posn;
@ -311,13 +328,13 @@ static int in_numeric(const unsigned int gbdata[], const int length, const int i
/* Whether in four-byte or not. If in four-byte, *p_fourbyte is set to position after four-byte, /* Whether in four-byte or not. If in four-byte, *p_fourbyte is set to position after four-byte,
* and *p_fourbyte_cost is set to per-position cost */ * and *p_fourbyte_cost is set to per-position cost */
static int in_fourbyte(const unsigned int gbdata[], const int length, const int in_posn, static int hx_in_fourbyte(const unsigned int ddata[], const int length, const int in_posn,
unsigned int *p_end, unsigned int *p_cost) { unsigned int *p_end, unsigned int *p_cost) {
if (in_posn < (int) *p_end) { if (in_posn < (int) *p_end) {
return 1; return 1;
} }
if (in_posn == length - 1 || !isFourByte(gbdata[in_posn], gbdata[in_posn + 1])) { if (in_posn == length - 1 || !hx_isFourByte(ddata[in_posn], ddata[in_posn + 1])) {
*p_end = 0; *p_end = 0;
return 0; return 0;
} }
@ -340,7 +357,7 @@ static int in_fourbyte(const unsigned int gbdata[], const int length, const int
/* Calculate optimized encoding modes. Adapted from Project Nayuki */ /* Calculate optimized encoding modes. Adapted from Project Nayuki */
/* Copyright (c) Project Nayuki. (MIT License) See qr.c for detailed notice */ /* Copyright (c) Project Nayuki. (MIT License) See qr.c for detailed notice */
static void hx_define_mode(char *mode, const unsigned int gbdata[], const int length, const int debug) { static void hx_define_mode(char *mode, const unsigned int ddata[], const int length, const int debug_print) {
/* Must be in same order as HX_N etc */ /* Must be in same order as HX_N etc */
static const char mode_types[] = { 'n', 't', 'b', '1', '2', 'd', 'f', '\0' }; static const char mode_types[] = { 'n', 't', 'b', '1', '2', 'd', 'f', '\0' };
@ -394,14 +411,14 @@ static void hx_define_mode(char *mode, const unsigned int gbdata[], const int le
for (i = 0, cm_i = 0; i < length; i++, cm_i += HX_NUM_MODES) { for (i = 0, cm_i = 0; i < length; i++, cm_i += HX_NUM_MODES) {
memset(cur_costs, 0, HX_NUM_MODES * sizeof(unsigned int)); memset(cur_costs, 0, HX_NUM_MODES * sizeof(unsigned int));
if (in_numeric(gbdata, length, i, &numeric_end, &numeric_cost)) { if (hx_in_numeric(ddata, length, i, &numeric_end, &numeric_cost)) {
cur_costs[HX_N] = prev_costs[HX_N] + numeric_cost; cur_costs[HX_N] = prev_costs[HX_N] + numeric_cost;
char_modes[cm_i + HX_N] = 'n'; char_modes[cm_i + HX_N] = 'n';
text1 = 1; text1 = 1;
text2 = 0; text2 = 0;
} else { } else {
text1 = lookup_text1(gbdata[i]) != -1; text1 = hx_lookup_text1(ddata[i]) != -1;
text2 = lookup_text2(gbdata[i]) != -1; text2 = hx_lookup_text2(ddata[i]) != -1;
} }
if (text1 || text2) { if (text1 || text2) {
@ -417,20 +434,20 @@ static void hx_define_mode(char *mode, const unsigned int gbdata[], const int le
} }
/* Binary mode can encode anything */ /* Binary mode can encode anything */
cur_costs[HX_B] = prev_costs[HX_B] + (gbdata[i] > 0xFF ? 96 : 48); /* (16 : 8) * HX_MULT */ cur_costs[HX_B] = prev_costs[HX_B] + (ddata[i] > 0xFF ? 96 : 48); /* (16 : 8) * HX_MULT */
char_modes[cm_i + HX_B] = 'b'; char_modes[cm_i + HX_B] = 'b';
if (in_fourbyte(gbdata, length, i, &fourbyte_end, &fourbyte_cost)) { if (hx_in_fourbyte(ddata, length, i, &fourbyte_end, &fourbyte_cost)) {
cur_costs[HX_F] = prev_costs[HX_F] + fourbyte_cost; cur_costs[HX_F] = prev_costs[HX_F] + fourbyte_cost;
char_modes[cm_i + HX_F] = 'f'; char_modes[cm_i + HX_F] = 'f';
} else { } else {
if (isDoubleByte(gbdata[i])) { if (hx_isDoubleByte(ddata[i])) {
cur_costs[HX_D] = prev_costs[HX_D] + 90; /* 15 * HX_MULT */ cur_costs[HX_D] = prev_costs[HX_D] + 90; /* 15 * HX_MULT */
char_modes[cm_i + HX_D] = 'd'; char_modes[cm_i + HX_D] = 'd';
if (isRegion1(gbdata[i])) { /* Subset */ if (hx_isRegion1(ddata[i])) { /* Subset */
cur_costs[HX_1] = prev_costs[HX_1] + 72; /* 12 * HX_MULT */ cur_costs[HX_1] = prev_costs[HX_1] + 72; /* 12 * HX_MULT */
char_modes[cm_i + HX_1] = '1'; char_modes[cm_i + HX_1] = '1';
} else if (isRegion2(gbdata[i])) { /* Subset */ } else if (hx_isRegion2(ddata[i])) { /* Subset */
cur_costs[HX_2] = prev_costs[HX_2] + 72; /* 12 * HX_MULT */ cur_costs[HX_2] = prev_costs[HX_2] + 72; /* 12 * HX_MULT */
char_modes[cm_i + HX_2] = '2'; char_modes[cm_i + HX_2] = '2';
} }
@ -478,21 +495,35 @@ static void hx_define_mode(char *mode, const unsigned int gbdata[], const int le
mode[i] = cur_mode; mode[i] = cur_mode;
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf(" Mode: %.*s\n", length, mode); printf(" Mode: %.*s\n", length, mode);
} }
} }
/* Call `hx_define_mode()` for each segment */
static void hx_define_mode_segs(char mode[], const unsigned int ddata[], const struct zint_seg segs[],
const int seg_count, const int debug_print) {
int i;
const unsigned int *dd = ddata;
char *m = mode;
for (i = 0; i < seg_count; i++) {
hx_define_mode(m, dd, segs[i].length, debug_print);
m += segs[i].length;
dd += segs[i].length;
}
}
/* Convert input data to binary stream */ /* Convert input data to binary stream */
static void calculate_binary(char binary[], const char mode[], unsigned int source[], const int length, const int eci, static void hx_calculate_binary(char binary[], const char mode[], const unsigned int ddata[], const int length,
int *bin_len, const int debug) { const int eci, int *p_bp, const int debug_print) {
int position = 0; int position = 0;
int i, count, encoding_value; int i, count, encoding_value;
int first_byte, second_byte; int first_byte, second_byte;
int third_byte, fourth_byte; int third_byte, fourth_byte;
int glyph; int glyph;
int submode; int submode;
int bp = 0; int bp = *p_bp;
if (eci != 0) { if (eci != 0) {
/* Encoding ECI assignment number, according to Table 5 */ /* Encoding ECI assignment number, according to Table 5 */
@ -512,7 +543,7 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
int block_length = 0; int block_length = 0;
int double_byte = 0; int double_byte = 0;
do { do {
if (mode[position] == 'b' && source[position + block_length] > 0xFF) { if (mode[position] == 'b' && ddata[position + block_length] > 0xFF) {
double_byte++; double_byte++;
} }
block_length++; block_length++;
@ -524,7 +555,7 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
/* Mode indicator */ /* Mode indicator */
bp = bin_append_posn(1, 4, binary, bp); bp = bin_append_posn(1, 4, binary, bp);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Numeric\n"); printf("Numeric\n");
} }
@ -532,17 +563,17 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
i = 0; i = 0;
while (i < block_length) { while (i < block_length) {
const int first = ctoi((const char) source[position + i]); const int first = ctoi((const char) ddata[position + i]);
count = 1; count = 1;
encoding_value = first; encoding_value = first;
if (i + 1 < block_length && mode[position + i + 1] == 'n') { if (i + 1 < block_length && mode[position + i + 1] == 'n') {
const int second = ctoi((const char) source[position + i + 1]); const int second = ctoi((const char) ddata[position + i + 1]);
count = 2; count = 2;
encoding_value = (encoding_value * 10) + second; encoding_value = (encoding_value * 10) + second;
if (i + 2 < block_length && mode[position + i + 2] == 'n') { if (i + 2 < block_length && mode[position + i + 2] == 'n') {
const int third = ctoi((const char) source[position + i + 2]); const int third = ctoi((const char) ddata[position + i + 2]);
count = 3; count = 3;
encoding_value = (encoding_value * 10) + third; encoding_value = (encoding_value * 10) + third;
} }
@ -550,7 +581,7 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
bp = bin_append_posn(encoding_value, 10, binary, bp); bp = bin_append_posn(encoding_value, 10, binary, bp);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("0x%3x (%d)", encoding_value, encoding_value); printf("0x%3x (%d)", encoding_value, encoding_value);
} }
@ -570,7 +601,7 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
break; break;
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf(" (TERM %d)\n", count); printf(" (TERM %d)\n", count);
} }
@ -580,7 +611,7 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
/* Mode indicator */ /* Mode indicator */
bp = bin_append_posn(2, 4, binary, bp); bp = bin_append_posn(2, 4, binary, bp);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Text\n"); printf("Text\n");
} }
@ -590,25 +621,25 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
while (i < block_length) { while (i < block_length) {
if (getsubmode(source[i + position]) != submode) { if (hx_getsubmode(ddata[i + position]) != submode) {
/* Change submode */ /* Change submode */
bp = bin_append_posn(62, 6, binary, bp); bp = bin_append_posn(62, 6, binary, bp);
submode = getsubmode(source[i + position]); submode = hx_getsubmode(ddata[i + position]);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("SWITCH "); printf("SWITCH ");
} }
} }
if (submode == 1) { if (submode == 1) {
encoding_value = lookup_text1(source[i + position]); encoding_value = hx_lookup_text1(ddata[i + position]);
} else { } else {
encoding_value = lookup_text2(source[i + position]); encoding_value = hx_lookup_text2(ddata[i + position]);
} }
bp = bin_append_posn(encoding_value, 6, binary, bp); bp = bin_append_posn(encoding_value, 6, binary, bp);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("%.2x [ASC %.2x] ", encoding_value, source[i + position]); printf("%.2x [ASC %.2x] ", encoding_value, ddata[i + position]);
} }
i++; i++;
} }
@ -616,7 +647,7 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
/* Terminator */ /* Terminator */
bp = bin_append_posn(63, 6, binary, bp); bp = bin_append_posn(63, 6, binary, bp);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("\n"); printf("\n");
} }
break; break;
@ -628,7 +659,7 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
/* Count indicator */ /* Count indicator */
bp = bin_append_posn(block_length + double_byte, 13, binary, bp); bp = bin_append_posn(block_length + double_byte, 13, binary, bp);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Binary Mode (%d):", block_length + double_byte); printf("Binary Mode (%d):", block_length + double_byte);
} }
@ -637,35 +668,35 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
while (i < block_length) { while (i < block_length) {
/* 8-bit bytes with no conversion */ /* 8-bit bytes with no conversion */
bp = bin_append_posn(source[i + position], source[i + position] > 0xFF ? 16 : 8, binary, bp); bp = bin_append_posn(ddata[i + position], ddata[i + position] > 0xFF ? 16 : 8, binary, bp);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf(" %02x", (int) source[i + position]); printf(" %02x", (int) ddata[i + position]);
} }
i++; i++;
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("\n"); printf("\n");
} }
break; break;
case '1': case '1':
/* Region 1 encoding */ /* Region One encoding */
/* Mode indicator */ /* Mode indicator */
if (position == 0 || mode[position - 1] != '2') { /* Unless previous mode Region 2 */ if (position == 0 || mode[position - 1] != '2') { /* Unless previous mode Region Two */
bp = bin_append_posn(4, 4, binary, bp); bp = bin_append_posn(4, 4, binary, bp);
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Region 1%s\n", position == 0 || mode[position - 1] != '2' ? "" : " (NO indicator)" ); printf("Region One%s\n", position == 0 || mode[position - 1] != '2' ? "" : " (NO indicator)" );
} }
i = 0; i = 0;
while (i < block_length) { while (i < block_length) {
first_byte = (source[i + position] & 0xff00) >> 8; first_byte = (ddata[i + position] & 0xff00) >> 8;
second_byte = source[i + position] & 0xff; second_byte = ddata[i + position] & 0xff;
/* Subset 1 */ /* Subset 1 */
glyph = (0x5e * (first_byte - 0xb0)) + (second_byte - 0xa1); glyph = (0x5e * (first_byte - 0xb0)) + (second_byte - 0xa1);
@ -678,12 +709,12 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
} }
/* Subset 3 */ /* Subset 3 */
if ((source[i + position] >= 0xa8a1) && (source[i + position] <= 0xa8c0)) { if ((ddata[i + position] >= 0xa8a1) && (ddata[i + position] <= 0xa8c0)) {
glyph = (second_byte - 0xa1) + 0xfca; glyph = (second_byte - 0xa1) + 0xfca;
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("%.3x [GB %.4x] ", glyph, source[i + position]); printf("%.3x [GB %.4x] ", glyph, ddata[i + position]);
} }
bp = bin_append_posn(glyph, 12, binary, bp); bp = bin_append_posn(glyph, 12, binary, bp);
@ -694,33 +725,33 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
bp = bin_append_posn(position + block_length == length || mode[position + block_length] != '2' bp = bin_append_posn(position + block_length == length || mode[position + block_length] != '2'
? 4095 : 4094, 12, binary, bp); ? 4095 : 4094, 12, binary, bp);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("(TERM %x)\n", position + block_length == length || mode[position + block_length] != '2' printf("(TERM %x)\n", position + block_length == length || mode[position + block_length] != '2'
? 4095 : 4094); ? 4095 : 4094);
} }
break; break;
case '2': case '2':
/* Region 2 encoding */ /* Region Two encoding */
/* Mode indicator */ /* Mode indicator */
if (position == 0 || mode[position - 1] != '1') { /* Unless previous mode Region 1 */ if (position == 0 || mode[position - 1] != '1') { /* Unless previous mode Region One */
bp = bin_append_posn(5, 4, binary, bp); bp = bin_append_posn(5, 4, binary, bp);
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Region 2%s\n", position == 0 || mode[position - 1] != '1' ? "" : " (NO indicator)" ); printf("Region Two%s\n", position == 0 || mode[position - 1] != '1' ? "" : " (NO indicator)" );
} }
i = 0; i = 0;
while (i < block_length) { while (i < block_length) {
first_byte = (source[i + position] & 0xff00) >> 8; first_byte = (ddata[i + position] & 0xff00) >> 8;
second_byte = source[i + position] & 0xff; second_byte = ddata[i + position] & 0xff;
glyph = (0x5e * (first_byte - 0xd8)) + (second_byte - 0xa1); glyph = (0x5e * (first_byte - 0xd8)) + (second_byte - 0xa1);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("%.3x [GB %.4x] ", glyph, source[i + position]); printf("%.3x [GB %.4x] ", glyph, ddata[i + position]);
} }
bp = bin_append_posn(glyph, 12, binary, bp); bp = bin_append_posn(glyph, 12, binary, bp);
@ -731,7 +762,7 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
bp = bin_append_posn(position + block_length == length || mode[position + block_length] != '1' bp = bin_append_posn(position + block_length == length || mode[position + block_length] != '1'
? 4095 : 4094, 12, binary, bp); ? 4095 : 4094, 12, binary, bp);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("(TERM %x)\n", position + block_length == length || mode[position + block_length] != '1' printf("(TERM %x)\n", position + block_length == length || mode[position + block_length] != '1'
? 4095 : 4094); ? 4095 : 4094);
} }
@ -742,15 +773,15 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
/* Mode indicator */ /* Mode indicator */
bp = bin_append_posn(6, 4, binary, bp); bp = bin_append_posn(6, 4, binary, bp);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Double byte\n"); printf("Double byte\n");
} }
i = 0; i = 0;
while (i < block_length) { while (i < block_length) {
first_byte = (source[i + position] & 0xff00) >> 8; first_byte = (ddata[i + position] & 0xff00) >> 8;
second_byte = source[i + position] & 0xff; second_byte = ddata[i + position] & 0xff;
if (second_byte <= 0x7e) { if (second_byte <= 0x7e) {
glyph = (0xbe * (first_byte - 0x81)) + (second_byte - 0x40); glyph = (0xbe * (first_byte - 0x81)) + (second_byte - 0x40);
@ -758,7 +789,7 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
glyph = (0xbe * (first_byte - 0x81)) + (second_byte - 0x41); glyph = (0xbe * (first_byte - 0x81)) + (second_byte - 0x41);
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("%.4x ", glyph); printf("%.4x ", glyph);
} }
@ -771,13 +802,13 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
/* Terminator sequence of length 12 is a mistake /* Terminator sequence of length 12 is a mistake
- confirmed by Wang Yi */ - confirmed by Wang Yi */
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("\n"); printf("\n");
} }
break; break;
case 'f': case 'f':
/* Four-byte encoding */ /* Four-byte encoding */
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Four byte\n"); printf("Four byte\n");
} }
@ -788,15 +819,15 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
/* Mode indicator */ /* Mode indicator */
bp = bin_append_posn(7, 4, binary, bp); bp = bin_append_posn(7, 4, binary, bp);
first_byte = (source[i + position] & 0xff00) >> 8; first_byte = (ddata[i + position] & 0xff00) >> 8;
second_byte = source[i + position] & 0xff; second_byte = ddata[i + position] & 0xff;
third_byte = (source[i + position + 1] & 0xff00) >> 8; third_byte = (ddata[i + position + 1] & 0xff00) >> 8;
fourth_byte = source[i + position + 1] & 0xff; fourth_byte = ddata[i + position + 1] & 0xff;
glyph = (0x3138 * (first_byte - 0x81)) + (0x04ec * (second_byte - 0x30)) + glyph = (0x3138 * (first_byte - 0x81)) + (0x04ec * (second_byte - 0x30)) +
(0x0a * (third_byte - 0x81)) + (fourth_byte - 0x30); (0x0a * (third_byte - 0x81)) + (fourth_byte - 0x30);
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("%d ", glyph); printf("%d ", glyph);
} }
@ -806,7 +837,7 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
/* No terminator */ /* No terminator */
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("\n"); printf("\n");
} }
break; break;
@ -816,11 +847,26 @@ static void calculate_binary(char binary[], const char mode[], unsigned int sour
} while (position < length); } while (position < length);
binary[bp] = '\0'; if (debug_print) printf("Binary (%d): %.*s\n", bp, bp, binary);
if (debug & ZINT_DEBUG_PRINT) printf("Binary (%d): %s\n", bp, binary); *p_bp = bp;
}
*bin_len = bp; /* Call `hx_calculate_binary()` for each segment */
static void hx_calculate_binary_segs(char binary[], const char mode[], const unsigned int ddata[],
const struct zint_seg segs[], const int seg_count, int *p_bin_len, const int debug_print) {
int i;
const unsigned int *dd = ddata;
const char *m = mode;
int bp = 0;
for (i = 0; i < seg_count; i++) {
hx_calculate_binary(binary, m, dd, segs[i].length, segs[i].eci, &bp, debug_print);
m += segs[i].length;
dd += segs[i].length;
}
*p_bin_len = bp;
} }
/* Finder pattern for top left of symbol */ /* Finder pattern for top left of symbol */
@ -1111,7 +1157,7 @@ static void hx_add_ecc(unsigned char fullstream[], const unsigned char datastrea
} }
static void hx_set_function_info(unsigned char *grid, const int size, const int version, const int ecc_level, static void hx_set_function_info(unsigned char *grid, const int size, const int version, const int ecc_level,
const int bitmask, const int debug) { const int bitmask, const int debug_print) {
int i, j; int i, j;
char function_information[34]; char function_information[34];
unsigned char fi_cw[3] = {0}; unsigned char fi_cw[3] = {0};
@ -1148,7 +1194,7 @@ static void hx_set_function_info(unsigned char *grid, const int size, const int
function_information[i] = '0'; function_information[i] = '0';
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Version: %d, ECC: %d, Mask: %d, Structural Info: %.34s\n", version, ecc_level, bitmask, printf("Version: %d, ECC: %d, Mask: %d, Structural Info: %.34s\n", version, ecc_level, bitmask,
function_information); function_information);
} }
@ -1175,7 +1221,8 @@ static void hx_set_function_info(unsigned char *grid, const int size, const int
} }
/* Rearrange data in batches of 13 codewords (section 5.8.2) */ /* Rearrange data in batches of 13 codewords (section 5.8.2) */
static void make_picket_fence(const unsigned char fullstream[], unsigned char picket_fence[], const int streamsize) { static void hx_make_picket_fence(const unsigned char fullstream[], unsigned char picket_fence[],
const int streamsize) {
int i, start; int i, start;
int output_position = 0; int output_position = 0;
@ -1340,7 +1387,7 @@ static int hx_evaluate(const unsigned char *local, const int size) {
/* TODO: Haven't been able to replicate (or even get close to) the penalty scores in ISO/IEC 20830:2021 /* TODO: Haven't been able to replicate (or even get close to) the penalty scores in ISO/IEC 20830:2021
* Annex K examples */ * Annex K examples */
static void hx_apply_bitmask(unsigned char *grid, const int size, const int version, const int ecc_level, static void hx_apply_bitmask(unsigned char *grid, const int size, const int version, const int ecc_level,
const int user_mask, const int debug) { const int user_mask, const int debug_print) {
int x, y; int x, y;
int i, j, r, k; int i, j, r, k;
int pattern, penalty[4] = {0}; int pattern, penalty[4] = {0};
@ -1390,7 +1437,7 @@ static void hx_apply_bitmask(unsigned char *grid, const int size, const int vers
local[k] = grid[k] & 0x0f; local[k] = grid[k] & 0x0f;
} }
/* Set the Structural Info */ /* Set the Structural Info */
hx_set_function_info(local, size, version, ecc_level, pattern, 0 /*debug*/); hx_set_function_info(local, size, version, ecc_level, pattern, 0 /*debug_print*/);
/* Evaluate result */ /* Evaluate result */
penalty[pattern] = hx_evaluate(local, size); penalty[pattern] = hx_evaluate(local, size);
@ -1406,7 +1453,7 @@ static void hx_apply_bitmask(unsigned char *grid, const int size, const int vers
} }
} }
/* Set the Structural Info */ /* Set the Structural Info */
hx_set_function_info(local, size, version, ecc_level, pattern, 0 /*debug*/); hx_set_function_info(local, size, version, ecc_level, pattern, 0 /*debug_print*/);
/* Evaluate result */ /* Evaluate result */
penalty[pattern] = hx_evaluate(local, size); penalty[pattern] = hx_evaluate(local, size);
@ -1416,7 +1463,7 @@ static void hx_apply_bitmask(unsigned char *grid, const int size, const int vers
} }
} }
if (debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Mask: %d (%s)", best_pattern, user_mask ? "specified" : "automatic"); printf("Mask: %d (%s)", best_pattern, user_mask ? "specified" : "automatic");
if (!user_mask) { if (!user_mask) {
for (pattern = 0; pattern < 4; pattern++) printf(" %d:%d", pattern, penalty[pattern]); for (pattern = 0; pattern < 4; pattern++) printf(" %d:%d", pattern, penalty[pattern]);
@ -1438,11 +1485,11 @@ static void hx_apply_bitmask(unsigned char *grid, const int size, const int vers
} }
} }
/* Set the Structural Info */ /* Set the Structural Info */
hx_set_function_info(grid, size, version, ecc_level, best_pattern, debug); hx_set_function_info(grid, size, version, ecc_level, best_pattern, debug_print);
} }
/* Han Xin Code - main */ /* Han Xin Code - main */
INTERNAL int hanxin(struct zint_symbol *symbol, unsigned char source[], int length) { INTERNAL int hanxin(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int warn_number = 0; int warn_number = 0;
int est_binlen; int est_binlen;
int ecc_level = symbol->option_1; int ecc_level = symbol->option_1;
@ -1453,14 +1500,17 @@ INTERNAL int hanxin(struct zint_symbol *symbol, unsigned char source[], int leng
int size_squared; int size_squared;
int codewords; int codewords;
int bin_len; int bin_len;
const int eci_length = get_eci_length(symbol->eci, source, length); const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
const int eci_length_segs = get_eci_length_segs(segs, seg_count);
#ifndef _MSC_VER #ifndef _MSC_VER
unsigned int gbdata[eci_length + 1]; struct zint_seg local_segs[seg_count];
char mode[eci_length]; unsigned int ddata[eci_length_segs];
char mode[eci_length_segs];
#else #else
unsigned int *gbdata = (unsigned int *) _alloca((eci_length + 1) * sizeof(unsigned int)); struct zint_seg *local_segs = (struct zint_seg *) _alloca(sizeof(struct zint_seg) * seg_count);
char *mode = (char *) _alloca(eci_length); unsigned int *ddata = (unsigned int *) _alloca(sizeof(unsigned int) * eci_length_segs);
char *mode = (char *) _alloca(eci_length_segs);
char *binary; char *binary;
unsigned char *datastream; unsigned char *datastream;
unsigned char *fullstream; unsigned char *fullstream;
@ -1468,6 +1518,8 @@ INTERNAL int hanxin(struct zint_symbol *symbol, unsigned char source[], int leng
unsigned char *grid; unsigned char *grid;
#endif #endif
segs_cpy(segs, seg_count, local_segs); /* Shallow copy (needed to set default ECI & protect lengths) */
/* If ZINT_FULL_MULTIBYTE set use Hanzi mode in DATA_MODE or for non-GB 18030 in UNICODE_MODE */ /* If ZINT_FULL_MULTIBYTE set use Hanzi mode in DATA_MODE or for non-GB 18030 in UNICODE_MODE */
full_multibyte = (symbol->option_3 & 0xFF) == ZINT_FULL_MULTIBYTE; full_multibyte = (symbol->option_3 & 0xFF) == ZINT_FULL_MULTIBYTE;
user_mask = (symbol->option_3 >> 8) & 0x0F; /* User mask is pattern + 1, so >= 1 and <= 4 */ user_mask = (symbol->option_3 >> 8) & 0x0F; /* User mask is pattern + 1, so >= 1 and <= 4 */
@ -1476,35 +1528,40 @@ INTERNAL int hanxin(struct zint_symbol *symbol, unsigned char source[], int leng
} }
if ((symbol->input_mode & 0x07) == DATA_MODE) { if ((symbol->input_mode & 0x07) == DATA_MODE) {
gb18030_cpy(source, &length, gbdata, full_multibyte); gb18030_cpy_segs(local_segs, seg_count, ddata, full_multibyte);
} else { } else {
int done = 0; unsigned int *dd = ddata;
if (symbol->eci != 32) { /* Unless ECI 32 (GB 18030) */ for (i = 0; i < seg_count; i++) {
/* Try other conversions (ECI 0 defaults to ISO/IEC 8859-1) */ int done = 0;
int error_number = gb18030_utf8_to_eci(symbol->eci, source, &length, gbdata, full_multibyte); if (local_segs[i].eci != 32 || seg_count > 1) { /* Unless ECI 32 (GB 18030) or have multiple segments */
if (error_number == 0) { /* Try other conversions (ECI 0 defaults to ISO/IEC 8859-1) */
done = 1; int error_number = gb18030_utf8_to_eci(local_segs[i].eci, local_segs[i].source, &local_segs[i].length,
} else if (symbol->eci) { dd, full_multibyte);
sprintf(symbol->errtxt, "545: Invalid character in input data for ECI %d", symbol->eci); if (error_number == 0) {
return error_number; done = 1;
} else if (local_segs[i].eci || seg_count > 1) {
sprintf(symbol->errtxt, "545: Invalid character in input data for ECI %d", local_segs[i].eci);
return error_number;
}
} }
} if (!done) {
if (!done) { /* Try GB 18030 */
/* Try GB 18030 */ int error_number = gb18030_utf8(symbol, local_segs[i].source, &local_segs[i].length, dd);
int error_number = gb18030_utf8(symbol, source, &length, gbdata); if (error_number != 0) {
if (error_number != 0) { return error_number;
return error_number; }
} if (local_segs[i].eci != 32) {
if (symbol->eci != 32) { strcpy(symbol->errtxt, "543: Converted to GB 18030 but no ECI specified");
strcpy(symbol->errtxt, "543: Converted to GB 18030 but no ECI specified"); warn_number = ZINT_WARN_NONCOMPLIANT;
warn_number = ZINT_WARN_NONCOMPLIANT; }
} }
dd += local_segs[i].length;
} }
} }
hx_define_mode(mode, gbdata, length, symbol->debug); hx_define_mode_segs(mode, ddata, local_segs, seg_count, debug_print);
est_binlen = calculate_binlength(mode, gbdata, length, symbol->eci); est_binlen = hx_calc_binlen_segs(mode, ddata, local_segs, seg_count);
#ifndef _MSC_VER #ifndef _MSC_VER
char binary[est_binlen + 1]; char binary[est_binlen + 1];
@ -1516,12 +1573,12 @@ INTERNAL int hanxin(struct zint_symbol *symbol, unsigned char source[], int leng
ecc_level = 1; ecc_level = 1;
} }
calculate_binary(binary, mode, gbdata, length, symbol->eci, &bin_len, symbol->debug); hx_calculate_binary_segs(binary, mode, ddata, local_segs, seg_count, &bin_len, debug_print);
codewords = bin_len >> 3; codewords = bin_len >> 3;
if (bin_len & 0x07) { if (bin_len & 0x07) {
codewords++; codewords++;
} }
if (symbol->debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Num. of codewords: %d\n", codewords); printf("Num. of codewords: %d\n", codewords);
} }
@ -1619,7 +1676,7 @@ INTERNAL int hanxin(struct zint_symbol *symbol, unsigned char source[], int leng
} }
} }
if (symbol->debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Datastream (%d): ", data_codewords); printf("Datastream (%d): ", data_codewords);
for (i = 0; i < data_codewords; i++) { for (i = 0; i < data_codewords; i++) {
printf("%.2x ", datastream[i]); printf("%.2x ", datastream[i]);
@ -1634,7 +1691,7 @@ INTERNAL int hanxin(struct zint_symbol *symbol, unsigned char source[], int leng
hx_add_ecc(fullstream, datastream, data_codewords, version, ecc_level); hx_add_ecc(fullstream, datastream, data_codewords, version, ecc_level);
if (symbol->debug & ZINT_DEBUG_PRINT) { if (debug_print) {
printf("Fullstream (%d): ", hx_total_codewords[version - 1]); printf("Fullstream (%d): ", hx_total_codewords[version - 1]);
for (i = 0; i < hx_total_codewords[version - 1]; i++) { for (i = 0; i < hx_total_codewords[version - 1]; i++) {
printf("%.2x ", fullstream[i]); printf("%.2x ", fullstream[i]);
@ -1642,7 +1699,7 @@ INTERNAL int hanxin(struct zint_symbol *symbol, unsigned char source[], int leng
printf("\n"); printf("\n");
} }
make_picket_fence(fullstream, picket_fence, hx_total_codewords[version - 1]); hx_make_picket_fence(fullstream, picket_fence, hx_total_codewords[version - 1]);
/* Populate grid */ /* Populate grid */
j = 0; j = 0;
@ -1660,7 +1717,7 @@ INTERNAL int hanxin(struct zint_symbol *symbol, unsigned char source[], int leng
} }
} }
hx_apply_bitmask(grid, size, version, ecc_level, user_mask, symbol->debug); hx_apply_bitmask(grid, size, version, ecc_level, user_mask, debug_print);
symbol->width = size; symbol->width = size;
symbol->rows = size; symbol->rows = size;

View File

@ -1,7 +1,7 @@
/* hanxin.h - definitions for Han Xin code /* hanxin.h - definitions for Han Xin code
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2016 Zoe Stuart Copyright (C) 2016 Zoe Stuart
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -30,8 +30,11 @@
SUCH DAMAGE. SUCH DAMAGE.
*/ */
#ifndef Z_HANXIN_H
#define Z_HANXIN_H
/* Data from table B1: Data capacity of Han Xin Code */ /* Data from table B1: Data capacity of Han Xin Code */
static const unsigned short int hx_total_codewords[] = { static const unsigned short hx_total_codewords[] = {
25, 37, 50, 54, 69, 84, 100, 117, 136, 155, 161, 181, 203, 225, 249, 25, 37, 50, 54, 69, 84, 100, 117, 136, 155, 161, 181, 203, 225, 249,
273, 299, 325, 353, 381, 411, 422, 453, 485, 518, 552, 587, 623, 660, 273, 299, 325, 353, 381, 411, 422, 453, 485, 518, 552, 587, 623, 660,
698, 737, 754, 794, 836, 878, 922, 966, 1011, 1058, 1105, 1126, 1175, 698, 737, 754, 794, 836, 878, 922, 966, 1011, 1058, 1105, 1126, 1175,
@ -41,7 +44,7 @@ static const unsigned short int hx_total_codewords[] = {
3500, 3585, 3671, 3758, 3798, 3886 3500, 3585, 3671, 3758, 3798, 3886
}; };
static const unsigned short int hx_data_codewords_L1[] = { static const unsigned short hx_data_codewords_L1[] = {
21, 31, 42, 46, 57, 70, 84, 99, 114, 131, 135, 153, 171, 189, 209, 229, 21, 31, 42, 46, 57, 70, 84, 99, 114, 131, 135, 153, 171, 189, 209, 229,
251, 273, 297, 321, 345, 354, 381, 407, 436, 464, 493, 523, 554, 586, 619, 251, 273, 297, 321, 345, 354, 381, 407, 436, 464, 493, 523, 554, 586, 619,
634, 666, 702, 738, 774, 812, 849, 888, 929, 946, 987, 1028, 1071, 1115, 634, 666, 702, 738, 774, 812, 849, 888, 929, 946, 987, 1028, 1071, 1115,
@ -51,7 +54,7 @@ static const unsigned short int hx_data_codewords_L1[] = {
3083, 3156, 3190, 3264 3083, 3156, 3190, 3264
}; };
static const unsigned short int hx_data_codewords_L2[] = { static const unsigned short hx_data_codewords_L2[] = {
17, 25, 34, 38, 49, 58, 70, 81, 96, 109, 113, 127, 143, 157, 175, 191, 209, 17, 25, 34, 38, 49, 58, 70, 81, 96, 109, 113, 127, 143, 157, 175, 191, 209,
227, 247, 267, 287, 296, 317, 339, 362, 386, 411, 437, 462, 488, 515, 528, 227, 247, 267, 287, 296, 317, 339, 362, 386, 411, 437, 462, 488, 515, 528,
556, 586, 614, 646, 676, 707, 740, 773, 788, 823, 856, 893, 929, 966, 1004, 556, 586, 614, 646, 676, 707, 740, 773, 788, 823, 856, 893, 929, 966, 1004,
@ -61,7 +64,7 @@ static const unsigned short int hx_data_codewords_L2[] = {
2720 2720
}; };
static const unsigned short int hx_data_codewords_L3[] = { static const unsigned short hx_data_codewords_L3[] = {
13, 19, 26, 30, 37, 46, 54, 63, 74, 83, 87, 97, 109, 121, 135, 147, 161, 13, 19, 26, 30, 37, 46, 54, 63, 74, 83, 87, 97, 109, 121, 135, 147, 161,
175, 191, 205, 221, 228, 245, 261, 280, 298, 317, 337, 358, 376, 397, 408, 175, 191, 205, 221, 228, 245, 261, 280, 298, 317, 337, 358, 376, 397, 408,
428, 452, 474, 498, 522, 545, 572, 597, 608, 635, 660, 689, 717, 746, 774, 428, 452, 474, 498, 522, 545, 572, 597, 608, 635, 660, 689, 717, 746, 774,
@ -70,7 +73,7 @@ static const unsigned short int hx_data_codewords_L3[] = {
1713, 1756, 1800, 1844, 1890, 1935, 1983, 2030, 2050, 2098 1713, 1756, 1800, 1844, 1890, 1935, 1983, 2030, 2050, 2098
}; };
static const unsigned short int hx_data_codewords_L4[] = { static const unsigned short hx_data_codewords_L4[] = {
9, 15, 20, 22, 27, 34, 40, 47, 54, 61, 65, 73, 81, 89, 99, 109, 119, 129, 9, 15, 20, 22, 27, 34, 40, 47, 54, 61, 65, 73, 81, 89, 99, 109, 119, 129,
141, 153, 165, 168, 181, 195, 208, 220, 235, 251, 264, 280, 295, 302, 318, 141, 153, 165, 168, 181, 195, 208, 220, 235, 251, 264, 280, 295, 302, 318,
334, 352, 368, 386, 405, 424, 441, 450, 469, 490, 509, 531, 552, 574, 595, 605, 334, 352, 368, 386, 405, 424, 441, 450, 469, 490, 509, 531, 552, 574, 595, 605,
@ -119,7 +122,7 @@ static const char hx_module_m[] = {
}; };
/* Error correction block sizes from Table D1 */ /* Error correction block sizes from Table D1 */
static const unsigned short int hx_table_d1[] = { static const unsigned short hx_table_d1[] = {
/* #blocks, k, 2t, #blocks, k, 2t, #blocks, k, 2t */ /* #blocks, k, 2t, #blocks, k, 2t, #blocks, k, 2t */
1, 21, 4, 0, 0, 0, 0, 0, 0, // version 1 1, 21, 4, 0, 0, 0, 0, 0, 0, // version 1
1, 17, 8, 0, 0, 0, 0, 0, 0, 1, 17, 8, 0, 0, 0, 0, 0, 0,
@ -458,3 +461,6 @@ static const unsigned short int hx_table_d1[] = {
2, 26, 26, 62, 33, 28, 0, 0, 0, 2, 26, 26, 62, 33, 28, 0, 0, 0,
79, 18, 28, 4, 33, 30, 0, 0, 0 79, 18, 28, 4, 33, 30, 0, 0, 0
}; };
/* vim: set ts=4 sw=4 et : */
#endif /* Z_HANXIN_H */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -29,9 +29,8 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */ #ifndef Z_LARGE_H
#ifndef __LARGE_H #define Z_LARGE_H
#define __LARGE_H
#ifndef _MSC_VER #ifndef _MSC_VER
#include <stdint.h> #include <stdint.h>
@ -77,4 +76,5 @@ INTERNAL char *large_dump(const large_int *t, char *buf);
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __LARGE_H */ /* vim: set ts=4 sw=4 et : */
#endif /* Z_LARGE_H */

View File

@ -1,7 +1,7 @@
/* library.c - external functions of libzint /* library.c - external functions of libzint
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -28,7 +28,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
@ -162,15 +161,15 @@ INTERNAL int usps_imail(struct zint_symbol *symbol, unsigned char source[], int
INTERNAL int rm4scc(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */ INTERNAL int rm4scc(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */
INTERNAL int auspost(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */ INTERNAL int auspost(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */
INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 16k */ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 16k */
INTERNAL int pdf417(struct zint_symbol *symbol, unsigned char source[], int length); /* PDF417 */ INTERNAL int pdf417(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* PDF417 */
INTERNAL int micropdf417(struct zint_symbol *symbol, unsigned char chaine[], int length); /* Micro PDF417 */ INTERNAL int micropdf417(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Micro PDF417 */
INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Maxicode */
INTERNAL int dbar_omn(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */ INTERNAL int dbar_omn(struct zint_symbol *symbol, unsigned char source[], int length); /* DataBar Omnidirectional */
INTERNAL int dbar_ltd(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */ INTERNAL int dbar_ltd(struct zint_symbol *symbol, unsigned char source[], int length); /* DataBar Limited */
INTERNAL int dbar_exp(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Expanded */ INTERNAL int dbar_exp(struct zint_symbol *symbol, unsigned char source[], int length); /* DataBar Expanded */
INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */
INTERNAL int kix(struct zint_symbol *symbol, unsigned char source[], int length); /* TNT KIX Code */ INTERNAL int kix(struct zint_symbol *symbol, unsigned char source[], int length); /* TNT KIX Code */
INTERNAL int aztec(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Code */ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Aztec Code */
INTERNAL int code32(struct zint_symbol *symbol, unsigned char source[], int length); /* Italian Pharmacode */ INTERNAL int code32(struct zint_symbol *symbol, unsigned char source[], int length); /* Italian Pharmacode */
INTERNAL int daft(struct zint_symbol *symbol, unsigned char source[], int length); /* DAFT Code */ INTERNAL int daft(struct zint_symbol *symbol, unsigned char source[], int length); /* DAFT Code */
INTERNAL int ean14(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-14 */ INTERNAL int ean14(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-14 */
@ -181,20 +180,21 @@ INTERNAL int koreapost(struct zint_symbol *symbol, unsigned char source[], int l
INTERNAL int japanpost(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */ INTERNAL int japanpost(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */
INTERNAL int code49(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 49 */ INTERNAL int code49(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 49 */
INTERNAL int channel(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */ INTERNAL int channel(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */
INTERNAL int codeone(struct zint_symbol *symbol, unsigned char source[], int length); /* Code One */ INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Code One */
INTERNAL int gridmatrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Grid Matrix */ INTERNAL int gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Grid Matrix */
INTERNAL int hanxin(struct zint_symbol *symbol, unsigned char source[], int length); /* Han Xin */ INTERNAL int hanxin(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Han Xin */
INTERNAL int dotcode(struct zint_symbol *symbol, unsigned char source[], int length); /* DotCode */ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* DotCode */
INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int length); /* Codablock */ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int length); /* Codablock */
INTERNAL int upnqr(struct zint_symbol *symbol, unsigned char source[], int length); /* UPNQR */ INTERNAL int upnqr(struct zint_symbol *symbol, unsigned char source[], int length); /* UPNQR */
INTERNAL int qrcode(struct zint_symbol *symbol, unsigned char source[], int length); /* QR Code */ INTERNAL int qrcode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* QR Code */
INTERNAL int datamatrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Data Matrix (IEC16022) */ /* Data Matrix (IEC16022) */
INTERNAL int datamatrix(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count);
/* VIN Code (Vehicle Identification Number) */ /* VIN Code (Vehicle Identification Number) */
INTERNAL int vin(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int vin(struct zint_symbol *symbol, unsigned char source[], int length);
/* Royal Mail 4-state Mailmark */ /* Royal Mail 4-state Mailmark */
INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int length);
INTERNAL int ultra(struct zint_symbol *symbol, unsigned char source[], int length); /* Ultracode */ INTERNAL int ultra(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Ultracode */
INTERNAL int rmqr(struct zint_symbol *symbol, unsigned char source[], int length); /* rMQR */ INTERNAL int rmqr(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* rMQR */
INTERNAL int dpd(struct zint_symbol *symbol, unsigned char source[], int length); /* DPD Code */ INTERNAL int dpd(struct zint_symbol *symbol, unsigned char source[], int length); /* DPD Code */
INTERNAL int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to PNG/BMP/PCX */ INTERNAL int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to PNG/BMP/PCX */
@ -289,7 +289,10 @@ static int dump_plot(struct zint_symbol *symbol) {
static const char TECHNETIUM[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; /* Same as SILVER (CODE39) */ static const char TECHNETIUM[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; /* Same as SILVER (CODE39) */
/* Process health industry bar code data */ /* Process health industry bar code data */
static int hibc(struct zint_symbol *symbol, unsigned char source[], int length) { static int hibc(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
unsigned char *source = segs[0].source;
int length = segs[0].length;
int i; int i;
int counter, error_number = 0; int counter, error_number = 0;
char to_process[110 + 2 + 1]; char to_process[110 + 2 + 1];
@ -317,45 +320,48 @@ static int hibc(struct zint_symbol *symbol, unsigned char source[], int length)
to_process[++length] = TECHNETIUM[counter]; to_process[++length] = TECHNETIUM[counter];
to_process[++length] = '\0'; to_process[++length] = '\0';
segs[0].source = (unsigned char *) to_process;
segs[0].length = length;
switch (symbol->symbology) { switch (symbol->symbology) {
case BARCODE_HIBC_128: case BARCODE_HIBC_128:
error_number = code128(symbol, (unsigned char *) to_process, length); error_number = code128(symbol, segs[0].source, segs[0].length);
ustrcpy(symbol->text, "*"); ustrcpy(symbol->text, "*");
ustrcat(symbol->text, to_process); ustrcat(symbol->text, to_process);
ustrcat(symbol->text, "*"); ustrcat(symbol->text, "*");
break; break;
case BARCODE_HIBC_39: case BARCODE_HIBC_39:
symbol->option_2 = 0; symbol->option_2 = 0;
error_number = code39(symbol, (unsigned char *) to_process, length); error_number = code39(symbol, segs[0].source, segs[0].length);
ustrcpy(symbol->text, "*"); ustrcpy(symbol->text, "*");
ustrcat(symbol->text, to_process); ustrcat(symbol->text, to_process);
ustrcat(symbol->text, "*"); ustrcat(symbol->text, "*");
break; break;
case BARCODE_HIBC_DM: case BARCODE_HIBC_DM:
error_number = datamatrix(symbol, (unsigned char *) to_process, length); error_number = datamatrix(symbol, segs, seg_count);
break; break;
case BARCODE_HIBC_QR: case BARCODE_HIBC_QR:
error_number = qrcode(symbol, (unsigned char *) to_process, length); error_number = qrcode(symbol, segs, seg_count);
break; break;
case BARCODE_HIBC_PDF: case BARCODE_HIBC_PDF:
error_number = pdf417(symbol, (unsigned char *) to_process, length); error_number = pdf417(symbol, segs, seg_count);
break; break;
case BARCODE_HIBC_MICPDF: case BARCODE_HIBC_MICPDF:
error_number = micropdf417(symbol, (unsigned char *) to_process, length); error_number = micropdf417(symbol, segs, seg_count);
break; break;
case BARCODE_HIBC_AZTEC: case BARCODE_HIBC_AZTEC:
error_number = aztec(symbol, (unsigned char *) to_process, length); error_number = aztec(symbol, segs, seg_count);
break; break;
case BARCODE_HIBC_BLOCKF: case BARCODE_HIBC_BLOCKF:
error_number = codablockf(symbol, (unsigned char *) to_process, length); error_number = codablockf(symbol, segs[0].source, segs[0].length);
break; break;
} }
return error_number; return error_number;
} }
/* Returns 1 if symbology MUST have GS1 data */
static int check_force_gs1(const int symbology) { static int check_force_gs1(const int symbology) {
/* Returns 1 if symbology MUST have GS1 data */
switch (symbology) { switch (symbology) {
case BARCODE_GS1_128: case BARCODE_GS1_128:
@ -370,8 +376,8 @@ static int check_force_gs1(const int symbology) {
return is_composite(symbology); return is_composite(symbology);
} }
/* Returns 1 if symbology supports GS1 data */
static int gs1_compliant(const int symbology) { static int gs1_compliant(const int symbology) {
/* Returns 1 if symbology supports GS1 data */
switch (symbology) { switch (symbology) {
case BARCODE_CODE16K: case BARCODE_CODE16K:
@ -393,8 +399,8 @@ static int gs1_compliant(const int symbology) {
return check_force_gs1(symbology); return check_force_gs1(symbology);
} }
/* Returns 1 if symbology can encode the ECI character */
static int supports_eci(const int symbology) { static int supports_eci(const int symbology) {
/* Returns 1 if symbology can encode the ECI character */
switch (symbology) { switch (symbology) {
case BARCODE_AZTEC: case BARCODE_AZTEC:
@ -417,8 +423,27 @@ static int supports_eci(const int symbology) {
return 0; return 0;
} }
/* Returns 1 if symbology is Health Industry Bar Code */
static int is_hibc(const int symbology) {
switch (symbology) {
case BARCODE_HIBC_128:
case BARCODE_HIBC_39:
case BARCODE_HIBC_DM:
case BARCODE_HIBC_QR:
case BARCODE_HIBC_PDF:
case BARCODE_HIBC_MICPDF:
case BARCODE_HIBC_BLOCKF:
case BARCODE_HIBC_AZTEC:
return 1;
break;
}
return 0;
}
/* Returns 1 if symbology supports HRT */
static int has_hrt(const int symbology) { static int has_hrt(const int symbology) {
/* Returns 1 if symbology supports HRT */
if (is_fixed_ratio(symbology)) { if (is_fixed_ratio(symbology)) {
return 0; return 0;
@ -463,9 +488,16 @@ static int has_hrt(const int symbology) {
return 1; return 1;
} }
/* Suppress warning ISO C forbids initialization between function pointer and void * */
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
/* Used for dispatching barcodes and for whether symbol id valid */ /* Used for dispatching barcodes and for whether symbol id valid */
typedef int (*barcode_func_t)(struct zint_symbol *, unsigned char *, int); typedef int (*barcode_segs_func_t)(struct zint_symbol *, struct zint_seg[], const int);
static const barcode_func_t barcode_funcs[BARCODE_LAST + 1] = { typedef int (*barcode_func_t)(struct zint_symbol *, unsigned char[], int);
static const void *barcode_funcs[BARCODE_LAST + 1] = {
NULL, code11, c25standard, c25inter, c25iata, /*0-4*/ NULL, code11, c25standard, c25inter, c25iata, /*0-4*/
NULL, c25logic, c25ind, code39, excode39, /*5-9*/ NULL, c25logic, c25ind, code39, excode39, /*5-9*/
NULL, NULL, NULL, eanx, eanx, /*10-14*/ NULL, NULL, NULL, eanx, eanx, /*10-14*/
@ -498,22 +530,26 @@ static const barcode_func_t barcode_funcs[BARCODE_LAST + 1] = {
rmqr, rmqr,
}; };
static int reduced_charset(struct zint_symbol *symbol, unsigned char *source, int length); static int reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count);
static int extended_or_reduced_charset(struct zint_symbol *symbol, unsigned char *source, const int length) { static int extended_or_reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int error_number = 0; int error_number = 0;
switch (symbol->symbology) { switch (symbol->symbology) {
/* These are the "elite" standards which have support for specific character sets */ /* These are the "elite" standards which have support for specific character sets + ECI */
case BARCODE_QRCODE: case BARCODE_QRCODE:
case BARCODE_MICROQR:
case BARCODE_GRIDMATRIX: case BARCODE_GRIDMATRIX:
case BARCODE_HANXIN: case BARCODE_HANXIN:
case BARCODE_UPNQR:
case BARCODE_RMQR: case BARCODE_RMQR:
error_number = (*barcode_funcs[symbol->symbology])(symbol, source, length); error_number = (*(barcode_segs_func_t)barcode_funcs[symbol->symbology])(symbol, segs, seg_count);
break; break;
default: error_number = reduced_charset(symbol, source, length); /* These are the standards which have support for specific character sets but not ECI */
case BARCODE_MICROQR:
case BARCODE_UPNQR:
error_number = (*(barcode_func_t)barcode_funcs[symbol->symbology])(symbol, segs[0].source,
segs[0].length);
break;
default: error_number = reduced_charset(symbol, segs, seg_count);
break; break;
} }
@ -521,36 +557,69 @@ static int extended_or_reduced_charset(struct zint_symbol *symbol, unsigned char
} }
/* These are the "norm" standards which only support Latin-1 at most, though a few support ECI */ /* These are the "norm" standards which only support Latin-1 at most, though a few support ECI */
static int reduced_charset(struct zint_symbol *symbol, unsigned char *source, int length) { static int reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int error_number = 0; int error_number = 0;
unsigned char *preprocessed = source; int i;
const int eci_length = get_eci_length(symbol->eci, source, length);
#ifndef _MSC_VER #ifndef _MSC_VER
unsigned char preprocessed_buf[eci_length + 1]; struct zint_seg local_segs[seg_count];
int convertible[seg_count];
#else #else
unsigned char *preprocessed_buf = (unsigned char *) _alloca(eci_length + 1); struct zint_seg *local_segs = (struct zint_seg *) _alloca(sizeof(struct zint_seg) * seg_count);
int *convertible = (int *) _alloca(sizeof(int) * seg_count);
#endif
if ((symbol->input_mode & 0x07) == UNICODE_MODE && is_eci_convertible_segs(segs, seg_count, convertible)) {
unsigned char *preprocessed;
const int eci_length_segs = get_eci_length_segs(segs, seg_count);
#ifndef _MSC_VER
unsigned char preprocessed_buf[eci_length_segs + seg_count];
#else
unsigned char *preprocessed_buf = (unsigned char *) _alloca(eci_length_segs + seg_count);
#endif #endif
if ((symbol->input_mode & 0x07) == UNICODE_MODE && is_eci_convertible(symbol->eci)) {
/* Prior check ensures ECI only set for those that support it */ /* Prior check ensures ECI only set for those that support it */
segs_cpy(segs, seg_count, local_segs); /* Shallow copy (needed to set default ECIs) */
preprocessed = preprocessed_buf; preprocessed = preprocessed_buf;
error_number = utf8_to_eci(symbol->eci, source, preprocessed, &length); for (i = 0; i < seg_count; i++) {
if (error_number != 0) { if (convertible[i]) {
if (symbol->eci) { error_number = utf8_to_eci(local_segs[i].eci, local_segs[i].source, preprocessed,
sprintf(symbol->errtxt, "244: Invalid character in input data for ECI %d", symbol->eci); &local_segs[i].length);
} else { if (error_number != 0) {
strcpy(symbol->errtxt, "204: Invalid character in input data (ISO/IEC 8859-1 only)"); if (local_segs[i].eci) {
sprintf(symbol->errtxt, "244: Invalid character in input data for ECI %d", local_segs[i].eci);
} else {
strcpy(symbol->errtxt, "204: Invalid character in input data (ISO/IEC 8859-1 only)");
}
return error_number;
}
local_segs[i].source = preprocessed;
preprocessed += local_segs[i].length + 1;
} }
return error_number; }
if (supports_eci(symbol->symbology) || is_hibc(symbol->symbology)) {
error_number = (*(barcode_segs_func_t)barcode_funcs[symbol->symbology])(symbol, local_segs, seg_count);
} else {
error_number = (*(barcode_func_t)barcode_funcs[symbol->symbology])(symbol, local_segs[0].source,
local_segs[0].length);
}
} else {
if (supports_eci(symbol->symbology) || is_hibc(symbol->symbology)) {
segs_cpy(segs, seg_count, local_segs); /* Shallow copy (needed to set default ECIs) */
error_number = (*(barcode_segs_func_t)barcode_funcs[symbol->symbology])(symbol, local_segs, seg_count);
} else {
error_number = (*(barcode_func_t)barcode_funcs[symbol->symbology])(symbol, segs[0].source,
segs[0].length);
} }
} }
error_number = (*barcode_funcs[symbol->symbology])(symbol, preprocessed, length);
return error_number; return error_number;
} }
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
STATIC_UNLESS_ZINT_TEST void strip_bom(unsigned char *source, int *input_length) { STATIC_UNLESS_ZINT_TEST void strip_bom(unsigned char *source, int *input_length) {
int i; int i;
@ -693,38 +762,93 @@ STATIC_UNLESS_ZINT_TEST int escape_char_process(struct zint_symbol *symbol, unsi
/* Encode a barcode. If `length` is 0, `source` must be NUL-terminated. */ /* Encode a barcode. If `length` is 0, `source` must be NUL-terminated. */
int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int length) { int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int length) {
int error_number, warn_number; struct zint_seg segs[1];
#ifdef _MSC_VER
if (!symbol) return ZINT_ERROR_INVALID_DATA;
segs[0].eci = symbol->eci;
segs[0].source = (unsigned char *) source;
segs[0].length = length;
return ZBarcode_Encode_Segs(symbol, segs, 1);
}
/* Encode a barcode with multiple ECI segments. */
int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[], const int seg_count) {
int error_number, warn_number = 0;
int total_len = 0;
int have_zero_eci = 0;
int i;
unsigned char *local_source; unsigned char *local_source;
#ifndef _MSC_VER
struct zint_seg local_segs[seg_count > 0 ? seg_count : 1];
#else
struct zint_seg *local_segs;
unsigned char *local_sources;
local_segs = (struct zint_seg *) _alloca(sizeof(struct zint_seg) * (seg_count > 0 ? seg_count : 1));
#endif #endif
if (!symbol) return ZINT_ERROR_INVALID_DATA; if (!symbol) return ZINT_ERROR_INVALID_DATA;
if (segs == NULL) {
return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "200: Input segments NULL");
}
if (seg_count <= 0) {
return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "205: Input segment count 0");
}
if (seg_count > ZINT_MAX_SEG_COUNT) {
return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "771: Too many input segments (max 256)");
}
/* Check segment lengths */
for (i = 0; i < seg_count; i++) {
local_segs[i] = segs[i];
if (local_segs[i].source == NULL) {
sprintf(symbol->errtxt, "772: Input segment %d source NULL", i);
return error_tag(symbol, ZINT_ERROR_INVALID_DATA, NULL);
}
if (local_segs[i].length <= 0) {
local_segs[i].length = (int) ustrlen(local_segs[i].source);
}
if (local_segs[i].length <= 0) {
sprintf(symbol->errtxt, "773: Input segment %d length zero", i);
return error_tag(symbol, ZINT_ERROR_INVALID_DATA, NULL);
}
if (local_segs[i].length > ZINT_MAX_DATA_LEN) {
return error_tag(symbol, ZINT_ERROR_TOO_LONG, "777: Input data too long");
}
total_len += local_segs[i].length;
}
if (symbol->debug & ZINT_DEBUG_PRINT) { if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("ZBarcode_Encode: symbology: %d, input_mode: 0x%X, ECI: %d, option_1: %d, option_2: %d," printf("ZBarcode_Encode_Segs: symbology: %d, input_mode: 0x%X, ECI: %d, option_1: %d, option_2: %d,"
" option_3: %d, scale: %g\n output_options: 0x%X, fg: %s, bg: %s," " option_3: %d, scale: %g\n output_options: 0x%X, fg: %s, bg: %s,"
" length: %d, First 10 source: \"%.*s\", First 10 primary: \"%.10s\"\n", " seg_count: %d, length[0] %d," " First 10 source[0] \"%.*s\", First 10 primary: \"%.10s\"\n",
symbol->symbology, symbol->input_mode, symbol->eci, symbol->option_1, symbol->option_2, symbol->symbology, symbol->input_mode, symbol->eci, symbol->option_1, symbol->option_2,
symbol->option_3, symbol->scale, symbol->output_options, symbol->fgcolour, symbol->bgcolour, symbol->option_3, symbol->scale, symbol->output_options, symbol->fgcolour, symbol->bgcolour,
length, length < 10 ? length : 10, source ? (const char *) source : "<NULL>", symbol->primary); seg_count, local_segs[0].length, local_segs[0].length < 10 ? local_segs[0].length : 10,
local_segs[0].source, symbol->primary);
} }
warn_number = 0; if (total_len > ZINT_MAX_DATA_LEN) {
if (source == NULL) {
return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "200: Input data NULL");
}
if (length <= 0) {
length = (int) ustrlen(source);
}
if (length <= 0) {
return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "205: No input data");
}
if (length > ZINT_MAX_DATA_LEN) {
return error_tag(symbol, ZINT_ERROR_TOO_LONG, "243: Input data too long"); return error_tag(symbol, ZINT_ERROR_TOO_LONG, "243: Input data too long");
} }
/* First check the symbology field */ /* Reconcile symbol ECI and first segment ECI if both set */
if (symbol->eci != local_segs[0].eci) {
if (symbol->eci && local_segs[0].eci) {
sprintf(symbol->errtxt, "774: Symbol ECI %d must match segment zero ECI %d", symbol->eci,
local_segs[0].eci);
return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, NULL);
}
if (symbol->eci) {
local_segs[0].eci = symbol->eci;
} else {
symbol->eci = local_segs[0].eci;
}
}
/* Check the symbology field */
if (!ZBarcode_ValidID(symbol->symbology)) { if (!ZBarcode_ValidID(symbol->symbology)) {
int orig_symbology = symbol->symbology; /* For self-check */ int orig_symbology = symbol->symbology; /* For self-check */
if (symbol->symbology < 1) { if (symbol->symbology < 1) {
@ -835,15 +959,27 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int
} }
} }
if (symbol->eci != 0) { if (seg_count > 1 && !supports_eci(symbol->symbology)) {
if (!(supports_eci(symbol->symbology))) { return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "775: Symbology does not support multiple segments");
return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "217: Symbology does not support ECI switching"); }
}
if ((symbol->eci < 0) || (symbol->eci == 1) || (symbol->eci == 2) || (symbol->eci > 999999)) { /* Check ECI(s) */
return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "218: Invalid ECI mode"); for (i = 0; i < seg_count; i++) {
if (local_segs[i].eci) {
if (!supports_eci(symbol->symbology)) {
return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "217: Symbology does not support ECI switching");
}
if (local_segs[i].eci < 0 || local_segs[i].eci == 1 || local_segs[i].eci == 2 || local_segs[i].eci == 14
|| local_segs[i].eci == 19 || local_segs[i].eci > 999999) {
sprintf(symbol->errtxt, "218: Invalid ECI code %d", local_segs[i].eci);
return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, NULL);
}
} else {
have_zero_eci = 1;
} }
} }
/* Check other symbol fields */
if ((symbol->scale < 0.01f) || (symbol->scale > 100.0f)) { if ((symbol->scale < 0.01f) || (symbol->scale > 100.0f)) {
return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "227: Scale out of range (0.01 to 100)"); return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "227: Scale out of range (0.01 to 100)");
} }
@ -875,29 +1011,50 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int
symbol->input_mode = DATA_MODE; /* Reset completely TODO: in future, warn/error */ symbol->input_mode = DATA_MODE; /* Reset completely TODO: in future, warn/error */
} }
if ((symbol->input_mode & 0x07) == UNICODE_MODE && !is_valid_utf8(source, length)) { if ((symbol->input_mode & 0x07) == GS1_MODE && !gs1_compliant(symbol->symbology)) {
return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "245: Invalid UTF-8 in input data"); return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "220: Selected symbology does not support GS1 mode");
} }
if (seg_count > 1) {
#ifndef _MSC_VER /* Note: GS1_MODE not currently supported when using multiple segments */
unsigned char local_source[length + 1]; if ((symbol->input_mode & 0x07) == GS1_MODE) {
#else return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "776: GS1_MODE not supported for multiple segments");
local_source = (unsigned char *) _alloca(length + 1);
#endif
memcpy(local_source, source, length);
local_source[length] = '\0';
/* Start acting on input mode */
if (symbol->input_mode & ESCAPE_MODE) {
error_number = escape_char_process(symbol, local_source, &length); /* Only returns errors, not warnings */
if (error_number != 0) {
return error_tag(symbol, error_number, NULL);
} }
} }
if ((symbol->input_mode & 0x07) == UNICODE_MODE) { if ((symbol->input_mode & 0x07) == UNICODE_MODE) {
strip_bom(local_source, &length); for (i = 0; i < seg_count; i++) {
if (!is_valid_utf8(local_segs[i].source, local_segs[i].length)) {
return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "245: Invalid UTF-8 in input data");
}
}
}
#ifndef _MSC_VER
unsigned char local_sources[total_len + seg_count];
#else
local_sources = (unsigned char *) _alloca(total_len + seg_count);
#endif
for (i = 0, local_source = local_sources; i < seg_count; i++) {
local_segs[i].source = local_source;
memcpy(local_segs[i].source, segs[i].source, local_segs[i].length);
local_segs[i].source[local_segs[i].length] = '\0';
local_source += local_segs[i].length + 1;
}
/* Start acting on input mode */
if (symbol->input_mode & ESCAPE_MODE) {
for (i = 0; i < seg_count; i++) {
error_number = escape_char_process(symbol, local_segs[i].source, &local_segs[i].length);
if (error_number != 0) { /* Only returns errors, not warnings */
return error_tag(symbol, error_number, NULL);
}
}
}
if ((symbol->input_mode & 0x07) == UNICODE_MODE) {
/* Only strip BOM on first segment */
strip_bom(local_segs[0].source, &local_segs[0].length);
} }
if (((symbol->input_mode & 0x07) == GS1_MODE) || (check_force_gs1(symbol->symbology))) { if (((symbol->input_mode & 0x07) == GS1_MODE) || (check_force_gs1(symbol->symbology))) {
@ -906,11 +1063,11 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int
// handle it themselves // handle it themselves
if (is_composite(symbol->symbology) || !check_force_gs1(symbol->symbology)) { if (is_composite(symbol->symbology) || !check_force_gs1(symbol->symbology)) {
#ifndef _MSC_VER #ifndef _MSC_VER
unsigned char reduced[length + 1]; unsigned char reduced[local_segs[0].length + 1];
#else #else
unsigned char *reduced = (unsigned char *) _alloca(length + 1); unsigned char *reduced = (unsigned char *) _alloca(local_segs[0].length + 1);
#endif #endif
error_number = gs1_verify(symbol, local_source, length, reduced); error_number = gs1_verify(symbol, local_segs[0].source, local_segs[0].length, reduced);
if (error_number) { if (error_number) {
static const char in_2d_comp[] = " in 2D component"; static const char in_2d_comp[] = " in 2D component";
if (is_composite(symbol->symbology) if (is_composite(symbol->symbology)
@ -923,29 +1080,29 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int
} }
warn_number = error_number; /* Override any previous warning (errtxt has been overwritten) */ warn_number = error_number; /* Override any previous warning (errtxt has been overwritten) */
} }
ustrcpy(local_source, reduced); // Cannot contain NUL char ustrcpy(local_segs[0].source, reduced); // Cannot contain NUL char
length = (int) ustrlen(local_source); local_segs[0].length = (int) ustrlen(reduced);
} }
} else { } else {
return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "220: Selected symbology does not support GS1 mode"); return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "220: Selected symbology does not support GS1 mode");
} }
} }
error_number = extended_or_reduced_charset(symbol, local_source, length); error_number = extended_or_reduced_charset(symbol, local_segs, seg_count);
if ((error_number == ZINT_ERROR_INVALID_DATA) && symbol->eci == 0 && supports_eci(symbol->symbology) if ((error_number == ZINT_ERROR_INVALID_DATA) && have_zero_eci && supports_eci(symbol->symbology)
&& (symbol->input_mode & 0x07) == UNICODE_MODE) { && (symbol->input_mode & 0x07) == UNICODE_MODE) {
/* Try another ECI mode */ /* Try another ECI mode */
symbol->eci = get_best_eci(local_source, length); const int first_eci_set = get_best_eci_segs(symbol, local_segs, seg_count);
if (symbol->eci != 0) { if (first_eci_set != 0) {
error_number = extended_or_reduced_charset(symbol, local_source, length); error_number = extended_or_reduced_charset(symbol, local_segs, seg_count);
/* Inclusion of ECI more noteworthy than other warnings, so overwrite (if any) */ /* Inclusion of ECI more noteworthy than other warnings, so overwrite (if any) */
if (error_number < ZINT_ERROR) { if (error_number < ZINT_ERROR) {
error_number = ZINT_WARN_USES_ECI; error_number = ZINT_WARN_USES_ECI;
if (!(symbol->debug & ZINT_DEBUG_TEST)) { if (!(symbol->debug & ZINT_DEBUG_TEST)) {
sprintf(symbol->errtxt, "222: Encoded data includes ECI %d", symbol->eci); sprintf(symbol->errtxt, "222: Encoded data includes ECI %d", first_eci_set);
} }
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Added ECI %d\n", symbol->eci); if (symbol->debug & ZINT_DEBUG_PRINT) printf("Added ECI %d\n", first_eci_set);
} }
} }
} }
@ -1069,10 +1226,24 @@ int ZBarcode_Buffer_Vector(struct zint_symbol *symbol, int rotate_angle) {
/* Encode and output a symbol to file `symbol->outfile` */ /* Encode and output a symbol to file `symbol->outfile` */
int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, const unsigned char *source, int length, int rotate_angle) { int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, const unsigned char *source, int length, int rotate_angle) {
struct zint_seg segs[1];
if (!symbol) return ZINT_ERROR_INVALID_DATA;
segs[0].eci = symbol->eci;
segs[0].source = (unsigned char *) source;
segs[0].length = length;
return ZBarcode_Encode_Segs_and_Print(symbol, segs, 1, rotate_angle);
}
/* Encode a symbol with multiple ECI segments and output to file `symbol->outfile` */
int ZBarcode_Encode_Segs_and_Print(struct zint_symbol *symbol, const struct zint_seg segs[], const int seg_count,
int rotate_angle) {
int error_number; int error_number;
int first_err; int first_err;
error_number = ZBarcode_Encode(symbol, source, length); error_number = ZBarcode_Encode_Segs(symbol, segs, seg_count);
if (error_number >= ZINT_ERROR) { if (error_number >= ZINT_ERROR) {
return error_number; return error_number;
} }
@ -1088,10 +1259,24 @@ int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, const unsigned char *s
/* Encode and output a symbol to memory as raster (`symbol->bitmap`) */ /* Encode and output a symbol to memory as raster (`symbol->bitmap`) */
int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, const unsigned char *source, int length, int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, const unsigned char *source, int length,
int rotate_angle) { int rotate_angle) {
struct zint_seg segs[1];
if (!symbol) return ZINT_ERROR_INVALID_DATA;
segs[0].eci = symbol->eci;
segs[0].source = (unsigned char *) source;
segs[0].length = length;
return ZBarcode_Encode_Segs_and_Buffer(symbol, segs, 1, rotate_angle);
}
/* Encode a symbol with multiple ECI segments and output to memory as raster (`symbol->bitmap`) */
int ZBarcode_Encode_Segs_and_Buffer(struct zint_symbol *symbol, const struct zint_seg segs[],
const int seg_count, int rotate_angle) {
int error_number; int error_number;
int first_err; int first_err;
error_number = ZBarcode_Encode(symbol, source, length); error_number = ZBarcode_Encode_Segs(symbol, segs, seg_count);
if (error_number >= ZINT_ERROR) { if (error_number >= ZINT_ERROR) {
return error_number; return error_number;
} }
@ -1108,10 +1293,24 @@ int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, const unsigned char *
/* Encode and output a symbol to memory as vector (`symbol->vector`) */ /* Encode and output a symbol to memory as vector (`symbol->vector`) */
int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol, const unsigned char *source, int length, int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol, const unsigned char *source, int length,
int rotate_angle) { int rotate_angle) {
struct zint_seg segs[1];
if (!symbol) return ZINT_ERROR_INVALID_DATA;
segs[0].eci = symbol->eci;
segs[0].source = (unsigned char *) source;
segs[0].length = length;
return ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, segs, 1, rotate_angle);
}
/* Encode a symbol with multiple ECI segments and output to memory as vector (`symbol->vector`) */
int ZBarcode_Encode_Segs_and_Buffer_Vector(struct zint_symbol *symbol, const struct zint_seg segs[],
const int seg_count, int rotate_angle) {
int error_number; int error_number;
int first_err; int first_err;
error_number = ZBarcode_Encode(symbol, source, length); error_number = ZBarcode_Encode_Segs(symbol, segs, seg_count);
if (error_number >= ZINT_ERROR) { if (error_number >= ZINT_ERROR) {
return error_number; return error_number;
} }
@ -1601,3 +1800,5 @@ int ZBarcode_Version(void) {
} }
return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE; return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2010-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2010-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -29,7 +29,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
/* Includes corrections thanks to Monica Swanson @ Source Technologies */ /* Includes corrections thanks to Monica Swanson @ Source Technologies */
#include <stdio.h> #include <stdio.h>
@ -114,7 +113,7 @@ static void maxi_bump(unsigned char set[], unsigned char character[], const int
} }
/* If the value is present in array, return the value, else return badvalue */ /* If the value is present in array, return the value, else return badvalue */
static int value_in_array(const unsigned char val, const unsigned char arr[], const int badvalue, static int maxi_value_in_array(const unsigned char val, const unsigned char arr[], const int badvalue,
const int arrLength) { const int arrLength) {
int i; int i;
for (i = 0; i < arrLength; i++) { for (i = 0; i < arrLength; i++) {
@ -125,13 +124,13 @@ static int value_in_array(const unsigned char val, const unsigned char arr[], co
/* Choose the best set from previous and next set in the range of the setval array, if no value can be found we /* Choose the best set from previous and next set in the range of the setval array, if no value can be found we
* return setval[0] */ * return setval[0] */
static int bestSurroundingSet(const int index, const int length, const unsigned char set[], static int maxi_bestSurroundingSet(const int index, const int length, const unsigned char set[], const int sp,
const unsigned char setval[], const int setLength) { const unsigned char setval[], const int setLength) {
int badValue = -1; int badValue = -1;
int option1 = value_in_array(set[index - 1], setval, badValue, setLength); int option1 = maxi_value_in_array(set[sp + index - 1], setval, badValue, setLength);
if (index + 1 < length) { if (index + 1 < length) {
// we have two options to check (previous & next) // we have two options to check (previous & next)
int option2 = value_in_array(set[index + 1], setval, badValue, setLength); int option2 = maxi_value_in_array(set[sp + index + 1], setval, badValue, setLength);
if (option2 != badValue && option1 > option2) { if (option2 != badValue && option1 > option2) {
return option2; return option2;
} }
@ -144,10 +143,11 @@ static int bestSurroundingSet(const int index, const int length, const unsigned
} }
/* Format text according to Appendix A */ /* Format text according to Appendix A */
static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, const unsigned char in_source[], static int maxi_text_process(unsigned char set[144], unsigned char character[144], const int mode,
int length, const int structapp_cw, const int eci, const int scm_vv, const int debug_print) { const unsigned char in_source[], int length, const int eci, const int scm_vv, int *p_sp,
const int debug_print) {
unsigned char set[144], character[144] = {0}; int sp = *p_sp;
int i, count, current_set, padding_set; int i, count, current_set, padding_set;
static const unsigned char set15[2] = { 1, 5 }; static const unsigned char set15[2] = { 1, 5 };
@ -161,12 +161,38 @@ static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, c
unsigned char *source_buf = (unsigned char *) _alloca(length + 9); unsigned char *source_buf = (unsigned char *) _alloca(length + 9);
#endif #endif
if (length > 144) { if (sp + length > 144) {
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} }
/* Insert ECI at the beginning of message if needed */
/* Encode ECI assignment numbers according to table 3 */
if (eci != 0) {
if (sp + 1 + length > 144) return ZINT_ERROR_TOO_LONG;
character[sp++] = 27; // ECI
if (eci <= 31) {
if (sp + 1 + length > 144) return ZINT_ERROR_TOO_LONG;
character[sp++] = eci;
} else if (eci <= 1023) {
if (sp + 2 + length > 144) return ZINT_ERROR_TOO_LONG;
character[sp++] = 0x20 | ((eci >> 6) & 0x0F);
character[sp++] = eci & 0x3F;
} else if (eci <= 32767) {
if (sp + 3 + length > 144) return ZINT_ERROR_TOO_LONG;
character[sp++] = 0x30 | ((eci >> 12) & 0x07);
character[sp++] = (eci >> 6) & 0x3F;
character[sp++] = eci & 0x3F;
} else {
if (sp + 4 + length > 144) return ZINT_ERROR_TOO_LONG;
character[sp++] = 0x38 | ((eci >> 18) & 0x03);
character[sp++] = (eci >> 12) & 0x3F;
character[sp++] = (eci >> 6) & 0x3F;
character[sp++] = eci & 0x3F;
}
}
if (scm_vv != -1) { /* Add SCM prefix */ if (scm_vv != -1) { /* Add SCM prefix */
if (length > 135) { if (sp + length > 135) {
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} }
sprintf((char *) source_buf, "[)>\03601\035%02d", scm_vv); /* [)>\R01\Gvv */ sprintf((char *) source_buf, "[)>\03601\035%02d", scm_vv); /* [)>\R01\Gvv */
@ -175,117 +201,115 @@ static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, c
length += 9; length += 9;
} }
memset(set, 255, 144);
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
/* Look up characters in table from Appendix A - this gives /* Look up characters in table from Appendix A - this gives
value and code set for most characters */ value and code set for most characters */
set[i] = maxiCodeSet[source[i]]; set[sp + i] = maxiCodeSet[source[i]];
character[i] = maxiSymbolChar[source[i]]; character[sp + i] = maxiSymbolChar[source[i]];
} }
/* If a character can be represented in more than one code set, /* If a character can be represented in more than one code set,
pick which version to use */ pick which version to use */
if (set[0] == 0) { if (set[sp + 0] == 0) {
if (character[0] == 13) { if (character[sp + 0] == 13) {
character[0] = 0; character[sp + 0] = 0;
} }
set[0] = 1; set[sp + 0] = 1;
} }
for (i = 1; i < length; i++) { for (i = 1; i < length; i++) {
if (set[i] == 0) { if (set[sp + i] == 0) {
/* Special character */ /* Special character */
if (character[i] == 13) { if (character[sp + i] == 13) {
/* Carriage Return */ /* Carriage Return */
set[i] = bestSurroundingSet(i, length, set, set15, 2); set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set15, 2);
if (set[i] == 5) { if (set[sp + i] == 5) {
character[i] = 13; character[sp + i] = 13;
} else { } else {
character[i] = 0; character[sp + i] = 0;
} }
} else if (character[i] == 28) { } else if (character[sp + i] == 28) {
/* FS */ /* FS */
set[i] = bestSurroundingSet(i, length, set, set12345, 5); set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5);
if (set[i] == 5) { if (set[sp + i] == 5) {
character[i] = 32; character[sp + i] = 32;
} }
} else if (character[i] == 29) { } else if (character[sp + i] == 29) {
/* GS */ /* GS */
set[i] = bestSurroundingSet(i, length, set, set12345, 5); set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5);
if (set[i] == 5) { if (set[sp + i] == 5) {
character[i] = 33; character[sp + i] = 33;
} }
} else if (character[i] == 30) { } else if (character[sp + i] == 30) {
/* RS */ /* RS */
set[i] = bestSurroundingSet(i, length, set, set12345, 5); set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5);
if (set[i] == 5) { if (set[sp + i] == 5) {
character[i] = 34; character[sp + i] = 34;
} }
} else if (character[i] == 32) { } else if (character[sp + i] == 32) {
/* Space */ /* Space */
set[i] = bestSurroundingSet(i, length, set, set12345, 5); set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5);
if (set[i] == 1) { if (set[sp + i] == 1) {
character[i] = 32; character[sp + i] = 32;
} else if (set[i] == 2) { } else if (set[sp + i] == 2) {
character[i] = 47; character[sp + i] = 47;
} else { } else {
character[i] = 59; character[sp + i] = 59;
} }
} else if (character[i] == 44) { } else if (character[sp + i] == 44) {
/* Comma */ /* Comma */
set[i] = bestSurroundingSet(i, length, set, set12, 2); set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2);
if (set[i] == 2) { if (set[sp + i] == 2) {
character[i] = 48; character[sp + i] = 48;
} }
} else if (character[i] == 46) { } else if (character[sp + i] == 46) {
/* Full Stop */ /* Full Stop */
set[i] = bestSurroundingSet(i, length, set, set12, 2); set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2);
if (set[i] == 2) { if (set[sp + i] == 2) {
character[i] = 49; character[sp + i] = 49;
} }
} else if (character[i] == 47) { } else if (character[sp + i] == 47) {
/* Slash */ /* Slash */
set[i] = bestSurroundingSet(i, length, set, set12, 2); set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2);
if (set[i] == 2) { if (set[sp + i] == 2) {
character[i] = 50; character[sp + i] = 50;
} }
} else if (character[i] == 58) { } else if (character[sp + i] == 58) {
/* Colon */ /* Colon */
set[i] = bestSurroundingSet(i, length, set, set12, 2); set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2);
if (set[i] == 2) { if (set[sp + i] == 2) {
character[i] = 51; character[sp + i] = 51;
} }
} }
} }
} }
padding_set = set[length - 1] == 2 ? 2 : 1; padding_set = set[sp + length - 1] == 2 ? 2 : 1;
for (i = length; i < 144; i++) { for (i = length; sp + i < 144; i++) {
/* Add the padding */ /* Add the padding */
set[i] = padding_set; set[sp + i] = padding_set;
character[i] = 33; character[sp + i] = 33;
} }
/* Find candidates for number compression */ /* Find candidates for number compression */
/* Note the prohibition on number compression in the primary message in ISO/IEC 16023:2000 B.1 (1) /* Note the prohibition on number compression in the primary message in ISO/IEC 16023:2000 B.1 (1)
applies to modes 2 & 3 only */ applies to modes 2 & 3 only */
count = 0; count = 0;
for (i = 0; i < 144; i++) { for (i = 0; sp + i < 144; i++) {
if ((set[i] == 1) && ((character[i] >= 48) && (character[i] <= 57))) { if ((set[sp + i] == 1) && ((character[sp + i] >= 48) && (character[sp + i] <= 57))) {
/* Character is a number */ /* Character is a number */
count++; count++;
if (count == 9) { if (count == 9) {
/* Nine digits in a row can be compressed */ /* Nine digits in a row can be compressed */
memset(set + i - 8, 6, 9); /* Set set of nine digits to 6 */ memset(set + sp + i - 8, 6, 9); /* Set set of nine digits to 6 */
count = 0; count = 0;
} }
} else { } else {
@ -298,58 +322,59 @@ static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, c
i = 0; i = 0;
do { do {
if ((set[i] != current_set) && (set[i] != 6)) { if ((set[sp + i] != current_set) && (set[sp + i] != 6)) {
switch (set[i]) { switch (set[sp + i]) {
case 1: case 1:
if (current_set == 2) { /* Set B */ if (current_set == 2) { /* Set B */
if (i + 1 < 144 && set[i + 1] == 1) { if (sp + i + 1 < 144 && set[sp + i + 1] == 1) {
if (i + 2 < 144 && set[i + 2] == 1) { if (sp + i + 2 < 144 && set[sp + i + 2] == 1) {
if (i + 3 < 144 && set[i + 3] == 1) { if (sp + i + 3 < 144 && set[sp + i + 3] == 1) {
/* Latch A */ /* Latch A */
maxi_bump(set, character, i, &length); maxi_bump(set, character, sp + i, &length);
character[i] = 63; /* Set B Latch A */ character[sp + i] = 63; /* Set B Latch A */
current_set = 1; current_set = 1;
i += 3; /* Next 3 Set A so skip over */ i += 3; /* Next 3 Set A so skip over */
if (debug_print) printf("LCHA "); if (debug_print) printf("LCHA ");
} else { } else {
/* 3 Shift A */ /* 3 Shift A */
maxi_bump(set, character, i, &length); maxi_bump(set, character, sp + i, &length);
character[i] = 57; /* Set B triple shift A */ character[sp + i] = 57; /* Set B triple shift A */
i += 2; /* Next 2 Set A so skip over */ i += 2; /* Next 2 Set A so skip over */
if (debug_print) printf("3SHA "); if (debug_print) printf("3SHA ");
} }
} else { } else {
/* 2 Shift A */ /* 2 Shift A */
maxi_bump(set, character, i, &length); maxi_bump(set, character, sp + i, &length);
character[i] = 56; /* Set B double shift A */ character[sp + i] = 56; /* Set B double shift A */
i++; /* Next Set A so skip over */ i++; /* Next Set A so skip over */
if (debug_print) printf("2SHA "); if (debug_print) printf("2SHA ");
} }
} else { } else {
/* Shift A */ /* Shift A */
maxi_bump(set, character, i, &length); maxi_bump(set, character, sp + i, &length);
character[i] = 59; /* Set A Shift B */ character[sp + i] = 59; /* Set A Shift B */
if (debug_print) printf("SHA "); if (debug_print) printf("SHA ");
} }
} else { /* All sets other than B only have latch */ } else { /* All sets other than B only have latch */
/* Latch A */ /* Latch A */
maxi_bump(set, character, i, &length); maxi_bump(set, character, sp + i, &length);
character[i] = 58; /* Sets C,D,E Latch A */ character[sp + i] = 58; /* Sets C,D,E Latch A */
current_set = 1; current_set = 1;
if (debug_print) printf("LCHA "); if (debug_print) printf("LCHA ");
} }
break; break;
case 2: /* Set B */ case 2: /* Set B */
if (current_set != 1 || (i + 1 < 144 && set[i + 1] == 2)) { /* If not Set A or next Set B */ /* If not Set A or next Set B */
if (current_set != 1 || (sp + i + 1 < 144 && set[sp + i + 1] == 2)) {
/* Latch B */ /* Latch B */
maxi_bump(set, character, i, &length); maxi_bump(set, character, sp + i, &length);
character[i] = 63; /* Sets A,C,D,E Latch B */ character[sp + i] = 63; /* Sets A,C,D,E Latch B */
current_set = 2; current_set = 2;
if (debug_print) printf("LCHB "); if (debug_print) printf("LCHB ");
} else { /* Only available from Set A */ } else { /* Only available from Set A */
/* Shift B */ /* Shift B */
maxi_bump(set, character, i, &length); maxi_bump(set, character, sp + i, &length);
character[i] = 59; /* Set B Shift A */ character[sp + i] = 59; /* Set B Shift A */
if (debug_print) printf("SHB "); if (debug_print) printf("SHB ");
} }
break; break;
@ -357,116 +382,107 @@ static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, c
case 4: /* Set D */ case 4: /* Set D */
case 5: /* Set E */ case 5: /* Set E */
/* If first and next 3 same set, or not first and previous and next 2 same set */ /* If first and next 3 same set, or not first and previous and next 2 same set */
if ((i == 0 && i + 3 < 144 && set[i + 1] == set[i] && set[i + 2] == set[i] if ((sp + i == 0 && sp + i + 3 < 144 && set[sp + i + 1] == set[sp + i]
&& set[i + 3] == set[i]) && set[sp + i + 2] == set[sp + i] && set[sp + i + 3] == set[sp + i])
|| (i > 0 && set[i - 1] == set[i] && i + 2 < 144 && set[i + 1] == set[i] || (sp + i > 0 && set[sp + i - 1] == set[sp + i] && sp + i + 2 < 144
&& set[i + 2] == set[i])) { && set[sp + i + 1] == set[sp + i] && set[sp + i + 2] == set[sp + i])) {
/* Lock in C/D/E */ /* Lock in C/D/E */
if (i == 0) { if (sp + i == 0) {
maxi_bump(set, character, i, &length); maxi_bump(set, character, sp + i, &length);
character[i] = 60 + set[i] - 3; character[sp + i] = 60 + set[sp + i] - 3;
i++; /* Extra bump */ i++; /* Extra bump */
maxi_bump(set, character, i, &length); maxi_bump(set, character, sp + i, &length);
character[i] = 60 + set[i] - 3; character[sp + i] = 60 + set[sp + i] - 3;
i += 3; /* Next 3 same set so skip over */ i += 3; /* Next 3 same set so skip over */
} else { } else {
/* Add single Shift to previous Shift */ /* Add single Shift to previous Shift */
maxi_bump(set, character, i - 1, &length); maxi_bump(set, character, sp + i - 1, &length);
character[i - 1] = 60 + set[i] - 3; character[sp + i - 1] = 60 + set[sp + i] - 3;
i += 2; /* Next 2 same set so skip over */ i += 2; /* Next 2 same set so skip over */
} }
current_set = set[i]; current_set = set[sp + i];
if (debug_print) printf("LCK%c ", 'C' + set[i] - 3); if (debug_print) printf("LCK%c ", 'C' + set[sp + i] - 3);
} else { } else {
/* Shift C/D/E */ /* Shift C/D/E */
maxi_bump(set, character, i, &length); maxi_bump(set, character, sp + i, &length);
character[i] = 60 + set[i] - 3; character[sp + i] = 60 + set[sp + i] - 3;
if (debug_print) printf("SH%c ", 'C' + set[i] - 3); if (debug_print) printf("SH%c ", 'C' + set[sp + i] - 3);
} }
break; break;
} }
i++; /* Allow for bump */ i++; /* Allow for bump */
} }
i++; i++;
} while (i < 144); } while (sp + i < 144);
if (debug_print) printf("\n"); if (debug_print) printf("\n");
/* Number compression has not been forgotten! - It's handled below */ /* Number compression has not been forgotten! - It's handled below */
i = 0; i = 0;
do { do {
if (set[i] == 6) { if (set[sp + i] == 6) {
/* Number compression */ /* Number compression */
int value = to_int(character + i, 9); int value = to_int(character + sp + i, 9);
character[i] = 31; /* NS */ character[sp + i] = 31; /* NS */
character[i + 1] = (value & 0x3f000000) >> 24; character[sp + i + 1] = (value & 0x3f000000) >> 24;
character[i + 2] = (value & 0xfc0000) >> 18; character[sp + i + 2] = (value & 0xfc0000) >> 18;
character[i + 3] = (value & 0x3f000) >> 12; character[sp + i + 3] = (value & 0x3f000) >> 12;
character[i + 4] = (value & 0xfc0) >> 6; character[sp + i + 4] = (value & 0xfc0) >> 6;
character[i + 5] = (value & 0x3f); character[sp + i + 5] = (value & 0x3f);
i += 6; i += 6;
memmove(set + i, set + i + 3, 141 - i); memmove(set + sp + i, set + sp + i + 3, 141 - (sp + i));
memmove(character + i, character + i + 3, 141 - i); memmove(character + sp + i, character + sp + i + 3, 141 - (sp + i));
length -= 3; length -= 3;
} else { } else {
i++; i++;
} }
} while (i <= 135); /* 144 - 9 */ } while (sp + i <= 135); /* 144 - 9 */
/* Insert ECI at the beginning of message if needed */
/* Encode ECI assignment numbers according to table 3 */
if (eci != 0) {
maxi_bump(set, character, 0, &length);
character[0] = 27; // ECI
if (eci <= 31) {
maxi_bump(set, character, 1, &length);
character[1] = eci;
} else if (eci <= 1023) {
maxi_bump(set, character, 1, &length);
maxi_bump(set, character, 1, &length);
character[1] = 0x20 | ((eci >> 6) & 0x0F);
character[2] = eci & 0x3F;
} else if (eci <= 32767) {
maxi_bump(set, character, 1, &length);
maxi_bump(set, character, 1, &length);
maxi_bump(set, character, 1, &length);
character[1] = 0x30 | ((eci >> 12) & 0x07);
character[2] = (eci >> 6) & 0x3F;
character[3] = eci & 0x3F;
} else {
maxi_bump(set, character, 1, &length);
maxi_bump(set, character, 1, &length);
maxi_bump(set, character, 1, &length);
maxi_bump(set, character, 1, &length);
character[1] = 0x38 | ((eci >> 18) & 0x03);
character[2] = (eci >> 12) & 0x3F;
character[3] = (eci >> 6) & 0x3F;
character[4] = eci & 0x3F;
}
}
/* Insert Structured Append at beginning if needed */
if (structapp_cw) {
maxi_bump(set, character, 0, &length);
character[0] = 33; // PAD
maxi_bump(set, character, 1, &length);
character[1] = structapp_cw;
}
if (debug_print) printf("Length: %d\n", length); if (debug_print) printf("Length: %d\n", length);
if (((mode == 2) || (mode == 3)) && (length > 84)) { if (((mode == 2) || (mode == 3)) && (sp + length > 84)) {
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} else if (((mode == 4) || (mode == 6)) && (length > 93)) { } else if (((mode == 4) || (mode == 6)) && (sp + length > 93)) {
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} else if ((mode == 5) && (length > 77)) { } else if ((mode == 5) && (sp + length > 77)) {
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} }
*p_sp = sp + length;
return 0;
}
/* Call `maxi_text_process()` for each segment, dealing with Structured Append beforehand and populating
`maxi_codeword` afterwards */
static int maxi_text_process_segs(unsigned char maxi_codeword[144], const int mode, const struct zint_seg segs[],
const int seg_count, const int structapp_cw, int scm_vv, const int debug_print) {
unsigned char set[144], character[144] = {0};
int i;
int error_number;
int sp = 0;
memset(set, 255, 144);
/* Insert Structured Append at beginning if needed */
if (structapp_cw) {
character[sp++] = 33; // PAD
character[sp++] = structapp_cw;
}
for (i = 0; i < seg_count; i++) {
error_number = maxi_text_process(set, character, mode, segs[i].source, segs[i].length, segs[i].eci, scm_vv,
&sp, debug_print);
if (error_number != 0) {
return error_number;
}
scm_vv = -1;
}
/* Copy the encoded text into the codeword array */ /* Copy the encoded text into the codeword array */
if ((mode == 2) || (mode == 3)) { if ((mode == 2) || (mode == 3)) {
for (i = 0; i < 84; i++) { /* secondary only */ for (i = 0; i < 84; i++) { /* secondary only */
@ -534,9 +550,9 @@ static void maxi_do_primary_3(unsigned char maxi_codeword[144], unsigned char po
maxi_codeword[9] = ((service & 0x3f0) >> 4); maxi_codeword[9] = ((service & 0x3f0) >> 4);
} }
INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int length) { INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int i, j, block, shift, mode, lp = 0; int i, j, block, shift, mode, lp = 0;
int error_number = 0, eclen; int error_number, eclen;
unsigned char maxi_codeword[144] = {0}; unsigned char maxi_codeword[144] = {0};
int scm_vv = -1; int scm_vv = -1;
int structapp_cw = 0; int structapp_cw = 0;
@ -658,10 +674,10 @@ INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int le
structapp_cw = (symbol->structapp.count - 1) | ((symbol->structapp.index - 1) << 3); structapp_cw = (symbol->structapp.count - 1) | ((symbol->structapp.index - 1) << 3);
} }
i = maxi_text_process(maxi_codeword, mode, source, length, structapp_cw, symbol->eci, scm_vv, debug_print); error_number = maxi_text_process_segs(maxi_codeword, mode, segs, seg_count, structapp_cw, scm_vv, debug_print);
if (i == ZINT_ERROR_TOO_LONG) { if (error_number == ZINT_ERROR_TOO_LONG) {
strcpy(symbol->errtxt, "553: Input data too long"); strcpy(symbol->errtxt, "553: Input data too long");
return i; return error_number;
} }
/* All the data is sorted - now do error correction */ /* All the data is sorted - now do error correction */
@ -724,3 +740,5 @@ INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int le
return error_number; return error_number;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -1,7 +1,7 @@
/* pdf417.c - Handles PDF417 stacked symbology */ /* pdf417.c - Handles PDF417 stacked symbology */
/* Zint - A barcode generating program using libpng /* Zint - A barcode generating program using libpng
Copyright (C) 2008-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
Portions Copyright (C) 2004 Grandzebu Portions Copyright (C) 2004 Grandzebu
Bug Fixes thanks to KL Chin <klchin@users.sourceforge.net> Bug Fixes thanks to KL Chin <klchin@users.sourceforge.net>
@ -30,7 +30,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
/* This code is adapted from "Code barre PDF 417 / PDF 417 barcode" v2.5.0 /* This code is adapted from "Code barre PDF 417 / PDF 417 barcode" v2.5.0
which is Copyright (C) 2004 (Grandzebu). which is Copyright (C) 2004 (Grandzebu).
@ -461,11 +460,11 @@ static void pdf_numbprocess(int *chainemc, int *mclength, const unsigned char ch
} }
/* Initial processing of data, shared by `pdf417()` and `micropdf417()` */ /* Initial processing of data, shared by `pdf417()` and `micropdf417()` */
static int pdf_initial(struct zint_symbol *symbol, unsigned char chaine[], const int length, const int is_micro, static int pdf_initial(struct zint_symbol *symbol, unsigned char chaine[], const int length, const int eci,
int chainemc[PDF_MAX_LEN], int *p_mclength, int structapp_cws[18], int *p_structapp_cp) { const int is_micro, int chainemc[PDF_MAX_LEN], int *p_mclength) {
int i, indexchaine, indexliste, mode; int i, indexchaine, indexliste, mode;
int liste[2][PDF_MAX_LEN] = {{0}}; int liste[2][PDF_MAX_LEN] = {{0}};
int mclength, structapp_cp = 0; int mclength;
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
/* 456 */ /* 456 */
@ -507,7 +506,63 @@ static int pdf_initial(struct zint_symbol *symbol, unsigned char chaine[], const
/* 541 - now compress the data */ /* 541 - now compress the data */
indexchaine = 0; indexchaine = 0;
mclength = is_micro ? 0 : 1; /* Allow for length descriptor for full symbol */ mclength = *p_mclength;
if (mclength == 0 && !is_micro) {
mclength++; /* Allow for length descriptor for full symbol */
}
if (*p_mclength == 0 && (symbol->output_options & READER_INIT)) {
chainemc[mclength++] = 921; /* Reader Initialisation */
}
if (eci != 0) {
if (eci > 811799) {
strcpy(symbol->errtxt, "472: Invalid ECI");
return ZINT_ERROR_INVALID_OPTION;
}
/* Encoding ECI assignment number, according to Table 8 */
if (eci <= 899) {
chainemc[mclength++] = 927; /* ECI */
chainemc[mclength++] = eci;
} else if (eci <= 810899) {
chainemc[mclength++] = 926; /* ECI */
chainemc[mclength++] = (eci / 900) - 1;
chainemc[mclength++] = eci % 900;
} else {
chainemc[mclength++] = 925; /* ECI */
chainemc[mclength++] = eci - 810900;
}
}
for (i = 0; i < indexliste; i++) {
switch (liste[1][i]) {
case TEX: /* 547 - text mode */
pdf_textprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], is_micro);
break;
case BYT: /* 670 - octet stream mode */
pdf_byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], debug_print);
break;
case NUM: /* 712 - numeric mode */
pdf_numbprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i]);
break;
}
indexchaine = indexchaine + liste[0][i];
}
*p_mclength = mclength;
return 0;
}
/* Call `pdf_initial()` for each segment, dealing with Structured Append beforehand */
static int pdf_initial_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count,
const int is_micro, int chainemc[PDF_MAX_LEN], int *p_mclength, int structapp_cws[18],
int *p_structapp_cp) {
int i;
int error_number = 0;
int structapp_cp = 0;
*p_mclength = 0;
if (symbol->structapp.count) { if (symbol->structapp.count) {
int id_cnt = 0, ids[10]; int id_cnt = 0, ids[10];
@ -558,53 +613,21 @@ static int pdf_initial(struct zint_symbol *symbol, unsigned char chaine[], const
structapp_cws[structapp_cp++] = 922; /* Special last segment terminator */ structapp_cws[structapp_cp++] = 922; /* Special last segment terminator */
} }
} }
if (symbol->output_options & READER_INIT) {
chainemc[mclength++] = 921; /* Reader Initialisation */
}
if (symbol->eci != 0) {
if (symbol->eci > 811799) {
strcpy(symbol->errtxt, "472: Invalid ECI");
return ZINT_ERROR_INVALID_OPTION;
}
/* Encoding ECI assignment number, according to Table 8 */
if (symbol->eci <= 899) {
chainemc[mclength++] = 927; /* ECI */
chainemc[mclength++] = symbol->eci;
} else if (symbol->eci <= 810899) {
chainemc[mclength++] = 926; /* ECI */
chainemc[mclength++] = (symbol->eci / 900) - 1;
chainemc[mclength++] = symbol->eci % 900;
} else {
chainemc[mclength++] = 925; /* ECI */
chainemc[mclength++] = symbol->eci - 810900;
}
}
for (i = 0; i < indexliste; i++) {
switch (liste[1][i]) {
case TEX: /* 547 - text mode */
pdf_textprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], is_micro);
break;
case BYT: /* 670 - octet stream mode */
pdf_byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], debug_print);
break;
case NUM: /* 712 - numeric mode */
pdf_numbprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i]);
break;
}
indexchaine = indexchaine + liste[0][i];
}
*p_mclength = mclength;
*p_structapp_cp = structapp_cp; *p_structapp_cp = structapp_cp;
return 0; for (i = 0; i < seg_count; i++) {
error_number = pdf_initial(symbol, segs[i].source, segs[i].length, segs[i].eci, is_micro, chainemc,
p_mclength);
if (error_number) { /* Only errors return >= ZINT_ERROR */
return error_number;
}
}
return error_number;
} }
/* 366 */ /* 366 */
static int pdf_enc(struct zint_symbol *symbol, unsigned char chaine[], const int length) { static int pdf_enc(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int i, j, longueur, loop, mccorrection[520] = {0}, offset; int i, j, longueur, loop, mccorrection[520] = {0}, offset;
int total, chainemc[PDF_MAX_LEN], mclength, c1, c2, c3, dummy[35]; int total, chainemc[PDF_MAX_LEN], mclength, c1, c2, c3, dummy[35];
int rows, cols, ecc, ecc_cws, padding; int rows, cols, ecc, ecc_cws, padding;
@ -616,12 +639,12 @@ static int pdf_enc(struct zint_symbol *symbol, unsigned char chaine[], const int
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
static const int ecc_num_cws[] = { 2, 4, 8, 16, 32, 64, 128, 256, 512 }; static const int ecc_num_cws[] = { 2, 4, 8, 16, 32, 64, 128, 256, 512 };
if (length > PDF_MAX_LEN) { if (segs_length(segs, seg_count) > PDF_MAX_LEN) {
strcpy(symbol->errtxt, "463: Input string too long"); strcpy(symbol->errtxt, "463: Input string too long");
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} }
error_number = pdf_initial(symbol, chaine, length, 0 /*is_micro*/, chainemc, &mclength, structapp_cws, error_number = pdf_initial_segs(symbol, segs, seg_count, 0 /*is_micro*/, chainemc, &mclength, structapp_cws,
&structapp_cp); &structapp_cp);
if (error_number) { /* Only errors return >= ZINT_ERROR */ if (error_number) { /* Only errors return >= ZINT_ERROR */
return error_number; return error_number;
@ -856,7 +879,7 @@ static int pdf_enc(struct zint_symbol *symbol, unsigned char chaine[], const int
} }
/* 345 */ /* 345 */
INTERNAL int pdf417(struct zint_symbol *symbol, unsigned char source[], int length) { INTERNAL int pdf417(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int codeerr, error_number; int codeerr, error_number;
error_number = 0; error_number = 0;
@ -887,7 +910,7 @@ INTERNAL int pdf417(struct zint_symbol *symbol, unsigned char source[], int leng
} }
/* 349 */ /* 349 */
codeerr = pdf_enc(symbol, source, length); codeerr = pdf_enc(symbol, segs, seg_count);
/* 352 */ /* 352 */
if (codeerr != 0) { if (codeerr != 0) {
@ -899,7 +922,7 @@ INTERNAL int pdf417(struct zint_symbol *symbol, unsigned char source[], int leng
} }
/* like PDF417 only much smaller! */ /* like PDF417 only much smaller! */
INTERNAL int micropdf417(struct zint_symbol *symbol, unsigned char chaine[], int length) { INTERNAL int micropdf417(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int i, k, j, longueur, mccorrection[50] = {0}, offset; int i, k, j, longueur, mccorrection[50] = {0}, offset;
int total, chainemc[PDF_MAX_LEN], mclength, error_number = 0; int total, chainemc[PDF_MAX_LEN], mclength, error_number = 0;
char pattern[580]; char pattern[580];
@ -910,7 +933,7 @@ INTERNAL int micropdf417(struct zint_symbol *symbol, unsigned char chaine[], int
int LeftRAP, CentreRAP, RightRAP, Cluster, loop; int LeftRAP, CentreRAP, RightRAP, Cluster, loop;
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
if (length > MICRO_PDF_MAX_LEN) { if (segs_length(segs, seg_count) > MICRO_PDF_MAX_LEN) {
strcpy(symbol->errtxt, "474: Input data too long"); strcpy(symbol->errtxt, "474: Input data too long");
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} }
@ -921,7 +944,7 @@ INTERNAL int micropdf417(struct zint_symbol *symbol, unsigned char chaine[], int
/* Encoding starts out the same as PDF417, so use the same code */ /* Encoding starts out the same as PDF417, so use the same code */
error_number = pdf_initial(symbol, chaine, length, 1 /*is_micro*/, chainemc, &mclength, structapp_cws, error_number = pdf_initial_segs(symbol, segs, seg_count, 1 /*is_micro*/, chainemc, &mclength, structapp_cws,
&structapp_cp); &structapp_cp);
if (error_number) { /* Only errors return >= ZINT_ERROR */ if (error_number) { /* Only errors return >= ZINT_ERROR */
return error_number; return error_number;
@ -1230,3 +1253,5 @@ INTERNAL int micropdf417(struct zint_symbol *symbol, unsigned char chaine[], int
#undef TEX #undef TEX
#undef BYT #undef BYT
#undef NUM #undef NUM
/* vim: set ts=4 sw=4 et : */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
Portions Copyright (C) 2004 Grandzebu Portions Copyright (C) 2004 Grandzebu
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -30,12 +30,11 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
/* See "pdf417_tabs.h" for table definitions */ /* See "pdf417_tabs.h" for table definitions */
#ifndef __PDF417_H #ifndef Z_PDF417_H
#define __PDF417_H #define Z_PDF417_H
/* PDF417 error correction coefficients from Grand Zebu */ /* PDF417 error correction coefficients from Grand Zebu */
INTERNAL_DATA_EXTERN const unsigned short pdf_coefrs[1022]; INTERNAL_DATA_EXTERN const unsigned short pdf_coefrs[1022];
@ -60,4 +59,5 @@ INTERNAL_DATA_EXTERN const unsigned short pdf_rap_centre[52];
INTERNAL void pdf_byteprocess(int *chainemc, int *mclength, const unsigned char chaine[], int start, const int length, INTERNAL void pdf_byteprocess(int *chainemc, int *mclength, const unsigned char chaine[], int start, const int length,
const int debug); const int debug);
#endif /* __PDF417_H */ /* vim: set ts=4 sw=4 et : */
#endif /* Z_PDF417_H */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
Portions Copyright (C) 2004 Grandzebu Portions Copyright (C) 2004 Grandzebu
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -30,15 +30,14 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
/* this file contains the character table, the pre-calculated coefficients and the /* this file contains the character table, the pre-calculated coefficients and the
codeword patterns taken from lines 416 to 454 of pdf417.frm */ codeword patterns taken from lines 416 to 454 of pdf417.frm */
/* See "pdf417.h" for declarations */ /* See "pdf417.h" for declarations */
#ifndef __PDF417_TABS_H #ifndef Z_PDF417_TABS_H
#define __PDF417_TABS_H #define Z_PDF417_TABS_H
/* PDF417 error correction coefficients from Grand Zebu */ /* PDF417 error correction coefficients from Grand Zebu */
INTERNAL_DATA const unsigned short pdf_coefrs[1022] = { INTERNAL_DATA const unsigned short pdf_coefrs[1022] = {
@ -511,4 +510,5 @@ INTERNAL_DATA const unsigned short pdf_rap_centre[52] = {
0x2DC, 0x2DE 0x2DC, 0x2DE
}; };
#endif /* __PDF417_TABS_H */ /* vim: set ts=4 sw=4 et : */
#endif /* Z_PDF417_TABS_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* qr.h Data for QR Code, Micro QR Code and rMQR /* qr.h Data for QR Code, Micro QR Code and rMQR
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2006 Kentaro Fukuchi <fukuchi@megaui.net> Copyright (C) 2006 Kentaro Fukuchi <fukuchi@megaui.net>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -29,7 +29,9 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#ifndef Z_QR_H
#define Z_QR_H
/* From ISO/IEC 18004:2015 Table 5 Encoding/decoding table for Alphanumeric mode */ /* From ISO/IEC 18004:2015 Table 5 Encoding/decoding table for Alphanumeric mode */
static const char qr_alphanumeric[59] = { static const char qr_alphanumeric[59] = {
@ -40,37 +42,37 @@ static const char qr_alphanumeric[59] = {
}; };
/* From ISO/IEC 18004:2015 Table 7 */ /* From ISO/IEC 18004:2015 Table 7 */
static const unsigned short int qr_data_codewords_L[] = { static const unsigned short qr_data_codewords_L[] = {
19, 34, 55, 80, 108, 136, 156, 194, 232, 274, 324, 370, 428, 461, 523, 589, 647, 19, 34, 55, 80, 108, 136, 156, 194, 232, 274, 324, 370, 428, 461, 523, 589, 647,
721, 795, 861, 932, 1006, 1094, 1174, 1276, 1370, 1468, 1531, 1631, 721, 795, 861, 932, 1006, 1094, 1174, 1276, 1370, 1468, 1531, 1631,
1735, 1843, 1955, 2071, 2191, 2306, 2434, 2566, 2702, 2812, 2956 1735, 1843, 1955, 2071, 2191, 2306, 2434, 2566, 2702, 2812, 2956
}; };
static const unsigned short int qr_data_codewords_M[] = { static const unsigned short qr_data_codewords_M[] = {
16, 28, 44, 64, 86, 108, 124, 154, 182, 216, 254, 290, 334, 365, 415, 453, 507, 16, 28, 44, 64, 86, 108, 124, 154, 182, 216, 254, 290, 334, 365, 415, 453, 507,
563, 627, 669, 714, 782, 860, 914, 1000, 1062, 1128, 1193, 1267, 563, 627, 669, 714, 782, 860, 914, 1000, 1062, 1128, 1193, 1267,
1373, 1455, 1541, 1631, 1725, 1812, 1914, 1992, 2102, 2216, 2334 1373, 1455, 1541, 1631, 1725, 1812, 1914, 1992, 2102, 2216, 2334
}; };
static const unsigned short int qr_data_codewords_Q[] = { static const unsigned short qr_data_codewords_Q[] = {
13, 22, 34, 48, 62, 76, 88, 110, 132, 154, 180, 206, 244, 261, 295, 325, 367, 13, 22, 34, 48, 62, 76, 88, 110, 132, 154, 180, 206, 244, 261, 295, 325, 367,
397, 445, 485, 512, 568, 614, 664, 718, 754, 808, 871, 911, 397, 445, 485, 512, 568, 614, 664, 718, 754, 808, 871, 911,
985, 1033, 1115, 1171, 1231, 1286, 1354, 1426, 1502, 1582, 1666 985, 1033, 1115, 1171, 1231, 1286, 1354, 1426, 1502, 1582, 1666
}; };
static const unsigned short int qr_data_codewords_H[] = { static const unsigned short qr_data_codewords_H[] = {
9, 16, 26, 36, 46, 60, 66, 86, 100, 122, 140, 158, 180, 197, 223, 253, 283, 9, 16, 26, 36, 46, 60, 66, 86, 100, 122, 140, 158, 180, 197, 223, 253, 283,
313, 341, 385, 406, 442, 464, 514, 538, 596, 628, 661, 701, 313, 341, 385, 406, 442, 464, 514, 538, 596, 628, 661, 701,
745, 793, 845, 901, 961, 986, 1054, 1096, 1142, 1222, 1276 745, 793, 845, 901, 961, 986, 1054, 1096, 1142, 1222, 1276
}; };
static const unsigned short int qr_total_codewords[] = { static const unsigned short qr_total_codewords[] = {
26, 44, 70, 100, 134, 172, 196, 242, 292, 346, 404, 466, 532, 581, 655, 733, 815, 26, 44, 70, 100, 134, 172, 196, 242, 292, 346, 404, 466, 532, 581, 655, 733, 815,
901, 991, 1085, 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, 901, 991, 1085, 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051,
2185, 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706 2185, 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706
}; };
static const unsigned short int rmqr_height[] = { static const unsigned short rmqr_height[] = {
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
@ -79,7 +81,7 @@ static const unsigned short int rmqr_height[] = {
17, 17, 17, 17, 17 17, 17, 17, 17, 17
}; };
static const unsigned short int rmqr_width[] = { static const unsigned short rmqr_width[] = {
43, 59, 77, 99, 139, 43, 59, 77, 99, 139,
43, 59, 77, 99, 139, 43, 59, 77, 99, 139,
27, 43, 59, 77, 99, 139, 27, 43, 59, 77, 99, 139,
@ -88,7 +90,7 @@ static const unsigned short int rmqr_width[] = {
43, 59, 77, 99, 139 43, 59, 77, 99, 139
}; };
static const unsigned short int rmqr_data_codewords_M[] = { static const unsigned short rmqr_data_codewords_M[] = {
6, 12, 20, 28, 44, // R7x 6, 12, 20, 28, 44, // R7x
12, 21, 31, 42, 63, // R9x 12, 21, 31, 42, 63, // R9x
7, 19, 31, 43, 57, 84, // R11x 7, 19, 31, 43, 57, 84, // R11x
@ -97,7 +99,7 @@ static const unsigned short int rmqr_data_codewords_M[] = {
39, 56, 78, 100, 152 // R17x 39, 56, 78, 100, 152 // R17x
}; };
static const unsigned short int rmqr_data_codewords_H[] = { static const unsigned short rmqr_data_codewords_H[] = {
3, 7, 10, 14, 24, // R7x 3, 7, 10, 14, 24, // R7x
7, 11, 17, 22, 33, // R9x 7, 11, 17, 22, 33, // R9x
5, 11, 15, 23, 29, 42, // R11x 5, 11, 15, 23, 29, 42, // R11x
@ -106,11 +108,11 @@ static const unsigned short int rmqr_data_codewords_H[] = {
21, 28, 38, 56, 76 // R17x 21, 28, 38, 56, 76 // R17x
}; };
static const short int rmqr_fixed_height_upper_bound[] = { static const short rmqr_fixed_height_upper_bound[] = {
-1, 4, 9, 15, 21, 26, 31 -1, 4, 9, 15, 21, 26, 31
}; };
static const unsigned short int rmqr_total_codewords[] = { static const unsigned short rmqr_total_codewords[] = {
13, 21, 32, 44, 68, // R7x 13, 21, 32, 44, 68, // R7x
21, 33, 49, 66, 99, // R9x 21, 33, 49, 66, 99, // R9x
15, 31, 47, 67, 89, 132, // R11x 15, 31, 47, 67, 89, 132, // R11x
@ -120,7 +122,7 @@ static const unsigned short int rmqr_total_codewords[] = {
}; };
static const unsigned short int rmqr_numeric_cci[] = { static const unsigned short rmqr_numeric_cci[] = {
4, 5, 6, 7, 7, 4, 5, 6, 7, 7,
5, 6, 7, 7, 8, 5, 6, 7, 7, 8,
4, 6, 7, 7, 8, 8, 4, 6, 7, 7, 8, 8,
@ -129,7 +131,7 @@ static const unsigned short int rmqr_numeric_cci[] = {
7, 8, 8, 8, 9 7, 8, 8, 8, 9
}; };
static const unsigned short int rmqr_alphanum_cci[] = { static const unsigned short rmqr_alphanum_cci[] = {
3, 5, 5, 6, 6, 3, 5, 5, 6, 6,
5, 5, 6, 6, 7, 5, 5, 6, 6, 7,
4, 5, 6, 6, 7, 7, 4, 5, 6, 6, 7, 7,
@ -138,7 +140,7 @@ static const unsigned short int rmqr_alphanum_cci[] = {
6, 7, 7, 8, 8 6, 7, 7, 8, 8
}; };
static const unsigned short int rmqr_byte_cci[] = { static const unsigned short rmqr_byte_cci[] = {
3, 4, 5, 5, 6, 3, 4, 5, 5, 6,
4, 5, 5, 6, 6, 4, 5, 5, 6, 6,
3, 5, 5, 6, 6, 7, 3, 5, 5, 6, 6, 7,
@ -147,7 +149,7 @@ static const unsigned short int rmqr_byte_cci[] = {
6, 6, 7, 7, 8 6, 6, 7, 7, 8
}; };
static const unsigned short int rmqr_kanji_cci[] = { static const unsigned short rmqr_kanji_cci[] = {
2, 3, 4, 5, 5, 2, 3, 4, 5, 5,
3, 4, 5, 5, 6, 3, 4, 5, 5, 6,
2, 4, 5, 5, 6, 6, 2, 4, 5, 5, 6, 6,
@ -194,7 +196,7 @@ static const char rmqr_blocks_H[] = {
2, 2, 3, 4, 6 // R17x 2, 2, 3, 4, 6 // R17x
}; };
static const unsigned short int qr_sizes[] = { static const unsigned short qr_sizes[] = {
21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97,
101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177
}; };
@ -208,7 +210,7 @@ static const char qr_align_loopsize[] = {
}; };
// Table E1 - Row/column coordinates of center module of alignment patterns // Table E1 - Row/column coordinates of center module of alignment patterns
static const unsigned short int qr_table_e1[] = { static const unsigned short qr_table_e1[] = {
6, 18, 0, 0, 0, 0, 0, 6, 18, 0, 0, 0, 0, 0,
6, 22, 0, 0, 0, 0, 0, 6, 22, 0, 0, 0, 0, 0,
6, 26, 0, 0, 0, 0, 0, 6, 26, 0, 0, 0, 0, 0,
@ -251,7 +253,7 @@ static const unsigned short int qr_table_e1[] = {
}; };
// Table D1 - Column coordinates of centre module of alignment patterns // Table D1 - Column coordinates of centre module of alignment patterns
static const unsigned short int rmqr_table_d1[] = { static const unsigned short rmqr_table_d1[] = {
21, 0, 0, 0, 21, 0, 0, 0,
19, 39, 0, 0, 19, 39, 0, 0,
25, 51, 0, 0, 25, 51, 0, 0,
@ -302,3 +304,6 @@ static const unsigned int rmqr_format_info_right[] = {
0x129B9, 0x1369C, 0x14A08, 0x1552D, 0x16B67, 0x17442, 0x18D6A, 0x1924F, 0x1AC05, 0x1B320, 0x129B9, 0x1369C, 0x14A08, 0x1552D, 0x16B67, 0x17442, 0x18D6A, 0x1924F, 0x1AC05, 0x1B320,
0x1CFB4, 0x1D091, 0x1EEDB, 0x1F1FE 0x1CFB4, 0x1D091, 0x1EEDB, 0x1F1FE
}; };
/* vim: set ts=4 sw=4 et : */
#endif /* Z_QR_H */

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
/* /*
* Adapted from the GNU LIBICONV library and patched to make compatible with * Adapted from the GNU LIBICONV library and patched to make compatible with
* https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFTJIS.TXT * https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFTJIS.TXT
@ -1516,7 +1515,7 @@ INTERNAL int sjis_wctomb_zint(unsigned int *r, const unsigned int wc) {
/* Convert UTF-8 string to Shift JIS and place in array of ints */ /* Convert UTF-8 string to Shift JIS and place in array of ints */
INTERNAL int sjis_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length, INTERNAL int sjis_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length,
unsigned int *jisdata) { unsigned int *ddata) {
int error_number; int error_number;
unsigned int i, length; unsigned int i, length;
#ifndef _MSC_VER #ifndef _MSC_VER
@ -1531,7 +1530,7 @@ INTERNAL int sjis_utf8(struct zint_symbol *symbol, const unsigned char source[],
} }
for (i = 0, length = *p_length; i < length; i++) { for (i = 0, length = *p_length; i < length; i++) {
if (!sjis_wctomb_zint(jisdata + i, utfdata[i])) { if (!sjis_wctomb_zint(ddata + i, utfdata[i])) {
strcpy(symbol->errtxt, "800: Invalid character in input data"); strcpy(symbol->errtxt, "800: Invalid character in input data");
return ZINT_ERROR_INVALID_DATA; return ZINT_ERROR_INVALID_DATA;
} }
@ -1541,7 +1540,7 @@ INTERNAL int sjis_utf8(struct zint_symbol *symbol, const unsigned char source[],
} }
/* Convert UTF-8 string to ECI and place in array of ints */ /* Convert UTF-8 string to ECI and place in array of ints */
INTERNAL int sjis_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *jisdata, INTERNAL int sjis_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte) { const int full_multibyte) {
if (is_eci_convertible(eci)) { if (is_eci_convertible(eci)) {
@ -1559,9 +1558,9 @@ INTERNAL int sjis_utf8_to_eci(const int eci, const unsigned char source[], int *
return error_number; return error_number;
} }
sjis_cpy(converted, p_length, jisdata, full_multibyte); sjis_cpy(converted, p_length, ddata, full_multibyte);
} else { } else {
sjis_cpy(source, p_length, jisdata, full_multibyte); sjis_cpy(source, p_length, ddata, full_multibyte);
} }
return 0; return 0;
@ -1569,7 +1568,7 @@ INTERNAL int sjis_utf8_to_eci(const int eci, const unsigned char source[], int *
/* If `full_multibyte` set, copy byte input stream to array of ints, putting double-bytes that match QR Kanji mode in /* If `full_multibyte` set, copy byte input stream to array of ints, putting double-bytes that match QR Kanji mode in
* a single entry. If `full_multibyte` not set, do a straight copy */ * a single entry. If `full_multibyte` not set, do a straight copy */
INTERNAL void sjis_cpy(const unsigned char source[], int *p_length, unsigned int *jisdata, const int full_multibyte) { INTERNAL void sjis_cpy(const unsigned char source[], int *p_length, unsigned int *ddata, const int full_multibyte) {
unsigned int i, j, jis, length; unsigned int i, j, jis, length;
unsigned char c; unsigned char c;
@ -1581,20 +1580,34 @@ INTERNAL void sjis_cpy(const unsigned char source[], int *p_length, unsigned int
if ((jis >= 0x8140 && jis <= 0x9FFC) || (jis >= 0xE040 && jis <= 0xEBBF)) { if ((jis >= 0x8140 && jis <= 0x9FFC) || (jis >= 0xE040 && jis <= 0xEBBF)) {
/* This may or may not be valid Shift JIS, but don't care as long as it can be encoded in /* This may or may not be valid Shift JIS, but don't care as long as it can be encoded in
* QR Kanji mode */ * QR Kanji mode */
jisdata[j] = jis; ddata[j] = jis;
i++; i++;
} else { } else {
jisdata[j] = c; ddata[j] = c;
} }
} else { } else {
jisdata[j] = c; ddata[j] = c;
} }
} }
*p_length = j; *p_length = j;
} else { } else {
/* Straight copy */ /* Straight copy */
for (i = 0, length = *p_length; i < length; i++) { for (i = 0, length = *p_length; i < length; i++) {
jisdata[i] = source[i]; ddata[i] = source[i];
} }
} }
} }
/* Call `sjis_cpy()` for each segment */
INTERNAL void sjis_cpy_segs(struct zint_seg segs[], const int seg_count, unsigned int *ddata,
const int full_multibyte) {
int i;
unsigned int *dd = ddata;
for (i = 0; i < seg_count; i++) {
sjis_cpy(segs[i].source, &segs[i].length, dd, full_multibyte);
dd += segs[i].length;
}
}
/* vim: set ts=4 sw=4 et : */

View File

@ -1,7 +1,7 @@
/* sjis.h - Unicode to Shift JIS /* sjis.h - Unicode to Shift JIS
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -28,10 +28,9 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#ifndef SJIS_H #ifndef Z_SJIS_H
#define SJIS_H #define Z_SJIS_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -39,13 +38,17 @@ extern "C" {
INTERNAL int sjis_wctomb_zint(unsigned int *r, const unsigned int wc); INTERNAL int sjis_wctomb_zint(unsigned int *r, const unsigned int wc);
INTERNAL int sjis_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length, INTERNAL int sjis_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length,
unsigned int *jisdata); unsigned int *ddata);
INTERNAL int sjis_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *jisdata, INTERNAL int sjis_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte);
INTERNAL void sjis_cpy(const unsigned char source[], int *p_length, unsigned int *ddata, const int full_multibyte);
INTERNAL void sjis_cpy_segs(struct zint_seg segs[], const int seg_count, unsigned int *ddata,
const int full_multibyte); const int full_multibyte);
INTERNAL void sjis_cpy(const unsigned char source[], int *p_length, unsigned int *jisdata, const int full_multibyte);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* SJIS_H */ /* vim: set ts=4 sw=4 et : */
#endif /* Z_SJIS_H */

View File

@ -341,7 +341,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -318,7 +317,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -392,3 +391,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -2431,7 +2431,7 @@ static void test_encode(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
@ -2459,6 +2459,290 @@ static void test_encode(int index, int generate, int debug) {
testFinish(); testFinish();
} }
static void test_encode_segs(int index, int generate, int debug) {
struct item {
int input_mode;
int output_options;
int option_1;
int option_2;
struct zint_seg segs[3];
int ret;
int expected_rows;
int expected_width;
int bwipp_cmp;
char *comment;
char *expected;
};
struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, -1, -1, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 15, 15, 1, "ISO/IEC 24778:2008 16.5 example",
"001111000011111"
"110111100100011"
"111100001000111"
"101111111111111"
"001100000001111"
"000101111101101"
"110101000101101"
"011101010101001"
"101101000101010"
"110101111101001"
"000100000001011"
"000111111111111"
"010001100010001"
"001010111001010"
"000001011100111"
},
/* 1*/ { UNICODE_MODE, -1, -1, -1, { { TU(""), -1, 0 }, { TU("Ж"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 15, 15, 1, "ISO/IEC 24778:2008 16.5 example auto-ECI",
"001111000011111"
"110111100100011"
"111100001000111"
"101111111111111"
"001100000001111"
"000101111101101"
"110101000101101"
"011101010101001"
"101101000101010"
"110101111101001"
"000100000001011"
"000111111111111"
"010001100010001"
"001010111001010"
"000001011100111"
},
/* 2*/ { UNICODE_MODE, -1, -1, 2, { { TU("Ж"), -1, 7 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, 0, 19, 19, 1, "ISO/IEC 24778:2008 16.5 example inverted",
"0000011010000000000"
"0000001101101010000"
"0111000110100011110"
"0010011111100001110"
"0001110100110010000"
"0110111111111111110"
"0000010000000100011"
"1100110111110110000"
"0011110100010110101"
"1100010101010100001"
"1110010100010100000"
"1001010111110100000"
"1001010000000100011"
"0011011111111110001"
"0100001111100000111"
"1011111010011010111"
"1111010101011010101"
"1000001011111001010"
"0100000000011100111"
},
/* 3*/ { UNICODE_MODE, -1, -1, 2, { { TU("Ж"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 19, 19, 1, "ISO/IEC 24778:2008 16.5 example inverted auto-ECI",
"0000011010000000000"
"0000001101101010000"
"0111000110100011110"
"0010011111100001110"
"0001110100110010000"
"0110111111111111110"
"0000010000000100011"
"1100110111110110000"
"0011110100010110101"
"1100010101010100001"
"1110010100010100000"
"1001010111110100000"
"1001010000000100011"
"0011011111111110001"
"0100001111100000111"
"1011111010011010111"
"1111010101011010101"
"1000001011111001010"
"0100000000011100111"
},
/* 4*/ { UNICODE_MODE, -1, -1, -1, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 49, 49, 0, "AIM ITS/04-023:2022 Annex A example; BWIPP different encodation (better)",
"0000110010100000001100011100010010010010100010101"
"0001100000010101011010010100011100000001000100010"
"0001110011110000000000101101100110101001100000000"
"0110001001100100100100110111000111101010011110100"
"0001011110100011010010001000111110010110111010111"
"0010010001101101100111010110111000001101001111101"
"0110001110110010010000111001100100011001100101001"
"0110001101010110010001010100001101001110000110000"
"1010101010101010101010101010101010101010101010101"
"0100110100001010010110010100111110010110001010010"
"1110111010111110101110101010011011000100100100010"
"1000000100001011101010010110010011101011000101001"
"0101101011110000011100001001000011010101101101111"
"0010001100010010110111110101101001011110000011010"
"0100000011001011111011111011111010001101100110000"
"1000010001011000100111100100010100101010001101101"
"0101110010010100010110101010010100011001111001011"
"1101110001010101111001110000100101000010001111000"
"0001110110000111111111111111111101110001111110000"
"0000010101001010011000000000001110111111001001000"
"0000010010100111111011111111101101100011110000110"
"1000010100010111101010000000101011000001010011101"
"1110011111100110111010111110101000110101100100011"
"0101100000101101001010100010101011101000001111110"
"1010101010101010101010101010101010101010101010101"
"1011101100001100011010100010101111011100011001000"
"0011111111100111101010111110101111011100111111001"
"1000100100011010001010000000101010000101001110110"
"0111000010011110111011111111101000101101110100000"
"0100100101000110001000000000001010101001001111100"
"0110011110001110101111111111111111101101110011101"
"0011011000010110000010110100110010001000001001100"
"0001100111010000001111001101101000000111100000011"
"0111100000100011110011100001000110110000011010011"
"0110011110111110100010011001001011111111101100100"
"0111111001101011000101000001010010110100001101000"
"1101000010001010010001101010001111110111101100110"
"1011110000000110111001010011000110001000000110110"
"0000010110110000101010001110111000011101101001001"
"1010010100110110000011000000110100110100000100001"
"1010101010101010101010101010101010101010101010101"
"0000100100100000000110100100000001001000011010110"
"1000101110101110011110001000100100110100111100001"
"0000110101111100011101100000001111001111010100000"
"0101000010011111110110101100010011010010101110100"
"0000100101011010101001110100111010000000001010011"
"0001001111111100100111011100111101001111101100011"
"1001101000110101111010100111100011111001000100101"
"0001001010011000000100101101100110101000100000000"
},
/* 5*/ { DATA_MODE, -1, -1, -1, { { TU("\357"), 1, 0 }, { TU("\357"), 1, 7 }, { TU("\357"), 1, 0 } }, 0, 19, 19, 1, "Standard example + extra seg, data mode",
"1110011101010111000"
"1100010001011100011"
"1001110101000010110"
"0001000011101001111"
"0001110100111011000"
"1111111111111110101"
"1100110000000111011"
"0110010111110100111"
"1110110100010101011"
"1010010101010110001"
"0010010100010100111"
"0001110111110111010"
"0011110000000111100"
"0000011111111110001"
"0111001101000000011"
"0011000000111110111"
"1111111001101000010"
"0110001101100001010"
"0111100111100000010"
},
/* 6*/ { UNICODE_MODE, -1, -1, -1, { { TU("12345678"), -1, 3 }, { TU("ABCDEFGH"), -1, 4 }, { TU("123456789"), -1, 5 } }, 0, 23, 23, 0, "Mode change between segs; BWIPP different encodation",
"00100011011101100111000"
"00101011010000010111111"
"00011001010101011010100"
"01011001100000101110000"
"00011000100010011101100"
"00110000100011111111000"
"01001111100101001111000"
"01000111111111111000110"
"01010111000000011000101"
"11010101011111011111000"
"11111101010001011100100"
"00100011010101011101010"
"01000001010001010001111"
"10111101011111010110010"
"10001001000000010111000"
"00001001111111111011111"
"10101100101001000010000"
"10110011100001111000110"
"11101000100001111011010"
"00010010100111001011100"
"11111111000010000100001"
"10101100001011010010000"
"10001000000000111000011"
},
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
char escaped[1024];
char cmp_buf[32768];
char cmp_msg[1024];
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); // Only do ZXing-C++ test if asked, too slow otherwise
testStart("test_encode_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, BARCODE_AZTEC, data[i].input_mode, -1 /*eci*/,
data[i].option_1, data[i].option_2, -1, data[i].output_options, NULL, 0, debug);
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
char escaped1[4096];
char escaped2[4096];
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length;
int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length;
printf(" /*%3d*/ { %s, %s, %d, %d, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n",
i, testUtilInputModeName(data[i].input_mode), testUtilOutputOptionsName(data[i].output_options),
data[i].option_1, data[i].option_2,
testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci,
testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci,
testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci,
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment);
testUtilModulesPrint(symbol, " ", "\n");
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) {
if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
ret = testUtilBwippSegs(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf));
assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected);
}
}
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length, debug)) {
if (data[i].input_mode == DATA_MODE) {
if (debug & ZINT_DEBUG_TEST_PRINT) {
printf("i:%d multiple segments in DATA_MODE not currently supported for ZXing-C++ testing (%s)\n",
i, testUtilBarcodeName(symbol->symbology));
}
} else {
int cmp_len, ret_len;
char modules_dump[22801 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length,
modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count,
NULL /*primary*/, escaped, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped);
}
}
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
// #181 Nico Gunkel OSS-Fuzz // #181 Nico Gunkel OSS-Fuzz
static void test_fuzz(int index, int debug) { static void test_fuzz(int index, int debug) {
@ -3011,6 +3295,7 @@ int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_options", test_options, 1, 0, 1 }, { "test_options", test_options, 1, 0, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_encode_segs", test_encode_segs, 1, 1, 1 },
{ "test_fuzz", test_fuzz, 1, 0, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 },
{ "test_perf", test_perf, 1, 0, 1 }, { "test_perf", test_perf, 1, 0, 1 },
}; };

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -448,7 +447,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -507,3 +506,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -497,7 +496,7 @@ static void test_encode(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -567,3 +566,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -456,7 +456,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -74,112 +73,118 @@ static void test_large(int index, int debug) {
/* 25*/ { -1, 1, { 0, 0, "" }, "A", 14, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 25*/ { -1, 1, { 0, 0, "" }, "A", 14, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 26*/ { 3, 1, { 0, 0, "" }, "A", 4, 0, 16, 18 }, /* With ECI */ /* 26*/ { 3, 1, { 0, 0, "" }, "A", 4, 0, 16, 18 }, /* With ECI */
/* 27*/ { 3, 1, { 0, 0, "" }, "A", 5, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 27*/ { 3, 1, { 0, 0, "" }, "A", 5, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 26*/ { -1, 1, { 1, 2, "" }, "A", 10, 0, 16, 18 }, /* With Structured Append */ /* 28*/ { -1, 1, { 1, 2, "" }, "A", 10, 0, 16, 18 }, /* With Structured Append */
/* 27*/ { -1, 1, { 1, 2, "" }, "A", 11, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 29*/ { -1, 1, { 1, 2, "" }, "A", 11, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 28*/ { 3, 1, { 1, 2, "" }, "A", 2, 0, 16, 18 }, /* With ECI and Structured Append 1st symbol */ /* 30*/ { 3, 1, { 1, 2, "" }, "A", 2, 0, 16, 18 }, /* With ECI and Structured Append 1st symbol */
/* 29*/ { 3, 1, { 1, 2, "" }, "A", 3, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 31*/ { 3, 1, { 1, 2, "" }, "A", 3, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 30*/ { 3, 1, { 2, 2, "" }, "A", 4, 0, 16, 18 }, /* With ECI and Structured Append subsequent symbol */ /* 32*/ { 3, 1, { 2, 2, "" }, "A", 4, 0, 16, 18 }, /* With ECI and Structured Append subsequent symbol */
/* 31*/ { 3, 1, { 2, 2, "" }, "A", 5, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 33*/ { 3, 1, { 2, 2, "" }, "A", 5, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 32*/ { -1, 1, { 0, 0, "" }, "\001", 10, 0, 16, 18 }, /* 34*/ { -1, 1, { 0, 0, "" }, "\001", 10, 0, 16, 18 },
/* 33*/ { -1, 1, { 0, 0, "" }, "\001", 11, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 35*/ { -1, 1, { 0, 0, "" }, "\001", 11, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 34*/ { -1, 1, { 0, 0, "" }, "\200", 8, 0, 16, 18 }, /* 36*/ { -1, 1, { 0, 0, "" }, "\200", 8, 0, 16, 18 },
/* 35*/ { -1, 1, { 0, 0, "" }, "\200", 9, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 37*/ { -1, 1, { 0, 0, "" }, "\200", 9, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 36*/ { -1, 2, { 0, 0, "" }, "1", 44, 0, 22, 22 }, /* Version B */ /* 38*/ { -1, 2, { 0, 0, "" }, "1", 44, 0, 22, 22 }, /* Version B */
/* 37*/ { -1, 2, { 0, 0, "" }, "1", 45, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 39*/ { -1, 2, { 0, 0, "" }, "1", 45, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 38*/ { -1, 2, { 0, 0, "" }, "A", 27, 0, 22, 22 }, /* 40*/ { -1, 2, { 0, 0, "" }, "A", 27, 0, 22, 22 },
/* 39*/ { -1, 2, { 0, 0, "" }, "A", 28, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 41*/ { -1, 2, { 0, 0, "" }, "A", 28, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 40*/ { -1, 2, { 0, 0, "" }, "A", 26, 0, 22, 22 }, /* 42*/ { -1, 2, { 0, 0, "" }, "A", 26, 0, 22, 22 },
/* 41*/ { -1, 2, { 0, 0, "" }, "\001", 19, 0, 22, 22 }, /* 43*/ { -1, 2, { 0, 0, "" }, "\001", 19, 0, 22, 22 },
/* 42*/ { -1, 2, { 0, 0, "" }, "\001", 20, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 44*/ { -1, 2, { 0, 0, "" }, "\001", 20, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 43*/ { -1, 2, { 0, 0, "" }, "\200", 17, 0, 22, 22 }, /* 45*/ { -1, 2, { 0, 0, "" }, "\200", 17, 0, 22, 22 },
/* 44*/ { -1, 2, { 0, 0, "" }, "\200", 18, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 46*/ { -1, 2, { 0, 0, "" }, "\200", 18, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 45*/ { -1, 3, { 0, 0, "" }, "1", 104, 0, 28, 32 }, /* Version C */ /* 47*/ { -1, 3, { 0, 0, "" }, "1", 104, 0, 28, 32 }, /* Version C */
/* 46*/ { -1, 3, { 0, 0, "" }, "1", 105, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 48*/ { -1, 3, { 0, 0, "" }, "1", 105, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 47*/ { -1, 3, { 0, 0, "" }, "A", 64, 0, 28, 32 }, /* 49*/ { -1, 3, { 0, 0, "" }, "A", 64, 0, 28, 32 },
/* 48*/ { -1, 3, { 0, 0, "" }, "A", 65, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 50*/ { -1, 3, { 0, 0, "" }, "A", 65, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 49*/ { -1, 3, { 0, 0, "" }, "\001", 44, 0, 28, 32 }, /* 51*/ { -1, 3, { 0, 0, "" }, "\001", 44, 0, 28, 32 },
/* 50*/ { -1, 3, { 0, 0, "" }, "\001", 45, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 52*/ { -1, 3, { 0, 0, "" }, "\001", 45, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 51*/ { -1, 3, { 0, 0, "" }, "\200", 42, 0, 28, 32 }, /* 53*/ { -1, 3, { 0, 0, "" }, "\200", 42, 0, 28, 32 },
/* 52*/ { -1, 3, { 0, 0, "" }, "\200", 43, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 54*/ { -1, 3, { 0, 0, "" }, "\200", 43, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 53*/ { -1, 4, { 0, 0, "" }, "1", 217, 0, 40, 42 }, /* Version D */ /* 55*/ { -1, 4, { 0, 0, "" }, "1", 217, 0, 40, 42 }, /* Version D */
/* 54*/ { -1, 4, { 0, 0, "" }, "1", 218, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 56*/ { -1, 4, { 0, 0, "" }, "1", 218, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 55*/ { -1, 4, { 0, 0, "" }, "A", 135, 0, 40, 42 }, /* 57*/ { -1, 4, { 0, 0, "" }, "A", 135, 0, 40, 42 },
/* 56*/ { -1, 4, { 0, 0, "" }, "A", 136, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 58*/ { -1, 4, { 0, 0, "" }, "A", 136, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 57*/ { -1, 4, { 0, 0, "" }, "\001", 91, 0, 40, 42 }, /* 59*/ { -1, 4, { 0, 0, "" }, "\001", 91, 0, 40, 42 },
/* 58*/ { -1, 4, { 0, 0, "" }, "\001", 92, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 60*/ { -1, 4, { 0, 0, "" }, "\001", 92, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 59*/ { -1, 4, { 0, 0, "" }, "\200", 89, 0, 40, 42 }, /* 61*/ { -1, 4, { 0, 0, "" }, "\200", 89, 0, 40, 42 },
/* 60*/ { -1, 4, { 0, 0, "" }, "\200", 90, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 62*/ { -1, 4, { 0, 0, "" }, "\200", 90, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 61*/ { -1, 5, { 0, 0, "" }, "1", 435, 0, 52, 54 }, /* Version E (note 435 multiple of 3) */ /* 63*/ { -1, 5, { 0, 0, "" }, "1", 435, 0, 52, 54 }, /* Version E (note 435 multiple of 3) */
/* 62*/ { -1, 5, { 0, 0, "" }, "1", 436, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 64*/ { -1, 5, { 0, 0, "" }, "1", 436, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 63*/ { -1, 5, { 0, 0, "" }, "1", 434, ZINT_ERROR_TOO_LONG, -1, -1 }, /* NOTE: a quirk of decimal end-of-data processing is existence of "lower maxs" if digits are not a multiple of 3 */ /* 65*/ { -1, 5, { 0, 0, "" }, "1", 434, ZINT_ERROR_TOO_LONG, -1, -1 }, /* NOTE: a quirk of decimal end-of-data processing is existence of "lower maxs" if digits are not a multiple of 3 */
/* 64*/ { -1, 5, { 0, 0, "" }, "1", 433, 0, 52, 54 }, /* 66*/ { -1, 5, { 0, 0, "" }, "1", 433, 0, 52, 54 },
/* 65*/ { -1, 5, { 0, 0, "" }, "A", 271, 0, 52, 54 }, /* 67*/ { -1, 5, { 0, 0, "" }, "A", 271, 0, 52, 54 },
/* 66*/ { -1, 5, { 0, 0, "" }, "A", 272, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 68*/ { -1, 5, { 0, 0, "" }, "A", 272, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 67*/ { -1, 5, { 0, 0, "" }, "\001", 182, 0, 52, 54 }, /* 69*/ { -1, 5, { 0, 0, "" }, "\001", 182, 0, 52, 54 },
/* 68*/ { -1, 5, { 0, 0, "" }, "\001", 183, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 70*/ { -1, 5, { 0, 0, "" }, "\001", 183, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 69*/ { -1, 5, { 0, 0, "" }, "\200", 180, 0, 52, 54 }, /* 71*/ { -1, 5, { 0, 0, "" }, "\200", 180, 0, 52, 54 },
/* 70*/ { -1, 5, { 0, 0, "" }, "\200", 181, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 72*/ { -1, 5, { 0, 0, "" }, "\200", 181, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 71*/ { -1, 6, { 0, 0, "" }, "1", 886, 0, 70, 76 }, /* Version F */ /* 73*/ { -1, 6, { 0, 0, "" }, "1", 886, 0, 70, 76 }, /* Version F */
/* 72*/ { -1, 6, { 0, 0, "" }, "1", 887, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 74*/ { -1, 6, { 0, 0, "" }, "1", 887, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 73*/ { -1, 6, { 0, 0, "" }, "A", 553, 0, 70, 76 }, /* 75*/ { -1, 6, { 0, 0, "" }, "A", 553, 0, 70, 76 },
/* 74*/ { -1, 6, { 0, 0, "" }, "A", 554, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 76*/ { -1, 6, { 0, 0, "" }, "A", 554, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 75*/ { -1, 6, { 0, 0, "" }, "\001", 370, 0, 70, 76 }, /* 77*/ { -1, 6, { 0, 0, "" }, "\001", 370, 0, 70, 76 },
/* 76*/ { -1, 6, { 0, 0, "" }, "\001", 371, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 78*/ { -1, 6, { 0, 0, "" }, "\001", 371, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 77*/ { -1, 6, { 0, 0, "" }, "\200", 368, 0, 70, 76 }, /* 79*/ { -1, 6, { 0, 0, "" }, "\200", 368, 0, 70, 76 },
/* 78*/ { -1, 6, { 0, 0, "" }, "\200", 369, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 80*/ { -1, 6, { 0, 0, "" }, "\200", 369, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 79*/ { -1, 7, { 0, 0, "" }, "1", 1755, 0, 104, 98 }, /* Version G (note 1755 multiple of 3) */ /* 81*/ { -1, 7, { 0, 0, "" }, "1", 1755, 0, 104, 98 }, /* Version G (note 1755 multiple of 3) */
/* 80*/ { -1, 7, { 0, 0, "" }, "1", 1756, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 82*/ { -1, 7, { 0, 0, "" }, "1", 1756, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 81*/ { -1, 7, { 0, 0, "" }, "1", 1754, ZINT_ERROR_TOO_LONG, -1, -1 }, /* NOTE: a quirk of decimal end-of-data processing is existence of "lower maxs" if digits are not a multiple of 3 */ /* 83*/ { -1, 7, { 0, 0, "" }, "1", 1754, ZINT_ERROR_TOO_LONG, -1, -1 }, /* NOTE: a quirk of decimal end-of-data processing is existence of "lower maxs" if digits are not a multiple of 3 */
/* 82*/ { -1, 7, { 0, 0, "" }, "1", 1753, 0, 104, 98 }, /* 84*/ { -1, 7, { 0, 0, "" }, "1", 1753, 0, 104, 98 },
/* 83*/ { -1, 7, { 0, 0, "" }, "A", 1096, 0, 104, 98 }, /* 85*/ { -1, 7, { 0, 0, "" }, "A", 1096, 0, 104, 98 },
/* 84*/ { -1, 7, { 0, 0, "" }, "A", 1097, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 86*/ { -1, 7, { 0, 0, "" }, "A", 1097, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 85*/ { -1, 7, { 0, 0, "" }, "\001", 732, 0, 104, 98 }, /* 87*/ { -1, 7, { 0, 0, "" }, "\001", 732, 0, 104, 98 },
/* 86*/ { -1, 7, { 0, 0, "" }, "\001", 733, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 88*/ { -1, 7, { 0, 0, "" }, "\001", 733, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 87*/ { -1, 7, { 0, 0, "" }, "\200", 730, 0, 104, 98 }, /* 89*/ { -1, 7, { 0, 0, "" }, "\200", 730, 0, 104, 98 },
/* 88*/ { -1, 7, { 0, 0, "" }, "\200", 731, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 90*/ { -1, 7, { 0, 0, "" }, "\200", 731, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 89*/ { -1, 8, { 0, 0, "" }, "1", 3550, 0, 148, 134 }, /* Version H */ /* 91*/ { -1, 8, { 0, 0, "" }, "1", 3550, 0, 148, 134 }, /* Version H */
/* 90*/ { -1, 8, { 0, 0, "" }, "1", 3551, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 92*/ { -1, 8, { 0, 0, "" }, "1", 3551, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 91*/ { -1, 8, { 0, 0, "" }, "A", 2218, 0, 148, 134 }, /* 93*/ { -1, 8, { 0, 0, "" }, "A", 2218, 0, 148, 134 },
/* 92*/ { -1, 8, { 0, 0, "" }, "A", 2219, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 94*/ { -1, 8, { 0, 0, "" }, "A", 2219, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 93*/ { -1, 8, { 0, 0, "" }, "\001", 1480, 0, 148, 134 }, /* 95*/ { -1, 8, { 0, 0, "" }, "\001", 1480, 0, 148, 134 },
/* 94*/ { -1, 8, { 0, 0, "" }, "\001", 1481, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 96*/ { -1, 8, { 0, 0, "" }, "\001", 1481, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 95*/ { -1, 8, { 0, 0, "" }, "\200", 1478, 0, 148, 134 }, /* 97*/ { -1, 8, { 0, 0, "" }, "\200", 1478, 0, 148, 134 },
/* 96*/ { -1, 8, { 0, 0, "" }, "\200", 1479, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 98*/ { -1, 8, { 0, 0, "" }, "\200", 1479, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 97*/ { -1, 9, { 0, 0, "" }, "1", 6, 0, 8, 11 }, /* Version S-10 */ /* 99*/ { -1, 9, { 0, 0, "" }, "1", 6, 0, 8, 11 }, /* Version S-10 */
/* 98*/ { -1, 9, { 0, 0, "" }, "1", 7, 0, 8, 21 }, /* -> S-20 */ /*100*/ { -1, 9, { 0, 0, "" }, "1", 7, 0, 8, 21 }, /* -> S-20 */
/* 99*/ { -1, 9, { 0, 0, "" }, "1", 12, 0, 8, 21 }, /* Version S-20 */ /*101*/ { -1, 9, { 0, 0, "" }, "1", 12, 0, 8, 21 }, /* Version S-20 */
/*100*/ { -1, 9, { 0, 0, "" }, "1", 13, 0, 8, 31 }, /* -> S-30 */ /*102*/ { -1, 9, { 0, 0, "" }, "1", 13, 0, 8, 31 }, /* -> S-30 */
/*101*/ { -1, 9, { 0, 0, "" }, "1", 18, 0, 8, 31 }, /* Version S-30 */ /*103*/ { -1, 9, { 0, 0, "" }, "1", 18, 0, 8, 31 }, /* Version S-30 */
/*102*/ { -1, 9, { 0, 0, "" }, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, /*104*/ { -1, 9, { 0, 0, "" }, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1 },
/*103*/ { -1, 9, { 0, 0, "" }, "1", 17, 0, 8, 31 }, /*105*/ { -1, 9, { 0, 0, "" }, "1", 17, 0, 8, 31 },
/*104*/ { -1, 10, { 0, 0, "" }, "1", 22, 0, 16, 17 }, /* Version T-16 */ /*106*/ { -1, 10, { 0, 0, "" }, "1", 22, 0, 16, 17 }, /* Version T-16 */
/*105*/ { -1, 10, { 0, 0, "" }, "1", 23, 0, 16, 33 }, /* -> T-32 */ /*107*/ { -1, 10, { 0, 0, "" }, "1", 23, 0, 16, 33 }, /* -> T-32 */
/*106*/ { -1, 10, { 0, 0, "" }, "A", 13, 0, 16, 17 }, /*108*/ { -1, 10, { 0, 0, "" }, "A", 13, 0, 16, 17 },
/*107*/ { -1, 10, { 0, 0, "" }, "A", 14, 0, 16, 33 }, /* -> T-32 */ /*109*/ { -1, 10, { 0, 0, "" }, "A", 14, 0, 16, 33 }, /* -> T-32 */
/*108*/ { -1, 10, { 0, 0, "" }, "\001", 10, 0, 16, 17 }, /*110*/ { -1, 10, { 0, 0, "" }, "\001", 10, 0, 16, 17 },
/*109*/ { -1, 10, { 0, 0, "" }, "\001", 11, 0, 16, 33 }, /* -> T-32 */ /*111*/ { -1, 10, { 0, 0, "" }, "\001", 11, 0, 16, 33 }, /* -> T-32 */
/*110*/ { -1, 10, { 0, 0, "" }, "\200", 8, 0, 16, 17 }, /*112*/ { -1, 10, { 0, 0, "" }, "\200", 8, 0, 16, 17 },
/*111*/ { -1, 10, { 0, 0, "" }, "\200", 9, 0, 16, 33 }, /* -> T-32 */ /*113*/ { -1, 10, { 0, 0, "" }, "\200", 9, 0, 16, 33 }, /* -> T-32 */
/*112*/ { -1, 10, { 0, 0, "" }, "1", 56, 0, 16, 33 }, /* Version T-32 */ /*114*/ { -1, 10, { 0, 0, "" }, "1", 56, 0, 16, 33 }, /* Version T-32 */
/*113*/ { -1, 10, { 0, 0, "" }, "1", 57, 0, 16, 49 }, /* -> T-48 */ /*115*/ { -1, 10, { 0, 0, "" }, "1", 57, 0, 16, 49 }, /* -> T-48 */
/*114*/ { -1, 10, { 0, 0, "" }, "A", 34, 0, 16, 33 }, /*116*/ { -1, 10, { 0, 0, "" }, "A", 34, 0, 16, 33 },
/*115*/ { -1, 10, { 0, 0, "" }, "A", 35, 0, 16, 49 }, /* -> T-48 */ /*117*/ { -1, 10, { 0, 0, "" }, "A", 35, 0, 16, 49 }, /* -> T-48 */
/*116*/ { -1, 10, { 0, 0, "" }, "\001", 24, 0, 16, 33 }, /*118*/ { -1, 10, { 0, 0, "" }, "\001", 24, 0, 16, 33 },
/*117*/ { -1, 10, { 0, 0, "" }, "\001", 25, 0, 16, 49 }, /* -> T-48 */ /*119*/ { -1, 10, { 0, 0, "" }, "\001", 25, 0, 16, 49 }, /* -> T-48 */
/*118*/ { -1, 10, { 0, 0, "" }, "\200", 22, 0, 16, 33 }, /*120*/ { -1, 10, { 0, 0, "" }, "\200", 22, 0, 16, 33 },
/*119*/ { -1, 10, { 0, 0, "" }, "\200", 23, 0, 16, 49 }, /* -> T-48 */ /*121*/ { -1, 10, { 0, 0, "" }, "\200", 23, 0, 16, 49 }, /* -> T-48 */
/*120*/ { -1, 10, { 0, 0, "" }, "1", 90, 0, 16, 49 }, /* Version T-48 (note 90 multiple of 3) */ /*122*/ { -1, 10, { 0, 0, "" }, "1", 90, 0, 16, 49 }, /* Version T-48 (note 90 multiple of 3) */
/*121*/ { -1, 10, { 0, 0, "" }, "1", 91, ZINT_ERROR_TOO_LONG, -1, -1 }, /*123*/ { -1, 10, { 0, 0, "" }, "1", 91, ZINT_ERROR_TOO_LONG, -1, -1 },
/*122*/ { -1, 10, { 0, 0, "" }, "1", 89, ZINT_ERROR_TOO_LONG, -1, -1 }, /* NOTE: a quirk of decimal end-of-data processing is existence of "lower maxs" if digits are not a multiple of 3 */ /*124*/ { -1, 10, { 0, 0, "" }, "1", 89, ZINT_ERROR_TOO_LONG, -1, -1 }, /* NOTE: a quirk of decimal end-of-data processing is existence of "lower maxs" if digits are not a multiple of 3 */
/*123*/ { -1, 10, { 0, 0, "" }, "1", 88, 0, 16, 49 }, /*125*/ { -1, 10, { 0, 0, "" }, "1", 88, 0, 16, 49 },
/*124*/ { -1, 10, { 0, 0, "" }, "A", 55, 0, 16, 49 }, /*126*/ { -1, 10, { 0, 0, "" }, "A", 55, 0, 16, 49 },
/*125*/ { -1, 10, { 0, 0, "" }, "A", 56, ZINT_ERROR_TOO_LONG, -1, -1 }, /*127*/ { -1, 10, { 0, 0, "" }, "A", 56, ZINT_ERROR_TOO_LONG, -1, -1 },
/*126*/ { -1, 10, { 0, 0, "" }, "A", 90, ZINT_ERROR_TOO_LONG, -1, -1 }, /*128*/ { -1, 10, { 0, 0, "" }, "A", 90, ZINT_ERROR_TOO_LONG, -1, -1 },
/*127*/ { -1, 10, { 0, 0, "" }, "\001", 38, 0, 16, 49 }, /*129*/ { -1, 10, { 0, 0, "" }, "\001", 38, 0, 16, 49 },
/*128*/ { -1, 10, { 0, 0, "" }, "\001", 39, ZINT_ERROR_TOO_LONG, -1, -1 }, /*130*/ { -1, 10, { 0, 0, "" }, "\001", 39, ZINT_ERROR_TOO_LONG, -1, -1 },
/*129*/ { -1, 10, { 0, 0, "" }, "\001", 90, ZINT_ERROR_TOO_LONG, -1, -1 }, /*131*/ { -1, 10, { 0, 0, "" }, "\001", 90, ZINT_ERROR_TOO_LONG, -1, -1 },
/*130*/ { -1, 10, { 0, 0, "" }, "\200", 36, 0, 16, 49 }, /*132*/ { -1, 10, { 0, 0, "" }, "\\", 38, 0, 16, 49 },
/*131*/ { -1, 10, { 0, 0, "" }, "\200", 37, ZINT_ERROR_TOO_LONG, -1, -1 }, /*133*/ { -1, 10, { 0, 0, "" }, "\\", 39, ZINT_ERROR_TOO_LONG, -1, -1 },
/*134*/ { -1, 10, { 0, 0, "" }, "\200", 36, 0, 16, 49 },
/*135*/ { -1, 10, { 0, 0, "" }, "\200", 37, ZINT_ERROR_TOO_LONG, -1, -1 },
/*136*/ { 3, 10, { 0, 0, "" }, "A", 46, 0, 16, 49 }, /* Version T-48 with ECI (9 less as PAD escape char + "\123456") */
/*137*/ { 3, 10, { 0, 0, "" }, "A", 47, ZINT_ERROR_TOO_LONG, -1, -1 },
/*138*/ { 3, 10, { 0, 0, "" }, "\001", 32, 0, 16, 49 },
/*139*/ { 3, 10, { 0, 0, "" }, "\001", 33, ZINT_ERROR_TOO_LONG, -1, -1 },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@ -2927,7 +2932,7 @@ static void test_encode(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -2944,6 +2949,405 @@ static void test_encode(int index, int generate, int debug) {
testFinish(); testFinish();
} }
static void test_encode_segs(int index, int generate, int debug) {
struct item {
int input_mode;
int option_2;
struct zint_structapp structapp;
struct zint_seg segs[3];
int ret;
int expected_rows;
int expected_width;
int bwipp_cmp;
char *comment;
char *expected;
};
// Figure examples AIM USS Code One (USSCO) Revision March 3, 2000
struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 16, 18, 1, "Standard example",
"100011010111100011"
"000110110110110111"
"010110100010001000"
"110110001000101001"
"111010001111111011"
"000010000000100000"
"111111111111111111"
"000000000000000000"
"011111111111111110"
"010000000000000010"
"011111111111111110"
"101101111011100110"
"100001001111100110"
"010110111000101011"
"001010010011101001"
"010100101110110001"
},
/* 1*/ { UNICODE_MODE, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 16, 18, 1, "Standard example auto-ECI",
"100011010111100011"
"000110110110110111"
"010110100010001000"
"110110001000101001"
"111010001111111011"
"000010000000100000"
"111111111111111111"
"000000000000000000"
"011111111111111110"
"010000000000000010"
"011111111111111110"
"101101111011100110"
"100001001111100110"
"010110111000101011"
"001010010011101001"
"010100101110110001"
},
/* 2*/ { UNICODE_MODE, -1, { 0, 0, "" }, { { TU("Ж"), -1, 7 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, 0, 22, 22, 1, "Standard example inverted",
"1000110101010110001000"
"0001101101110100100010"
"1000101110001101011000"
"1001101011011111010010"
"1000101000111000111000"
"0010100101101101110001"
"1000101000100010001101"
"0000100000000000100000"
"1111111111111111111111"
"0000000000000000000000"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0001000100010001101111"
"1010110111011111100100"
"1100011010110110101000"
"1111001110101001101101"
"1011101010111001100100"
"0010011101100011101011"
"0011010111000001111101"
},
/* 3*/ { UNICODE_MODE, -1, { 0, 0, "" }, { { TU("Ж"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 22, 22, 1, "Standard example inverted auto-ECI",
"1000110101010110001000"
"0001101101110100100010"
"1000101110001101011000"
"1001101011011111010010"
"1000101000111000111000"
"0010100101101101110001"
"1000101000100010001101"
"0000100000000000100000"
"1111111111111111111111"
"0000000000000000000000"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0001000100010001101111"
"1010110111011111100100"
"1100011010110110101000"
"1111001110101001101101"
"1011101010111001100100"
"0010011101100011101011"
"0011010111000001111101"
},
/* 4*/ { UNICODE_MODE, -1, { 0, 0, "" }, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 70, 76, 0, "AIM ITS/04-023:2022 Annex A example; BWIPP different encodation",
"1000110101010110001000100011111010110011011010101111000111000010111011110011"
"0001101101110100100010010110111110100101111100011011101000110101010010101010"
"0111101111011010010111011010001100110000001000101000110001000100001101101011"
"0000101011011101100100110010010001001000010000001011010011100011000100100001"
"1111100000100110111110011110110100000010000011101001010001000011011100100100"
"1100101111101000110111111110010010000100110010101010101001100011100101100001"
"0111101011111100101010001110001011100101100010001010011110001111001011101100"
"0000101000111101011101101010111100111101001000101011110111101001100111100011"
"1111100011010001100110011010011001100010101111001010111110001001010110100111"
"1011101010011111111111011110110001010000100110001010001000000000001001101000"
"0110100110001000110110001010001000110011001100101001000100101111001011101110"
"0101101100000001000001000010110100010010100000001001110010010101000100100110"
"1011111010101111011011111011001010111101110010101100111100111011001101111011"
"0100100010111101011100010010110110101010100110111010110001001110101011101100"
"1101100011101010101010101110001011010101100010001010010101111011000011101101"
"1011101010001101000001001110111100011101001000101000110001111101100010101000"
"0110100000100100110011100010111100010010100001011010011100010111110100100111"
"0010101000101100001101000010101100110001111110111011000001011110101011101110"
"0010100110000010010000111110011101011000000101111001010000001000001000101000"
"0111100100110110111100101110101110111100011001011011001000010011111001101000"
"1110101100110101100110110010101011000011111110101000110010110100101110100010"
"1111100111101001000001010010011110001000111111101001011101110000011011100101"
"1000101000100010001000100010100010001000100010001010001000100010001000101000"
"0001100001000100010001000110000100010001000100011000010001000100010001100001"
"1000111000100010001000100011100010001000100010001110001000100010001000111000"
"0001100001000100010001000110000100010001000100011000010001000100010001100001"
"1000101000100010001000100010100010001000100010001010001000100010001000101000"
"0001100001000100010001000110000100010001000100011000010001000100010001100001"
"1000101000100010001000100010100010001000100010001010001000100010001000101000"
"0001100001000100010001000110000100010001000100011000010001000100010001100001"
"0000100000000000000000000010000000000000000000001000000000000000000000100000"
"1111111111111111111111111111111111111111111111111111111111111111111111111111"
"0000000000000000000000000010000000000000000000000000000000000000000000100000"
"1111111111111111111111111111111111111111111111111111111111111111111111111111"
"0000000000000000000000000010000000000000000000000000000000000000000000100000"
"1111111111111111111111111111111111111111111111111111111111111111111111111111"
"0000000000000000000000000000000000000000000000000000000000000000000000000000"
"0111111111111111111111111111111111111111111111111111111111111111111111111110"
"0100000000000000000000000000000000000000000000000000000000000000000000000010"
"0111111111111111111111111111111111111111111111111111111111111111111111111110"
"1000101000100010001000100010100010001000100010001010001000100010001000101000"
"0001100001000100010001000110000100010001000100011000010001000100010001100001"
"1000101000100010001000100010100010001000100010001010001000100010001000101000"
"0001100001000100010001000110000100010001000100011000010001000100010001100001"
"1000101000100010001000100010100010001000100010001010001000100010001000101000"
"0001110001000100010001000111000100010001000100011100010001000100010001110001"
"1000101000100010001000100010100010001000100010001010001000100010001000101000"
"0001100001000100010001000110000100010001000100011000010001000100010001100001"
"1000101000100010001000100010100010001000100010001010001000100010001000101000"
"0001100001000100010001000110000100010001000100011000010001000100010001100001"
"1000101000100010001000100010100010001000100010001010001000100010001000101000"
"0001100001000100010001000110000100010001000100011000010001000100010001100001"
"1000101000100010001000100010100010001000100010001010001000111001101111100110"
"0001100001000100010001000110000100010001000100011000010001000110100010100101"
"0101101000101000110010110110001110100100110101001000001100000010011101100010"
"0100101100111011100101111110111100100011111000111010110101000110001000100111"
"1011100010000010011110111110111011110111001100111000101011101100001101100001"
"0011111101010101000010110011010000101111001101011101101100000011001101111110"
"1001101110000000010100100110001000011000010000001001100010100101011001100000"
"1010100110110100010001001110110010011100001101001000000010100010111111100101"
"0001101110111011011001101110001100010010110101111000101011101001111000100000"
"0100100011110110101101100110010110110100101011001011011000011001000111100011"
"1010101111011001001000100110010011010011110100101010010111000101001001100110"
"1011100010101101111110010010001011100010010101111001001111010100011111100001"
"0110101001011011001101100110110001100100010000101011010010101001110100100110"
"1101101000100011101100101110100110011111100111111001010100100101111101100010"
"1100100010111011001011100010100100011110001000101011000010100011101011101111"
"1110100101000010010101100010010111010111001110011010010101111110100000100011"
"0110101011010011001101110110100011011101001011011001000100000001110011101110"
"1110110001111000110010010111100110011010101100011101011011100000011001110111"
},
/* 5*/ { UNICODE_MODE, -1, { 0, 0, "" }, { { TU("price:$439.97"), -1, 3 }, { TU("零售价:¥3149.79"), -1, 29 }, { TU("Preis:444,90 €"), -1, 17 } }, 0, 40, 42, 1, "AIM ITS/04-023:2022 Annex A example price only",
"100011010101011000101100100001110111110110"
"000110110111010010001010010100010011101010"
"011010011000110010101010001100101110100101"
"010010011010110101111001101011110011101101"
"100010100010011110001000110011101100101101"
"001010001011110111101001000100111010101011"
"101110110100111010101010101010110010101101"
"110010101110100011011000000100111111100001"
"010110100010001001011001011101100110100111"
"110110001000100011001001001101101010100100"
"001110101000110010111001001011100010101000"
"101110111001011101111000000110110101100001"
"100011100010001000101100100010001000111000"
"000110000100010001001001000100010001100001"
"100010100010001000101000100010001000101000"
"000010000000000000001000000000000000100000"
"111111111111111111111111111111111111111111"
"000000000000000000000000000000000000000000"
"011111111111111111111111111111111111111110"
"010000000000000000000000000000000000000010"
"011111111111111111111111111111111111111110"
"010000000000000000000000000000000000000010"
"011111111111111111111111111111111111111110"
"010000000000000000000000000000000000000010"
"011111111111111111111111111111111111111110"
"000110000100010001001001000100010001100001"
"100010100010001000101000100010001000101000"
"000111000100010001001101000100010001110001"
"100010100010001000101000100010001000101000"
"000110000100010001001001000100010001100001"
"100010101101011000011000010110000000101110"
"000110111010101011001011011010010011100010"
"100010000110000101101011111101110001100010"
"010110010000111010111000101011000010101010"
"111010111101001011001010101000001111100000"
"011110101101000001001001011001010000100111"
"110110011011111111111000000001111100101100"
"110110001001101110101011000011000000101111"
"100110111001001100101001010010001011100111"
"111011100100101100101111011011100100111101"
},
/* 6*/ { DATA_MODE, -1, { 0, 0, "" }, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, 0, 22, 22, 1, "Standard example + extra seg, data mode",
"1000110101111000110101"
"0001101101101101111101"
"1000101000100011100011"
"0010100010100110110111"
"0101101000100010001110"
"1101100010001001011011"
"0011101000100010000010"
"0000100000000000100000"
"1111111111111111111111"
"0000000000000000000000"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0111000100010001100011"
"1100010110011101101111"
"1100000111010111101001"
"0010000001001111101110"
"1100100101010100100110"
"1110101101100111101011"
"1001101001111010111100"
},
/* 7*/ { UNICODE_MODE, -1, { 1, 15, "" }, { { TU("A"), -1, 3 }, { TU("B"), -1, 4 }, { TU("C"), -1, 5 } }, 0, 22, 22, 1, "Structured Append (Group mode) 1st symbol, with ECI",
"1000111110000001010101"
"0001101001111011011101"
"1000101000100001000101"
"0010100010010100101101"
"1000101000100001000101"
"0010100010011000111101"
"1000101000100001000111"
"0000100000000000100000"
"1111111111111111111111"
"0000000000000000000000"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0010001001110100100100"
"0010010011001111101011"
"1101000100011110101010"
"0000000001000101101000"
"1101010110111101101011"
"0011010110111100101011"
"1111101011110000110101"
},
/* 8*/ { UNICODE_MODE, -1, { 3, 15, "" }, { { TU("A"), -1, 3 }, { TU("B"), -1, 4 }, { TU("C"), -1, 5 } }, 0, 22, 22, 1, "Structured Append (Group mode) subsequent symbol, with ECI",
"0010111110010110001000"
"1100101001110100100010"
"1000100100010110001000"
"0101100010110100100010"
"1000100100010110001000"
"0110100011110100100010"
"1000100100100010001100"
"0000100000000000100000"
"1111111111111111111111"
"0000000000000000000000"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0111010000010001101101"
"0001110000100010101101"
"0101011110011000101110"
"1111110110000110100111"
"0100001100101001100010"
"1111010111000111100011"
"0010100111110110110101"
},
/* 9*/ { UNICODE_MODE, -1, { 128, 128, "" }, { { TU("A"), -1, 3 }, { TU("B"), -1, 4 }, { TU("C"), -1, 5 } }, 0, 22, 22, 1, "Structured Append (Extended Group mode)",
"1000111000111001011000"
"0000100000100111010010"
"1000101000010001011000"
"0010100101001011010010"
"1000101000010001011000"
"0010100110001111010010"
"1000101000010010000001"
"0000100000000000100000"
"1111111111111111111111"
"0000000000000000000000"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0100000000000000000010"
"0111111111111111111110"
"0010011101000001101001"
"1111101010101110101001"
"0111011000100101100010"
"1111010000001010101101"
"0010001100101010101111"
"0000110101011010101000"
"0110000110100100110110"
},
/* 10*/ { UNICODE_MODE, 9, { 0, 0, "" }, { { TU("A"), -1, 3 }, { TU("B"), -1, 4 }, { TU("C"), -1, 5 } }, ZINT_ERROR_INVALID_OPTION, 0, 0, 1, "Multiple segments not suppoted for Version S",
""
},
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
char escaped[8192];
char bwipp_buf[32768];
char bwipp_msg[1024];
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
testStart("test_encode_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
if ((debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) printf("i:%d\n", i);
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, BARCODE_CODEONE, data[i].input_mode, -1 /*eci*/,
-1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/,
NULL, 0, debug);
if (data[i].structapp.count) {
symbol->structapp = data[i].structapp;
}
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
char escaped1[4096];
char escaped2[4096];
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length;
int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length;
printf(" /*%3d*/ { %s, %d, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n",
i, testUtilInputModeName(data[i].input_mode), data[i].option_2,
data[i].structapp.index, data[i].structapp.count, data[i].structapp.id,
testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci,
testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci,
testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci,
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment);
if (ret < ZINT_ERROR) {
testUtilModulesPrint(symbol, " ", "\n");
} else {
printf(" \"\"\n");
}
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n",
i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n",
i, symbol->width, data[i].expected_width);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n",
i, ret, width, row);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
ret = testUtilBwippSegs(i, symbol, -1, data[i].option_2, -1, data[i].segs, seg_count, NULL, bwipp_buf, sizeof(bwipp_buf));
assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected);
}
}
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_fuzz(int index, int debug) { static void test_fuzz(int index, int debug) {
struct item { struct item {
@ -2990,6 +3394,7 @@ int main(int argc, char *argv[]) {
{ "test_large", test_large, 1, 0, 1 }, { "test_large", test_large, 1, 0, 1 },
{ "test_input", test_input, 1, 0, 1 }, { "test_input", test_input, 1, 0, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_encode_segs", test_encode_segs, 1, 1, 1 },
{ "test_fuzz", test_fuzz, 1, 0, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 },
}; };
@ -2999,3 +3404,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -102,7 +102,7 @@ static void test_large(int index, int debug) {
testFinish(); testFinish();
} }
int hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char *source, int source_len); int c128_hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char source[], const int length);
static void test_hrt_cpy_iso8859_1(int index, int debug) { static void test_hrt_cpy_iso8859_1(int index, int debug) {
@ -157,7 +157,7 @@ static void test_hrt_cpy_iso8859_1(int index, int debug) {
length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length; length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length;
ret = hrt_cpy_iso8859_1(&symbol, (unsigned char *) data[i].data, length); ret = c128_hrt_cpy_iso8859_1(&symbol, (unsigned char *) data[i].data, length);
if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) { if (index != -1 && (debug & ZINT_DEBUG_TEST_PRINT)) {
for (j = 0; j < ret; j++) { for (j = 0; j < ret; j++) {
fprintf(stderr, "symbol.text[%d] %2X\n", j, symbol.text[j]); fprintf(stderr, "symbol.text[%d] %2X\n", j, symbol.text[j]);
@ -822,7 +822,7 @@ static void test_encode(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -333,7 +332,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -364,3 +363,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -247,7 +246,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -277,3 +276,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -67,86 +66,90 @@ static void test_is_sane(int index) {
/* 1*/ { IS_SPC_F, "\000", 1, 0, " " }, /* 1*/ { IS_SPC_F, "\000", 1, 0, " " },
/* 2*/ { IS_HSH_F, "#", -1, 1, "#" }, /* 2*/ { IS_HSH_F, "#", -1, 1, "#" },
/* 3*/ { IS_HSH_F, " ", -1, 0, "#" }, /* 3*/ { IS_HSH_F, " ", -1, 0, "#" },
/* 4*/ { IS_PLS_F, "+", -1, 1, "+" }, /* 4*/ { IS_AST_F, "*", -1, 1, "*" },
/* 5*/ { IS_PLS_F, " ", -1, 0, "+" }, /* 5*/ { IS_AST_F, " ", -1, 0, "*" },
/* 6*/ { IS_MNS_F, "-", -1, 1, "-" }, /* 6*/ { IS_PLS_F, "+", -1, 1, "+" },
/* 7*/ { IS_MNS_F, " ", -1, 0, "-" }, /* 7*/ { IS_PLS_F, " ", -1, 0, "+" },
/* 8*/ { IS_NUM_F, "0123456789", -1, 1, "0123456789" }, // NEON /* 8*/ { IS_MNS_F, "-", -1, 1, "-" },
/* 9*/ { IS_NUM_F, "0123456789 ", -1, 0, "0123456789" }, /* 9*/ { IS_MNS_F, " ", -1, 0, "-" },
/* 10*/ { IS_NUM_F, "012345678A9", -1, 0, "0123456789" }, /* 10*/ { IS_NUM_F, "0123456789", -1, 1, "0123456789" }, // NEON
/* 11*/ { IS_UPO_F, "GHIJKLMNOPQRSTUVWYZ", -1, 1, "GHIJKLMNOPQRSTUVWYZ" }, /* 11*/ { IS_NUM_F, "0123456789 ", -1, 0, "0123456789" },
/* 12*/ { IS_UPO_F, "FGHIJKLMNOPQRSTUVWYZ", -1, 0, "GHIJKLMNOPQRSTUVWYZ" }, /* 12*/ { IS_NUM_F, "012345678A9", -1, 0, "0123456789" },
/* 13*/ { IS_LWO_F, "ghijklmnopqrstuvwyz", -1, 1, "ghijklmnopqrstuvwyz" }, /* 13*/ { IS_UPO_F, "GHIJKLMNOPQRSTUVWYZ", -1, 1, "GHIJKLMNOPQRSTUVWYZ" },
/* 14*/ { IS_LWO_F, "fghijklmnopqrstuvwyz", -1, 0, "ghijklmnopqrstuvwyz" }, /* 14*/ { IS_UPO_F, "FGHIJKLMNOPQRSTUVWYZ", -1, 0, "GHIJKLMNOPQRSTUVWYZ" },
/* 15*/ { IS_UHX_F, "ABCDEF", -1, 1, "ABCDEF" }, /* 15*/ { IS_LWO_F, "ghijklmnopqrstuvwyz", -1, 1, "ghijklmnopqrstuvwyz" },
/* 16*/ { IS_UHX_F, "ABCDEf", -1, 0, "ABCDEF" }, /* 16*/ { IS_LWO_F, "fghijklmnopqrstuvwyz", -1, 0, "ghijklmnopqrstuvwyz" },
/* 17*/ { IS_LHX_F, "abcdef", -1, 1, "abcdef" }, /* 17*/ { IS_UHX_F, "ABCDEF", -1, 1, "ABCDEF" },
/* 18*/ { IS_LHX_F, "abcdeF", -1, 0, "abcdef" }, /* 18*/ { IS_UHX_F, "ABCDEf", -1, 0, "ABCDEF" },
/* 19*/ { IS_UPR_F, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, /* 19*/ { IS_LHX_F, "abcdef", -1, 1, "abcdef" },
/* 20*/ { IS_UPR_F, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", -1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, /* 20*/ { IS_LHX_F, "abcdeF", -1, 0, "abcdef" },
/* 21*/ { IS_UPR_F, "X", -1, 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, /* 21*/ { IS_UPR_F, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
/* 22*/ { IS_UPR_F, "x", -1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, /* 22*/ { IS_UPR_F, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", -1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
/* 23*/ { IS_LWR_F, "abcdefghijklmnopqrstuvwxyz", -1, 1, "abcdefghijklmnopqrstuvwxyz" }, /* 23*/ { IS_UPR_F, "X", -1, 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
/* 24*/ { IS_LWR_F, "abcdefghijklmnopqrstuvwxyz ", -1, 0, "abcdefghijklmnopqrstuvwxyz" }, /* 24*/ { IS_UPR_F, "x", -1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
/* 25*/ { IS_LWR_F, "x", -1, 1, "abcdefghijklmnopqrstuvwxyz" }, /* 25*/ { IS_LWR_F, "abcdefghijklmnopqrstuvwxyz", -1, 1, "abcdefghijklmnopqrstuvwxyz" },
/* 26*/ { IS_LWR_F, "X", -1, 0, "abcdefghijklmnopqrstuvwxyz" }, /* 26*/ { IS_LWR_F, "abcdefghijklmnopqrstuvwxyz ", -1, 0, "abcdefghijklmnopqrstuvwxyz" },
/* 27*/ { IS_UX__F, "X", -1, 1, "X" }, /* 27*/ { IS_LWR_F, "x", -1, 1, "abcdefghijklmnopqrstuvwxyz" },
/* 28*/ { IS_UX__F, "x", -1, 0, "X" }, /* 28*/ { IS_LWR_F, "X", -1, 0, "abcdefghijklmnopqrstuvwxyz" },
/* 29*/ { IS_LX__F, "x", -1, 1, "x" }, /* 29*/ { IS_UX__F, "X", -1, 1, "X" },
/* 30*/ { IS_LX__F, "X", -1, 0, "x" }, /* 30*/ { IS_UX__F, "x", -1, 0, "X" },
/* 31*/ { IS_C82_F, "!\"%&'()*,./:;<=>?_", -1, 1, "!\"%&'()*,./:;<=>?_" }, // CSET82 punctuation less "-+" /* 31*/ { IS_LX__F, "x", -1, 1, "x" },
/* 32*/ { IS_C82_F, "!\"%&'()*,./:;<=>?_ ", -1, 0, "!\"%&'()*,./:;<=>?_" }, /* 32*/ { IS_LX__F, "X", -1, 0, "x" },
/* 33*/ { IS_C82_F, "-", -1, 0, "!\"%&'()*,./:;<=>?_" }, /* 33*/ { IS_C82_F, "!\"%&'(),./:;<=>?_", -1, 1, "!\"%&'(),./:;<=>?_" }, // CSET82 punctuation less "*+-"
/* 34*/ { IS_C82_F, "$", -1, 0, "!\"%&'()*,./:;<=>?_" }, /* 34*/ { IS_C82_F, "!\"%&'(),./:;<=>?_ ", -1, 0, "!\"%&'(),./:;<=>?_" },
/* 35*/ { IS_SIL_F, ".$/%", -1, 1, ".$/%" }, // SILVER punctuation less " -+" /* 35*/ { IS_C82_F, "-", -1, 0, "!\"%&'(),./:;<=>?_" },
/* 36*/ { IS_SIL_F, ".$/% " , -1, 0, ".$/%" }, /* 36*/ { IS_C82_F, "$", -1, 0, "!\"%&'(),./:;<=>?_" },
/* 37*/ { IS_SIL_F, "-", -1, 0, ".$/%" }, /* 37*/ { IS_SIL_F, ".$/%", -1, 1, ".$/%" }, // SILVER punctuation less " +-"
/* 38*/ { IS_CLI_F, "$:/.", -1, 1, "$:/." }, // CALCIUM INNER punctuation less "-+" /* 38*/ { IS_SIL_F, ".$/% " , -1, 0, ".$/%" },
/* 39*/ { IS_CLI_F, "$:/. ", -1, 0, "$:/." }, /* 39*/ { IS_SIL_F, "-", -1, 0, ".$/%" },
/* 40*/ { IS_CLI_F, "+", -1, 0, "$:/." }, /* 40*/ { IS_CLI_F, "$:/.", -1, 1, "$:/." }, // CALCIUM INNER punctuation less "+-"
/* 41*/ { IS_ARS_F, "ABCDEFGHJKLMNPRSTUVWXYZ", -1, 1, "ABCDEFGHJKLMNPRSTUVWXYZ" }, // ARSENIC uppercase /* 41*/ { IS_CLI_F, "$:/. ", -1, 0, "$:/." },
/* 42*/ { IS_ARS_F, "ABCDEFGHJKLMNPRSTUVWXYZ ", -1, 0, "ABCDEFGHJKLMNPRSTUVWXYZ" }, /* 42*/ { IS_CLI_F, "+", -1, 0, "$:/." },
/* 43*/ { IS_ARS_F, "I", -1, 0, "ABCDEFGHJKLMNPRSTUVWXYZ" }, /* 43*/ { IS_ARS_F, "ABCDEFGHJKLMNPRSTUVWXYZ", -1, 1, "ABCDEFGHJKLMNPRSTUVWXYZ" }, // ARSENIC uppercase
/* 44*/ { IS_ARS_F, "O", -1, 0, "ABCDEFGHJKLMNPRSTUVWXYZ" }, /* 44*/ { IS_ARS_F, "ABCDEFGHJKLMNPRSTUVWXYZ ", -1, 0, "ABCDEFGHJKLMNPRSTUVWXYZ" },
/* 45*/ { IS_NUM_F | IS_UHX_F, "0123456789ABCDEF", -1, 1, "0123456789ABCDEF" }, // SSET /* 45*/ { IS_ARS_F, "I", -1, 0, "ABCDEFGHJKLMNPRSTUVWXYZ" },
/* 46*/ { IS_NUM_F | IS_UHX_F, "0123456789ABCDEf", -1, 0, "0123456789ABCDEF" }, /* 46*/ { IS_ARS_F, "O", -1, 0, "ABCDEFGHJKLMNPRSTUVWXYZ" },
/* 47*/ { IS_NUM_F | IS_PLS_F, "0123456789+", -1, 1, "0123456789+" }, // SODIUM_PLS /* 47*/ { IS_NUM_F | IS_UHX_F, "0123456789ABCDEF", -1, 1, "0123456789ABCDEF" }, // SSET
/* 48*/ { IS_NUM_F | IS_PLS_F, "0123456789+-", -1, 0, "0123456789+" }, /* 48*/ { IS_NUM_F | IS_UHX_F, "0123456789ABCDEf", -1, 0, "0123456789ABCDEF" },
/* 49*/ { IS_NUM_F | IS_UX__F, "0123456789X", -1, 1, "0123456789X" }, // ISBNX_SANE /* 49*/ { IS_NUM_F | IS_PLS_F, "0123456789+", -1, 1, "0123456789+" }, // SODIUM_PLS
/* 50*/ { IS_NUM_F | IS_UX__F, "0123456789x", -1, 0, "0123456789X" }, /* 50*/ { IS_NUM_F | IS_PLS_F, "0123456789+-", -1, 0, "0123456789+" },
/* 51*/ { IS_NUM_F | IS_UX__F | IS_LX__F | IS_PLS_F, "0123456789Xx+", -1, 1, "0123456789Xx+" }, // ISBNX_ADDON_SANE /* 51*/ { IS_NUM_F | IS_UX__F, "0123456789X", -1, 1, "0123456789X" }, // ISBNX_SANE
/* 52*/ { IS_NUM_F | IS_UX__F | IS_LX__F | IS_PLS_F, "0123456789Xx+Y", -1, 0, "0123456789Xx+" }, /* 52*/ { IS_NUM_F | IS_UX__F, "0123456789x", -1, 0, "0123456789X" },
/* 53*/ { IS_NUM_F | IS_MNS_F, "0123456789-", -1, 1, "0123456789-" }, // SODIUM_MNS /* 53*/ { IS_NUM_F | IS_UX__F | IS_LX__F | IS_PLS_F, "0123456789Xx+", -1, 1, "0123456789Xx+" }, // ISBNX_ADDON_SANE
/* 54*/ { IS_NUM_F | IS_MNS_F, "0123456789-+", -1, 0, "0123456789-" }, /* 54*/ { IS_NUM_F | IS_UX__F | IS_LX__F | IS_PLS_F, "0123456789Xx+Y", -1, 0, "0123456789Xx+" },
/* 55*/ { IS_C82_F | IS_MNS_F | IS_PLS_F | IS_NUM_F | IS_UPR_F | IS_LWR_F, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz", -1, 1, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" }, // CSET82 /* 55*/ { IS_NUM_F | IS_MNS_F, "0123456789-", -1, 1, "0123456789-" }, // SODIUM_MNS
/* 56*/ { IS_C82_F | IS_MNS_F | IS_PLS_F | IS_NUM_F | IS_UPR_F | IS_LWR_F, " ", -1, 0, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" }, /* 56*/ { IS_NUM_F | IS_MNS_F, "0123456789-+", -1, 0, "0123456789-" },
/* 57*/ { IS_C82_F | IS_MNS_F | IS_PLS_F | IS_NUM_F | IS_UPR_F | IS_LWR_F, "#", -1, 0, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" }, /* 57*/ { IS_C82_F | IS_AST_F | IS_MNS_F | IS_PLS_F | IS_NUM_F | IS_UPR_F | IS_LWR_F, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz", -1, 1, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" }, // CSET82
/* 58*/ { IS_C82_F | IS_MNS_F | IS_PLS_F | IS_NUM_F | IS_UPR_F | IS_LWR_F, "$", -1, 0, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" }, /* 58*/ { IS_C82_F | IS_AST_F | IS_MNS_F | IS_PLS_F | IS_NUM_F | IS_UPR_F | IS_LWR_F, " ", -1, 0, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" },
/* 59*/ { IS_C82_F | IS_MNS_F | IS_PLS_F | IS_NUM_F | IS_UPR_F | IS_LWR_F, "@", -1, 0, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" }, /* 59*/ { IS_C82_F | IS_AST_F | IS_MNS_F | IS_PLS_F | IS_NUM_F | IS_UPR_F | IS_LWR_F, "#", -1, 0, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" },
/* 60*/ { IS_LWR_F | IS_C82_F | IS_PLS_F | IS_MNS_F | IS_SPC_F, "abcdefghijklmnopqrstuvwxyz!\"%&'()*+,-./:;<=>?_ ", -1, 1, "abcdefghijklmnopqrstuvwxyz!\"%&'()*+,-./:;<=>?_ " }, // IS_ISOIEC_F /* 60*/ { IS_C82_F | IS_AST_F | IS_MNS_F | IS_PLS_F | IS_NUM_F | IS_UPR_F | IS_LWR_F, "$", -1, 0, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" },
/* 61*/ { IS_LWR_F | IS_C82_F | IS_PLS_F | IS_MNS_F | IS_SPC_F, "abcdefghijklmnopqrstuvwxyz!\"%&'()*+,-./:;<=>?_ #", -1, 0, "abcdefghijklmnopqrstuvwxyz!\"%&'()*+,-./:;<=>?_ " }, /* 61*/ { IS_C82_F | IS_AST_F | IS_MNS_F | IS_PLS_F | IS_NUM_F | IS_UPR_F | IS_LWR_F, "@", -1, 0, "!\"%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" },
/* 62*/ { IS_LWR_F | IS_C82_F | IS_PLS_F | IS_MNS_F | IS_SPC_F, "$", -1, 0, "abcdefghijklmnopqrstuvwxyz!\"%&'()*+,-./:;<=>?_ " }, /* 62*/ { IS_LWR_F | IS_C82_F | IS_AST_F | IS_PLS_F | IS_MNS_F | IS_SPC_F, "abcdefghijklmnopqrstuvwxyz!\"%&'()*+,-./:;<=>?_ ", -1, 1, "abcdefghijklmnopqrstuvwxyz!\"%&'()*+,-./:;<=>?_ " }, // IS_ISOIEC_F
/* 63*/ { IS_MNS_F | IS_SIL_F | IS_SPC_F | IS_PLS_F, "-. $/+%", -1, 1, "" }, /* 63*/ { IS_LWR_F | IS_C82_F | IS_AST_F | IS_PLS_F | IS_MNS_F | IS_SPC_F, "abcdefghijklmnopqrstuvwxyz!\"%&'()*+,-./:;<=>?_ #", -1, 0, "abcdefghijklmnopqrstuvwxyz!\"%&'()*+,-./:;<=>?_ " },
/* 64*/ { IS_MNS_F | IS_SIL_F | IS_SPC_F | IS_PLS_F, "-. $/!+%", -1, 0, "" }, /* 64*/ { IS_LWR_F | IS_C82_F | IS_AST_F | IS_PLS_F | IS_MNS_F | IS_SPC_F, "$", -1, 0, "abcdefghijklmnopqrstuvwxyz!\"%&'()*+,-./:;<=>?_ " },
/* 65*/ { IS_NUM_F | IS_UPR_F | IS_MNS_F | IS_SIL_F | IS_SPC_F | IS_PLS_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%", -1, 1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" }, // SILVER /* 65*/ { IS_MNS_F | IS_SIL_F | IS_SPC_F | IS_PLS_F, "-. $/+%", -1, 1, "" },
/* 66*/ { IS_NUM_F | IS_UPR_F | IS_MNS_F | IS_SIL_F | IS_SPC_F | IS_PLS_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%a", -1, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" }, /* 66*/ { IS_MNS_F | IS_SIL_F | IS_SPC_F | IS_PLS_F, "-. $/!+%", -1, 0, "" },
/* 67*/ { IS_NUM_F | IS_ARS_F, "0123456789ABCDEFGHJKLMNPRSTUVWXYZ", -1, 1, "0123456789ABCDEFGHJKLMNPRSTUVWXYZ" }, // ARSENIC /* 67*/ { IS_NUM_F | IS_UPR_F | IS_MNS_F | IS_SIL_F | IS_SPC_F | IS_PLS_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%", -1, 1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" }, // SILVER
/* 68*/ { IS_NUM_F | IS_ARS_F, "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ", -1, 0, "0123456789ABCDEFGHJKLMNPRSTUVWXYZ" }, /* 68*/ { IS_NUM_F | IS_UPR_F | IS_MNS_F | IS_SIL_F | IS_SPC_F | IS_PLS_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%a", -1, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" },
/* 69*/ { IS_NUM_F | IS_ARS_F, "0123456789ABCDEFGHJKLMNPRSTUVWXYz", -1, 0, "0123456789ABCDEFGHJKLMNPRSTUVWXYZ" }, /* 69*/ { IS_NUM_F | IS_ARS_F, "0123456789ABCDEFGHJKLMNPRSTUVWXYZ", -1, 1, "0123456789ABCDEFGHJKLMNPRSTUVWXYZ" }, // ARSENIC
/* 70*/ { IS_NUM_F | IS_UPR_F | IS_LWR_F | IS_SPC_F | IS_HSH_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #", -1, 1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #" }, // GDSET /* 70*/ { IS_NUM_F | IS_ARS_F, "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ", -1, 0, "0123456789ABCDEFGHJKLMNPRSTUVWXYZ" },
/* 71*/ { IS_NUM_F | IS_UPR_F | IS_LWR_F | IS_SPC_F | IS_HSH_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #!", -1, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #" }, /* 71*/ { IS_NUM_F | IS_ARS_F, "0123456789ABCDEFGHJKLMNPRSTUVWXYz", -1, 0, "0123456789ABCDEFGHJKLMNPRSTUVWXYZ" },
/* 72*/ { IS_NUM_F | IS_MNS_F | IS_CLI_F | IS_PLS_F, "0123456789-$:/.+", -1, 1, "0123456789-$:/.+" }, // CALCIUM_INNER /* 72*/ { IS_NUM_F | IS_UPR_F | IS_LWR_F | IS_SPC_F | IS_HSH_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #", -1, 1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #" }, // GDSET
/* 73*/ { IS_NUM_F | IS_MNS_F | IS_CLI_F | IS_PLS_F, "0123456789-$:/.+ ", -1, 0, "0123456789-$:/.+" }, /* 73*/ { IS_NUM_F | IS_UPR_F | IS_LWR_F | IS_SPC_F | IS_HSH_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #!", -1, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #" },
/* 74*/ { IS_NUM_F | IS_MNS_F | IS_CLI_F | IS_PLS_F, "0123456789-$:/.+!", -1, 0, "0123456789-$:/.+" }, /* 74*/ { IS_NUM_F | IS_MNS_F | IS_CLI_F | IS_PLS_F, "0123456789-$:/.+", -1, 1, "0123456789-$:/.+" }, // CALCIUM_INNER
/* 75*/ { IS_NUM_F | IS_UPR_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, 1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, // KRSET /* 75*/ { IS_NUM_F | IS_MNS_F | IS_CLI_F | IS_PLS_F, "0123456789-$:/.+ ", -1, 0, "0123456789-$:/.+" },
/* 76*/ { IS_NUM_F | IS_UPR_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYz", -1, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, /* 76*/ { IS_NUM_F | IS_MNS_F | IS_CLI_F | IS_PLS_F, "0123456789-$:/.+!", -1, 0, "0123456789-$:/.+" },
/* 77*/ { IS_NUM_F | IS_UPR_F | IS_SPC_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ ", -1, 1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " }, // RUBIDIUM /* 77*/ { IS_NUM_F | IS_UPR_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, 1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, // KRSET
/* 78*/ { IS_NUM_F | IS_UPR_F | IS_SPC_F, "0123456789aBCDEFGHIJKLMNOPQRSTUVWXYZ ", -1, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " }, /* 78*/ { IS_NUM_F | IS_UPR_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYz", -1, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
/* 79*/ { IS_NUM_F | IS_MNS_F | IS_UPR_F, "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, 1, "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, // SHKASUTSET /* 79*/ { IS_NUM_F | IS_UPR_F | IS_SPC_F, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ ", -1, 1, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " }, // RUBIDIUM
/* 80*/ { IS_NUM_F | IS_MNS_F | IS_UPR_F, "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYz", -1, 0, "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, /* 80*/ { IS_NUM_F | IS_UPR_F | IS_SPC_F, "0123456789aBCDEFGHIJKLMNOPQRSTUVWXYZ ", -1, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " },
/* 81*/ { IS_NUM_F | IS_MNS_F | IS_UPR_F, "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, 1, "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, // SHKASUTSET
/* 82*/ { IS_NUM_F | IS_MNS_F | IS_UPR_F, "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYz", -1, 0, "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
/* 83*/ { IS_NUM_F | IS_UPR_F | IS_SPC_F | IS_AST_F | IS_PLS_F | IS_MNS_F | IS_SIL_F | IS_CLI_F, "1234567890 $%*+-./:ABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, 1, "1234567890 $%*+-./:ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, // QR_ALPHA
/* 84*/ { IS_NUM_F | IS_UPR_F | IS_SPC_F | IS_AST_F | IS_PLS_F | IS_MNS_F | IS_SIL_F | IS_CLI_F, "1234567890 $%*+-./:ABCDEFGHIJKLMNOPQRSTUVWXYz", -1, 0, "1234567890 $%*+-./:ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, j, length, ret;
testStart("test_is_sane"); testStart("test_is_sane");
@ -167,6 +170,15 @@ static void test_is_sane(int index) {
assert_zero(ret, "i:%d orig_ret %d, ret %d != 0\n", i, orig_ret, ret); assert_zero(ret, "i:%d orig_ret %d, ret %d != 0\n", i, orig_ret, ret);
} }
} }
ret = 1;
for (j = 0; j < length; j++) {
if (!is_chr(data[i].flg, data[i].data[j])) {
ret = 0;
break;
}
}
assert_equal(ret, data[i].ret, "i:%d is_chr() ret %d != %d\n", i, ret, data[i].ret);
} }
testFinish(); testFinish();
@ -416,3 +428,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -1570,7 +1569,7 @@ static void test_examples(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -1735,7 +1734,7 @@ static void test_odd_numbered_numeric(int index, int generate, int debug) {
assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -1866,7 +1865,7 @@ static void test_ean128_cc_shift(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -2409,7 +2408,7 @@ static void test_encodation_0(int index, int generate, int debug) {
assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -2546,7 +2545,7 @@ static void test_encodation_10(int index, int generate, int debug) {
assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -2962,7 +2961,7 @@ static void test_encodation_11(int index, int generate, int debug) {
assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -3118,7 +3117,7 @@ static void test_addongap(int index, int generate, int debug) {
assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) {
ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, composite, composite_length, symbol->primary, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -3608,3 +3607,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -653,8 +653,11 @@ static void test_reader_init(int index, int generate, int debug) {
testFinish(); testFinish();
} }
#define ZINT_TEST_ENCODING
#ifdef ZINT_TEST_ENCODING
STATIC_UNLESS_ZINT_TEST int dm_encode(struct zint_symbol *symbol, const unsigned char source[], STATIC_UNLESS_ZINT_TEST int dm_encode(struct zint_symbol *symbol, const unsigned char source[],
unsigned char target[], int *p_length, int *p_binlen); const int length, const int eci, const int gs1, unsigned char target[], int *p_tp);
#endif
static void test_input(int index, int generate, int debug) { static void test_input(int index, int generate, int debug) {
@ -967,7 +970,7 @@ static void test_input(int index, int generate, int debug) {
} else { } else {
char modules_dump[144 * 144 + 1]; char modules_dump[144 * 144 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump);
@ -988,13 +991,14 @@ static void test_input(int index, int generate, int debug) {
} }
} }
#ifdef ZINT_TEST_ENCODING
if (ret < ZINT_ERROR) { if (ret < ZINT_ERROR) {
if (i && (data[i].input_mode & 0x07) == (data[i - 1].input_mode & 0x07) && !(data[i].input_mode & FAST_MODE) && (data[i - 1].input_mode & FAST_MODE) if (i && (data[i].input_mode & 0x07) == (data[i - 1].input_mode & 0x07) && !(data[i].input_mode & FAST_MODE) && (data[i - 1].input_mode & FAST_MODE)
&& data[i].eci == data[i - 1].eci && data[i].option_2 == data[i - 1].option_2 && data[i].eci == data[i - 1].eci && data[i].option_2 == data[i - 1].option_2
&& data[i].option_3 == data[i - 1].option_3 && data[i].output_options == data[i - 1].output_options && data[i].option_3 == data[i - 1].option_3 && data[i].output_options == data[i - 1].output_options
&& strcmp(data[i].data, data[i - 1].data) == 0) { && strcmp(data[i].data, data[i - 1].data) == 0) {
unsigned char binary[2][2200]; unsigned char binary[2][2200];
int inputlen; int gs1;
int binlen; int binlen;
int binlens[2] = {0}; int binlens[2] = {0};
unsigned char reduced[1000]; unsigned char reduced[1000];
@ -1012,18 +1016,18 @@ static void test_input(int index, int generate, int debug) {
} else { } else {
text = (unsigned char *) data[i].data; text = (unsigned char *) data[i].data;
} }
inputlen = length;
binlen = 0; binlen = 0;
symbol->input_mode = data[i - 1].input_mode; symbol->input_mode = data[i - 1].input_mode;
ret = dm_encode(symbol, text, binary[0], &inputlen, &binlen); gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1;
ret = dm_encode(symbol, text, length, symbol->eci, gs1, binary[0], &binlen);
assert_zero(ret, "i:%d dm_encode() FAST_MODE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); assert_zero(ret, "i:%d dm_encode() FAST_MODE ret %d != 0 (%s)\n", i, ret, symbol->errtxt);
binlens[0] = binlen; binlens[0] = binlen;
inputlen = length;
binlen = 0; binlen = 0;
symbol->input_mode = data[i].input_mode; symbol->input_mode = data[i].input_mode;
ret = dm_encode(symbol, text, binary[1], &inputlen, &binlen); gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1;
ret = dm_encode(symbol, text, length, symbol->eci, gs1, binary[1], &binlen);
assert_zero(ret, "i:%d dm_encode() minimal ret %d != 0 (%s)\n", i, ret, symbol->errtxt); assert_zero(ret, "i:%d dm_encode() minimal ret %d != 0 (%s)\n", i, ret, symbol->errtxt);
binlens[1] = binlen; binlens[1] = binlen;
@ -1035,6 +1039,7 @@ static void test_input(int index, int generate, int debug) {
} }
} }
} }
#endif
} }
ZBarcode_Delete(symbol); ZBarcode_Delete(symbol);
@ -1736,7 +1741,7 @@ static void test_encode(int index, int generate, int debug) {
"11110110001001001010110111010110" "11110110001001001010110111010110"
"11111111111111111111111111111111" "11111111111111111111111111111111"
}, },
/* 33*/ { BARCODE_DATAMATRIX, GS1_MODE, -1, -1, -1, -1, "[01]00012345678905[17]180401[21]ABCDEFGHIJKL12345678[91]ABCDEFGHI123456789[92]abcdefghi", -1, 0, 32, 32, 0, "GGS Figure 5.6.3.2-3 (left) **NOT SAME** different encodation; BWIPP different encodation", 1, /* 33*/ { BARCODE_DATAMATRIX, GS1_MODE, -1, -1, -1, -1, "[01]00012345678905[17]180401[21]ABCDEFGHIJKL12345678[91]ABCDEFGHI123456789[92]abcdefghi", -1, 0, 32, 32, 0, "GGS Figure 5.6.3.2-3 (left) **NOT SAME** different encodation; BWIPP different encodation", 2,
"10101010101010101010101010101010" "10101010101010101010101010101010"
"11001000010111111001100001001011" "11001000010111111001100001001011"
"10001001100001101101000101000010" "10001001100001101101000101000010"
@ -5219,7 +5224,7 @@ static void test_encode(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
@ -5239,12 +5244,13 @@ static void test_encode(int index, int generate, int debug) {
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped); i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped);
} }
#ifdef ZINT_TEST_ENCODING
if (i && (data[i].input_mode & 0x07) == (data[i - 1].input_mode & 0x07) && !(data[i].input_mode & FAST_MODE) && (data[i - 1].input_mode & FAST_MODE) if (i && (data[i].input_mode & 0x07) == (data[i - 1].input_mode & 0x07) && !(data[i].input_mode & FAST_MODE) && (data[i - 1].input_mode & FAST_MODE)
&& data[i].eci == data[i - 1].eci && data[i].option_2 == data[i - 1].option_2 && data[i].eci == data[i - 1].eci && data[i].option_2 == data[i - 1].option_2
&& data[i].option_3 == data[i - 1].option_3 && data[i].output_options == data[i - 1].output_options && data[i].option_3 == data[i - 1].option_3 && data[i].output_options == data[i - 1].output_options
&& strcmp(data[i].data, data[i - 1].data) == 0) { && strcmp(data[i].data, data[i - 1].data) == 0) {
unsigned char binary[2][2200]; unsigned char binary[2][2200];
int inputlen; int gs1;
int binlen; int binlen;
int binlens[2] = {0}; int binlens[2] = {0};
@ -5252,18 +5258,18 @@ static void test_encode(int index, int generate, int debug) {
"i:%d data[i].expected_rows * data[i].expected_width %d > data[i - 1].expected_rows * data[i - 1].expected_width %d\n", i, "i:%d data[i].expected_rows * data[i].expected_width %d > data[i - 1].expected_rows * data[i - 1].expected_width %d\n", i,
data[i].expected_rows * data[i].expected_width, data[i - 1].expected_rows * data[i - 1].expected_width); data[i].expected_rows * data[i].expected_width, data[i - 1].expected_rows * data[i - 1].expected_width);
inputlen = length;
binlen = 0; binlen = 0;
symbol->input_mode = data[i - 1].input_mode; symbol->input_mode = data[i - 1].input_mode;
ret = dm_encode(symbol, (unsigned char *) data[i].data, binary[0], &inputlen, &binlen); gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1;
ret = dm_encode(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[0], &binlen);
assert_zero(ret, "i:%d dm_encode() FAST_MODE ret %d != 0 (%s)\n", i, ret, symbol->errtxt); assert_zero(ret, "i:%d dm_encode() FAST_MODE ret %d != 0 (%s)\n", i, ret, symbol->errtxt);
binlens[0] = binlen; binlens[0] = binlen;
inputlen = length;
binlen = 0; binlen = 0;
symbol->input_mode = data[i].input_mode; symbol->input_mode = data[i].input_mode;
ret = dm_encode(symbol, (unsigned char *) data[i].data, binary[1], &inputlen, &binlen); gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1;
ret = dm_encode(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[1], &binlen);
assert_zero(ret, "i:%d dm_encode() minimal ret %d != 0 (%s)\n", i, ret, symbol->errtxt); assert_zero(ret, "i:%d dm_encode() minimal ret %d != 0 (%s)\n", i, ret, symbol->errtxt);
binlens[1] = binlen; binlens[1] = binlen;
@ -5272,6 +5278,287 @@ static void test_encode(int index, int generate, int debug) {
assert_equal(binlens[0], binlens[1] + data[i].expected_diff, "i:%d binlens[0] %d != %d binlens[1] (%d) + expected_diff (%d)\n", assert_equal(binlens[0], binlens[1] + data[i].expected_diff, "i:%d binlens[0] %d != %d binlens[1] (%d) + expected_diff (%d)\n",
i, binlens[0], binlens[1] + data[i].expected_diff, binlens[1], data[i].expected_diff); i, binlens[0], binlens[1] + data[i].expected_diff, binlens[1], data[i].expected_diff);
} }
#endif
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_encode_segs(int index, int generate, int debug) {
struct item {
int symbology;
int input_mode;
int output_options;
int option_2;
int option_3;
struct zint_structapp structapp;
struct zint_seg segs[3];
int ret;
int expected_rows;
int expected_width;
int bwipp_cmp;
char *comment;
char *expected;
};
struct item data[] = {
/* 0*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 14, 14, 1, "ISO 16022:2006 11.6 example",
"10101010101010"
"10000100111111"
"11101100000000"
"11111010010001"
"11000110001000"
"11110110011111"
"10111101000000"
"10010010000111"
"10100110111100"
"11011111011011"
"10101001101110"
"10001001101001"
"10011111100000"
"11111111111111"
},
/* 1*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 14, 14, 1, "ISO 16022:2006 11.6 example auto-ECI",
"10101010101010"
"10000100111111"
"11101100000000"
"11111010010001"
"11000110001000"
"11110110011111"
"10111101000000"
"10010010000111"
"10100110111100"
"11011111011011"
"10101001101110"
"10001001101001"
"10011111100000"
"11111111111111"
},
/* 2*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 7 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, 0, 14, 14, 1, "ISO 16022:2006 11.6 example auto-ECI inverted",
"10101010101010"
"10001111001101"
"10011111110110"
"10001100000111"
"10000011111010"
"11000001100101"
"11100001111110"
"10101101000111"
"11101101001110"
"11100001000001"
"11110100111010"
"10010111100111"
"10011001010000"
"11111111111111"
},
/* 3*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 14, 14, 1, "ISO 16022:2006 11.6 example inverted auto-ECI",
"10101010101010"
"10001111001101"
"10011111110110"
"10001100000111"
"10000011111010"
"11000001100101"
"11100001111110"
"10101101000111"
"11101101001110"
"11100001000001"
"11110100111010"
"10010111100111"
"10011001010000"
"11111111111111"
},
/* 4*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 52, 52, 0, "AIM ITS/04-023:2022 Annex A example **NOT SAME** example corrupt??; BWIPP different encodation",
"1010101010101010101010101010101010101010101010101010"
"1001111110000011100010110111011001110111111001111011"
"1000000101110101100111011011101110011001111001000100"
"1100110100101001111110011111001110000110000111101111"
"1001101110101111110111110010111100011101001000010110"
"1110110010010101001110011111001001011001010001001001"
"1011111001110110111110111010011000101100110010000110"
"1000010111011001010111101110001100011011110011000011"
"1010010110001000100110010010011001000110001111101100"
"1011011010010000111001000111010000010101010000010111"
"1111001000010000010000010011101110011011010011011100"
"1000110001001000001100000111110000001111010011110111"
"1100100011001001011000011011010010110010100000101000"
"1011000000001101110101001110111010000100000100111111"
"1010001011100101001100110011110011100111001010100000"
"1010001110111001100001100111100110001111011001011101"
"1001110101011110011000011010110101111101000110000000"
"1001010111111011101111111111001000100011111111011001"
"1100000100000111010100111010110101110011010011100000"
"1000011000010011111011011110111111100101010110011001"
"1000001000101000011010100011000110110100000100011100"
"1000110110011010111111001111101001001001110000000101"
"1100011111101110000011100010100101111110100101100010"
"1110100000110111110110010111010101111110111110111001"
"1101100110011001001101000011110110101011001001101110"
"1111111111111111111111111111111111111111111111111111"
"1010101010101010101010101010101010101010101010101010"
"1010001100010001001111010111111001010101000110010101"
"1000110000010111111000011011110010101010101000011100"
"1001110110101100101110010111101010011011011011110111"
"1010110000000100101010010010111000010101100001001000"
"1111100001101000011110000111000100111111010100001101"
"1001110010010010000000010011010110010001101101111110"
"1011010010011010100000000111110110010101000100100001"
"1011000111011001111010110010101101100100010010100000"
"1110100011100110001001101111110010111100010010001101"
"1111111010100111111010111010000011100111111010111110"
"1101000000010110010000000110000001010011000001000011"
"1101100101110111000011111011100101000100110001101000"
"1011110111000000000110111111000110000011001101110111"
"1100011000010001101101011011010011100011000010001100"
"1011001111111111110011100111001000001000101001000111"
"1011000101011101100001111010011101011000000000100110"
"1000010011100100111000010110010110010111100010100011"
"1000010111101101110100000010001110000111110010111000"
"1010111010111001011110010111000010010001010111101011"
"1101011010010010011000011010110111000101111000011100"
"1111111000111101110111011111011110101111100100010011"
"1100110000000100110000111011100110101110101011011000"
"1101101101001110001100100111011110110000000010010101"
"1101011000011011100011100010001001010110110010101110"
"1111111111111111111111111111111111111111111111111111"
},
/* 5*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("price:$439.97"), -1, 3 }, { TU("零售价:¥3149.79"), -1, 29 }, { TU("Preis:444,90 €"), -1, 17 } }, 0, 16, 48, 1, "AIM ITS/04-023:2022 Annex A example price only",
"101010101010101010101010101010101010101010101010"
"100001110110010111001111101001001000110101101111"
"100001011100111101001110111101110011001101011100"
"110010100011100110010101100101101010001101110111"
"100101010111111010110010111000011000011000001110"
"111000011111100110110101110110010001000000001001"
"111001110100011100001100111010100000001100101100"
"100100100000111101000111100000111111000101110111"
"110101111100000101011100100010011101010101001110"
"100101111010010100101111110011010011011010100001"
"110001110001010011101100100000100001010111000000"
"110111110100110011000001110000000100010011100011"
"100001001001011101011100110101010101100000100010"
"101000111110011010011101111110111000001110011011"
"110011100111011000101110100011101100000110010010"
"111111111111111111111111111111111111111111111111"
},
/* 6*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, 0, 8, 32, 1, "Standard example + extra seg, data mode",
"10101010101010101010101010101010"
"10000100100011111101000010000011"
"11101100000000101110100001010100"
"11111011110010011011000100011111"
"11000111100111101101010111010110"
"11110110010001111100110110010101"
"11111110000111001100101011000000"
"11111111111111111111111111111111"
},
/* 7*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, -1, -1, { 1, 2, "001001" }, { { TU("A"), -1, 3 }, { TU("B"), -1, 4 }, { TU("C"), -1, 5 } }, 0, 12, 26, 1, "",
"10101010101010101010101010"
"10000100011110000011000101"
"10011100111010100100011000"
"11111100100100001110011111"
"11000010000100110011010100"
"11000000110100010011001001"
"11100000111111010111000000"
"10011101101010000100011101"
"11011000101010010101011000"
"10000100000010000011010001"
"10000011000001110111011000"
"11111111111111111111111111"
},
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
char escaped[8192];
char cmp_buf[32768];
char cmp_msg[1024];
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); // Only do ZXing-C++ test if asked, too slow otherwise
testStart("test_encode_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
if ((debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) printf("i:%d\n", i);
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/,
-1 /*option_1*/, data[i].option_2, data[i].option_3, data[i].output_options,
NULL, 0, debug);
if (data[i].structapp.count) {
symbol->structapp = data[i].structapp;
}
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
char escaped1[4096];
char escaped2[4096];
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length;
int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length;
printf(" /*%3d*/ { %s, %s, %s, %d, %s, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n",
i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode),
testUtilOutputOptionsName(data[i].output_options),
data[i].option_2, testUtilOption3Name(data[i].option_3),
data[i].structapp.index, data[i].structapp.count, data[i].structapp.id,
testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci,
testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci,
testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci,
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment);
testUtilModulesPrint(symbol, " ", "\n");
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, debug)) {
if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
ret = testUtilBwippSegs(i, symbol, -1, data[i].option_2, -1, data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf));
assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected);
}
}
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length, debug)) {
if (data[i].input_mode == DATA_MODE) {
if (debug & ZINT_DEBUG_TEST_PRINT) {
printf("i:%d multiple segments in DATA_MODE not currently supported for ZXing-C++ testing (%s)\n",
i, testUtilBarcodeName(symbol->symbology));
}
} else {
int cmp_len, ret_len;
char modules_dump[144 * 144 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length,
modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count,
NULL /*primary*/, escaped, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped);
}
}
} }
} }
@ -5281,6 +5568,7 @@ static void test_encode(int index, int generate, int debug) {
testFinish(); testFinish();
} }
#ifdef ZINT_TEST_ENCODING
static void test_minimalenc(int index, int debug) { static void test_minimalenc(int index, int debug) {
struct item { struct item {
@ -6320,7 +6608,7 @@ static void test_minimalenc(int index, int debug) {
struct zint_symbol *symbol; struct zint_symbol *symbol;
unsigned char binary[2][2200]; unsigned char binary[2][2200];
int inputlen; int gs1;
int binlen; int binlen;
int binlens[2] = {0}; int binlens[2] = {0};
@ -6336,18 +6624,18 @@ static void test_minimalenc(int index, int debug) {
length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, data[i].output_options, data[i].data, data[i].length, debug); length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, data[i].output_options, data[i].data, data[i].length, debug);
inputlen = length;
binlen = 0; binlen = 0;
symbol->input_mode |= FAST_MODE; symbol->input_mode |= FAST_MODE;
ret = dm_encode(symbol, (unsigned char *) data[i].data, binary[0], &inputlen, &binlen); gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1;
ret = dm_encode(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[0], &binlen);
assert_equal(ret, data[i].ret, "i:%d dm_encode() FAST_MODE ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d dm_encode() FAST_MODE ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
binlens[0] = binlen; binlens[0] = binlen;
inputlen = length;
binlen = 0; binlen = 0;
symbol->input_mode &= ~FAST_MODE; symbol->input_mode &= ~FAST_MODE;
ret = dm_encode(symbol, (unsigned char *) data[i].data, binary[1], &inputlen, &binlen); gs1 = (symbol->input_mode & 0x07) != GS1_MODE ? 0 : (symbol->output_options & GS1_GS_SEPARATOR) ? 2 : 1;
ret = dm_encode(symbol, (unsigned char *) data[i].data, length, symbol->eci, gs1, binary[1], &binlen);
assert_equal(ret, data[i].ret, "i:%d dm_encode() minimal ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d dm_encode() minimal ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
binlens[1] = binlen; binlens[1] = binlen;
@ -6371,6 +6659,7 @@ static void test_minimalenc(int index, int debug) {
testFinish(); testFinish();
} }
#endif
#include <time.h> #include <time.h>
@ -6554,7 +6843,10 @@ int main(int argc, char *argv[]) {
{ "test_reader_init", test_reader_init, 1, 1, 1 }, { "test_reader_init", test_reader_init, 1, 1, 1 },
{ "test_input", test_input, 1, 1, 1 }, { "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_encode_segs", test_encode_segs, 1, 1, 1 },
#ifdef ZINT_TEST_ENCODING
{ "test_minimalenc", test_minimalenc, 1, 0, 1 }, { "test_minimalenc", test_minimalenc, 1, 0, 1 },
#endif
{ "test_perf", test_perf, 1, 0, 1 }, { "test_perf", test_perf, 1, 0, 1 },
}; };

View File

@ -148,62 +148,70 @@ static void test_input(int index, int generate, int debug) {
struct item { struct item {
int input_mode; int input_mode;
int eci; int eci;
int option_2;
int option_3;
struct zint_structapp structapp; struct zint_structapp structapp;
char *data; char *data;
int length; int length;
int ret; int ret;
char *expected; char *expected;
int bwipp_cmp;
char *comment; char *comment;
}; };
struct item data[] = { struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, { 0, 0, "" }, "A", -1, 0, "66 21", "" }, /* 0*/ { UNICODE_MODE, -1, 13, -1, { 0, 0, "" }, "A", -1, 0, "66 21 6A", 1, "" },
/* 1*/ { UNICODE_MODE, 3, { 0, 0, "" }, "A", -1, 0, "6C 03 66 21", "" }, /* 1*/ { UNICODE_MODE, 3, -1, -1, { 0, 0, "" }, "A", -1, 0, "6C 03 66 21", 1, "" },
/* 2*/ { UNICODE_MODE, 40, { 0, 0, "" }, "A", -1, 0, "6C 28 00 00 66 21", "" }, /* 2*/ { UNICODE_MODE, 40, 18, -1, { 0, 0, "" }, "A", -1, 0, "6C 28 00 00 66 21", 1, "" },
/* 3*/ { UNICODE_MODE, 113, { 0, 0, "" }, "A", -1, 0, "6C 28 00 49 66 21", "" }, /* 3*/ { UNICODE_MODE, 113, 18, -1, { 0, 0, "" }, "A", -1, 0, "6C 28 00 49 66 21", 1, "" },
/* 4*/ { UNICODE_MODE, 899, { 0, 0, "" }, "A", -1, 0, "6C 28 07 44 66 21", "" }, /* 4*/ { UNICODE_MODE, 899, 18, -1, { 0, 0, "" }, "A", -1, 0, "6C 28 07 44 66 21", 1, "" },
/* 5*/ { UNICODE_MODE, 12769, { 0, 0, "" }, "A", -1, 0, "6C 28 70 49 66 21", "" }, /* 5*/ { UNICODE_MODE, 12769, 18, 8 << 8, { 0, 0, "" }, "A", -1, 0, "6C 28 70 49 66 21", 1, "" },
/* 6*/ { UNICODE_MODE, 811799, { 0, 0, "" }, "A", -1, 0, "6C 67 40 50 66 21", "" }, /* 6*/ { UNICODE_MODE, 811799, 18, -1, { 0, 0, "" }, "A", -1, 0, "6C 67 40 50 66 21", 1, "" },
/* 7*/ { UNICODE_MODE, 811800, { 0, 0, "" }, "A", -1, ZINT_ERROR_INVALID_OPTION, "Error 525: Invalid ECI", "" }, /* 7*/ { UNICODE_MODE, 811800, -1, -1, { 0, 0, "" }, "A", -1, ZINT_ERROR_INVALID_OPTION, "Error 525: Invalid ECI", 1, "" },
/* 8*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\000", 1, 0, "65 40", "LatchA (0x65) NUL" }, /* 8*/ { UNICODE_MODE, -1, 13, -1, { 0, 0, "" }, "\000", 1, 0, "65 40 6A", 1, "LatchA (0x65) NUL PAD" },
/* 9*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\010", -1, 0, "65 48", "LatchA (0x65) BS" }, /* 9*/ { UNICODE_MODE, -1, 13, -1, { 0, 0, "" }, "\010", -1, 0, "65 48 6A", 1, "LatchA (0x65) BS PAD" },
/* 10*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\011", -1, 0, "65 49", "Lead special; LatchA (0x65) HT" }, /* 10*/ { UNICODE_MODE, -1, 13, -1, { 0, 0, "" }, "\011", -1, 0, "65 49 6A", 1, "Lead special; LatchA (0x65) HT PAD" },
/* 11*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\034", -1, 0, "65 5C", "Lead special; LatchA (0x65) FS" }, /* 11*/ { UNICODE_MODE, -1, 13, -1, { 0, 0, "" }, "\034", -1, 0, "65 5C 6A", 1, "Lead special; LatchA (0x65) FS PAD" },
/* 12*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\035", -1, 0, "65 5D", "Lead special; LatchA (0x65) GS" }, /* 12*/ { UNICODE_MODE, -1, 13, -1, { 0, 0, "" }, "\035", -1, 0, "65 5D 6A", 1, "Lead special; LatchA (0x65) GS PAD" },
/* 13*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\036", -1, 0, "65 5E", "Lead special; LatchA (0x65) RS" }, /* 13*/ { UNICODE_MODE, -1, 13, -1, { 0, 0, "" }, "\036", -1, 0, "65 5E 6A", 1, "Lead special; LatchA (0x65) RS PAD" },
/* 14*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\037", -1, 0, "65 5F", "LatchA (0x65) US" }, /* 14*/ { UNICODE_MODE, -1, 13, -1, { 0, 0, "" }, "\037", -1, 0, "65 5F 6A", 1, "LatchA (0x65) US PAD" },
/* 15*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\177", -1, 0, "66 5F", "ShiftB (0x66) DEL" }, /* 15*/ { UNICODE_MODE, -1, 13, -1, { 0, 0, "" }, "\177", -1, 0, "66 5F 6A", 1, "ShiftB (0x66) DEL PAD" },
/* 16*/ { UNICODE_MODE, -1, { 0, 0, "" }, "[)>\03605\035A\036\004", -1, 0, "6A 61 21", "[)>RS 05 GS A RS EOT; LatchB (0x6A) Macro97 (0x61) A" }, /* 16*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "[)>\03605\035A\036\004", -1, 0, "6A 61 21", 1, "[)>RS 05 GS A RS EOT; LatchB (0x6A) Macro97 (0x61) A" },
/* 17*/ { UNICODE_MODE, -1, { 0, 0, "" }, "[)>\03606\035\011\034\035\036\036\004", -1, 0, "6A 62 61 62 63 64", "[)>RS 06 GS HT FS GS RS RS EOT; LatchB (0x6A) Macro98 (0x62) HT FS GS RS" }, /* 17*/ { UNICODE_MODE, -1, 17, -1, { 0, 0, "" }, "[)>\03606\035\011\034\035\036\036\004", -1, 0, "6A 62 61 62 63 64 6A", 1, "[)>RS 06 GS HT FS GS RS RS EOT; LatchB (0x6A) Macro98 (0x62) HT FS GS RS PAD" },
/* 18*/ { UNICODE_MODE, -1, { 0, 0, "" }, "[)>\03612\03512345\036\004", -1, 0, "6A 63 11 67 17 2D", "[)>RS 12 GS A RS EOT; LatchB (0x6A) Macro99 (0x63) 1 2xShiftC (0x67) 23 45" }, /* 18*/ { UNICODE_MODE, -1, 17, -1, { 0, 0, "" }, "[)>\03612\03512345\036\004", -1, 0, "6A 63 11 67 17 2D 6A", 1, "[)>RS 12 GS A RS EOT; LatchB (0x6A) Macro99 (0x63) 1 2xShiftC (0x67) 23 45 PAD" },
/* 19*/ { UNICODE_MODE, -1, { 0, 0, "" }, "[)>\03601Blah\004", -1, 0, "6A 64 10 11 22 4C 41 48", "[)>RS 01 Blah EOT; LatchB (0x6A) Macro100 (0x64) 0 1 B l a h" }, /* 19*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "[)>\03601Blah\004", -1, 0, "6A 64 10 11 22 4C 41 48 6A", 1, "[)>RS 01 Blah EOT; LatchB (0x6A) Macro100 (0x64) 0 1 B l a h PAD" },
/* 20*/ { UNICODE_MODE, -1, { 0, 0, "" }, "[)>\03605\035A\004", -1, 0, "6A 64 10 15 63 21", "[)>RS 05 GS A EOT; LatchB (0x6A) Macro100 (0x64) 0 5 HT A" }, /* 20*/ { UNICODE_MODE, -1, 22, -1, { 0, 0, "" }, "[)>\03605\035A\004", -1, 0, "65 3B 09 1E 5E 10 15 5D 21 44", 1, "NOTE: no longer using Macro for malformed 05/06/12" },
/* 21*/ { UNICODE_MODE, -1, { 0, 0, "" }, "[)>\03606A\004", -1, 0, "6A 64 10 16 21", "[)>RS 06 A EOT; LatchB (0x6A) Macro100 (0x64) 0 6 A" }, /* 21*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "[)>\03606A\004", -1, 0, "65 3B 09 1E 5E 10 16 21 44", 1, "NOTE: no longer using Macro for malformed 05/06/12" },
/* 22*/ { UNICODE_MODE, -1, { 0, 0, "" }, "[)>\036991\036\004", -1, 0, "6A 64 19 19 11 64", "[)>RS 99 1 RS EOT; LatchB (0x6A) Macro100 (0x64) 9 9 1 RS" }, /* 22*/ { UNICODE_MODE, -1, 13, -1, { 0, 0, "" }, "[)>\036991\036\004", -1, 0, "6A 64 19 19 11 64", 1, "[)>RS 99 1 RS EOT; LatchB (0x6A) Macro100 (0x64) 9 9 1 RS" },
/* 23*/ { UNICODE_MODE, -1, { 0, 0, "" }, "1712345610", -1, 0, "6B 64 0C 22 38", "FNC1 (0x6B) 17..10 12 34 56" }, /* 23*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "1712345610", -1, 0, "6B 64 0C 22 38", 1, "FNC1 (0x6B) 17..10 12 34 56" },
/* 24*/ { GS1_MODE, -1, { 0, 0, "" }, "[17]123456[10]123", -1, ZINT_WARN_NONCOMPLIANT, "64 0C 22 38 0C 66 13", "17..10 12 34 56 12 ShiftB (0x66) 3" }, /* 24*/ { GS1_MODE, -1, -1, -1, { 0, 0, "" }, "[17]123456[10]123", -1, ZINT_WARN_NONCOMPLIANT, "64 0C 22 38 0C 66 13", 0, "17..10 12 34 56 12 ShiftB (0x66) 3; BWIPP does not allow bad month" },
/* 25*/ { GS1_MODE, -1, { 0, 0, "" }, "[90]ABC[90]abc[90]123", -1, 0, "5A 6A 21 22 23 6B 19 10 41 42 43 6B 19 67 01 17", "90 LatchB (0x6A) A B C FNC1 (0x6B) 9 0 a b c FNC1 (0x6B) 9 2xShitfC (0x67) 01 23" }, /* 25*/ { GS1_MODE, -1, -1, -1, { 0, 0, "" }, "[90]ABC[90]abc[90]123", -1, 0, "5A 6A 21 22 23 6B 19 10 41 42 43 6B 19 67 01 17 6A", 1, "90 LatchB (0x6A) A B C FNC1 (0x6B) 9 0 a b c FNC1 (0x6B) 9 2xShitfC (0x67) 01 23 PAD" },
/* 26*/ { GS1_MODE | GS1PARENS_MODE, -1, { 0, 0, "" }, "(90)ABC(90)abc(90)123", -1, 0, "5A 6A 21 22 23 6B 19 10 41 42 43 6B 19 67 01 17", "90 LatchB (0x6A) A B C FNC1 (0x6B) 9 0 a b c FNC1 (0x6B) 9 2xShitfC (0x67) 01 23" }, /* 26*/ { GS1_MODE | GS1PARENS_MODE, -1, -1, -1, { 0, 0, "" }, "(90)ABC(90)abc(90)123", -1, 0, "5A 6A 21 22 23 6B 19 10 41 42 43 6B 19 67 01 17 6A", 1, "90 LatchB (0x6A) A B C FNC1 (0x6B) 9 0 a b c FNC1 (0x6B) 9 2xShitfC (0x67) 01 23 PAD" },
/* 27*/ { UNICODE_MODE, -1, { 0, 0, "" }, "99aA[{00\000", 9, 0, "6B 63 6A 41 21 3B 5B 10 10 65 40", "FNC1 (0x6B) 99 LatchB (0x6A) a A [ { 0 0 ShiftA (0x65) NUL" }, /* 27*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "99aA[{00\000", 9, 0, "6B 63 6A 41 21 3B 5B 10 10 65 40", 1, "FNC1 (0x6B) 99 LatchB (0x6A) a A [ { 0 0 ShiftA (0x65) NUL" },
/* 28*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\015\012", -1, 0, "66 60", "ShiftB (0x66) CR/LF" }, /* 28*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "\015\012", -1, 0, "66 60", 0, "ShiftB (0x66) CR/LF; BWIPP different encodation" },
/* 29*/ { UNICODE_MODE, -1, { 0, 0, "" }, "A\015\012", -1, 0, "67 21 60", "2xShiftB (0x67) A CR/LF" }, /* 29*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A\015\012", -1, 0, "67 21 60", 0, "2xShiftB (0x67) A CR/LF; BWIPP different encodation" },
/* 30*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\015\015\012", -1, 0, "65 4D 4D 4A", "LatchA (0x65) CR CR LF" }, /* 30*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "\015\015\012", -1, 0, "65 4D 4D 4A", 1, "LatchA (0x65) CR CR LF" },
/* 31*/ { UNICODE_MODE, -1, { 0, 0, "" }, "ABCDE12345678", -1, 0, "6A 21 22 23 24 25 69 0C 22 38 4E", "LatchB (0x6A) A B C D 4xShiftC 12 34 56 78" }, /* 31*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "ABCDE12345678", -1, 0, "6A 21 22 23 24 25 69 0C 22 38 4E", 1, "LatchB (0x6A) A B C D 4xShiftC 12 34 56 78" },
/* 32*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\000ABCD1234567890", 15, 0, "65 40 21 22 23 24 6A 0C 22 38 4E 5A", "LatchA (0x65) NULL A B C D LatchC (0x6A) 12 34 56 78 90" }, /* 32*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "\000ABCD1234567890", 15, 0, "65 40 21 22 23 24 6A 0C 22 38 4E 5A 6A", 1, "LatchA (0x65) NULL A B C D LatchC (0x6A) 12 34 56 78 90 PAD" },
/* 33*/ { DATA_MODE, -1, { 0, 0, "" }, "\141\142\143\144\145\200\201\202\203\204\377", -1, 0, "6A 41 42 43 44 45 70 31 5A 35 21 5A 5F 02 31", "LatchB (0x6A) a b c d e BinaryLatch (0x70) 0x80 0x81 0x82 0x83 0x84 0xFF" }, /* 33*/ { DATA_MODE, -1, -1, 2 << 8, { 0, 0, "" }, "\141\142\143\144\145\200\201\202\203\204\377", -1, 0, "6A 41 42 43 44 45 70 31 5A 35 21 5A 5F 02 31", 1, "LatchB (0x6A) a b c d e BinaryLatch (0x70) 0x80 0x81 0x82 0x83 0x84 0xFF" },
/* 34*/ { DATA_MODE, -1, { 0, 0, "" }, "\200\061\062\240\063\064\201\202\065\066", -1, 0, "6E 40 0C 6F 00 22 70 03 10 42 6E 15 16", "UpperShiftA (0x6E) NUL 12 UpperShiftB (0x6F) SP 34 BinaryLatch (0x70) 0x81 0x82 TermB (0x6E) 5 6" }, /* 34*/ { DATA_MODE, -1, -1, -1, { 0, 0, "" }, "\200\061\062\240\063\064\201\202\065\066", -1, 0, "6E 40 0C 6F 00 22 70 03 10 42 6E 15 16", 1, "UpperShiftA (0x6E) NUL 12 UpperShiftB (0x6F) SP 34 BinaryLatch (0x70) 0x81 0x82 TermB (0x6E) 5 6" },
/* 35*/ { DATA_MODE, -1, { 0, 0, "" }, "\200\201\202\203\061\062\063\064", -1, 0, "70 13 56 0A 59 2C 67 0C 22", "BinaryLatch (0x70) 0x80 0x81 0x82 0x83 Intr2xShiftC (0x67) 12 3" }, /* 35*/ { DATA_MODE, -1, -1, -1, { 0, 0, "" }, "\200\201\202\203\061\062\063\064", -1, 0, "70 13 56 0A 59 2C 67 0C 22", 1, "BinaryLatch (0x70) 0x80 0x81 0x82 0x83 Intr2xShiftC (0x67) 12 3" },
/* 36*/ { DATA_MODE, -1, { 0, 0, "" }, "\001\200\201\202\203\204\200\201\202\203\204", -1, 0, "65 41 70 31 5A 35 21 5A 5F 31 5A 35 21 5A 5F", "LatchA (0x65) SOH BinaryLatch (0x70) 0x80 0x81 0x82 0x83 0x80 0x81 0x82 0x83" }, /* 36*/ { DATA_MODE, -1, -1, -1, { 0, 0, "" }, "\001\200\201\202\203\204\200\201\202\203\204", -1, 0, "65 41 70 31 5A 35 21 5A 5F 31 5A 35 21 5A 5F", 1, "LatchA (0x65) SOH BinaryLatch (0x70) 0x80 0x81 0x82 0x83 0x80 0x81 0x82 0x83" },
/* 37*/ { UNICODE_MODE, -1, { 0, 0, "" }, "\001abc\011\015\012\036", -1, 0, "65 41 65 41 42 43 61 60 64", "LatchA (0x65) SOH 6xShiftB (0x65) a b c HT CR/LF RS" }, /* 37*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "\001abc\011\015\012\036", -1, 0, "65 41 65 41 42 43 61 60 64", 1, "LatchA (0x65) SOH 6xShiftB (0x65) a b c HT CR/LF RS" },
/* 38*/ { UNICODE_MODE, -1, { 35, 35, "" }, "ABCDE", -1, 0, "6A 21 22 23 24 25 3A 3A 6C", "LatchB (0x6A) A B C D E Z Z FNC2" }, /* 38*/ { UNICODE_MODE, -1, -1, -1, { 35, 35, "" }, "ABCDE", -1, 0, "6A 21 22 23 24 25 3A 3A 6C", 1, "LatchB (0x6A) A B C D E Z Z FNC2" },
/* 39*/ { UNICODE_MODE, -1, { 9, 10, "" }, "1234567890", -1, 0, "6B 0C 22 38 4E 5A 65 19 21 6C", "FNC1 (0x6B) 12 34 56 78 90 LatchA (0x65) 9 A FNC2" }, /* 39*/ { UNICODE_MODE, -1, -1, -1, { 9, 10, "" }, "1234567890", -1, 0, "6B 0C 22 38 4E 5A 65 19 21 6C", 1, "FNC1 (0x6B) 12 34 56 78 90 LatchA (0x65) 9 A FNC2" },
/* 40*/ { UNICODE_MODE, -1, { 2, 3, "" }, "\001\002\003\004", -1, 0, "65 41 42 43 44 12 13 6C", "LatchA (0x65) <SOH> <STX> <ETX> <EOT> 2 3 FNC2" }, /* 40*/ { UNICODE_MODE, -1, -1, -1, { 2, 3, "" }, "\001\002\003\004", -1, 0, "65 41 42 43 44 6A 12 13 6C", 1, "LatchA (0x65) <SOH> <STX> <ETX> <EOT> PAD 2 3 FNC2" },
/* 41*/ { DATA_MODE, -1, { 1, 34, "" }, "\200\201\202\203", -1, 0, "70 13 56 0A 59 2C 6D 11 39 6C", "BinaryLatch (0x70) (...) TermA (0x6D) 1 Y FNC2" }, /* 41*/ { DATA_MODE, -1, -1, -1, { 1, 34, "" }, "\200\201\202\203", -1, 0, "70 13 56 0A 59 2C 6D 11 39 6C", 1, "BinaryLatch (0x70) (...) TermA (0x6D) 1 Y FNC2" },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
struct zint_symbol *symbol; struct zint_symbol *symbol;
char escaped[1024]; char escaped[1024];
char cmp_buf[32768];
char cmp_msg[1024];
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); // Only do ZXing-C++ test if asked, too slow otherwise
testStart("test_input"); testStart("test_input");
@ -216,7 +224,9 @@ static void test_input(int index, int generate, int debug) {
debug |= ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt debug |= ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
length = testUtilSetSymbol(symbol, BARCODE_DOTCODE, data[i].input_mode, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, data[i].length, debug); length = testUtilSetSymbol(symbol, BARCODE_DOTCODE, data[i].input_mode, data[i].eci,
-1 /*option_1*/, data[i].option_2, data[i].option_3, -1 /*output_options*/,
data[i].data, data[i].length, debug);
if (data[i].structapp.count) { if (data[i].structapp.count) {
symbol->structapp = data[i].structapp; symbol->structapp = data[i].structapp;
} }
@ -225,13 +235,41 @@ static void test_input(int index, int generate, int debug) {
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) { if (generate) {
printf(" /*%3d*/ { %s, %d, { %d, %d, \"%s\" }, \"%s\", %d, %s, \"%s\", \"%s\" },\n", printf(" /*%3d*/ { %s, %d, %d, %d, { %d, %d, \"%s\" }, \"%s\", %d, %s, \"%s\", %d, \"%s\" },\n",
i, testUtilInputModeName(data[i].input_mode), data[i].eci, i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_2, data[i].option_3,
data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, data[i].structapp.index, data[i].structapp.count, data[i].structapp.id,
testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)),
data[i].length, testUtilErrorName(data[i].ret), symbol->errtxt, data[i].comment); data[i].length, testUtilErrorName(data[i].ret), symbol->errtxt, data[i].bwipp_cmp, data[i].comment);
} else { } else {
assert_zero(strcmp((char *) symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); assert_zero(strcmp((char *) symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected);
if (ret < ZINT_ERROR) {
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, debug)) {
if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
char modules_dump[200 * 200 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump);
}
}
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) {
int cmp_len, ret_len;
char modules_dump[200 * 200 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %.*s\nexpected: %.*s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped);
}
}
} }
ZBarcode_Delete(symbol); ZBarcode_Delete(symbol);
@ -955,6 +993,80 @@ static void test_encode(int index, int generate, int debug) {
"1000101000001" "1000101000001"
"0101010101000" "0101010101000"
}, },
/* 47*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, "[)>\03605\035101\036\004", -1, 0, 12, 17, 1, 1, "Macro 05",
"10000010001000101"
"00000001000000010"
"10001010100010001"
"01010000010000000"
"10001010000010001"
"01000000010000010"
"10100010101000001"
"01010100000001010"
"00001000101010101"
"01010001000101000"
"10101010101010101"
"01010001010101010"
},
/* 48*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, "[)>\03607Text\036\004", -1, 0, 14, 21, 1, 1, "Macro 07 (free form text)",
"100010001000001000101"
"010001000000010101010"
"000010101000100000101"
"010100000000010000000"
"001000100000000000100"
"010101010001010101010"
"101010101010100010100"
"010000010101000000000"
"001010001000001010001"
"000000000101010101010"
"001000000010001000001"
"000101000101000100000"
"100010101010100010101"
"000001010100010100000"
},
/* 49*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, "[)>\03605\035Študentska št.\0352198390\036\004", -1, ZINT_WARN_USES_ECI, 23, 34, 1, 1, "Macro 05 with ECI",
"1010101000100000101000001010000010"
"0101000001000101010100000101000001"
"1000101000101000100010100010001000"
"0000010001010001000100010001010000"
"0000101000100010000010001010101000"
"0001010001000100010000010101010100"
"0000100010100000101010001000001010"
"0100010100010100010000010101000001"
"1010101000100010000010000010001010"
"0101000100000100010001010000010001"
"0010101000100010001000001010101000"
"0100010100010001000101010000010000"
"0000101010100010000010100010100010"
"0101000000000001010001010001000001"
"0010100010000000101010100010100010"
"0101000100010101000100000100010100"
"0010100010000010101000101000001000"
"0001000100000101000100010000010101"
"1000100010100000100010001010100010"
"0101010001000001000101000101000100"
"0010000010001010100010001000001000"
"0100000001000100010001010100010101"
"1010001000001010101000000010101000"
},
/* 50*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, "[)>\03607Τεχτ\036\004", -1, ZINT_WARN_USES_ECI, 17, 26, 1, 1, "Macro 07 with ECI",
"10001010001000100000101000"
"00010101000101000000010101"
"00100010100000100010001000"
"00010101000101010101000100"
"10101000100010001010000000"
"00000100010100010100000001"
"00001010101000100000001010"
"01010000010001010100010100"
"00000010100010101010000010"
"00010101000101000101000001"
"00101000101000100010001000"
"00010101000100000001010100"
"10100010000010001010001000"
"00010100010100010000010001"
"10001000101000101010001000"
"01000101010100000000000101"
"10100010000010101010000010"
},
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@ -1007,7 +1119,7 @@ static void test_encode(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
@ -1039,6 +1151,401 @@ static void test_encode(int index, int generate, int debug) {
testFinish(); testFinish();
} }
static void test_encode_segs(int index, int generate, int debug) {
struct item {
int input_mode;
int option_2;
int option_3;
struct zint_structapp structapp;
struct zint_seg segs[3];
int ret;
int expected_rows;
int expected_width;
int bwipp_cmp;
int zxingcpp_cmp;
char *comment;
char *expected;
};
// ISS DotCode, Rev 4.0, DRAFT 0.15, TSC Pre-PR #5, MAY 28, 2019
struct item data[] = {
/* 0*/ { UNICODE_MODE, 18, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 13, 18, 1, 1, "ISS DotCode Rev 4.0 13.5 example **NOT SAME** different encodation",
"100000001010101010"
"000100000100010101"
"001010000010101000"
"010101010001010001"
"100010100010000000"
"010100010100000101"
"001000101000000010"
"000001010101000100"
"100010100010000010"
"000001000101000001"
"101000101010100010"
"010100000000010001"
"100000101010000010"
},
/* 1*/ { UNICODE_MODE, 18, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 13, 18, 1, 1, "ISS DotCode Rev 4.0 13.5 example auto-ECI",
"100000001010101010"
"000100000100010101"
"001010000010101000"
"010101010001010001"
"100010100010000000"
"010100010100000101"
"001000101000000010"
"000001010101000100"
"100010100010000010"
"000001000101000001"
"101000101010100010"
"010100000000010001"
"100000101010000010"
},
/* 2*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 7 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, 0, 14, 21, 1, 1, "ISS DotCode Rev 4.0 13.5 example inverted",
"100010001010101010000"
"000100000101000001010"
"101000101000001000101"
"000001010100000101000"
"001010101010100010001"
"010001000001010101000"
"101000101000101010100"
"010101010001010001000"
"100010001000000000100"
"010100000001000100010"
"001000100010000000101"
"000000000100010100010"
"100010001000100000001"
"010101000100010001000"
},
/* 3*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 14, 21, 1, 1, "ISS DotCode Rev 4.0 13.5 example inverted auto-ECI",
"100010001010101010000"
"000100000101000001010"
"101000101000001000101"
"000001010100000101000"
"001010101010100010001"
"010001000001010101000"
"101000101000101010100"
"010101010001010001000"
"100010001000000000100"
"010100000001000100010"
"001000100010000000101"
"000000000100010100010"
"100010001000100000001"
"010101000100010001000"
},
/* 4*/ { UNICODE_MODE, 95, -1, { 0, 0, "" }, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 64, 95, 0, 1, "AIM ITS/04-023:2022 Annex A example; BWIPP different encodation",
"10101000100000001010000000101000101010100010001010000010001000101000101000001000001000100010101"
"00000101010001010000010101000000010100000001010101000101010100010101000101000100000100000100000"
"10100010100010001000100000001010100000001000101000101010001010001010000000101000001000101000101"
"01010001000100000000000001010000010100010101010100010001010001010000010000010000010100010000010"
"10000010101000100000001010000010000000000000000000100010100010100000101010001000000010001000000"
"00010100000101000001010100000101010101010000010001010100000100010101010001010101000101000000010"
"10001010001010101010000010001010000010101000001000101000001000101000100010101010001000000010100"
"00010100010100010101000000010001010101000101000101010001010101000000000101010001010100000101000"
"10100000000000000000101000100010101010001000101010001010101010000000000010000000100010101010001"
"01000100010001010001000000000000000001000100000100000001010100010100010001010001010101010100010"
"00101000101010101000000010101000001010001010100010101000000000101010101000101010101010100000101"
"00000101010101010100010001010101000101010000010001010001000001010101000100000100000001010001010"
"00101010000010101000101000100000101000100010001000101000101010000010100010100000001000001010101"
"01000000010001000101010100000100000000010101000100000100010000010000010100000101000100000001010"
"00001010101000101000100000001000001010100010000010101010100000101010100010000000100010001000001"
"01010101010101010100000000010100010000010101000101010100000101010000000000010000010100010101000"
"10000000001010000010101000100010000010100000100000100010100010000000101010101010100010000000100"
"00010000000000010001010101000101010101000000010100000100010001000101010101010001000001010101010"
"10100000100000101010101010100000100010101010100010000010001010100010100010000010100000001010001"
"01000001010000000101010001010001000001010100010000000100000000000001000100000100000101000101010"
"10000010101010100010001010101010000000000010101000101010000000101000001000101010101010100000100"
"00010101000100000100000101010000010100010001000001010100000100010101010001010101010001010001010"
"00001010101000000010000010001010001000101000100000000000001010000000001000001010000000100010100"
"01000001000101000101010000000101010101010101000001000001010101000101010100010001010000010000000"
"10101010000010001000000000000000101010001010001010001000100000100010101010101000101010101010000"
"01010100000101010000010101010001000101000100010101000100010001010001010101000000010101010101000"
"00100010101000100010100010101000101000001000001010001010001010001010100000100010000010100010001"
"00000000010100010001000000000100010000010000010101000001000001000101000101010100010100010100000"
"10100000101010001000001000101010100000100000101000100010100000101000001000100000101000001010000"
"00010101000101000101010101000101000001000001000000010001010100000100000100000101010000000101010"
"00100000000010100010101010101010101000100010100010100010001010100010001000101010101000100010000"
"01000100010000010000000101000101010100000100010100010101000101010001010001000100010100000000010"
"10001000001000001010101010000000001010101000101010000000100010001010000010001000101010100000101"
"01010101000001000100000001010000010100010100000101000000010100000000000000010101000001010001000"
"00001010100000000000001000100010100010101010000000001000100000001010100010000010000000001010001"
"01010101000101000001010100010000000001010100000100010101000101010101010001010000010101000100000"
"00001010001000101000000000001010101010000010001000101010001000101000101010001000000010100010101"
"00010001010000010100000000000101000001010001000101010101010001010101010101000101010100000101010"
"10101000100010000000101010100010000000001010100010101010001010000010101000101010001010100010101"
"01000100010000010101000101010000010101000101010001010001000001000000000000010101010101010001010"
"10000010001000100010100010101000001010100010001010000000101000101010000010000010100010001000100"
"01010000010101010101010100000001010100010000010000000000010100010100000100000000000001010000010"
"00100000000010101010001000001010001010001000101010101010101010001000100010101000001000001000100"
"00000100000101010001010101010100000001010101010000000100010100010001010001010101000001000101000"
"00001010001010001010000000100000100000101000101000101000100010101010101000000010101000101000101"
"01010101010001010100000000010001000001010001010101010101010100000001000000010101000101010100000"
"10100010101000101010101010100010100000000010100000000010001000100010001010001000101010001010001"
"01010001010000000001010101010101010100000101010001000100000001010000010100000000000101000001010"
"00001010100010101000101010001000101000101010001010101010001000100000001010100000100000101010100"
"00000001000101000101010001010001000001000001010101010101000000000101010101010000010000010000010"
"10100000000010101000001000000000000010001010100010001000001010000000000000001000000010101000000"
"00000100000100000100000000000100010100000100010000000000010000000101010001000001010101010101000"
"00101000101000000010000000001000101010100000000010100010100010001010101010101010001010000000100"
"01000101010000010000010100000001010100010001000001010101000101010100000101000101010100010100000"
"10101010101010000010100010101010000000000010001000100000001000100000100000100010100010101000101"
"01010000010001010001010100000101010001010001000101010001000101010000000101010001000000000101010"
"10000000000010101000100010100010101010100000001000101000100010000000100000101010000010100010001"
"00010101010100000001010101010000000101000100000100010001010001000100010000000101010100000001010"
"10101010001010101010001000101010000010101010100010001000100000001000101000000000101000001000001"
"01010100000101010100000000000100010101000101010100000000010101010001010000000100000001000100010"
"10000010100000100000101010001000100000000000100000000010100010001010001010100010100010000010100"
"00010000010101000101010101010101010000010100010000010001010000010100000101000100010000010000000"
"10100000100000001010101010101010001010001010000010100010001010101010000010001010000000100010001"
"01000001000100000101000101010100000000010001000100000101000100000100010101010101000101010100010"
},
/* 5*/ { DATA_MODE, -1, -1, { 0, 0, "" }, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, 0, 15, 22, 1, 1, "Standard example + extra seg, data mode",
"1000101010000000001000"
"0100000101000101000001"
"1000001000100010101000"
"0000010001000001010101"
"1000100000100010101010"
"0001010000010000010001"
"0010101000101010100010"
"0000010101000101000000"
"1000100010001010100000"
"0101000101000100010100"
"0010100000100000001010"
"0001000101000001010100"
"1010000010100010001010"
"0000010000010000010101"
"1010001010100000101010"
},
/* 6*/ { UNICODE_MODE, 38, -1, { 0, 0, "" }, { { TU("1234567890β"), -1, 9 }, { TU("1234567890点"), -1, 20 }, { TU("1234567890"), -1, 0 } }, 0, 23, 38, 0, 1, "FNC2 ECI & BIN_LATCH ECI; BWIPP different encodation",
"10000000001010100000101010100000100010"
"00000001010001000001010001010101000100"
"10001010100000101000001010001010101000"
"01000101010001010001000100000000010101"
"00001000100010001010100000101000100000"
"01000101010000010101010001000000010101"
"10001000101000101010000000100010000010"
"01000100010001010001010000010100010001"
"10101000000010001010000010101010000000"
"01010100010000010100010000010000010101"
"00000010100010001010000010000010100010"
"01010000010001010001000101000001010101"
"10000000000010001010101000101000000010"
"00010001010001010100010000010101000101"
"10000010101010101000000010001000100010"
"00000101000101010100010000010100010000"
"00001010101000000010100010001010000010"
"01010001000100000100010001010000010101"
"00001010001010001000000000101010100010"
"01010101010000000100010101010000010100"
"00101010100010000010100010000010000010"
"01010000010100010001010000010000010101"
"10000010100000001010100000100010001010"
},
/* 7*/ { UNICODE_MODE, 29, -1, { 0, 0, "" }, { { TU("çèéêëì"), -1, 0 }, { TU("òóô"), -1, 899 }, { TU(""), 0, 0 } }, 0, 20, 29, 1, 0, "BIN_LATCH ECI > 0xFF; ZXing-C++ test can't handle binary",
"10001010001010101000000010001"
"01000001000100010100010101010"
"10000000100000100000000010101"
"00010100010001000101010000000"
"10001000000000001010101010101"
"00000100010100010000010101000"
"10001000101000001000100000000"
"01010101000101010101000101010"
"10101010101010000010001010000"
"00000001000001010101010001010"
"10001000000010100000101010101"
"01000001010100010101010100000"
"00000010101000101000000000101"
"01000101000001000100000000000"
"00100010000010100010100000101"
"01010000010101000101010100010"
"10100000100010000010001000001"
"01010101000000000100000001010"
"10101000101010000010001010001"
"01010101010100010001010001010"
},
/* 8*/ { UNICODE_MODE, 29, -1, { 0, 0, "" }, { { TU("çèéêëì"), -1, 0 }, { TU("òóô"), -1, 65536 }, { TU(""), 0, 0 } }, 0, 22, 29, 1, 0, "BIN_LATCH ECI > 0xFFFF; ZXing-C++ test can't handle binary",
"10101000100000101000001010001"
"00010101000000000100010100000"
"10100010001010000010101010100"
"00010100010101000100010001010"
"00001000001010101010101010101"
"00010000000001000100010100010"
"10001000001010000010000010001"
"00000001010101010000000101010"
"10101010101000001010100010101"
"01000100000100010001010001000"
"10000000000000101010100000001"
"00010101000101000001000001000"
"00101010101000100000001000101"
"00010001010001000101000100010"
"00000000100010100010000000001"
"01000001000100000000010101010"
"10100010100010001010001010101"
"01000100010001010100010100000"
"10101010001000100010100000101"
"01000001000000010001000001000"
"10001010101000101010000010001"
"01010101010101010001010000010"
},
/* 9*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("[)>\03605\035"), -1, 0 }, { TU("A\036\004"), -1, 0 }, { TU(""), 0, 0 } }, 0, 10, 13, 1, 1, "Macro 05",
"1010001010101"
"0001000001010"
"1010100010001"
"0000000001000"
"1000101000100"
"0101010101000"
"1000001000001"
"0100010000010"
"0000100000100"
"0001010101010"
},
/* 10*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("[)>\03605\035"), -1, 0 }, { TU("Študentska št."), -1, 4 }, { TU("\0352198390\036\004"), -1, 0 } }, 0, 24, 35, 1, 1, "Macro 05 with ECI",
"10101000000010101000000000101010001"
"00010100000001000000000101010001010"
"00000010001000000010100010001000101"
"00000000010100010101000001010001010"
"00000010101010000000101010100010000"
"00010000000101000101010001000100000"
"10001000000000001010100000001000101"
"01000001010101010100000101010101010"
"00100010000010100010001010101000000"
"00010101010000000001010100010101000"
"00101000100010001000001000100010101"
"00010000010101010000010001010100000"
"10100010101010101010000010000000001"
"01010100000100010100000100000000010"
"10001000100010100010101000001010101"
"01010101010000000101000001000100010"
"10001010101000001010101000001000100"
"01000101010101000101010101010101000"
"10101010101000100010100000000000000"
"01000101010000000000010000000001000"
"00100010001000101000100010101000100"
"01000000000101010101010100000101010"
"10001010000010100000001010000010001"
"01010001000001010001010001010101010"
},
/* 11*/ { UNICODE_MODE, -1, -1, { 35, 35, "" }, { { TU("Τεχτ"), -1, 9 }, { TU("กขฯ"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 20, 29, 0, 1, "Structured Append with Terminate Latch A replaced",
"10101000001010000000001000101"
"01010101010101000000000100000"
"00101010001010100010101010001"
"01000100010000000101010100010"
"10000010100010001000100000000"
"00010000010101010100000101010"
"10100010101010101010001000001"
"00010101000000010101010001000"
"10000000100000101000101000101"
"01010000010001010001000100010"
"00101000000000100010001010101"
"01000001000101010001000001010"
"00001010000000000000100010101"
"00000101010101000100010001000"
"00101000001010001000001010101"
"01010101010100000100010001000"
"10000000101000100010100010001"
"00000000000000010001010101000"
"10101010001010101010100000001"
"01000101000001010100000100010"
},
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
char escaped[1024];
char cmp_buf[8192];
char cmp_msg[1024];
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); // Only do ZXing-C++ test if asked, too slow otherwise
testStart("test_encode_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
if ((debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) printf("i:%d\n", i);
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, BARCODE_DOTCODE, data[i].input_mode, -1 /*eci*/,
-1 /* option_1*/, data[i].option_2, data[i].option_3, -1 /*output_options*/, NULL, 0, debug);
if (data[i].structapp.count) {
symbol->structapp = data[i].structapp;
}
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
char escaped1[4096];
char escaped2[4096];
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length;
int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length;
printf(" /*%3d*/ { %s, %d, %s, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, %d, \"%s\",\n",
i, testUtilInputModeName(data[i].input_mode), data[i].option_2, testUtilOption3Name(data[i].option_3),
data[i].structapp.index, data[i].structapp.count, data[i].structapp.id,
testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci,
testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci,
testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci,
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].zxingcpp_cmp, data[i].comment);
testUtilModulesPrint(symbol, " ", "\n");
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, debug)) {
if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
ret = testUtilBwippSegs(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf));
assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected);
}
}
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length, debug)) {
if (!data[i].zxingcpp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not ZXing-C++ compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else if (data[i].input_mode == DATA_MODE) {
if (debug & ZINT_DEBUG_TEST_PRINT) {
printf("i:%d multiple segments in DATA_MODE not currently supported for ZXing-C++ testing (%s)\n",
i, testUtilBarcodeName(symbol->symbology));
}
} else {
int cmp_len, ret_len;
char modules_dump[16384];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length,
modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count,
NULL /*primary*/, escaped, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped);
}
}
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
// #181 Christian Hartlage / Nico Gunkel OSS-Fuzz // #181 Christian Hartlage / Nico Gunkel OSS-Fuzz
static void test_fuzz(int index, int debug) { static void test_fuzz(int index, int debug) {
@ -1238,7 +1745,7 @@ int main(int argc, char *argv[]) {
{ "test_options", test_options, 1, 0, 1 }, { "test_options", test_options, 1, 0, 1 },
{ "test_input", test_input, 1, 1, 1 }, { "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_fuzz", test_fuzz, 1, 0, 1 }, { "test_encode_segs", test_encode_segs, 1, 1, 1 },
{ "test_fuzz", test_fuzz, 1, 0, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 },
{ "test_generate", test_generate, 0, 1, 0 }, { "test_generate", test_generate, 0, 1, 0 },
{ "test_perf", test_perf, 1, 0, 1 }, { "test_perf", test_perf, 1, 0, 1 },

View File

@ -177,7 +177,7 @@ static void test_reduced_charset_input(int index, int debug) {
/* 38*/ { BARCODE_PDF417, UNICODE_MODE, 12, "Ĩ", 0, 12, "In ISO 8859-10; Note no characters in ISO 8859-10 that aren't also in earlier ISO pages" }, /* 38*/ { BARCODE_PDF417, UNICODE_MODE, 12, "Ĩ", 0, 12, "In ISO 8859-10; Note no characters in ISO 8859-10 that aren't also in earlier ISO pages" },
/* 39*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 13, "" }, /* 39*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 13, "" },
/* 40*/ { BARCODE_PDF417, UNICODE_MODE, 13, "", 0, 13, "" }, /* 40*/ { BARCODE_PDF417, UNICODE_MODE, 13, "", 0, 13, "" },
/* 41*/ { BARCODE_PDF417, UNICODE_MODE, 14, "A", ZINT_ERROR_INVALID_DATA, -1, "Reserved ECI" }, /* 41*/ { BARCODE_PDF417, UNICODE_MODE, 14, "A", ZINT_ERROR_INVALID_OPTION, -1, "Reserved ECI" },
/* 42*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 15, "" }, /* 42*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 15, "" },
/* 43*/ { BARCODE_PDF417, UNICODE_MODE, 15, "", 0, 15, "In ISO 8859-13 and ISO 8859-16 and Win 125x pages" }, /* 43*/ { BARCODE_PDF417, UNICODE_MODE, 15, "", 0, 15, "In ISO 8859-13 and ISO 8859-16 and Win 125x pages" },
/* 44*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 16, "In ISO 8859-14 only of single-byte pages" }, /* 44*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 16, "In ISO 8859-14 only of single-byte pages" },
@ -186,7 +186,7 @@ static void test_reduced_charset_input(int index, int debug) {
/* 47*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Ș", ZINT_WARN_USES_ECI, 18, "In ISO 8859-16 only of single-byte pages" }, /* 47*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Ș", ZINT_WARN_USES_ECI, 18, "In ISO 8859-16 only of single-byte pages" },
/* 48*/ { BARCODE_PDF417, UNICODE_MODE, 18, "Ș", 0, 18, "" }, /* 48*/ { BARCODE_PDF417, UNICODE_MODE, 18, "Ș", 0, 18, "" },
/* 49*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 26, "Not in any single-byte page" }, /* 49*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 26, "Not in any single-byte page" },
/* 50*/ { BARCODE_PDF417, UNICODE_MODE, 19, "A", ZINT_ERROR_INVALID_DATA, -1, "Reserved ECI" }, /* 50*/ { BARCODE_PDF417, UNICODE_MODE, 19, "A", ZINT_ERROR_INVALID_OPTION, -1, "Reserved ECI" },
/* 51*/ { BARCODE_PDF417, UNICODE_MODE, 20, "", 0, 20, "In Shift JIS" }, /* 51*/ { BARCODE_PDF417, UNICODE_MODE, 20, "", 0, 20, "In Shift JIS" },
/* 52*/ { BARCODE_PDF417, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" }, /* 52*/ { BARCODE_PDF417, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" },
/* 53*/ { BARCODE_PDF417, UNICODE_MODE, 20, "\\\\", 0, 20, "In Shift JIS" }, /* 53*/ { BARCODE_PDF417, UNICODE_MODE, 20, "\\\\", 0, 20, "In Shift JIS" },
@ -742,6 +742,12 @@ static void test_utf8_to_eci_ascii(void) {
/* 15*/ { 170, "}", -1, ZINT_ERROR_INVALID_DATA }, /* 15*/ { 170, "}", -1, ZINT_ERROR_INVALID_DATA },
/* 16*/ { 170, "~", -1, ZINT_ERROR_INVALID_DATA }, /* 16*/ { 170, "~", -1, ZINT_ERROR_INVALID_DATA },
/* 17*/ { 170, "\302\200", -1, ZINT_ERROR_INVALID_DATA }, /* 17*/ { 170, "\302\200", -1, ZINT_ERROR_INVALID_DATA },
/* 18*/ { 170, "~", -1, ZINT_ERROR_INVALID_DATA },
/* 19*/ { 1, "A", -1, ZINT_ERROR_INVALID_DATA },
/* 20*/ { 2, "A", -1, ZINT_ERROR_INVALID_DATA },
/* 21*/ { 14, "A", -1, ZINT_ERROR_INVALID_DATA },
/* 22*/ { 19, "A", -1, ZINT_ERROR_INVALID_DATA },
/* 23*/ { 26, "A", -1, ZINT_ERROR_INVALID_DATA },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@ -1177,6 +1183,138 @@ static void test_utf8_to_eci_euc_kr(void) {
} }
} }
static void test_utf8_to_eci_gbk(void) {
struct item {
char *data;
int length;
int ret;
int expected_length;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", 32, 0, 32 },
/* 1*/ { " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177", 96, 0, 96 },
/* 2*/ { "\302\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+0080
/* 3*/ { "\343\200\200", -1, 0, 2 }, // U+3000 IDEOGRAPHIC SPACE
/* 4*/ { "\357\277\277", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+FFFF
/* 5*/ { "\357\277\276", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+FFFE (reversed BOM) not allowed
/* 6*/ { "\355\240\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+D800 surrogate not allowed
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
const int eci = 31;
testStart("test_utf8_to_eci_gbk");
for (i = 0; i < data_size; i++) {
int out_length, eci_length;
char dest[1024];
length = data[i].length != -1 ? data[i].length : (int) strlen(data[i].data);
out_length = length;
eci_length = get_eci_length(eci, (const unsigned char *) data[i].data, length);
assert_nonzero(eci_length + 1 <= 1024, "i:%d eci_length %d + 1 > 1024\n", i, eci_length);
ret = utf8_to_eci(eci, (const unsigned char *) data[i].data, (unsigned char *) dest, &out_length);
assert_equal(ret, data[i].ret, "i:%d utf8_to_eci ret %d != %d\n", i, ret, data[i].ret);
if (ret == 0) {
assert_equal(out_length, data[i].expected_length, "i:%d length %d != %d\n", i, out_length, data[i].expected_length);
assert_nonzero(out_length <= eci_length, "i:%d out_length %d > eci_length %d\n", i, out_length, eci_length);
}
}
}
static void test_utf8_to_eci_gb18030(void) {
struct item {
char *data;
int length;
int ret;
int expected_length;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", 32, 0, 32 },
/* 1*/ { " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177", 96, 0, 96 },
/* 2*/ { "\302\200", -1, 0, 4 }, // Has mapping for U+0080
/* 3*/ { "\343\200\200", -1, 0, 2 }, // U+3000 IDEOGRAPHIC SPACE
/* 4*/ { "\357\277\277", -1, 0, 4 }, // Has mapping for U+FFFF
/* 5*/ { "\357\277\276", -1, 0, 4 }, // U+FFFE (reversed BOM) allowed
/* 6*/ { "\355\240\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+D800 surrogate not allowed
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
const int eci = 32;
testStart("test_utf8_to_eci_gb18030");
for (i = 0; i < data_size; i++) {
int out_length, eci_length;
char dest[1024];
length = data[i].length != -1 ? data[i].length : (int) strlen(data[i].data);
out_length = length;
eci_length = get_eci_length(eci, (const unsigned char *) data[i].data, length);
assert_nonzero(eci_length + 1 <= 1024, "i:%d eci_length %d + 1 > 1024\n", i, eci_length);
ret = utf8_to_eci(eci, (const unsigned char *) data[i].data, (unsigned char *) dest, &out_length);
assert_equal(ret, data[i].ret, "i:%d utf8_to_eci ret %d != %d\n", i, ret, data[i].ret);
if (ret == 0) {
assert_equal(out_length, data[i].expected_length, "i:%d length %d != %d\n", i, out_length, data[i].expected_length);
assert_nonzero(out_length <= eci_length, "i:%d out_length %d > eci_length %d\n", i, out_length, eci_length);
}
}
}
static void test_is_eci_convertible_segs(int index) {
struct item {
struct zint_seg segs[3];
int ret;
int expected_convertible[3];
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { { { TU("A"), -1, 0 }, { TU(""), 0, 0 }, { TU(""), 0, 0 } }, 1, { 1, -1, -1 } },
/* 1*/ { { { TU("A"), -1, 26 }, { TU(""), 0, 0 }, { TU(""), 0, 0 } }, 0, { 0, -1, -1 } },
/* 2*/ { { { TU("A"), -1, 36 }, { TU(""), 0, 0 }, { TU(""), 0, 0 } }, 0, { 0, -1, -1 } },
/* 3*/ { { { TU("A"), -1, 170 }, { TU(""), 0, 0 }, { TU(""), 0, 0 } }, 1, { 1, -1, -1 } },
/* 4*/ { { { TU("A"), -1, 899 }, { TU(""), 0, 0 }, { TU(""), 0, 0 } }, 0, { 0, -1, -1 } },
/* 5*/ { { { TU("A"), -1, 3 }, { TU(""), 0, 0 }, { TU(""), 0, 0 } }, 1, { 1, -1, -1 } },
/* 6*/ { { { TU("A"), -1, 899 }, { TU("A"), -1, 0 }, { TU(""), 0, 0 } }, 1, { 0, 1, -1 } },
/* 7*/ { { { TU("A"), -1, 0 }, { TU("A"), -1, 899 }, { TU(""), 0, 0 } }, 1, { 1, 0, -1 } },
/* 8*/ { { { TU("A"), -1, 3 }, { TU("A"), -1, 4 }, { TU("A"), -1, 35 } }, 1, { 1, 1, 1 } },
/* 9*/ { { { TU("A"), -1, 3 }, { TU("A"), -1, 899 }, { TU("A"), -1, 0 } }, 1, { 1, 0, 1 } },
/* 10*/ { { { TU("A"), -1, 899 }, { TU("A"), -1, 899 }, { TU("A"), -1, 0 } }, 1, { 0, 0, 1 } },
/* 11*/ { { { TU("A"), -1, 899 }, { TU("A"), -1, 0 }, { TU("A"), -1, 899 } }, 1, { 0, 1, 0 } },
/* 12*/ { { { TU("A"), -1, 899 }, { TU("A"), -1, 899 }, { TU("A"), -1, 899 } }, 0, { 0, 0, 0 } },
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
int convertible[3];
testStart("test_is_eci_convertible_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
for (j = 0; j < 3; j++) convertible[j] = -1;
ret = is_eci_convertible_segs(data[i].segs, seg_count, convertible);
assert_equal(ret, data[i].ret, "i:%d is_eci_convertible_segs ret %d != %d\n", i, ret, data[i].ret);
for (j = 0; j < 3; j++) {
assert_equal(convertible[j], data[i].expected_convertible[j], "i:%d is_eci_convertible_segs convertible[%d] %d != %d\n", i, j, convertible[j], data[i].expected_convertible[j]);
}
}
testFinish();
}
static void test_get_best_eci(int index) { static void test_get_best_eci(int index) {
struct item { struct item {
@ -1213,6 +1351,54 @@ static void test_get_best_eci(int index) {
testFinish(); testFinish();
} }
static void test_get_best_eci_segs(int index) {
struct item {
struct zint_seg segs[3];
int ret;
int expected_symbol_eci;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { { { TU("\300\301"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, 0, 0 },
/* 1*/ { { { TU("A"), -1, 0 }, { TU("\300\301"), -1, 0 }, { TU(""), 0, 0 } }, 0, 0 },
/* 2*/ { { { TU("A"), -1, 0 }, { TU("ÀÁ"), -1, 0 }, { TU(""), 0, 0 } }, 0, 0 }, // As 1st seg default ECI, 3 not returned
/* 3*/ { { { TU("A"), -1, 4 }, { TU("ÀÁ"), -1, 0 }, { TU(""), 0, 0 } }, 3, 0 },
/* 4*/ { { { TU("A"), -1, 0 }, { TU("Ђ"), -1, 0 }, { TU(""), 0, 0 } }, 7, 0 },
/* 5*/ { { { TU("A"), -1, 4 }, { TU("Ђ"), -1, 0 }, { TU(""), 0, 0 } }, 7, 0 },
/* 6*/ { { { TU("A"), -1, 0 }, { TU("Ђ"), -1, 7 }, { TU("Ѐ"), -1, 0 } }, 26, 0 }, // Cyrillic U+0400 not in single-byte code pages
/* 7*/ { { { TU("A"), -1, 0 }, { TU("Ђ"), -1, 0 }, { TU("β"), -1, 0 } }, 7, 0 },
/* 8*/ { { { TU("A"), -1, 0 }, { TU("Ђ"), -1, 7 }, { TU("β"), -1, 0 } }, 9, 0 },
/* 9*/ { { { TU("˜"), -1, 0 }, { TU("Ђ"), -1, 7 }, { TU(""), 0, 0 } }, 23, 23 },
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
testStart("test_get_best_eci_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
for (j = 0; j < seg_count; j++) {
if (data[i].segs[j].length < 0) data[i].segs[j].length = (int) ustrlen(data[i].segs[j].source);
}
ret = get_best_eci_segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d get_best_eci_segs ret %d != %d\n", i, ret, data[i].ret);
assert_equal(symbol->eci, data[i].expected_symbol_eci, "i:%d get_best_eci_segs symbol->eci %d != %d\n", i, symbol->eci, data[i].expected_symbol_eci);
ZBarcode_Delete(symbol);
}
testFinish();
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
@ -1229,7 +1415,11 @@ int main(int argc, char *argv[]) {
{ "test_utf8_to_eci_big5", test_utf8_to_eci_big5, 0, 0, 0 }, { "test_utf8_to_eci_big5", test_utf8_to_eci_big5, 0, 0, 0 },
{ "test_utf8_to_eci_gb2312", test_utf8_to_eci_gb2312, 0, 0, 0 }, { "test_utf8_to_eci_gb2312", test_utf8_to_eci_gb2312, 0, 0, 0 },
{ "test_utf8_to_eci_euc_kr", test_utf8_to_eci_euc_kr, 0, 0, 0 }, { "test_utf8_to_eci_euc_kr", test_utf8_to_eci_euc_kr, 0, 0, 0 },
{ "test_utf8_to_eci_gbk", test_utf8_to_eci_gbk, 0, 0, 0 },
{ "test_utf8_to_eci_gb18030", test_utf8_to_eci_gb18030, 0, 0, 0 },
{ "test_is_eci_convertible_segs", test_is_eci_convertible_segs, 1, 0, 0 },
{ "test_get_best_eci", test_get_best_eci, 1, 0, 0 }, { "test_get_best_eci", test_get_best_eci, 1, 0, 0 },
{ "test_get_best_eci_segs", test_get_best_eci_segs, 1, 0, 0 },
}; };
testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); testRun(argc, argv, funcs, ARRAY_SIZE(funcs));

View File

@ -34,6 +34,7 @@ static void test_large(int index, int debug) {
struct item { struct item {
int option_2; int option_2;
int option_3;
char *pattern; char *pattern;
int length; int length;
int ret; int ret;
@ -42,21 +43,27 @@ static void test_large(int index, int debug) {
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { -1, "1", 2751, 0, 162, 162 }, /* 0*/ { -1, -1, "1", 2751, 0, 162, 162 },
/* 1*/ { -1, "1", 2752, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 1*/ { -1, -1, "1", 2752, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 2*/ { -1, "1", 2755, ZINT_ERROR_TOO_LONG, -1, -1 }, // Triggers buffer > 9191 /* 2*/ { -1, -1, "1", 2755, ZINT_ERROR_TOO_LONG, -1, -1 }, // Triggers buffer > 9191
/* 3*/ { -1, "A", 1836, 0, 162, 162 }, /* 3*/ { -1, -1, "A", 1836, 0, 162, 162 },
/* 4*/ { -1, "A", 1837, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 4*/ { -1, -1, "A", 1837, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 5*/ { -1, "\200", 1143, 0, 162, 162 }, /* 5*/ { -1, -1, "A1", 1529, 0, 162, 162 },
/* 6*/ { -1, "\200", 1144, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 6*/ { -1, -1, "A1", 1530, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 7*/ { 1, "1", 18, 0, 18, 18 }, /* 7*/ { -1, -1, "\200", 1143, 0, 162, 162 },
/* 8*/ { 1, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 8*/ { -1, -1, "\200", 1144, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 9*/ { 1, "A", 13, 0, 18, 18 }, /* 9*/ { -1, ZINT_FULL_MULTIBYTE, "\241", 1410, 0, 162, 162 },
/* 10*/ { 1, "A", 14, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 10*/ { -1, ZINT_FULL_MULTIBYTE, "\241", 1412, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 11*/ { 1, "\200", 7, 0, 18, 18 }, /* 11*/ { 1, -1, "1", 18, 0, 18, 18 },
/* 12*/ { 1, "\200", 8, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 12*/ { 1, -1, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 13*/ { 11, "1", 1995, 0, 138, 138 }, /* 13*/ { 1, -1, "A", 13, 0, 18, 18 },
/* 14*/ { 11, "1", 1996, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 14*/ { 1, -1, "A", 14, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 15*/ { 1, -1, "\200", 7, 0, 18, 18 },
/* 16*/ { 1, -1, "\200", 8, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 17*/ { 1, ZINT_FULL_MULTIBYTE, "\241", 8, 0, 18, 18 },
/* 18*/ { 1, ZINT_FULL_MULTIBYTE, "\241", 10, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 19*/ { 11, -1, "1", 1995, 0, 138, 138 },
/* 20*/ { 11, -1, "1", 1996, ZINT_ERROR_TOO_LONG, -1, -1 },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@ -76,7 +83,7 @@ static void test_large(int index, int debug) {
testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length);
assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf));
length = testUtilSetSymbol(symbol, BARCODE_GRIDMATRIX, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug); length = testUtilSetSymbol(symbol, BARCODE_GRIDMATRIX, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, data[i].option_3, -1 /*output_options*/, data_buf, data[i].length, debug);
ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length); ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
@ -501,6 +508,351 @@ static void test_encode(int index, int generate, int debug) {
testFinish(); testFinish();
} }
static void test_encode_segs(int index, int generate, int debug) {
struct item {
int input_mode;
int option_1;
int option_2;
struct zint_structapp structapp;
struct zint_seg segs[3];
int ret;
int expected_rows;
int expected_width;
char *comment;
char *expected;
};
struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 30, 30, "Standard example",
"111111000000111111000000111111"
"111101011110111111011110111111"
"100101011110111111011110111111"
"110011000000100001000000100001"
"110011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011100110111010000110001011110"
"010000111111000110111101011110"
"000010100001000110110001000000"
"001000100001001100100001000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111101010110101001010000111111"
"101111011110100001000100111111"
"100011000000110111011000100001"
"110111000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011110110111010110110001011010"
"010110111111011110100001010000"
"011010100001000000101011011100"
"001000100001000000110001000110"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111001011100111111011000111111"
"100001001100111101001110111011"
"100001001010111011011110100011"
"101011000010100001001110100101"
"111111000000111111000000111111"
},
/* 1*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 30, 30, "Standard example auto-ECI",
"111111000000111111000000111111"
"111101011110111111011110111111"
"100101011110111111011110111111"
"110011000000100001000000100001"
"110011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011100110111010000110001011110"
"010000111111000110111101011110"
"000010100001000110110001000000"
"001000100001001100100001000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111101010110101001010000111111"
"101111011110100001000100111111"
"100011000000110111011000100001"
"110111000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011110110111010110110001011010"
"010110111111011110100001010000"
"011010100001000000101011011100"
"001000100001000000110001000110"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111001011100111111011000111111"
"100001001100111101001110111011"
"100001001010111011011110100011"
"101011000010100001001110100101"
"111111000000111111000000111111"
},
/* 2*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 7 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, 0, 30, 30, "Standard example inverted",
"111111000000111111000000111111"
"111001011110111111011110111111"
"101111011110111111011110111111"
"111101000000100001000000100001"
"101011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011010110111010000110001011110"
"000000111111000000100011011110"
"010000100001001010111011000000"
"011000100001010000110111000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111101010110101001010000111111"
"101011011110100011000110111111"
"111001000000111101000000100001"
"101011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011110110111010000110001011000"
"010000111111000000100011011000"
"001110100001001100101101001100"
"001100100001011000100001000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111111011110111101011000111111"
"101111011010110001001110111101"
"110011001000101101001010110111"
"111101011000101001011010101001"
"111111000000111111000000111111"
},
/* 3*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 30, 30, "Standard example inverted auto-ECI",
"111111000000111111000000111111"
"111001011110111111011110111111"
"101111011110111111011110111111"
"111101000000100001000000100001"
"101011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011010110111010000110001011110"
"000000111111000000100011011110"
"010000100001001010111011000000"
"011000100001010000110111000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111101010110101001010000111111"
"101011011110100011000110111111"
"111001000000111101000000100001"
"101011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011110110111010000110001011000"
"010000111111000000100011011000"
"001110100001001100101101001100"
"001100100001011000100001000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111111011110111101011000111111"
"101111011010110001001110111101"
"110011001000101101001010110111"
"111101011000101001011010101001"
"111111000000111111000000111111"
},
/* 4*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 78, 78, "AIM ITS/04-023:2022 Annex A example",
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100101000100100101000110100001000100100101000000100111000010100111000000100001"
"101001011010100111011110101001011100101111001110100001001110111101000110100101"
"101111011000100011001010101111000000110001000100110101001010110111001010111001"
"101011001010110111000010101111011100111011011100101001001100111101000000101101"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000000111011011010111001011000111001011010111111011010111111011110111011000100"
"011110101101010010110001000000101111010110111111000000100011011110111111011010"
"010010100001011010110101001010100011010000101001011110110001000010111111001100"
"001000100111000000110011001010111111000000110001011100100001011010101011010100"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100101011000110001010110110111010010110111010000110011010110110111011010100011"
"111001010010110001001100111011010100111111001110101111011100111101010110110001"
"111101011110100011000000111001001010100001001010110111000110111111000000101111"
"111111000010110111010000111011001000100011000010110011011100110101000000110001"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000100111001010110101101001000101001001000101111001000101011010100111111000110"
"000010111011011000110011011010111011011110101001011100110101011010111111010000"
"010010110001000000111011011110101001010010100011010110111011011110100011001010"
"011110100001000010111111011010110011011010110001011110111111000110101111011110"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100101011100110111001100100111000100100101000110100111001110110011011100100111"
"100011010100101111011110110001001110101111010000110001011000111011010010100001"
"111001010110111001000100101111000000110111000100111111000100101101011110101011"
"111101011010100011001010100111000100111111000100101101001010100001011110111111"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000010111111010110101101000000111101011000111101000110101111010110111111000000"
"001010111111011100100001010000110001000000100111011110110011011110100011001100"
"010110100111001100101011010110110001010110111101011000111001011100110001010100"
"000010100101011010101001011110110111011100101111010010100001001110100001010100"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100101011010110111001100100011011000110101011010100001001010110001011110100011"
"110111011010111011011100100011011100111111010110111111000000110001011110110011"
"110111010000110011001110111001010110101101001000111101010100100011001110110011"
"101111000000111111011000100101010110100001011010110001001000100001011110111111"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000110111001010100101101000100111011011010111111000010101101010000111011000000"
"011000111001001010111001010000100101010110111001001110101111001100101101001010"
"011010110101000010110011011010101011000010101101011100111101001010101111010110"
"011010101001001010101101011110111001010010101101000100101001000010100101000100"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100001011110110111001000100101000010100011000010100001001010110001011100100011"
"110011011110100001001000100001001010110111010100101101000000110001011110101101"
"110001001110111001001110100111001000101011011100100111000000111011010000100001"
"111011001000101111011010110111011110110011001100111111010000110111000000100111"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000110111111010000101001001100101111001100101101001100101111010010111111000010"
"000110100111000000100111011010100001011110101001011010111101011010111111000000"
"001010110001011100100101001110100001011100111001000100101011000100100001001000"
"000000100001010010100011001110111111001110100001000110111111001110100011001010"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100001011010110001010100110011010010110111010100110011010010110101011000100011"
"111111010100100111001110111111010010110101011000110011011110111011001010100111"
"111001011110110101011010100111011010110111011100101111001100100001001100100111"
"110011011100111001011100101111000000101011011110111011011010110011010110111001"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000000111111011110111101011110111001011010111111011110111111011110111001000010"
"001100111111000000111011011110101101011110111111000000101011011110100001000010"
"010010101111010000110111000000110001010110101001000000110111001010100001000110"
"000100111111000000101111010110100001011110110101000000110101010010100001001000"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100111000110100111000110100101000110100101000100100011000100100111000100100011"
"110011011100111011000100100011001010111001000110110101001100110011000110100001"
"111001000010100011001010100001000010100111010110111011000000110101011100110111"
"110111001010111011001010101011001000101111011110111001011010111111010100111111"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
},
/* 5*/ { DATA_MODE, -1, -1, { 0, 0, "" }, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, 0, 30, 30, "Standard example + extra seg, data mode",
"111111000000111111000000111111"
"111101011110111111011110111111"
"111011011110111111011110111111"
"111101000000100001000000100001"
"101001000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011010110111010000110001011110"
"000010111111000110111101011110"
"001010100001000110110001000000"
"011100100001001100100001000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111111010000101001010000111111"
"101111000000100001000100111111"
"110001001100110111011000100001"
"101111000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011110110001010010110001011010"
"010100110111010110111001001100"
"000110100001000000101011010010"
"010000100001000000110001000110"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111011011010111101011010111111"
"111001000110101111011000101001"
"111101011000111011010010111011"
"101101011100110001001000111001"
"111111000000111111000000111111"
},
/* 6*/ { UNICODE_MODE, -1, -1, { 1, 16, "" }, { { TU("齄齄"), -1, 29 }, { TU("Τεχτ"), -1, 0 }, { TU("Text"), -1, 0 } }, ZINT_WARN_USES_ECI, 30, 30, "Structured Append",
"111111000000111111000000111111"
"111011011000111101011010111111"
"101011000000101111001110100001"
"111011000010110111011100100011"
"110101010000101001000100111101"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011000110101010000110111011110"
"010110110001000010111111011110"
"011010100111011010111111000000"
"011100111111010000110111000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111011010100101001010110111111"
"111111011110101111011110111111"
"100101010010101101011010100001"
"100101011000100001011100100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011100110111010010110011011100"
"010110110101001100110001011000"
"000100110001000000101111010100"
"000100100011000100100001001010"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111011011010111001011000111011"
"111001010110100101011000111001"
"110111000010101001011100110011"
"100011011010111011001110101011"
"111111000000111111000000111111"
},
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
char escaped[8192];
testStart("test_encode_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, BARCODE_GRIDMATRIX, data[i].input_mode, -1 /*eci*/,
data[i].option_1, data[i].option_2, -1, -1 /*output_options*/,
NULL, 0, debug);
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
char escaped1[8192];
char escaped2[8192];
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length;
int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length;
printf(" /*%3d*/ { %s, %d, %d, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, \"%s\",\n",
i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2,
data[i].structapp.index, data[i].structapp.count, data[i].structapp.id,
testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci,
testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci,
testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci,
testUtilErrorName(data[i].ret),
symbol->rows, symbol->width, data[i].comment);
testUtilModulesPrint(symbol, " ", "\n");
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
#include <time.h> #include <time.h>
#define TEST_PERF_ITERATIONS 1000 #define TEST_PERF_ITERATIONS 1000
@ -593,6 +945,7 @@ int main(int argc, char *argv[]) {
{ "test_options", test_options, 1, 0, 1 }, { "test_options", test_options, 1, 0, 1 },
{ "test_input", test_input, 1, 1, 1 }, { "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_encode_segs", test_encode_segs, 1, 1, 1 },
{ "test_perf", test_perf, 1, 0, 1 }, { "test_perf", test_perf, 1, 0, 1 },
}; };

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -238,7 +237,7 @@ static void test_gs1_reduce(int index, int generate, int debug) {
assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, -1, -1, text, length, symbol->primary, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, -1, -1, -1, text, length, symbol->primary, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -2187,3 +2186,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -35,6 +35,7 @@ static void test_large(int index, int debug) {
struct item { struct item {
int option_1; int option_1;
int option_2; int option_2;
int option_3;
char *pattern; char *pattern;
int length; int length;
int ret; int ret;
@ -43,24 +44,28 @@ static void test_large(int index, int debug) {
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { -1, -1, "1", 7827, 0, 189, 189 }, /* 0*/ { -1, -1, -1, "1", 7827, 0, 189, 189 },
/* 1*/ { -1, -1, "1", 7828, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 1*/ { -1, -1, -1, "1", 7828, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 2*/ { -1, -1, "A", 4350, 0, 189, 189 }, /* 2*/ { -1, -1, -1, "A", 4350, 0, 189, 189 },
/* 3*/ { -1, -1, "A", 4351, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 3*/ { -1, -1, -1, "A", 4351, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 4*/ { -1, -1, "\200", 3261, 0, 189, 189 }, /* 4*/ { -1, -1, -1, "\200", 3261, 0, 189, 189 },
/* 5*/ { -1, -1, "\200", 3262, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 5*/ { -1, -1, -1, "\200", 3262, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 6*/ { -1, 1, "1", 45, 0, 23, 23 }, /* 6*/ { -1, -1, ZINT_FULL_MULTIBYTE, "\241", 4348, 0, 189, 189 },
/* 7*/ { -1, 1, "1", 46, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 7*/ { -1, -1, ZINT_FULL_MULTIBYTE, "\241", 4350, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 8*/ { -1, 1, "A", 26, 0, 23, 23 }, /* 8*/ { -1, 1, -1, "1", 45, 0, 23, 23 },
/* 9*/ { -1, 1, "A", 27, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 9*/ { -1, 1, -1, "1", 46, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 10*/ { -1, 1, "\200", 18, 0, 23, 23 }, /* 10*/ { -1, 1, -1, "A", 26, 0, 23, 23 },
/* 11*/ { -1, 1, "\200", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 11*/ { -1, 1, -1, "A", 27, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 12*/ { 2, 1, "A", 21, 0, 23, 23 }, /* 12*/ { -1, 1, -1, "\200", 18, 0, 23, 23 },
/* 13*/ { 2, 1, "A", 22, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 13*/ { -1, 1, -1, "\200", 19, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 14*/ { 3, 1, "A", 15, 0, 23, 23 }, /* 14*/ { -1, 1, ZINT_FULL_MULTIBYTE, "\241", 24, 0, 23, 23 },
/* 15*/ { 3, 1, "A", 16, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 15*/ { -1, 1, ZINT_FULL_MULTIBYTE, "\241", 26, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 16*/ { 4, 1, "A", 10, 0, 23, 23 }, /* 16*/ { 2, 1, -1, "A", 21, 0, 23, 23 },
/* 17*/ { 4, 1, "A", 11, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 17*/ { 2, 1, -1, "A", 22, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 18*/ { 3, 1, -1, "A", 15, 0, 23, 23 },
/* 19*/ { 3, 1, -1, "A", 16, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 20*/ { 4, 1, -1, "A", 10, 0, 23, 23 },
/* 21*/ { 4, 1, -1, "A", 11, ZINT_ERROR_TOO_LONG, -1, -1 },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@ -80,7 +85,7 @@ static void test_large(int index, int debug) {
testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length);
assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf));
length = testUtilSetSymbol(symbol, BARCODE_HANXIN, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug); length = testUtilSetSymbol(symbol, BARCODE_HANXIN, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data_buf, data[i].length, debug);
ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length); ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
@ -163,6 +168,7 @@ static void test_input(int index, int generate, int debug) {
int ret; int ret;
int expected_eci; int expected_eci;
char *expected; char *expected;
int zxingcpp_cmp;
char *comment; char *comment;
}; };
// é U+00E9 in ISO 8859-1 plus other ISO 8859 (but not in ISO 8859-7 or ISO 8859-11), Win 1250 plus other Win, in GB 18030 0xA8A6, UTF-8 C3A9 // é U+00E9 in ISO 8859-1 plus other ISO 8859 (but not in ISO 8859-7 or ISO 8859-11), Win 1250 plus other Win, in GB 18030 0xA8A6, UTF-8 C3A9
@ -175,97 +181,104 @@ static void test_input(int index, int generate, int debug) {
// 丂 U+4E02 GB 18030 2-byte Region 0x8140, UTF-8 E4B882 // 丂 U+4E02 GB 18030 2-byte Region 0x8140, UTF-8 E4B882
// <20> (REPLACEMENT CHARACTER) U+FFFD GB 18030 4-byte Region 0x81308130, UTF-8 EFBFBD (\357\277\275) // <20> (REPLACEMENT CHARACTER) U+FFFD GB 18030 4-byte Region 0x81308130, UTF-8 EFBFBD (\357\277\275)
struct item data[] = { struct item data[] = {
/* 0*/ { UNICODE_MODE, 0, -1, "é", -1, 0, 0, "30 00 F4 80 00 00 00 00 00", "B1 (ISO 8859-1)" }, /* 0*/ { UNICODE_MODE, 0, -1, "é", -1, 0, 0, "30 00 F4 80 00 00 00 00 00", 1, "B1 (ISO 8859-1)" },
/* 1*/ { UNICODE_MODE, 3, -1, "é", -1, 0, 3, "80 33 00 0F 48 00 00 00 00", "ECI-3 B1 (ISO 8859-1)" }, /* 1*/ { UNICODE_MODE, 3, -1, "é", -1, 0, 3, "80 33 00 0F 48 00 00 00 00", 1, "ECI-3 B1 (ISO 8859-1)" },
/* 2*/ { UNICODE_MODE, 29, -1, "é", -1, 0, 29, "81 D3 00 15 45 30 00 00 00", "ECI-29 B2 (GB 2312)" }, /* 2*/ { UNICODE_MODE, 29, -1, "é", -1, 0, 29, "81 D3 00 15 45 30 00 00 00", 1, "ECI-29 B2 (GB 2312)" },
/* 3*/ { UNICODE_MODE, 32, -1, "é", -1, 0, 32, "82 04 FC FF FF 00 00 00 00", "ECI-32 H(1)1 (GB 18030) (Region One)" }, /* 3*/ { UNICODE_MODE, 32, -1, "é", -1, 0, 32, "82 04 FC FF FF 00 00 00 00", 1, "ECI-32 H(1)1 (GB 18030) (Region One)" },
/* 4*/ { UNICODE_MODE, 26, -1, "é", -1, 0, 26, "81 A3 00 16 1D 48 00 00 00", "ECI-26 B2 (UTF-8)" }, /* 4*/ { UNICODE_MODE, 26, -1, "é", -1, 0, 26, "81 A3 00 16 1D 48 00 00 00", 1, "ECI-26 B2 (UTF-8)" },
/* 5*/ { UNICODE_MODE, 26, ZINT_FULL_MULTIBYTE, "é", -1, 0, 26, "81 A4 70 2F FF 00 00 00 00", "ECI-26 H(1)1 (Region One) (UTF-8) (full multibyte)" }, /* 5*/ { UNICODE_MODE, 26, ZINT_FULL_MULTIBYTE, "é", -1, 0, 26, "81 A4 70 2F FF 00 00 00 00", 1, "ECI-26 H(1)1 (Region One) (UTF-8) (full multibyte)" },
/* 6*/ { DATA_MODE, 0, -1, "é", -1, 0, 0, "30 01 61 D4 80 00 00 00 00", "B2 (UTF-8)" }, /* 6*/ { DATA_MODE, 0, -1, "é", -1, 0, 0, "30 01 61 D4 80 00 00 00 00", 1, "B2 (UTF-8)" },
/* 7*/ { DATA_MODE, 0, ZINT_FULL_MULTIBYTE, "é", -1, 0, 0, "47 02 FF F0 00 00 00 00 00", "H(1)1 (UTF-8) (Region One) (full multibyte)" }, /* 7*/ { DATA_MODE, 0, ZINT_FULL_MULTIBYTE, "é", -1, 0, 0, "47 02 FF F0 00 00 00 00 00", 1, "H(1)1 (UTF-8) (Region One) (full multibyte)" },
/* 8*/ { DATA_MODE, 0, -1, "\351", -1, 0, 0, "30 00 F4 80 00 00 00 00 00", "B1 (ISO 8859-1) (0xE9)" }, /* 8*/ { DATA_MODE, 0, -1, "\351", -1, 0, 0, "30 00 F4 80 00 00 00 00 00", 1, "B1 (ISO 8859-1) (0xE9)" },
/* 9*/ { UNICODE_MODE, 0, -1, "β", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 30 01 53 61 00 00 00 00 00", "B2 (GB 18030) (2-byte Region)" }, /* 9*/ { UNICODE_MODE, 0, -1, "β", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 30 01 53 61 00 00 00 00 00", 1, "B2 (GB 18030) (2-byte Region)" },
/* 10*/ { UNICODE_MODE, 9, -1, "β", -1, 0, 9, "80 93 00 0F 10 00 00 00 00", "ECI-9 B1 (ISO 8859-7)" }, /* 10*/ { UNICODE_MODE, 9, -1, "β", -1, 0, 9, "80 93 00 0F 10 00 00 00 00", 1, "ECI-9 B1 (ISO 8859-7)" },
/* 11*/ { UNICODE_MODE, 29, -1, "β", -1, 0, 29, "81 D3 00 15 36 10 00 00 00", "ECI-29 B2 (GB 2312)" }, /* 11*/ { UNICODE_MODE, 29, -1, "β", -1, 0, 29, "81 D3 00 15 36 10 00 00 00", 1, "ECI-29 B2 (GB 2312)" },
/* 12*/ { UNICODE_MODE, 32, -1, "β", -1, 0, 32, "82 03 00 15 36 10 00 00 00", "ECI-32 B2 (GB 18030) (2-byte Region)" }, /* 12*/ { UNICODE_MODE, 32, -1, "β", -1, 0, 32, "82 03 00 15 36 10 00 00 00", 1, "ECI-32 B2 (GB 18030) (2-byte Region)" },
/* 13*/ { UNICODE_MODE, 26, -1, "β", -1, 0, 26, "81 A3 00 16 75 90 00 00 00", "ECI-26 B2 (UTF-8)" }, /* 13*/ { UNICODE_MODE, 26, -1, "β", -1, 0, 26, "81 A3 00 16 75 90 00 00 00", 1, "ECI-26 B2 (UTF-8)" },
/* 14*/ { UNICODE_MODE, 26, ZINT_FULL_MULTIBYTE, "β", -1, 0, 26, "81 A4 B1 5F FF 00 00 00 00", "ECI-26 B2 (UTF-8) (full multibyte)" }, /* 14*/ { UNICODE_MODE, 26, ZINT_FULL_MULTIBYTE, "β", -1, 0, 26, "81 A4 B1 5F FF 00 00 00 00", 1, "ECI-26 B2 (UTF-8) (full multibyte)" },
/* 15*/ { DATA_MODE, 0, -1, "β", -1, 0, 0, "30 01 67 59 00 00 00 00 00", "B2 (UTF-8)" }, /* 15*/ { DATA_MODE, 0, -1, "β", -1, 0, 0, "30 01 67 59 00 00 00 00 00", 1, "B2 (UTF-8)" },
/* 16*/ { DATA_MODE, 0, ZINT_FULL_MULTIBYTE, "β", -1, 0, 0, "4B 15 FF F0 00 00 00 00 00", "H(1)1 (UTF-8) (Region One) (full multibyte)" }, /* 16*/ { DATA_MODE, 0, ZINT_FULL_MULTIBYTE, "β", -1, 0, 0, "4B 15 FF F0 00 00 00 00 00", 1, "H(1)1 (UTF-8) (Region One) (full multibyte)" },
/* 17*/ { UNICODE_MODE, 0, -1, "ÿ", -1, 0, 0, "30 00 FF 80 00 00 00 00 00", "B1 (ISO 8859-1)" }, /* 17*/ { UNICODE_MODE, 0, -1, "ÿ", -1, 0, 0, "30 00 FF 80 00 00 00 00 00", 1, "B1 (ISO 8859-1)" },
/* 18*/ { UNICODE_MODE, 0, -1, "ÿÿÿ", -1, 0, 0, "30 01 FF FF FF 80 00 00 00", "B3 (ISO 8859-1)" }, /* 18*/ { UNICODE_MODE, 0, -1, "ÿÿÿ", -1, 0, 0, "30 01 FF FF FF 80 00 00 00", 1, "B3 (ISO 8859-1)" },
/* 19*/ { UNICODE_MODE, 0, -1, "\302\200", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 00 00 00 00 00 00 00", "H(f)1 (GB 18030) (4-byte Region) (not DATA_MODE so GB 18030 mapping)" }, /* 19*/ { UNICODE_MODE, 0, -1, "\302\200", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 00 00 00 00 00 00 00", 1, "H(f)1 (GB 18030) (4-byte Region) (not DATA_MODE so GB 18030 mapping)" },
/* 20*/ { UNICODE_MODE, 0, ZINT_FULL_MULTIBYTE, "\302\200", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 00 00 00 00 00 00 00", "H(f)1 (GB 18030) (4-byte Region)" }, /* 20*/ { UNICODE_MODE, 0, ZINT_FULL_MULTIBYTE, "\302\200", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 00 00 00 00 00 00 00", 1, "H(f)1 (GB 18030) (4-byte Region)" },
/* 21*/ { DATA_MODE, 0, 0, "\302\200", -1, 0, 0, "30 01 61 40 00 00 00 00 00", "B2 (UTF-8)" }, /* 21*/ { DATA_MODE, 0, 0, "\302\200", -1, 0, 0, "30 01 61 40 00 00 00 00 00", 1, "B2 (UTF-8)" },
/* 22*/ { DATA_MODE, 0, ZINT_FULL_MULTIBYTE, "\302\200", -1, 0, 0, "30 01 61 40 00 00 00 00 00", "B2 (UTF-8) (full multibyte)" }, /* 22*/ { DATA_MODE, 0, ZINT_FULL_MULTIBYTE, "\302\200", -1, 0, 0, "30 01 61 40 00 00 00 00 00", 1, "B2 (UTF-8) (full multibyte)" },
/* 23*/ { UNICODE_MODE, 0, -1, "\302\200<EFBFBD>", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 00 38 26 7E 40 00 00", "H(f)2 (GB 18030) (both 4-byte Region) (not DATA_MODE so GB 18030 mapping)" }, /* 23*/ { UNICODE_MODE, 0, -1, "\302\200<EFBFBD>", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 00 38 26 7E 40 00 00", 1, "H(f)2 (GB 18030) (both 4-byte Region) (not DATA_MODE so GB 18030 mapping)" },
/* 24*/ { UNICODE_MODE, 0, ZINT_FULL_MULTIBYTE, "\302\200<EFBFBD>", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 00 38 26 7E 40 00 00", "H(f)2 (GB 18030) (both 4-byte Region)" }, /* 24*/ { UNICODE_MODE, 0, ZINT_FULL_MULTIBYTE, "\302\200<EFBFBD>", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 00 38 26 7E 40 00 00", 1, "H(f)2 (GB 18030) (both 4-byte Region)" },
/* 25*/ { UNICODE_MODE, 0, -1, "啊亍齄丂\302\200", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 64 68 50 3C AC 28 80 00 FF FE E0 00 00", "H(d)4 H(f)1 (GB 18030)" }, /* 25*/ { UNICODE_MODE, 0, -1, "啊亍齄丂\302\200", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 64 68 50 3C AC 28 80 00 FF FE E0 00 00", 1, "H(d)4 H(f)1 (GB 18030)" },
/* 26*/ { DATA_MODE, 0, -1, "\177\177", -1, 0, 0, "2F BD F7 F0 00 00 00 00 00", "T2 (ASCII)" }, /* 26*/ { DATA_MODE, 0, -1, "\177\177", -1, 0, 0, "2F BD F7 F0 00 00 00 00 00", 1, "T2 (ASCII)" },
/* 27*/ { DATA_MODE, 0, -1, "\177\177\177", -1, 0, 0, "2F BD F7 DF C0 00 00 00 00", "T3 (ASCII)" }, /* 27*/ { DATA_MODE, 0, -1, "\177\177\177", -1, 0, 0, "2F BD F7 DF C0 00 00 00 00", 1, "T3 (ASCII)" },
/* 28*/ { UNICODE_MODE, 0, -1, "123", -1, 0, 0, "11 EF FF 00 00 00 00 00 00", "N3 (ASCII)" }, /* 28*/ { UNICODE_MODE, 0, -1, "123", -1, 0, 0, "11 EF FF 00 00 00 00 00 00", 1, "N3 (ASCII)" },
/* 29*/ { UNICODE_MODE, 0, -1, "12345", -1, 0, 0, "11 EC 2D FF 80 00 00 00 00", "N5 (ASCII)" }, /* 29*/ { UNICODE_MODE, 0, -1, "12345", -1, 0, 0, "11 EC 2D FF 80 00 00 00 00", 1, "N5 (ASCII)" },
/* 30*/ { UNICODE_MODE, 0, -1, "Aa%$Bb9", -1, 0, 0, "22 A4 FA 18 3E 2E 52 7F 00", "T7 (ASCII)" }, /* 30*/ { UNICODE_MODE, 0, -1, "Aa%$Bb9", -1, 0, 0, "22 A4 FA 18 3E 2E 52 7F 00", 1, "T7 (ASCII)" },
/* 31*/ { UNICODE_MODE, 0, -1, "Summer Palace Ticket for 6 June 2015 13:00;2015年6月6日夜01時00分PM頤和園のチケット;2015년6월6일13시오후여름궁전티켓.2015年6月6号下午13:00的颐和园门票;", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning (171) 27 38 C3 0A 35 F9 CF 99 92 F9 26 A3 E7 3E 76 C9 AE A3 7F CC 08 04 0C CD EE 44 06 C4", "T20 B64 N4 H(f)1 T1 H(f)1 T1 H(f)1 T2 H(f)9 B35 (GB 18030)" }, /* 31*/ { UNICODE_MODE, 0, -1, "Summer Palace Ticket for 6 June 2015 13:00;2015年6月6日夜01時00分PM頤和園のチケット;2015년6월6일13시오후여름궁전티켓.2015年6月6号下午13:00的颐和园门票;", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning (171) 27 38 C3 0A 35 F9 CF 99 92 F9 26 A3 E7 3E 76 C9 AE A3 7F CC 08 04 0C CD EE 44 06 C4", 1, "T20 B64 N4 H(f)1 T1 H(f)1 T1 H(f)1 T2 H(f)9 B35 (GB 18030)" },
/* 32*/ { DATA_MODE, 0, -1, "Summer Palace Ticket for 6 June 2015 13:00;2015年6月6日夜01時00分PM頤和園のチケット;2015년6월6일13시오후여름궁전티켓.2015年6月6号下午13:00的颐和园门票;", -1, 0, 0, "(209) 27 38 C3 0A 35 F9 CF 99 92 F9 26 A3 E7 3E 76 C9 AE A3 7F CC 15 04 0C CD EE 44 06 C4", "T20 B117 (UTF-8)" }, /* 32*/ { DATA_MODE, 0, -1, "Summer Palace Ticket for 6 June 2015 13:00;2015年6月6日夜01時00分PM頤和園のチケット;2015년6월6일13시오후여름궁전티켓.2015年6月6号下午13:00的颐和园门票;", -1, 0, 0, "(209) 27 38 C3 0A 35 F9 CF 99 92 F9 26 A3 E7 3E 76 C9 AE A3 7F CC 15 04 0C CD EE 44 06 C4", 1, "T20 B117 (UTF-8)" },
/* 33*/ { UNICODE_MODE, 0, -1, "\000\014\033 #/059:<@AMZ", 15, 0, 0, "2F 80 31 B7 1F AF E0 05 27 EB 2E CB E2 96 8F F0 00", "T15 (ASCII)" }, /* 33*/ { UNICODE_MODE, 0, -1, "\000\014\033 #/059:<@AMZ", 15, 0, 0, "2F 80 31 B7 1F AF E0 05 27 EB 2E CB E2 96 8F F0 00", 1, "T15 (ASCII)" },
/* 34*/ { UNICODE_MODE, 0, -1, "Z[\\`alz{~\177", -1, 0, 0, "28 FE CF 4E 3E 92 FF 7E E7 CF 7F 00 00", "T10 (ASCII)" }, /* 34*/ { UNICODE_MODE, 0, -1, "Z[\\`alz{~\177", -1, 0, 0, "28 FE CF 4E 3E 92 FF 7E E7 CF 7F 00 00", 1, "T10 (ASCII)" },
/* 35*/ { DATA_MODE, 26, ZINT_FULL_MULTIBYTE, "\202\061\203\063", -1, 0, 26, "81 A7 01 B1 D8 00 00 00 00", "ECI-26 H(f)1 (GB 18030) (Invalid UTF-8, forces GB 2312/18030 utf8tosb() difference) NOTE: 2021-01-10 now UTF-8 is checked and mode -> DATA_MODE this test no longer shows difference" }, /* 35*/ { DATA_MODE, 26, ZINT_FULL_MULTIBYTE, "\202\061\203\063", -1, 0, 26, "81 A7 01 B1 D8 00 00 00 00", 0, "ECI-26 H(f)1 (GB 18030) (Invalid UTF-8, forces GB 2312/18030 utf8tosb() difference) NOTE: 2021-01-10 now UTF-8 is checked and mode -> DATA_MODE this test no longer shows difference; ZXing-C++ returns null string" },
/* 36*/ { UNICODE_MODE, 128, 0, "A", -1, 0, 128, "88 08 02 2B F0 00 00 00 00", "ECI > 127" }, /* 36*/ { UNICODE_MODE, 128, 0, "A", -1, 0, 128, "88 08 02 2B F0 00 00 00 00", 1, "ECI > 127" },
/* 37*/ { UNICODE_MODE, 16364, 0, "A", -1, 0, 16364, "8B FE C2 2B F0 00 00 00 00", "ECI > 16363" }, /* 37*/ { UNICODE_MODE, 16364, 0, "A", -1, 0, 16364, "8B FE C2 2B F0 00 00 00 00", 1, "ECI > 16363" },
/* 38*/ { UNICODE_MODE, 0, -1, "啊啊啊亍", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 40 00 00 00 00 FF E0 00 FF F0 00 00 00", "Region 1 (FFE terminator) -> Region 2 (no indicator)" }, /* 38*/ { UNICODE_MODE, 0, -1, "啊啊啊亍", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 40 00 00 00 00 FF E0 00 FF F0 00 00 00", 1, "Region One (FFE terminator) -> Region Two (no indicator)" },
/* 39*/ { UNICODE_MODE, 0, -1, "亍亍亍啊", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 50 00 00 00 00 FF E0 00 FF F0 00 00 00", "Region 2 (FFE terminator) -> Region 1 (no indicator)" }, /* 39*/ { UNICODE_MODE, 0, -1, "亍亍亍啊", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 50 00 00 00 00 FF E0 00 FF F0 00 00 00", 1, "Region Two (FFE terminator) -> Region One (no indicator)" },
/* 40*/ { UNICODE_MODE, 0, -1, "啊啊啊啊亍亍啊", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 40 00 00 00 00 00 0F FE 00 00 00 FF E0 00 FF F0 00", "Region 1 (FFE) -> Region 2 (FFE) -> Region 1" }, /* 40*/ { UNICODE_MODE, 0, -1, "啊啊啊啊亍亍啊", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 40 00 00 00 00 00 0F FE 00 00 00 FF E0 00 FF F0 00", 1, "Region One (FFE) -> Region Two (FFE) -> Region One" },
/* 41*/ { UNICODE_MODE, 0, -1, "亍亍亍亍啊啊亍", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 50 00 00 00 00 00 0F FE 00 00 00 FF E0 00 FF F0 00", "Region 2 (FFE) -> Region 1 (FFE) -> Region 2" }, /* 41*/ { UNICODE_MODE, 0, -1, "亍亍亍亍啊啊亍", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 50 00 00 00 00 00 0F FE 00 00 00 FF E0 00 FF F0 00", 1, "Region Two (FFE) -> Region One (FFE) -> Region Two" },
/* 42*/ { DATA_MODE, 0, ZINT_FULL_MULTIBYTE | (2 << 8), "é", -1, 0, 0, "47 02 FF F0 00 00 00 00 00", "H(1)1 (UTF-8) (Region One) (full multibyte with mask)" }, /* 42*/ { DATA_MODE, 0, ZINT_FULL_MULTIBYTE | (2 << 8), "é", -1, 0, 0, "47 02 FF F0 00 00 00 00 00", 1, "H(1)1 (UTF-8) (Region One) (full multibyte with mask)" },
/* 43*/ { UNICODE_MODE, 0, -1, "˘", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 01 16 80 00 00 00 00 00", "H(f)1 (GB 18030)" }, /* 43*/ { UNICODE_MODE, 0, -1, "˘", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 01 16 80 00 00 00 00 00", 1, "H(f)1 (GB 18030)" },
/* 44*/ { UNICODE_MODE, 4, -1, "˘", -1, 0, 4, "80 43 00 0D 10 00 00 00 00", "ECI-4 B1 (ISO 8859-2)" }, /* 44*/ { UNICODE_MODE, 4, -1, "˘", -1, 0, 4, "80 43 00 0D 10 00 00 00 00", 1, "ECI-4 B1 (ISO 8859-2)" },
/* 45*/ { UNICODE_MODE, 0, -1, "Ħ", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 47 80 00 00 00 00 00", "H(f)1 (GB 18030)" }, /* 45*/ { UNICODE_MODE, 0, -1, "Ħ", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 47 80 00 00 00 00 00", 1, "H(f)1 (GB 18030)" },
/* 46*/ { UNICODE_MODE, 5, -1, "Ħ", -1, 0, 5, "80 53 00 0D 08 00 00 00 00", "ECI-5 B1 (ISO 8859-3)" }, /* 46*/ { UNICODE_MODE, 5, -1, "Ħ", -1, 0, 5, "80 53 00 0D 08 00 00 00 00", 1, "ECI-5 B1 (ISO 8859-3)" },
/* 47*/ { UNICODE_MODE, 0, -1, "ĸ", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 50 00 00 00 00 00 00", "H(f)1 (GB 18030)" }, /* 47*/ { UNICODE_MODE, 0, -1, "ĸ", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 50 00 00 00 00 00 00", 1, "H(f)1 (GB 18030)" },
/* 48*/ { UNICODE_MODE, 6, -1, "ĸ", -1, 0, 6, "80 63 00 0D 10 00 00 00 00", "ECI-6 B1 (ISO 8859-4)" }, /* 48*/ { UNICODE_MODE, 6, -1, "ĸ", -1, 0, 6, "80 63 00 0D 10 00 00 00 00", 1, "ECI-6 B1 (ISO 8859-4)" },
/* 49*/ { UNICODE_MODE, 0, -1, "Ж", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 30 01 53 D4 00 00 00 00 00", "B2 (GB 18030)" }, /* 49*/ { UNICODE_MODE, 0, -1, "Ж", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 30 01 53 D4 00 00 00 00 00", 1, "B2 (GB 18030)" },
/* 50*/ { UNICODE_MODE, 7, -1, "Ж", -1, 0, 7, "80 73 00 0D B0 00 00 00 00", "ECI-7 B1 (ISO 8859-5)" }, /* 50*/ { UNICODE_MODE, 7, -1, "Ж", -1, 0, 7, "80 73 00 0D B0 00 00 00 00", 1, "ECI-7 B1 (ISO 8859-5)" },
/* 51*/ { UNICODE_MODE, 0, -1, "Ș", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 B9 80 00 00 00 00 00", "H(f)1 (GB 18030)" }, /* 51*/ { UNICODE_MODE, 0, -1, "Ș", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 00 B9 80 00 00 00 00 00", 1, "H(f)1 (GB 18030)" },
/* 52*/ { UNICODE_MODE, 18, -1, "Ș", -1, 0, 18, "81 23 00 0D 50 00 00 00 00", "ECI-18 B1 (ISO 8859-16)" }, /* 52*/ { UNICODE_MODE, 18, -1, "Ș", -1, 0, 18, "81 23 00 0D 50 00 00 00 00", 1, "ECI-18 B1 (ISO 8859-16)" },
/* 53*/ { UNICODE_MODE, 0, -1, "", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 30 01 52 E3 00 00 00 00 00", "B2 (GB 18030)" }, /* 53*/ { UNICODE_MODE, 0, -1, "", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 30 01 52 E3 00 00 00 00 00", 1, "B2 (GB 18030)" },
/* 54*/ { UNICODE_MODE, 20, -1, "", -1, 0, 20, "81 43 00 14 1B 28 00 00 00", "ECI-20 B2 (SHIFT JIS)" }, /* 54*/ { UNICODE_MODE, 20, -1, "", -1, 0, 20, "81 43 00 14 1B 28 00 00 00", 1, "ECI-20 B2 (SHIFT JIS)" },
/* 55*/ { UNICODE_MODE, 20, -1, "テテ", -1, 0, 20, "81 43 00 24 1B 2C 1B 28 00", "ECI-20 B4 (SHIFT JIS)" }, /* 55*/ { UNICODE_MODE, 20, -1, "テテ", -1, 0, 20, "81 43 00 24 1B 2C 1B 28 00", 1, "ECI-20 B4 (SHIFT JIS)" },
/* 56*/ { UNICODE_MODE, 20, -1, "\\\\", -1, 0, 20, "81 43 00 24 0A FC 0A F8 00", "ECI-20 B4 (SHIFT JIS)" }, /* 56*/ { UNICODE_MODE, 20, -1, "\\\\", -1, 0, 20, "81 43 00 24 0A FC 0A F8 00", 0, "ECI-20 B4 (SHIFT JIS); ZXing-C++ does straight-through ASCII conversion for Shift JIS" },
/* 57*/ { UNICODE_MODE, 0, -1, "", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 4E BC FF F0 00 00 00 00 00", "H(1)1 (GB 18030)" }, /* 57*/ { UNICODE_MODE, 0, -1, "", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 4E BC FF F0 00 00 00 00 00", 1, "H(1)1 (GB 18030)" },
/* 58*/ { UNICODE_MODE, 21, -1, "", -1, 0, 21, "81 53 00 0C 28 00 00 00 00", "ECI-21 B1 (Win 1250)" }, /* 58*/ { UNICODE_MODE, 21, -1, "", -1, 0, 21, "81 53 00 0C 28 00 00 00 00", 1, "ECI-21 B1 (Win 1250)" },
/* 59*/ { UNICODE_MODE, 0, -1, "Ґ", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 01 B9 00 00 00 00 00 00", "H(f)1 (GB 18030)" }, /* 59*/ { UNICODE_MODE, 0, -1, "Ґ", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 01 B9 00 00 00 00 00 00", 1, "H(f)1 (GB 18030)" },
/* 60*/ { UNICODE_MODE, 22, -1, "Ґ", -1, 0, 22, "81 63 00 0D 28 00 00 00 00", "ECI-22 B1 (Win 1251)" }, /* 60*/ { UNICODE_MODE, 22, -1, "Ґ", -1, 0, 22, "81 63 00 0D 28 00 00 00 00", 1, "ECI-22 B1 (Win 1251)" },
/* 61*/ { UNICODE_MODE, 0, -1, "˜", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 01 18 00 00 00 00 00 00", "H(f)1 (GB 18030)" }, /* 61*/ { UNICODE_MODE, 0, -1, "˜", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 01 18 00 00 00 00 00 00", 1, "H(f)1 (GB 18030)" },
/* 62*/ { UNICODE_MODE, 23, -1, "˜", -1, 0, 23, "81 73 00 0C C0 00 00 00 00", "ECI-23 B1 (Win 1252)" }, /* 62*/ { UNICODE_MODE, 23, -1, "˜", -1, 0, 23, "81 73 00 0C C0 00 00 00 00", 1, "ECI-23 B1 (Win 1252)" },
/* 63*/ { UNICODE_MODE, 24, -1, "پ", -1, 0, 24, "81 83 00 0C 08 00 00 00 00", "ECI-24 B1 (Win 1256)" }, /* 63*/ { UNICODE_MODE, 24, -1, "پ", -1, 0, 24, "81 83 00 0C 08 00 00 00 00", 1, "ECI-24 B1 (Win 1256)" },
/* 64*/ { UNICODE_MODE, 0, -1, "က", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 07 71 00 00 00 00 00 00", "H(f)1 (GB 18030)" }, /* 64*/ { UNICODE_MODE, 0, -1, "က", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 07 71 00 00 00 00 00 00", 1, "H(f)1 (GB 18030)" },
/* 65*/ { UNICODE_MODE, 25, -1, "က", -1, 0, 25, "81 92 F9 00 3F 00 00 00 00", "ECI-25 T2 (UCS-2BE)" }, /* 65*/ { UNICODE_MODE, 25, -1, "က", -1, 0, 25, "81 92 F9 00 3F 00 00 00 00", 1, "ECI-25 T2 (UCS-2BE)" },
/* 66*/ { UNICODE_MODE, 25, -1, "ကက", -1, 0, 25, "81 92 F9 00 10 03 F0 00 00", "ECI-25 T4 (UCS-2BE)" }, /* 66*/ { UNICODE_MODE, 25, -1, "ကက", -1, 0, 25, "81 92 F9 00 10 03 F0 00 00", 1, "ECI-25 T4 (UCS-2BE)" },
/* 67*/ { UNICODE_MODE, 25, -1, "12", -1, 0, 25, "81 93 00 20 01 88 01 90 00", "ECI-25 B4 (UCS-2BE ASCII)" }, /* 67*/ { UNICODE_MODE, 25, -1, "12", -1, 0, 25, "81 93 00 20 01 88 01 90 00", 1, "ECI-25 B4 (UCS-2BE ASCII)" },
/* 68*/ { UNICODE_MODE, 27, -1, "@", -1, 0, 27, "81 B2 FB 2F C0 00 00 00 00", "ECI-27 T1 (ASCII)" }, /* 68*/ { UNICODE_MODE, 27, -1, "@", -1, 0, 27, "81 B2 FB 2F C0 00 00 00 00", 1, "ECI-27 T1 (ASCII)" },
/* 69*/ { UNICODE_MODE, 0, -1, "", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 30 01 7E C9 80 00 00 00 00", "B2 (GB 18030)" }, /* 69*/ { UNICODE_MODE, 0, -1, "", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 30 01 7E C9 80 00 00 00 00", 1, "B2 (GB 18030)" },
/* 70*/ { UNICODE_MODE, 28, -1, "", -1, 0, 28, "81 C3 00 17 CE A8 00 00 00", "ECI-28 B2 (Big5)" }, /* 70*/ { UNICODE_MODE, 28, -1, "", -1, 0, 28, "81 C3 00 17 CE A8 00 00 00", 1, "ECI-28 B2 (Big5)" },
/* 71*/ { UNICODE_MODE, 28, -1, "龘龘", -1, 0, 28, "81 C3 00 27 CE AF CE A8 00", "ECI-28 B4 (Big5)" }, /* 71*/ { UNICODE_MODE, 28, -1, "龘龘", -1, 0, 28, "81 C3 00 27 CE AF CE A8 00", 1, "ECI-28 B4 (Big5)" },
/* 72*/ { UNICODE_MODE, 0, -1, "", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 5B BF FF F0 00 00 00 00 00", "H(2)1 (GB 18030)" }, /* 72*/ { UNICODE_MODE, 0, -1, "", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 5B BF FF F0 00 00 00 00 00", 1, "H(2)1 (GB 18030)" },
/* 73*/ { UNICODE_MODE, 29, -1, "", -1, 0, 29, "81 D3 00 17 BF F0 00 00 00", "ECI-29 B2 (GB 2312)" }, /* 73*/ { UNICODE_MODE, 29, -1, "", -1, 0, 29, "81 D3 00 17 BF F0 00 00 00", 1, "ECI-29 B2 (GB 2312)" },
/* 74*/ { UNICODE_MODE, 32, -1, "", -1, 0, 32, "82 05 BB FF FF 00 00 00 00", "ECI-32 H(2)1 (GB 2312)" }, /* 74*/ { UNICODE_MODE, 32, -1, "", -1, 0, 32, "82 05 BB FF FF 00 00 00 00", 1, "ECI-32 H(2)1 (GB 2312)" },
/* 75*/ { UNICODE_MODE, 29, -1, "齄齄", -1, 0, 29, "81 D3 00 27 BF F7 BF F0 00", "ECI-29 B4 (GB 2312)" }, /* 75*/ { UNICODE_MODE, 29, -1, "齄齄", -1, 0, 29, "81 D3 00 27 BF F7 BF F0 00", 1, "ECI-29 B4 (GB 2312)" },
/* 76*/ { UNICODE_MODE, 32, -1, "齄齄", -1, 0, 32, "82 05 BB FB BF FF F0 00 00", "ECI-32 H(2)2 (GB 2312)" }, /* 76*/ { UNICODE_MODE, 32, -1, "齄齄", -1, 0, 32, "82 05 BB FB BF FF F0 00 00", 1, "ECI-32 H(2)2 (GB 2312)" },
/* 77*/ { UNICODE_MODE, 0, -1, "", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 2B 5E 80 00 00 00 00 00", "H(f)1 (GB 18030)" }, /* 77*/ { UNICODE_MODE, 0, -1, "", -1, ZINT_WARN_NONCOMPLIANT, 0, "Warning 70 2B 5E 80 00 00 00 00 00", 1, "H(f)1 (GB 18030)" },
/* 78*/ { UNICODE_MODE, 30, -1, "", -1, 0, 30, "81 E3 00 15 85 08 00 00 00", "ECI-30 T2 (EUC-KR)" }, /* 78*/ { UNICODE_MODE, 30, -1, "", -1, 0, 30, "81 E3 00 15 85 08 00 00 00", 1, "ECI-30 T2 (EUC-KR)" },
/* 79*/ { UNICODE_MODE, 30, -1, "가가", -1, 0, 30, "81 E3 00 25 85 0D 85 08 00", "ECI-30 B4 (EUC-KR)" }, /* 79*/ { UNICODE_MODE, 30, -1, "가가", -1, 0, 30, "81 E3 00 25 85 0D 85 08 00", 1, "ECI-30 B4 (EUC-KR)" },
/* 80*/ { UNICODE_MODE, 170, -1, "?", -1, 0, 170, "88 0A A2 FB 1F C0 00 00 00", "ECI-170 L1 (ASCII invariant)" }, /* 80*/ { UNICODE_MODE, 170, -1, "?", -1, 0, 170, "88 0A A2 FB 1F C0 00 00 00", 1, "ECI-170 L1 (ASCII invariant)" },
/* 81*/ { DATA_MODE, 899, -1, "\200", -1, 0, 899, "88 38 33 00 0C 00 00 00 00", "ECI-899 B1 (8-bit binary)" }, /* 81*/ { DATA_MODE, 899, -1, "\200", -1, 0, 899, "88 38 33 00 0C 00 00 00 00", 1, "ECI-899 B1 (8-bit binary)" },
/* 82*/ { UNICODE_MODE, 900, -1, "é", -1, 0, 900, "88 38 43 00 16 1D 48 00 00", "ECI-900 B2 (no conversion)" }, /* 82*/ { UNICODE_MODE, 900, -1, "é", -1, 0, 900, "88 38 43 00 16 1D 48 00 00", 0, "ECI-900 B2 (no conversion); ZXing-C++ test can't handle UNICODE_MODE binary" },
/* 83*/ { UNICODE_MODE, 16384, -1, "é", -1, 0, 16384, "8C 04 00 03 00 16 1D 48 00", "ECI-16384 B2 (no conversion)" }, /* 83*/ { DATA_MODE, 900, -1, "\303\251", -1, 0, 900, "88 38 43 00 16 1D 48 00 00", 1, "ECI-900 B2 (no conversion)" },
/* 84*/ { UNICODE_MODE, 3, -1, "β", -1, ZINT_ERROR_INVALID_DATA, 3, "Error 545: Invalid character in input data for ECI 3", "" }, /* 84*/ { UNICODE_MODE, 16384, -1, "é", -1, 0, 16384, "8C 04 00 03 00 16 1D 48 00", 0, "ECI-16384 B2 (no conversion); ZXing-C++ test can't handle UNICODE_MODE binary" },
/* 85*/ { DATA_MODE, 16384, -1, "\303\251", -1, 0, 16384, "8C 04 00 03 00 16 1D 48 00", 1, "ECI-16384 B2 (no conversion)" },
/* 86*/ { UNICODE_MODE, 3, -1, "β", -1, ZINT_ERROR_INVALID_DATA, 3, "Error 545: Invalid character in input data for ECI 3", 1, "" },
/* 87*/ { GS1_MODE, -1, -1, "[10]01", -1, ZINT_ERROR_INVALID_OPTION, 0, "Error 220: Selected symbology does not support GS1 mode", 1, "" },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
struct zint_symbol *symbol; struct zint_symbol *symbol;
char escaped[1024]; char escaped[1024];
char cmp_buf[32768];
char cmp_msg[1024];
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); // Only do ZXing-C++ test if asked, too slow otherwise
testStart("test_input"); testStart("test_input");
@ -284,15 +297,34 @@ static void test_input(int index, int generate, int debug) {
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) { if (generate) {
printf(" /*%3d*/ { %s, %d, %s, \"%s\", %d, %s, %d, \"%s\", \"%s\" },\n", printf(" /*%3d*/ { %s, %d, %s, \"%s\", %d, %s, %d, \"%s\", %d, \"%s\" },\n",
i, testUtilInputModeName(data[i].input_mode), data[i].eci, testUtilOption3Name(data[i].option_3), i, testUtilInputModeName(data[i].input_mode), data[i].eci, testUtilOption3Name(data[i].option_3),
testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length,
testUtilErrorName(data[i].ret), ret < ZINT_ERROR ? symbol->eci : -1, symbol->errtxt, data[i].comment); testUtilErrorName(data[i].ret), ret < ZINT_ERROR ? symbol->eci : -1, symbol->errtxt,
data[i].zxingcpp_cmp, data[i].comment);
} else { } else {
if (ret < ZINT_ERROR) { if (ret < ZINT_ERROR) {
assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", i, symbol->eci, data[i].expected_eci); assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", i, symbol->eci, data[i].expected_eci);
} }
assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected);
if (ret < ZINT_ERROR) {
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) {
if (!data[i].zxingcpp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not ZXing-C++ compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
int cmp_len, ret_len;
char modules_dump[189 * 189 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, escaped, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %.*s\nexpected: %.*s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped);
}
}
}
} }
ZBarcode_Delete(symbol); ZBarcode_Delete(symbol);
@ -371,7 +403,7 @@ static void test_encode(int index, int generate, int debug) {
"1110101010000010000000001" "1110101010000010000000001"
"1110101011000100101111111" "1110101011000100101111111"
}, },
/* 2*/ { UNICODE_MODE, -1, -1, 24, 3 << 8, "汉信码标准\015\012中国物品编码中心\015\012北京网路畅想科技发展有限公司\015\012张成海、赵楠、黄燕滨、罗秋科、王毅、张铎、王越\015\012施煜、边峥、修兴强\015\012汉信码标准\015\012中国物品编码中心\015\012北京网路畅想科技发展有限公司", -1, ZINT_WARN_NONCOMPLIANT, 69, 69, "ISO 20830 Figure 2 **NOT SAME** different encodation, Binary mode not used by figure", /* 2*/ { UNICODE_MODE, -1, -1, 24, 3 << 8, "汉信码标准\015\012中国物品编码中心\015\012北京网路畅想科技发展有限公司\015\012张成海、赵楠、黄燕滨、罗秋科、王毅、张铎、王越\015\012施煜、边峥、修兴强\015\012汉信码标准\015\012中国物品编码中心\015\012北京网路畅想科技发展有限公司", -1, ZINT_WARN_NONCOMPLIANT, 69, 69, "ISO 20830 Figure 2 **NOT SAME** different encodation, Binary mode not used by figure, nor Region One/Two 0xFFE switching (same if force mode 11111tt11111111tt11111111111111tt11111211111111111112111tt121121111tt11111tt11111111tt11111111111111 and disable Region One/Two 0xFFE switch",
"111111100000010101011111111111111111000001110110100100011010101111111" "111111100000010101011111111111111111000001110110100100011010101111111"
"100000001000101000000000000000000010100000101100000001101001100000001" "100000001000101000000000000000000010100000101100000001101001100000001"
"101111100010110110110000010011001010001011001011111000011101001111101" "101111100010110110110000010011001010001011001011111000011101001111101"
@ -796,7 +828,7 @@ static void test_encode(int index, int generate, int debug) {
"11101010111010000000001" "11101010111010000000001"
"11101010011010001111111" "11101010011010001111111"
}, },
/* 13*/ { UNICODE_MODE, -1, -1, -1, 3 << 8, "汉信码标准", -1, ZINT_WARN_NONCOMPLIANT, 23, 23, "ISO 20830 Figure 4, explict mask 10, same except no alternating filler", /* 13*/ { UNICODE_MODE, -1, -1, -1, 3 << 8, "汉信码标准", -1, ZINT_WARN_NONCOMPLIANT, 23, 23, "ISO 20830 Figure 4, explicit mask 10, same except no alternating filler",
"11111110100001101111111" "11111110100001101111111"
"10000000101011100000001" "10000000101011100000001"
"10111110101110001111101" "10111110101110001111101"
@ -1753,7 +1785,7 @@ static void test_encode(int index, int generate, int debug) {
"11101010110101000000001" "11101010110101000000001"
"11101010101010001111111" "11101010101010001111111"
}, },
/* 32*/ { UNICODE_MODE, 7, 2, -1, -1, "Россия", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 7 Example 1 **NOT SAME** different encodation, figure uses Region 1", /* 32*/ { UNICODE_MODE, 7, 2, -1, -1, "Россия", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 7 Example 1 **NOT SAME** different encodation, figure uses Region One",
"11111110011010101111111" "11111110011010101111111"
"10000000010101100000001" "10000000010101100000001"
"10111110001010001111101" "10111110001010001111101"
@ -2021,7 +2053,7 @@ static void test_encode(int index, int generate, int debug) {
"11101010111110000000001" "11101010111110000000001"
"11101010101010001111111" "11101010101010001111111"
}, },
/* 42*/ { UNICODE_MODE, 13, 2, -1, -1, "บาร๋แค่ด", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 13 Example 1 **NOT SAME** example uses Region 1", /* 42*/ { UNICODE_MODE, 13, 2, -1, -1, "บาร๋แค่ด", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 13 Example 1 **NOT SAME** example uses Region One",
"11111110011010101111111" "11111110011010101111111"
"10000000010101100000001" "10000000010101100000001"
"10111110001010001111101" "10111110001010001111101"
@ -2558,7 +2590,7 @@ static void test_encode(int index, int generate, int debug) {
"11101010110101000000001" "11101010110101000000001"
"11101010101010001111111" "11101010101010001111111"
}, },
/* 63*/ { UNICODE_MODE, 29, 2, -1, -1, "条码", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 29 Example 1 **NOT SAME** example uses Region 1 mode", /* 63*/ { UNICODE_MODE, 29, 2, -1, -1, "条码", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 29 Example 1 **NOT SAME** example uses Region One mode",
"11111110011010101111111" "11111110011010101111111"
"10000000010001100000001" "10000000010001100000001"
"10111110001010001111101" "10111110001010001111101"
@ -2583,7 +2615,7 @@ static void test_encode(int index, int generate, int debug) {
"11101010110101000000001" "11101010110101000000001"
"11101010101010001111111" "11101010101010001111111"
}, },
/* 64*/ { UNICODE_MODE, 29, 2, -1, -1, "北京", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 29 Example 2 **NOT SAME** example uses Region 1 mode", /* 64*/ { UNICODE_MODE, 29, 2, -1, -1, "北京", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 29 Example 2 **NOT SAME** example uses Region One mode",
"11111110011010101111111" "11111110011010101111111"
"10000000010001100000001" "10000000010001100000001"
"10111110001010001111101" "10111110001010001111101"
@ -2608,7 +2640,7 @@ static void test_encode(int index, int generate, int debug) {
"11101010110101000000001" "11101010110101000000001"
"11101010101010001111111" "11101010101010001111111"
}, },
/* 65*/ { UNICODE_MODE, 30, 2, -1, -1, "바코드", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 30 Example 1 **NOT SAME** example uses Region 1 mode", /* 65*/ { UNICODE_MODE, 30, 2, -1, -1, "바코드", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 30 Example 1 **NOT SAME** example uses Region One mode",
"11111110011010101111111" "11111110011010101111111"
"10000000010001100000001" "10000000010001100000001"
"10111110001010001111101" "10111110001010001111101"
@ -2633,7 +2665,7 @@ static void test_encode(int index, int generate, int debug) {
"11101010110101000000001" "11101010110101000000001"
"11101010101010001111111" "11101010101010001111111"
}, },
/* 66*/ { UNICODE_MODE, 30, 2, -1, -1, "서울", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 30 Example 2 **NOT SAME** example uses Region 1 mode", /* 66*/ { UNICODE_MODE, 30, 2, -1, -1, "서울", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 30 Example 2 **NOT SAME** example uses Region One mode",
"11111110011010101111111" "11111110011010101111111"
"10000000010001100000001" "10000000010001100000001"
"10111110001010001111101" "10111110001010001111101"
@ -2658,7 +2690,7 @@ static void test_encode(int index, int generate, int debug) {
"11101010110101000000001" "11101010110101000000001"
"11101010101010001111111" "11101010101010001111111"
}, },
/* 67*/ { UNICODE_MODE, 31, 2, -1, -1, "条码", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 31 Example 1 **NOT SAME** example uses Region 1 mode", /* 67*/ { UNICODE_MODE, 31, 2, -1, -1, "条码", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 31 Example 1 **NOT SAME** example uses Region One mode",
"11111110011010101111111" "11111110011010101111111"
"10000000010001100000001" "10000000010001100000001"
"10111110001010001111101" "10111110001010001111101"
@ -2683,7 +2715,7 @@ static void test_encode(int index, int generate, int debug) {
"11101010110101000000001" "11101010110101000000001"
"11101010101010001111111" "11101010101010001111111"
}, },
/* 68*/ { UNICODE_MODE, 31, 2, -1, -1, "北京", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 31 Example 2 **NOT SAME** example uses Region 1 mode", /* 68*/ { UNICODE_MODE, 31, 2, -1, -1, "北京", -1, 0, 23, 23, "AIM ITS/04-023:2022 ECI 31 Example 2 **NOT SAME** example uses Region One mode",
"11111110011001001111111" "11111110011001001111111"
"10000000000000000000001" "10000000000000000000001"
"10111110011111101111101" "10111110011111101111101"
@ -3228,6 +3260,309 @@ static void test_encode(int index, int generate, int debug) {
testFinish(); testFinish();
} }
static void test_encode_segs(int index, int generate, int debug) {
struct item {
int input_mode;
int option_1;
int option_2;
int option_3;
struct zint_seg segs[3];
int ret;
int expected_rows;
int expected_width;
char *comment;
char *expected;
};
struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, -1, -1, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 23, 23, "Standard example",
"11111110101100101111111"
"10000000010110000000001"
"10111110110000001111101"
"10100000110101000000101"
"10101110001010101110101"
"10101110111110101110101"
"10101110001100001110101"
"00000000101110100000000"
"00010101111111001000000"
"11111101010110101111001"
"00111010100000101010110"
"10000101011001001100101"
"11001000111111101010100"
"00010100101000101011001"
"00000010011010110101000"
"00000000101011100000000"
"11111110000000001110101"
"00000010110111101110101"
"11111010110101001110101"
"00001010001000100000101"
"11101010000110101111101"
"11101010010110000000001"
"11101010101010101111111"
},
/* 1*/ { UNICODE_MODE, -1, -1, -1, { { TU(""), -1, 0 }, { TU("Ж"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 23, 23, "Standard example auto-ECI",
"11111110101100101111111"
"10000000010110000000001"
"10111110110000001111101"
"10100000110101000000101"
"10101110001010101110101"
"10101110111110101110101"
"10101110001100001110101"
"00000000101110100000000"
"00010101111111001000000"
"11111101010110101111001"
"00111010100000101010110"
"10000101011001001100101"
"11001000111111101010100"
"00010100101000101011001"
"00000010011010110101000"
"00000000101011100000000"
"11111110000000001110101"
"00000010110111101110101"
"11111010110101001110101"
"00001010001000100000101"
"11101010000110101111101"
"11101010010110000000001"
"11101010101010101111111"
},
/* 2*/ { UNICODE_MODE, -1, -1, -1, { { TU("Ж"), -1, 7 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, 0, 23, 23, "Standard example inverted",
"11111110111010001111111"
"10000000110110000000001"
"10111110111000101111101"
"10100000100010000000101"
"10101110001100001110101"
"10101110111010001110101"
"10101110010010001110101"
"00000000010101000000000"
"00010101101011110000000"
"00010100111110000010001"
"11100000000010101011000"
"10001001100101010100110"
"10101001111000110001111"
"00110100010101001111000"
"00000001101010110101000"
"00000000010110000000000"
"11111110001101001110101"
"00000010010101101110101"
"11111010001011001110101"
"00001010010110100000101"
"11101010101010101111101"
"11101010010101100000001"
"11101010001010101111111"
},
/* 3*/ { UNICODE_MODE, -1, -1, -1, { { TU("Ж"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 23, 23, "Standard example inverted auto-ECI",
"11111110111010001111111"
"10000000110110000000001"
"10111110111000101111101"
"10100000100010000000101"
"10101110001100001110101"
"10101110111010001110101"
"10101110010010001110101"
"00000000010101000000000"
"00010101101011110000000"
"00010100111110000010001"
"11100000000010101011000"
"10001001100101010100110"
"10101001111000110001111"
"00110100010101001111000"
"00000001101010110101000"
"00000000010110000000000"
"11111110001101001110101"
"00000010010101101110101"
"11111010001011001110101"
"00001010010110100000101"
"11101010101010101111101"
"11101010010101100000001"
"11101010001010101111111"
},
/* 4*/ { UNICODE_MODE, -1, -1, 4 << 8, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 51, 51, "AIM ITS/04-023:2022 Annex A example **NOT SAME ** example corrupt???",
"111111100111111110011011000110010101001011101111111"
"100000000000000011100101000111110000010100100000001"
"101111101110011011101101000011010010010001001111101"
"101000001001111010100101100101010111101100100000101"
"101011100001110010100101010100111100010110001110101"
"101011101000000011001001010001100001000011001110101"
"101011101001101011110101011110100011100100001110101"
"000000000000000011011110101000100111010001100000000"
"001000110010011010000001111010101101101100001000000"
"001010111000010011111011010010001101111101001001011"
"110010110000111010001010001111000001000110001001010"
"111100100000011010101001100000101101010001011010101"
"100010001001110010101001010001100011110011101001011"
"111001111101010011011111111101000010110100000011101"
"000100000100010010110111110000110100111011010011000"
"011001011101001011100101110010101010011101110011011"
"001100010000001011110101011000000010001111101010100"
"101011100100010011111111111111111101011000010100101"
"000111010000010000000000000000000110001101111011100"
"100001011001110000011011010111000101001111101101010"
"101000111100100101110100001001010111010000010010000"
"110101000011101100100010001100110110011100110010000"
"111101100011001000011101101110010101001010101010110"
"110100100010010011011011111011000100011100000101010"
"100011011101110000011101101001000100010010001110110"
"111110010100001001110110000001000101011111011001011"
"111101100101111110010000101001110111010011001110011"
"111000001110111101100100010100100111100101101100110"
"110000110011101100001111001100110101000010000110001"
"101110001001011110101001110101100101110001001100001"
"111101000101011001011111001101000111111010010001000"
"110010011000111100011011001100010111101011110101001"
"111100111101111111011101111110000111101100010100010"
"110001011010011101111100110100100111001110011100001"
"111111111111111110011011000100000111111111111111111"
"000000000000000011001010100111010000000000000000001"
"111010001110010010110011000010100110010010010111101"
"001100111011101011011100110010100101011101010101101"
"100010010001101010100111110101111101001001011101101"
"001100001000111010111110011000000000000010000011001"
"110101100010111010100010101001111010110011110100001"
"111011101001011010111111101101011101000001010101101"
"000000100011001011110010011110010010110000011000100"
"000000001001101010101111000010000011000100000000000"
"111111100101101011101001011000111110100111101110101"
"000000100101100011010011110011000101101100101110101"
"111110100110010010000111010110111001001101001110101"
"000010101010110010011001111100010010001010100000101"
"111010100110011010000010110001111100010001101111101"
"111010101000000011001110011001100001110110000000001"
"111010101011000011111111111111110101110100001111111"
},
/* 5*/ { DATA_MODE, -1, -1, -1, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, 0, 23, 23, "Standard example + extra seg, data mode",
"11111110101100001111111"
"10000000110110000000001"
"10111110110101101111101"
"10100000100101000000101"
"10101110001010001110101"
"10101110110001001110101"
"10101110010100001110101"
"00000000001110000000000"
"00010101101001110000000"
"10011101010001000011001"
"00111100100000101010010"
"11110101011000100100101"
"11000000001101101010100"
"00100110110011010010110"
"00000001101010110101000"
"00000000010111000000000"
"11111110011110001110101"
"00000010000110101110101"
"11111010000110001110101"
"00001010000100100000101"
"11101010101100101111101"
"11101010010101100000001"
"11101010001010101111111"
},
/* 6*/ { UNICODE_MODE, -1, -1, -1, { { TU("éÿ"), -1, 0 }, { TU("กขฯ"), -1, 13 }, { TU("αβγώ"), -1, 0 } }, ZINT_WARN_USES_ECI, 23, 23, "Auto-ECI",
"11111110001100001111111"
"10000000110101100000001"
"10111110001010101111101"
"10100000110101100000101"
"10101110001001101110101"
"10101110110010001110101"
"10101110001001001110101"
"00000000000001100000000"
"00010101001101011000000"
"11001010101111101100110"
"10101101010111000011011"
"01010001010101010101010"
"10010010101010001011000"
"00011110010000110000101"
"00000011001101010101000"
"00000000101111000000000"
"11111110001010001110101"
"00000010010101101110101"
"11111010101110001110101"
"00001010111010100000101"
"11101010111000001111101"
"11101010111001100000001"
"11101010001010001111111"
},
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
char escaped[8192];
char cmp_buf[32768];
char cmp_msg[1024];
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); // Only do ZXing-C++ test if asked, too slow otherwise
testStart("test_encode_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, BARCODE_HANXIN, data[i].input_mode, -1 /*eci*/,
data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/,
NULL, 0, debug);
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
char escaped1[8192];
char escaped2[8192];
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length;
int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length;
printf(" /*%3d*/ { %s, %d, %d, %s, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, \"%s\",\n",
i, testUtilInputModeName(data[i].input_mode),
data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3),
testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci,
testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci,
testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci,
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment);
testUtilModulesPrint(symbol, " ", "\n");
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
if (do_zxingcpp) {
if ((symbol->input_mode & 0x07) == DATA_MODE) {
if (debug & ZINT_DEBUG_TEST_PRINT) {
printf("i:%d multiple segments in DATA_MODE not currently supported for ZXing-C++ testing (%s)\n",
i, testUtilBarcodeName(symbol->symbology));
}
} else {
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
if (testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, length, debug)) {
int cmp_len, ret_len;
char modules_dump[49152];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, (const char *) data[i].segs[0].source, length,
modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count,
NULL /*primary*/, escaped, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped);
}
}
}
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
#include <time.h> #include <time.h>
#define TEST_PERF_ITERATIONS 1000 #define TEST_PERF_ITERATIONS 1000
@ -3250,7 +3585,7 @@ static void test_perf(int index, int debug) {
struct item data[] = { struct item data[] = {
/* 0*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, /* 0*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1,
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。", "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。",
0, 43, 43, "98 chars, Region 1 and Text" }, 0, 43, 43, "98 chars, Region One and Text" },
/* 1*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, /* 1*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1,
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。"
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。"
@ -3262,7 +3597,7 @@ static void test_perf(int index, int debug) {
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。"
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。"
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。", "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。",
0, 121, 121, "980 chars, Region 1 and Text" }, 0, 121, 121, "980 chars, Region One and Text" },
/* 2*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, /* 2*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1,
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。"
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。"
@ -3279,7 +3614,7 @@ static void test_perf(int index, int debug) {
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。"
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。" "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。"
"汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。", "汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。汉信码(Chinese-Sensible Code)是一种能够有效表示汉字、图像等信息的二维条码。",
0, 147, 147, "1470 chars, Region 1 and Text" }, 0, 147, 147, "1470 chars, Region One and Text" },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@ -3336,6 +3671,7 @@ int main(int argc, char *argv[]) {
{ "test_options", test_options, 1, 0, 1 }, { "test_options", test_options, 1, 0, 1 },
{ "test_input", test_input, 1, 1, 1 }, { "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_encode_segs", test_encode_segs, 1, 1, 1 },
{ "test_perf", test_perf, 1, 0, 1 }, { "test_perf", test_perf, 1, 0, 1 },
}; };

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
/* /*
* Intelligent Mail barcode Encoder Test Case Reference Set (csv file) * Intelligent Mail barcode Encoder Test Case Reference Set (csv file)
* Copyright (C) 2009 U.S. Postal Service * Copyright (C) 2009 U.S. Postal Service
@ -280,7 +279,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -311,3 +310,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
#include <fcntl.h> #include <fcntl.h>
@ -61,7 +60,7 @@ static void test_checks(int index, int debug) {
/* 0*/ { BARCODE_CODE128, -1, "1234", -1, -1, 3, 0, 0, 0, 0, -1, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", -1 }, /* 0*/ { BARCODE_CODE128, -1, "1234", -1, -1, 3, 0, 0, 0, 0, -1, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", -1 },
/* 1*/ { BARCODE_CODE128, -1, "1234", -1, -1, 0, 0, 0, 0, 0, -1, -1, -1, -1, 0, "", -1 }, /* 1*/ { BARCODE_CODE128, -1, "1234", -1, -1, 0, 0, 0, 0, 0, -1, -1, -1, -1, 0, "", -1 },
/* 2*/ { BARCODE_QRCODE, -1, "1234", -1, -1, 3, 0, 0, 0, 0, -1, -1, -1, -1, 0, "", -1 }, /* 2*/ { BARCODE_QRCODE, -1, "1234", -1, -1, 3, 0, 0, 0, 0, -1, -1, -1, -1, 0, "", -1 },
/* 3*/ { BARCODE_QRCODE, -1, "1234", -1, -1, 999999 + 1, 0, 0, 0, 0, -1, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 218: Invalid ECI mode", -1 }, /* 3*/ { BARCODE_QRCODE, -1, "1234", -1, -1, 999999 + 1, 0, 0, 0, 0, -1, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 218: Invalid ECI code 1000000", -1 },
/* 4*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, 0.009, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 227: Scale out of range (0.01 to 100)", -1 }, /* 4*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, 0.009, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 227: Scale out of range (0.01 to 100)", -1 },
/* 5*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, 100.01, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 227: Scale out of range (0.01 to 100)", -1 }, /* 5*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, 100.01, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 227: Scale out of range (0.01 to 100)", -1 },
/* 6*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, -1, 20.1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Dot size out of range (0.01 to 20)", -1 }, /* 6*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, -1, 20.1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Dot size out of range (0.01 to 20)", -1 },
@ -251,7 +250,7 @@ static void test_checks(int index, int debug) {
symbol->warn_level = data[i].warn_level; symbol->warn_level = data[i].warn_level;
} }
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); ret = ZBarcode_Encode(symbol, TU(data[i].data), length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode(%d) ret %d != %d (%s)\n", i, data[i].symbology, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode(%d) ret %d != %d (%s)\n", i, data[i].symbology, ret, data[i].ret, symbol->errtxt);
ret = strcmp(symbol->errtxt, data[i].expected); ret = strcmp(symbol->errtxt, data[i].expected);
@ -269,6 +268,68 @@ static void test_checks(int index, int debug) {
testFinish(); testFinish();
} }
static void test_checks_segs(int index, int debug) {
struct item {
int symbology;
int option_1;
struct zint_seg segs[2];
int seg_count;
int input_mode;
int eci;
int warn_level;
int ret;
char *expected;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { BARCODE_CODE128, -1, { { NULL, 0, 0 }, { NULL, 0, 0 } }, 0, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 205: Input segment count 0" },
/* 1*/ { BARCODE_CODE128, -1, { { NULL, 0, 0 }, { NULL, 0, 0 } }, 257, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 771: Too many input segments (max 256)" },
/* 2*/ { BARCODE_CODE128, -1, { { NULL, 0, 0 }, { NULL, 0, 0 } }, 1, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 772: Input segment 0 source NULL" },
/* 3*/ { BARCODE_CODE128, -1, { { TU(""), 0, 0 }, { NULL, 0, 0 } }, 1, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 773: Input segment 0 length zero" },
/* 4*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 0 }, { NULL, 0, 0 } }, 2, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 772: Input segment 1 source NULL" },
/* 4*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 0 }, { TU(""), 0, 0 } }, 2, -1, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 773: Input segment 1 length zero" },
/* 5*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 3 }, { TU("B"), 0, 0 } }, 2, -1, 4, -1, ZINT_ERROR_INVALID_OPTION, "Error 774: Symbol ECI 4 must match segment zero ECI 3" },
/* 6*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 3 }, { TU("B"), 0, 4 } }, 2, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 775: Symbology does not support multiple segments" },
/* 7*/ { BARCODE_CODE128, -1, { { TU("A"), 0, 3 }, { NULL, 0, 0 } }, 1, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching" },
/* 8*/ { BARCODE_AZTEC, -1, { { TU("A"), 0, 3 }, { TU("B"), 0, 1 } }, 2, -1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 218: Invalid ECI code 1" },
/* 9*/ { BARCODE_AZTEC, -1, { { TU("A"), 0, 3 }, { TU("B"), 0, 4 } }, 2, GS1_MODE, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 776: GS1_MODE not supported for multiple segments" },
/* 10*/ { BARCODE_AZTEC, -1, { { TU("A"), 0, 3 }, { TU("\200"), 0, 4 } }, 2, UNICODE_MODE, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 245: Invalid UTF-8 in input data" },
/* 11*/ { BARCODE_AZTEC, -1, { { TU("A"), 0, 3 }, { TU("B"), 0, 4 } }, 2, -1, -1, -1, 0, "" },
/* 12*/ { BARCODE_AZTEC, -1, { { TU("A"), 0, 0 }, { TU("B"), 0, 4 } }, 2, -1, 3, -1, 0, "" },
/* 13*/ { BARCODE_AZTEC, -1, { { TU("A"), ZINT_MAX_DATA_LEN, 3 }, { TU("B"), 1, 4 } }, 2, -1, -1, -1, ZINT_ERROR_TOO_LONG, "Error 243: Input data too long" },
};
int data_size = ARRAY_SIZE(data);
int i, ret;
struct zint_symbol *symbol;
testStart("test_checks_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, data[i].option_1, -1, -1, -1 /*output_options*/, NULL, 0, debug);
if (data[i].warn_level != -1) {
symbol->warn_level = data[i].warn_level;
}
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, data[i].seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs(%d) ret %d != %d (%s)\n", i, data[i].symbology, ret, data[i].ret, symbol->errtxt);
ret = strcmp(symbol->errtxt, data[i].expected);
assert_zero(ret, "i:%d (%d) strcmp(%s, %s) %d != 0\n", i, data[i].symbology, symbol->errtxt, data[i].expected, ret);
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_symbologies(void) { static void test_symbologies(void) {
int i, ret; int i, ret;
struct zint_symbol symbol = {0}; struct zint_symbol symbol = {0};
@ -277,7 +338,7 @@ static void test_symbologies(void) {
for (i = -1; i < 148; i++) { for (i = -1; i < 148; i++) {
symbol.symbology = i; symbol.symbology = i;
ret = ZBarcode_Encode(&symbol, (unsigned char *) "1", 0); ret = ZBarcode_Encode(&symbol, TU("1"), 0);
assert_notequal(ret, ZINT_ERROR_ENCODING_PROBLEM, "i:%d Encoding problem (%s)\n", i, symbol.errtxt); assert_notequal(ret, ZINT_ERROR_ENCODING_PROBLEM, "i:%d Encoding problem (%s)\n", i, symbol.errtxt);
} }
@ -322,7 +383,7 @@ static void test_input_mode(int index, int debug) {
length = testUtilSetSymbol(symbol, BARCODE_CODE49 /*Supports GS1*/, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); length = testUtilSetSymbol(symbol, BARCODE_CODE49 /*Supports GS1*/, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); ret = ZBarcode_Encode(symbol, TU(data[i].data), length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
assert_equal(symbol->input_mode, data[i].expected_input_mode, "i:%d symbol->input_mode %d != %d\n", i, symbol->input_mode, data[i].expected_input_mode); assert_equal(symbol->input_mode, data[i].expected_input_mode, "i:%d symbol->input_mode %d != %d\n", i, symbol->input_mode, data[i].expected_input_mode);
@ -349,7 +410,7 @@ static void test_escape_char_process(int index, int generate, int debug) {
/* 0*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 26, "01 05 08 09 0A 0B 0C 0D 0E 1C 1E 1F EB 02 5D 81 21 0D 92 2E 3D FD B6 9A 37 2A CD 61 FB 95", 0, "" }, /* 0*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 26, "01 05 08 09 0A 0B 0C 0D 0E 1C 1E 1F EB 02 5D 81 21 0D 92 2E 3D FD B6 9A 37 2A CD 61 FB 95", 0, "" },
/* 1*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 101, "(45) 67 62 43 40 44 47 48 29 6A 67 62 0B 49 4A 4B 4C 18 6A 67 62 0C 4D 5B 5D 5E 62 6A 67", 0, "" }, /* 1*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 101, "(45) 67 62 43 40 44 47 48 29 6A 67 62 0B 49 4A 4B 4C 18 6A 67 62 0C 4D 5B 5D 5E 62 6A 67", 0, "" },
/* 2*/ { BARCODE_CODE16K, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 70, "(20) 14 64 68 71 72 73 74 75 76 77 91 93 94 101 65 60 103 103 45 61", 0, "" }, /* 2*/ { BARCODE_CODE16K, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 70, "(20) 14 64 68 71 72 73 74 75 76 77 91 93 94 101 65 60 103 103 45 61", 0, "" },
/* 3*/ { BARCODE_DOTCODE, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 28, "65 40 44 47 48 49 4A 4B 4C 4D 5B 5D 5E 6E 41 3C", 0, "" }, /* 3*/ { BARCODE_DOTCODE, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 28, "65 40 44 47 48 49 4A 4B 4C 4D 5B 5D 5E 6E 41 3C 6A", 0, "" },
/* 4*/ { BARCODE_GRIDMATRIX, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 30, "30 1A 00 02 01 61 00 48 28 16 0C 06 46 63 51 74 05 38 00", 0, "" }, /* 4*/ { BARCODE_GRIDMATRIX, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 30, "30 1A 00 02 01 61 00 48 28 16 0C 06 46 63 51 74 05 38 00", 0, "" },
/* 5*/ { BARCODE_HANXIN, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 23, "2F 80 10 72 09 28 B3 0D 6F F3 00 20 E8 F4 0A E0 00", 0, "" }, /* 5*/ { BARCODE_HANXIN, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 23, "2F 80 10 72 09 28 B3 0D 6F F3 00 20 E8 F4 0A E0 00", 0, "" },
/* 6*/ { BARCODE_MAXICODE, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 30, "(144) 04 3E 3E 00 04 07 08 09 0A 0B 03 3D 2C 24 19 1E 23 1B 18 0E 0C 0D 1E 21 3C 1E 3C 31", 0, "" }, /* 6*/ { BARCODE_MAXICODE, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 30, "(144) 04 3E 3E 00 04 07 08 09 0A 0B 03 3D 2C 24 19 1E 23 1B 18 0E 0C 0D 1E 21 3C 1E 3C 31", 0, "" },
@ -380,6 +441,7 @@ static void test_escape_char_process(int index, int generate, int debug) {
/* 31*/ { BARCODE_DATAMATRIX, DATA_MODE, 17, "\\xA4", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" }, /* 31*/ { BARCODE_DATAMATRIX, DATA_MODE, 17, "\\xA4", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" },
/* 32*/ { BARCODE_DATAMATRIX, DATA_MODE, 28, "\\xB1\\x60", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 0, "Zint manual 4.10 Ex2" }, /* 32*/ { BARCODE_DATAMATRIX, DATA_MODE, 28, "\\xB1\\x60", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 0, "Zint manual 4.10 Ex2" },
/* 33*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 28, "\\u5E38", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 1, "" }, /* 33*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 28, "\\u5E38", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 1, "" },
/* 34*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, "\\u007F", 0, 10, "80 81 46 73 64 88 6A 84", 0, "" },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@ -403,7 +465,7 @@ static void test_escape_char_process(int index, int generate, int debug) {
length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode | ESCAPE_MODE, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode | ESCAPE_MODE, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); ret = ZBarcode_Encode(symbol, TU(data[i].data), length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) { if (generate) {
@ -711,12 +773,104 @@ static void test_encode_file_directory(void) {
testFinish(); testFinish();
} }
static void test_encode_file(void) {
int ret;
struct zint_symbol *symbol;
char *data = "1";
char *filename = "test_encode_file_in.txt";
char *outfile = "test_encode_file_out.gif";
FILE *fp;
testStart("test_encode_file");
(void) remove(filename); // In case junk hanging around
(void) remove(outfile); // In case junk hanging around
fp = fopen(filename, "w+");
assert_nonnull(fp, "fopen(%s) failed (%d)\n", filename, ferror(fp));
assert_notequal(fputs(data, fp), EOF, "fputs(%s) failed == EOF (%d)\n", data, ferror(fp));
ret = fclose(fp);
assert_zero(ret, "fclose(%s) %d != 0\n", filename, ret);
{
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
strcpy(symbol->outfile, outfile);
ret = ZBarcode_Encode_File_and_Print(symbol, filename, 0);
assert_zero(ret, "ret %d != 0 (%s)\n", ret, symbol->errtxt);
ret = remove(outfile);
assert_zero(ret, "remove(%s) != 0 (%d: %s)\n", outfile, errno, strerror(errno));
ZBarcode_Delete(symbol);
}
{
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
strcpy(symbol->outfile, outfile);
ret = ZBarcode_Encode_File_and_Buffer(symbol, filename, 0);
assert_zero(ret, "ret %d != 0 (%s)\n", ret, symbol->errtxt);
assert_nonnull(symbol->bitmap, "symbol->bitmap NULL (%s)\n", symbol->errtxt);
ZBarcode_Delete(symbol);
}
{
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
strcpy(symbol->outfile, outfile);
ret = ZBarcode_Encode_File_and_Buffer_Vector(symbol, filename, 0);
assert_zero(ret, "ret %d != 0 (%s)\n", ret, symbol->errtxt);
assert_nonnull(symbol->vector, "symbol->vector NULL (%s)\n", symbol->errtxt);
ZBarcode_Delete(symbol);
}
ret = remove(filename);
assert_zero(ret, "remove(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno));
testFinish();
}
static void test_encode_print_outfile_directory(void) {
int ret;
struct zint_symbol *symbol;
char dirname[] = "outdir.txt";
testStart("test_encode_print_outfile_directory");
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
(void) testUtilRmDir(dirname); // In case junk hanging around
ret = testUtilMkDir(dirname);
assert_zero(ret, "testUtilMkDir(%s) %d != 0 (%d: %s)\n", dirname, ret, errno, strerror(errno));
strcpy(symbol->outfile, dirname);
ret = ZBarcode_Encode_and_Print(symbol, TU("1"), 0, 0);
assert_equal(ret, ZINT_ERROR_FILE_ACCESS, "ret %d != ZINT_ERROR_FILE_ACCESS (%s)\n", ret, symbol->errtxt);
ret = testUtilRmDir(dirname);
assert_zero(ret, "testUtilRmDir(%s) %d != 0 (%d: %s)\n", dirname, ret, errno, strerror(errno));
ZBarcode_Delete(symbol);
testFinish();
}
static void test_bad_args(void) { static void test_bad_args(void) {
int ret; int ret;
struct zint_symbol *symbol; struct zint_symbol *symbol;
char *data = "1"; char *data = "1";
char *filename = "1.png"; char *filename = "1.png";
char *empty = ""; char *empty = "";
struct zint_seg seg = { TU("1"), -1, 4 };
struct zint_seg seg_empty = { TU(""), -1, 4 };
struct zint_seg seg_too_long = { TU("1"), ZINT_MAX_DATA_LEN + 1, 4 };
testStart("test_bad_args"); testStart("test_bad_args");
@ -736,12 +890,17 @@ static void test_bad_args(void) {
assert_zero(ret, "ZBarcode_Cap(10, ~0) ret 0x%X != 0\n", ret); assert_zero(ret, "ZBarcode_Cap(10, ~0) ret 0x%X != 0\n", ret);
// NULL symbol // NULL symbol
assert_equal(ZBarcode_Encode(NULL, (unsigned char *) data, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(NULL, data, 1) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode(NULL, TU(data), 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(NULL, data, 1) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Encode_Segs(NULL, &seg, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(NULL, &seg, 1) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Print(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Print(NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Print(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Print(NULL, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Buffer(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Buffer(NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Buffer(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Buffer(NULL, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Buffer_Vector(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Buffer_Vector(NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Buffer_Vector(NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Buffer_Vector(NULL, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Encode_and_Print(NULL, (unsigned char *) data, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_and_Print(NULL, TU(data), 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Encode_and_Buffer(NULL, (unsigned char *) data, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_Segs_and_Print(NULL, &seg, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Seg_and_Print(NULL, &seg, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Encode_and_Buffer(NULL, TU(data), 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Encode_Segs_and_Buffer(NULL, &seg, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer(NULL, &seg, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Encode_and_Buffer_Vector(NULL, TU(data), 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer_Vector(NULL, data, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Encode_Segs_and_Buffer_Vector(NULL, &seg, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer_Vector(NULL, &seg, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Encode_File(NULL, filename), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(NULL, filename) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_File(NULL, filename), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(NULL, filename) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Encode_File_and_Print(NULL, filename, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Print(NULL, filename, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_File_and_Print(NULL, filename, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Print(NULL, filename, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_equal(ZBarcode_Encode_File_and_Buffer(NULL, filename, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(NULL, filename, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_File_and_Buffer(NULL, filename, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(NULL, filename, 0) != ZINT_ERROR_INVALID_DATA\n");
@ -749,17 +908,29 @@ static void test_bad_args(void) {
symbol = ZBarcode_Create(); symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
// NULL data/filename // NULL data/segs/filename
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode(symbol, NULL, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(symbol, NULL, 1) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode(symbol, NULL, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(symbol, NULL, 1) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode(symbol, NULL, 1) no errtxt\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode(symbol, NULL, 1) no errtxt\n");
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_Segs(symbol, NULL, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(symbol, NULL, 1) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_Segs(symbol, NULL, 1) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_and_Print(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_and_Print(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Print(symbol, NULL, 1, 0) no errtxt\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Print(symbol, NULL, 1, 0) no errtxt\n");
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0) no errtxt\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Buffer(symbol, NULL, 1, 0) no errtxt\n");
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_Segs_and_Buffer(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_Segs_and_Buffer(symbol, NULL, 1, 0) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_and_Buffer_Vector(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer_Vector(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Buffer_Vector(symbol, NULL, 1, 0) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, NULL, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, NULL, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, NULL, 1, 0) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_File(symbol, NULL), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(symbol, NULL) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_File(symbol, NULL), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(symbol, NULL) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File(symbol, NULL) no errtxt\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File(symbol, NULL) no errtxt\n");
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
@ -768,18 +939,33 @@ static void test_bad_args(void) {
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0) no errtxt\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Buffer(symbol, NULL, 0) no errtxt\n");
// Empty data/filename
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode(symbol, (unsigned char *) empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_File_and_Buffer_Vector(symbol, NULL, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer_Vector(symbol, NULL, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Buffer_Vector(symbol, NULL, 0) no errtxt\n");
// Empty data/segs/filename
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode(symbol, TU(empty), 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode(symbol, empty, 0) no errtxt\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode(symbol, empty, 0) no errtxt\n");
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_and_Print(symbol, (unsigned char *) empty, 0, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(symbol, &seg_empty, 1) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_Segs(symbol, &seg_empty, 1) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_and_Print(symbol, TU(empty), 0, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Print(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Print(symbol, empty, 0, 0) no errtxt\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Print(symbol, empty, 0, 0) no errtxt\n");
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_and_Buffer(symbol, (unsigned char *) empty, 0, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_and_Buffer(symbol, TU(empty), 0, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Buffer(symbol, empty, 0, 0) no errtxt\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Buffer(symbol, empty, 0, 0) no errtxt\n");
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_Segs_and_Buffer(symbol, &seg_empty, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer(symbol, &seg_empty, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_Segs_and_Buffer(symbol, &seg_empty, 1, 0) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_and_Buffer_Vector(symbol, TU(empty), 0, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_and_Buffer_Vector(symbol, empty, 0, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_and_Buffer_Vector(symbol, empty, 0, 0) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, &seg_empty, 1, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, &seg_empty, 1, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, &seg_empty, 1, 0) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_File(symbol, empty), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(symbol, empty) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_File(symbol, empty), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File(symbol, empty) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File(symbol, empty) no errtxt\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File(symbol, empty) no errtxt\n");
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
@ -788,11 +974,28 @@ static void test_bad_args(void) {
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Buffer(symbol, empty, 0) no errtxt\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Buffer(symbol, empty, 0) no errtxt\n");
// Data too big
symbol->errtxt[0] = '\0'; symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode(symbol, (unsigned char *) empty, ZINT_MAX_DATA_LEN + 1), ZINT_ERROR_TOO_LONG, "ZBarcode_Encode(symbol, empty, ZINT_MAX_DATA_LEN + 1) != ZINT_ERROR_TOO_LONG\n"); assert_equal(ZBarcode_Encode_File_and_Buffer_Vector(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer_Vector(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Buffer_Vector(symbol, empty, 0) no errtxt\n");
// Bad seg_count
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, ZINT_MAX_SEG_COUNT + 1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(symbol, &seg_empty, ZINT_MAX_SEG_COUNT + 1) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero((int) strlen(symbol->errtxt), "ZBarcode_Encode_Segs(symbol, &seg_empty, ZINT_MAX_SEG_COUNT + 1) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(symbol, &seg_empty, 0) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero((int) strlen(symbol->errtxt), "ZBarcode_Encode_Segs(symbol, &seg_empty, 0) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_Segs(symbol, &seg_empty, -1), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_Segs(symbol, &seg_empty, -1) != ZINT_ERROR_INVALID_DATA\n");
assert_nonzero((int) strlen(symbol->errtxt), "ZBarcode_Encode_Segs(symbol, &seg_empty, -1) no errtxt\n");
// Data/seg too big
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode(symbol, TU(empty), ZINT_MAX_DATA_LEN + 1), ZINT_ERROR_TOO_LONG, "ZBarcode_Encode(symbol, empty, ZINT_MAX_DATA_LEN + 1) != ZINT_ERROR_TOO_LONG\n");
assert_nonzero((int) strlen(symbol->errtxt), "ZBarcode_Encode(symbol, empty, ZINT_MAX_DATA_LEN + 1) no errtxt\n"); assert_nonzero((int) strlen(symbol->errtxt), "ZBarcode_Encode(symbol, empty, ZINT_MAX_DATA_LEN + 1) no errtxt\n");
symbol->errtxt[0] = '\0';
assert_equal(ZBarcode_Encode_Segs(symbol, &seg_too_long, 1), ZINT_ERROR_TOO_LONG, "ZBarcode_Encode_Segs(symbol, &seg_too_long, 1) != ZINT_ERROR_TOO_LONG\n");
assert_nonzero((int) strlen(symbol->errtxt), "ZBarcode_Encode_Segs(symbol, &seg_too_long, 1) no errtxt\n");
ZBarcode_Delete(symbol); ZBarcode_Delete(symbol);
@ -892,7 +1095,7 @@ static void test_strip_bom(void) {
strcpy(buf, data); strcpy(buf, data);
length = (int) strlen(buf); length = (int) strlen(buf);
strip_bom((unsigned char *) buf, &length); strip_bom(TU(buf), &length);
assert_equal(length, 1, "length %d != 1\n", length); assert_equal(length, 1, "length %d != 1\n", length);
assert_zero(buf[1], "buf[1] %d != 0\n", buf[1]); assert_zero(buf[1], "buf[1] %d != 0\n", buf[1]);
@ -900,7 +1103,7 @@ static void test_strip_bom(void) {
strcpy(buf, bom_only); strcpy(buf, bom_only);
length = (int) strlen(buf); length = (int) strlen(buf);
strip_bom((unsigned char *) buf, &length); strip_bom(TU(buf), &length);
assert_equal(length, 3, "BOM only length %d != 3\n", length); assert_equal(length, 3, "BOM only length %d != 3\n", length);
ret = strcmp(buf, bom_only); ret = strcmp(buf, bom_only);
assert_zero(ret, "BOM only strcmp ret %d != 0\n", ret); assert_zero(ret, "BOM only strcmp ret %d != 0\n", ret);
@ -922,7 +1125,7 @@ static void test_zero_outfile(void) {
assert_nonzero(symbol->outfile[0], "ZBarcode_Create() outfile zero\n"); assert_nonzero(symbol->outfile[0], "ZBarcode_Create() outfile zero\n");
symbol->outfile[0] = '\0'; symbol->outfile[0] = '\0';
ret = ZBarcode_Encode(symbol, (unsigned char *) data, 0); ret = ZBarcode_Encode(symbol, TU(data), 0);
assert_zero(ret, "ZBarcode_Encode(%s) ret %d != 0 (%s)\n", data, ret, symbol->errtxt); assert_zero(ret, "ZBarcode_Encode(%s) ret %d != 0 (%s)\n", data, ret, symbol->errtxt);
assert_zero(symbol->outfile[0], "ZBarcode_Encode() outfile non-zero\n"); assert_zero(symbol->outfile[0], "ZBarcode_Encode() outfile non-zero\n");
@ -960,7 +1163,7 @@ static void test_clear(void) {
// Raster // Raster
ret = ZBarcode_Encode(symbol, (unsigned char *) data, 0); ret = ZBarcode_Encode(symbol, TU(data), 0);
assert_zero(ret, "ZBarcode_Encode() ret %d != 0 (%s)\n", ret, symbol->errtxt); assert_zero(ret, "ZBarcode_Encode() ret %d != 0 (%s)\n", ret, symbol->errtxt);
assert_nonzero(symbol->rows, "ZBarcode_Encode() rows 0\n"); assert_nonzero(symbol->rows, "ZBarcode_Encode() rows 0\n");
@ -993,7 +1196,7 @@ static void test_clear(void) {
// Vector // Vector
ret = ZBarcode_Encode(symbol, (unsigned char *) data, 0); ret = ZBarcode_Encode(symbol, TU(data), 0);
assert_zero(ret, "ZBarcode_Encode() ret %d != 0 (%s)\n", ret, symbol->errtxt); assert_zero(ret, "ZBarcode_Encode() ret %d != 0 (%s)\n", ret, symbol->errtxt);
assert_nonzero(symbol->rows, "ZBarcode_Encode() rows 0\n"); assert_nonzero(symbol->rows, "ZBarcode_Encode() rows 0\n");
@ -1035,6 +1238,7 @@ int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_checks", test_checks, 1, 0, 1 }, { "test_checks", test_checks, 1, 0, 1 },
{ "test_checks_segs", test_checks_segs, 1, 0, 1 },
{ "test_symbologies", test_symbologies, 0, 0, 0 }, { "test_symbologies", test_symbologies, 0, 0, 0 },
{ "test_input_mode", test_input_mode, 1, 0, 1 }, { "test_input_mode", test_input_mode, 1, 0, 1 },
{ "test_escape_char_process", test_escape_char_process, 1, 1, 1 }, { "test_escape_char_process", test_escape_char_process, 1, 1, 1 },
@ -1044,6 +1248,8 @@ int main(int argc, char *argv[]) {
{ "test_encode_file_too_large", test_encode_file_too_large, 0, 0, 0 }, { "test_encode_file_too_large", test_encode_file_too_large, 0, 0, 0 },
{ "test_encode_file_unreadable", test_encode_file_unreadable, 0, 0, 0 }, { "test_encode_file_unreadable", test_encode_file_unreadable, 0, 0, 0 },
{ "test_encode_file_directory", test_encode_file_directory, 0, 0, 0 }, { "test_encode_file_directory", test_encode_file_directory, 0, 0, 0 },
{ "test_encode_file", test_encode_file, 0, 0, 0 },
{ "test_encode_print_outfile_directory", test_encode_print_outfile_directory, 0, 0, 0 },
{ "test_bad_args", test_bad_args, 0, 0, 0 }, { "test_bad_args", test_bad_args, 0, 0, 0 },
{ "test_valid_id", test_valid_id, 0, 0, 0 }, { "test_valid_id", test_valid_id, 0, 0, 0 },
{ "test_error_tag", test_error_tag, 1, 0, 0 }, { "test_error_tag", test_error_tag, 1, 0, 0 },
@ -1058,3 +1264,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -128,65 +128,72 @@ static void test_input(int index, int generate, int debug) {
int ret; int ret;
int expected_width; int expected_width;
char *expected; char *expected;
int bwipp_cmp;
int zxingcpp_cmp;
char *comment; char *comment;
}; };
struct item data[] = { struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 01 21 21 21 21 21 21 21 21 08 0E 19 2B 20 0C 24 06 32 1C 21 21 21 21 21 21 21 21", "" }, /* 0*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 01 21 21 21 21 21 21 21 21 08 0E 19 2B 20 0C 24 06 32 1C 21 21 21 21 21 21 21 21", 1, 1, "" },
/* 1*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", "" }, /* 1*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", 1, 1, "" },
/* 2*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "A123456", ZINT_ERROR_INVALID_DATA, 0, "Error 555: Non-numeric postcode in Primary Message", "" }, /* 2*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "A123456", ZINT_ERROR_INVALID_DATA, 0, "Error 555: Non-numeric postcode in Primary Message", 1, 1, "" },
/* 3*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "1123456", 0, 30, "(144) 12 00 00 00 00 10 30 1E 20 1C 1A 3D 1C 0D 1B 15 3C 17 3C 08 01 21 21 21 21 21 21 21", "1-digit postcode" }, /* 3*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "1123456", 0, 30, "(144) 12 00 00 00 00 10 30 1E 20 1C 1A 3D 1C 0D 1B 15 3C 17 3C 08 01 21 21 21 21 21 21 21", 0, 1, "1-digit postcode" },
/* 4*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "1 123456", 0, 30, "(144) 12 00 00 00 00 10 30 1E 20 1C 1A 3D 1C 0D 1B 15 3C 17 3C 08 01 21 21 21 21 21 21 21", "1-digit postcode" }, /* 4*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "1 123456", 0, 30, "(144) 12 00 00 00 00 10 30 1E 20 1C 1A 3D 1C 0D 1B 15 3C 17 3C 08 01 21 21 21 21 21 21 21", 0, 0, "1-digit postcode; ZXing-C++ test can't handle space" },
/* 5*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "123456789123456", 0, 30, "(144) 12 05 0D 2F 35 11 32 1E 20 1C 0D 1D 3B 12 22 3F 30 14 23 1A 01 21 21 21 21 21 21 21", "9-digit postcode" }, /* 5*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "123456789123456", 0, 30, "(144) 12 05 0D 2F 35 11 32 1E 20 1C 0D 1D 3B 12 22 3F 30 14 23 1A 01 21 21 21 21 21 21 21", 0, 1, "9-digit postcode" },
/* 6*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "1234567890123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", "10-digit postcode" }, /* 6*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "1234567890123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", 1, 1, "10-digit postcode" },
/* 7*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "1123456", 0, 30, "(144) 12 00 00 00 00 10 30 1E 20 1C 1A 3D 1C 0D 1B 15 3C 17 3C 08 01 21 21 21 21 21 21 21", "1-digit postcode" }, /* 7*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "1123456", 0, 30, "(144) 12 00 00 00 00 10 30 1E 20 1C 1A 3D 1C 0D 1B 15 3C 17 3C 08 01 21 21 21 21 21 21 21", 0, 1, "1-digit postcode" },
/* 8*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "123456789123456", 0, 30, "(144) 12 05 0D 2F 35 11 32 1E 20 1C 0D 1D 3B 12 22 3F 30 14 23 1A 01 21 21 21 21 21 21 21", "9-digit postcode" }, /* 8*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "123456789123456", 0, 30, "(144) 12 05 0D 2F 35 11 32 1E 20 1C 0D 1D 3B 12 22 3F 30 14 23 1A 01 21 21 21 21 21 21 21", 0, 1, "9-digit postcode" },
/* 9*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "1234567890123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", "10-digit postcode" }, /* 9*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "1234567890123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", 1, 1, "10-digit postcode" },
/* 10*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", "0-digit postcode" }, /* 10*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", 1, 1, "0-digit postcode" },
/* 11*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "12345678123456", 0, 30, "(144) 22 13 21 31 0B 00 32 1E 20 1C 04 14 07 30 10 07 08 28 1D 09 01 21 21 21 21 21 21 21", "8-digit postcode" }, /* 11*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "12345678123456", 0, 30, "(144) 22 13 21 31 0B 00 32 1E 20 1C 04 14 07 30 10 07 08 28 1D 09 01 21 21 21 21 21 21 21", 0, 1, "8-digit postcode" },
/* 12*/ { UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", "" }, /* 12*/ { UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Invalid length for Primary Message", 1, 1, "" },
/* 13*/ { UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, "A", -1, "A123456", 0, 30, "(144) 03 08 08 08 08 18 30 1E 20 1C 22 35 1C 0F 02 1A 26 04 10 31 01 21 21 21 21 21 21 21", "1-alphanumeric postcode" }, /* 13*/ { UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, "A", -1, "A123456", 0, 30, "(144) 03 08 08 08 08 18 30 1E 20 1C 22 35 1C 0F 02 1A 26 04 10 31 01 21 21 21 21 21 21 21", 1, 1, "1-alphanumeric postcode" },
/* 14*/ { UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, "A", -1, "1123456", 0, 30, "(144) 03 08 08 08 08 18 3C 1E 20 1C 13 37 07 2C 26 2D 18 29 3F 2C 01 21 21 21 21 21 21 21", "1-digit postcode" }, /* 14*/ { UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, "A", -1, "1123456", 0, 30, "(144) 03 08 08 08 08 18 3C 1E 20 1C 13 37 07 2C 26 2D 18 29 3F 2C 01 21 21 21 21 21 21 21", 0, 0, "1-digit postcode; ZXing-C++ test can't handle padding" },
/* 15*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "A123456", 0, 30, "(144) 03 08 08 08 08 18 30 1E 20 1C 22 35 1C 0F 02 1A 26 04 10 31 01 21 21 21 21 21 21 21", "1-alphanumeric postcode" }, /* 15*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "A123456", 0, 30, "(144) 03 08 08 08 08 18 30 1E 20 1C 22 35 1C 0F 02 1A 26 04 10 31 01 21 21 21 21 21 21 21", 1, 1, "1-alphanumeric postcode" },
/* 16*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "ABCDEF123456", 0, 30, "(144) 23 11 01 31 20 10 30 1E 20 1C 3C 1D 22 03 19 15 0F 20 0F 2A 01 21 21 21 21 21 21 21", "6-alphanumeric postcode" }, /* 16*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "ABCDEF123456", 0, 30, "(144) 23 11 01 31 20 10 30 1E 20 1C 3C 1D 22 03 19 15 0F 20 0F 2A 01 21 21 21 21 21 21 21", 1, 1, "6-alphanumeric postcode" },
/* 17*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "ABCDEFG123456", 0, 30, "(144) 23 11 01 31 20 10 30 1E 20 1C 3C 1D 22 03 19 15 0F 20 0F 2A 01 21 21 21 21 21 21 21", "7-alphanumeric postcode truncated" }, /* 17*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "ABCDEFG123456", 0, 30, "(144) 23 11 01 31 20 10 30 1E 20 1C 3C 1D 22 03 19 15 0F 20 0F 2A 01 21 21 21 21 21 21 21", 1, 0, "7-alphanumeric postcode truncated; ZXing-C++ test can't handle truncation" },
/* 18*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "ABCDE123456", 0, 30, "(144) 03 18 01 31 20 10 30 1E 20 1C 0F 38 38 1A 39 10 2F 37 22 12 01 21 21 21 21 21 21 21", "5-alphanumeric postcode" }, /* 18*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "ABCDE123456", 0, 30, "(144) 03 18 01 31 20 10 30 1E 20 1C 0F 38 38 1A 39 10 2F 37 22 12 01 21 21 21 21 21 21 21", 1, 1, "5-alphanumeric postcode" },
/* 19*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "AAAAAA 840001", 0, 30, "(144) 13 10 10 10 10 10 00 12 07 00 17 36 2E 38 04 29 16 0D 27 16 01 21 21 21 21 21 21 21", "6-alphanumeric postcode with padding" }, /* 19*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "AAAAAA 840001", 0, 30, "(144) 13 10 10 10 10 10 00 12 07 00 17 36 2E 38 04 29 16 0D 27 16 01 21 21 21 21 21 21 21", 1, 0, "6-alphanumeric postcode with padding; ZXing-C++ test can't handle padding" },
/* 20*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "AAAAA A840001", 0, 30, "(144) 03 18 10 10 10 10 00 12 07 00 19 07 29 31 26 01 23 2C 2E 07 01 21 21 21 21 21 21 21", "7-alphanumeric with embedded padding truncated" }, /* 20*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "AAAAA A840001", 0, 30, "(144) 03 18 10 10 10 10 00 12 07 00 19 07 29 31 26 01 23 2C 2E 07 01 21 21 21 21 21 21 21", 1, 0, "7-alphanumeric with embedded padding truncated; ZXing-C++ test can't handle truncation" },
/* 21*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "AA\015AAA840001", ZINT_ERROR_INVALID_DATA, 0, "Error 556: Invalid character in postcode in Primary Message", "Alphanumeric postcode with CR" }, /* 21*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "AA\015AAA840001", ZINT_ERROR_INVALID_DATA, 0, "Error 556: Invalid character in postcode in Primary Message", 1, 1, "Alphanumeric postcode with CR" },
/* 22*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "A#%-/A840001", 0, 30, "(144) 13 30 1B 1B 39 18 00 12 07 00 3F 1E 25 07 2A 1E 14 3C 28 2D 01 21 21 21 21 21 21 21", "Alphanumeric postcode with non-control Code A chars" }, /* 22*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "A#%-/A840001", 0, 30, "(144) 13 30 1B 1B 39 18 00 12 07 00 3F 1E 25 07 2A 1E 14 3C 28 2D 01 21 21 21 21 21 21 21", 1, 1, "Alphanumeric postcode with non-control Code A chars" },
/* 23*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "1A23456", ZINT_ERROR_INVALID_DATA, 0, "Error 552: Non-numeric country code or service class in Primary Message", "Non-numeric country code" }, /* 23*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "1A23456", ZINT_ERROR_INVALID_DATA, 0, "Error 552: Non-numeric country code or service class in Primary Message", 1, 1, "Non-numeric country code" },
/* 24*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "12345678912345A", ZINT_ERROR_INVALID_DATA, 0, "Error 552: Non-numeric country code or service class in Primary Message", "Non-numeric service class" }, /* 24*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "12345678912345A", ZINT_ERROR_INVALID_DATA, 0, "Error 552: Non-numeric country code or service class in Primary Message", 1, 1, "Non-numeric service class" },
/* 25*/ { UNICODE_MODE, -1, 0, -1, { 0, 0, "" }, "A", -1, "123456789123456", 0, 30, "(144) 12 05 0D 2F 35 11 32 1E 20 1C 0D 1D 3B 12 22 3F 30 14 23 1A 01 21 21 21 21 21 21 21", "Auto-determine mode 2" }, /* 25*/ { UNICODE_MODE, -1, 0, -1, { 0, 0, "" }, "A", -1, "123456789123456", 0, 30, "(144) 12 05 0D 2F 35 11 32 1E 20 1C 0D 1D 3B 12 22 3F 30 14 23 1A 01 21 21 21 21 21 21 21", 0, 1, "Auto-determine mode 2" },
/* 26*/ { UNICODE_MODE, -1, 0, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 554: Primary Message empty", "Auto-determine mode 2/3 requires primary message" }, /* 26*/ { UNICODE_MODE, -1, 0, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 554: Primary Message empty", 1, 1, "Auto-determine mode 2/3 requires primary message" },
/* 27*/ { UNICODE_MODE, -1, 0, -1, { 0, 0, "" }, "A", -1, "A23456123456", 0, 30, "(144) 23 1D 0D 3D 2C 1C 30 1E 20 1C 24 35 30 31 2A 0D 17 14 16 3D 01 21 21 21 21 21 21 21", "Auto-determine mode 3" }, /* 27*/ { UNICODE_MODE, -1, 0, -1, { 0, 0, "" }, "A", -1, "A23456123456", 0, 30, "(144) 23 1D 0D 3D 2C 1C 30 1E 20 1C 24 35 30 31 2A 0D 17 14 16 3D 01 21 21 21 21 21 21 21", 1, 1, "Auto-determine mode 3" },
/* 28*/ { UNICODE_MODE, -1, -1, 100, { 0, 0, "" }, "A", -1, "123456123456", 0, 30, "(144) 02 10 22 07 00 20 31 1E 20 1C 0E 29 13 1B 0D 26 36 25 3B 22 3B 2A 29 3B 28 1E 30 31", "SCM prefix version" }, /* 28*/ { UNICODE_MODE, -1, -1, 100, { 0, 0, "" }, "A", -1, "123456123456", 0, 30, "(144) 02 10 22 07 00 20 31 1E 20 1C 0E 29 13 1B 0D 26 36 25 3B 22 3B 2A 29 3B 28 1E 30 31", 0, 1, "SCM prefix version" },
/* 29*/ { UNICODE_MODE, -1, -1, 101, { 0, 0, "" }, "A", -1, "123456123456", ZINT_ERROR_INVALID_OPTION, 0, "Error 557: Invalid SCM prefix version", "SCM prefix version" }, /* 29*/ { UNICODE_MODE, -1, -1, 101, { 0, 0, "" }, "A", -1, "123456123456", ZINT_ERROR_INVALID_OPTION, 0, "Error 557: Invalid SCM prefix version", 1, 1, "SCM prefix version" },
/* 30*/ { UNICODE_MODE, 3, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 03 01 21 21 21 21 21 21 2F 14 23 21 05 24 27 00 24 0C 21 21 21 21 21 21 21 21", "" }, /* 30*/ { UNICODE_MODE, 3, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 03 01 21 21 21 21 21 21 2F 14 23 21 05 24 27 00 24 0C 21 21 21 21 21 21 21 21", 1, 1, "" },
/* 31*/ { UNICODE_MODE, 31, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 1F 01 21 21 21 21 21 21 00 2F 0E 09 39 3B 24 1A 21 05 21 21 21 21 21 21 21 21", "ECI 0x1F" }, /* 31*/ { UNICODE_MODE, 31, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 1F 01 21 21 21 21 21 21 00 2F 0E 09 39 3B 24 1A 21 05 21 21 21 21 21 21 21 21", 1, 1, "ECI 0x1F" },
/* 32*/ { UNICODE_MODE, 32, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 20 20 01 21 21 21 21 21 3D 15 0F 30 0D 22 24 35 22 06 21 21 21 21 21 21 21 21", "ECI 0x20" }, /* 32*/ { UNICODE_MODE, 32, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 20 20 01 21 21 21 21 21 3D 15 0F 30 0D 22 24 35 22 06 21 21 21 21 21 21 21 21", 1, 1, "ECI 0x20" },
/* 33*/ { UNICODE_MODE, 1023, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 2F 3F 01 21 21 21 21 21 2E 27 23 1D 35 19 21 04 3A 26 21 21 21 21 21 21 21 21", "ECI 0x3FF" }, /* 33*/ { UNICODE_MODE, 1023, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 2F 3F 01 21 21 21 21 21 2E 27 23 1D 35 19 21 04 3A 26 21 21 21 21 21 21 21 21", 1, 1, "ECI 0x3FF" },
/* 34*/ { UNICODE_MODE, 1024, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 30 10 00 01 21 21 21 21 11 2F 15 10 1D 29 06 35 14 2B 21 21 21 21 21 21 21 21", "ECI 0x400" }, /* 34*/ { UNICODE_MODE, 1024, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 30 10 00 01 21 21 21 21 11 2F 15 10 1D 29 06 35 14 2B 21 21 21 21 21 21 21 21", 1, 1, "ECI 0x400" },
/* 35*/ { UNICODE_MODE, 32767, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 37 3F 3F 01 21 21 21 21 3E 15 12 01 07 30 39 27 04 2B 21 21 21 21 21 21 21 21", "ECI 0x7FFF" }, /* 35*/ { UNICODE_MODE, 32767, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 37 3F 3F 01 21 21 21 21 3E 15 12 01 07 30 39 27 04 2B 21 21 21 21 21 21 21 21", 1, 1, "ECI 0x7FFF" },
/* 36*/ { UNICODE_MODE, 32768, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 38 08 00 00 01 21 21 21 10 30 3A 04 26 23 0E 21 3D 0F 21 21 21 21 21 21 21 21", "ECI 0x8000" }, /* 36*/ { UNICODE_MODE, 32768, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 38 08 00 00 01 21 21 21 10 30 3A 04 26 23 0E 21 3D 0F 21 21 21 21 21 21 21 21", 1, 1, "ECI 0x8000" },
/* 37*/ { UNICODE_MODE, 65535, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 38 0F 3F 3F 01 21 21 21 1C 0E 1D 39 3B 0D 38 25 00 30 21 21 21 21 21 21 21 21", "ECI 0xFFFF" }, /* 37*/ { UNICODE_MODE, 65535, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 38 0F 3F 3F 01 21 21 21 1C 0E 1D 39 3B 0D 38 25 00 30 21 21 21 21 21 21 21 21", 1, 1, "ECI 0xFFFF" },
/* 38*/ { UNICODE_MODE, 65536, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 38 10 00 00 01 21 21 21 2B 1F 24 06 38 2E 17 1B 10 2F 21 21 21 21 21 21 21 21", "ECI 0x10000" }, /* 38*/ { UNICODE_MODE, 65536, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 38 10 00 00 01 21 21 21 2B 1F 24 06 38 2E 17 1B 10 2F 21 21 21 21 21 21 21 21", 1, 1, "ECI 0x10000" },
/* 39*/ { UNICODE_MODE, 131071, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 38 1F 3F 3F 01 21 21 21 0F 05 09 04 2F 3A 17 09 36 31 21 21 21 21 21 21 21 21", "ECI 0x1FFFF" }, /* 39*/ { UNICODE_MODE, 131071, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 38 1F 3F 3F 01 21 21 21 0F 05 09 04 2F 3A 17 09 36 31 21 21 21 21 21 21 21 21", 1, 1, "ECI 0x1FFFF" },
/* 40*/ { UNICODE_MODE, 999999, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 3B 34 08 3F 01 21 21 21 26 3B 2B 23 08 17 32 05 26 35 21 21 21 21 21 21 21 21", "Max ECI" }, /* 40*/ { UNICODE_MODE, 999999, -1, -1, { 0, 0, "" }, "A", -1, "", 0, 30, "(144) 04 1B 3B 34 08 3F 01 21 21 21 26 3B 2B 23 08 17 32 05 26 35 21 21 21 21 21 21 21 21", 1, 1, "Max ECI" },
/* 41*/ { UNICODE_MODE, -1, 1, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 550: Invalid MaxiCode Mode", "" }, /* 41*/ { UNICODE_MODE, -1, 1, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 550: Invalid MaxiCode Mode", 1, 1, "" },
/* 42*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "\015", -1, "", 0, 30, "(144) 04 00 21 21 21 21 21 21 21 21 37 32 10 01 24 1B 10 11 38 0C 21 21 21 21 21 21 21 21", "" }, /* 42*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "\015", -1, "", 0, 30, "(144) 04 00 21 21 21 21 21 21 21 21 37 32 10 01 24 1B 10 11 38 0C 21 21 21 21 21 21 21 21", 1, 0, "ZXing-C++ test can't handle LF" },
/* 43*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "\001\034\001\035\001\036\001a:b", -1, "", 0, 30, "(144) 04 3E 3E 01 20 01 21 01 22 01 27 0B 35 01 08 0D 16 02 17 1A 3F 01 33 02 21 21 21 21", "" }, /* 43*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "\001\034\001\035\001\036\001a:b", -1, "", 0, 30, "(144) 04 3E 3E 01 20 01 21 01 22 01 27 0B 35 01 08 0D 16 02 17 1A 3F 01 33 02 21 21 21 21", 1, 1, "" },
/* 44*/ { UNICODE_MODE, -1, -1, -1, { 1, 2, "" }, "A", -1, "", 0, 30, "(144) 04 21 01 01 21 21 21 21 21 21 09 0B 26 03 37 0E 25 27 07 1E 21 21 21 21 21 21 21 21", "" }, /* 44*/ { UNICODE_MODE, -1, -1, -1, { 1, 2, "" }, "A", -1, "", 0, 30, "(144) 04 21 01 01 21 21 21 21 21 21 09 0B 26 03 37 0E 25 27 07 1E 21 21 21 21 21 21 21 21", 1, 1, "" },
/* 45*/ { UNICODE_MODE, -1, -1, -1, { 0, 2, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 559: Structured Append index out of range (1-2)", "" }, /* 45*/ { UNICODE_MODE, -1, -1, -1, { 0, 2, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 559: Structured Append index out of range (1-2)", 1, 1, "" },
/* 46*/ { UNICODE_MODE, -1, -1, -1, { 1, 1, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 558: Structured Append count out of range (2-8)", "" }, /* 46*/ { UNICODE_MODE, -1, -1, -1, { 1, 1, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 558: Structured Append count out of range (2-8)", 1, 1, "" },
/* 47*/ { UNICODE_MODE, -1, -1, -1, { 1, 9, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 558: Structured Append count out of range (2-8)", "" }, /* 47*/ { UNICODE_MODE, -1, -1, -1, { 1, 9, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 558: Structured Append count out of range (2-8)", 1, 1, "" },
/* 48*/ { UNICODE_MODE, -1, -1, -1, { 3, 2, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 559: Structured Append index out of range (1-2)", "" }, /* 48*/ { UNICODE_MODE, -1, -1, -1, { 3, 2, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 559: Structured Append index out of range (1-2)", 1, 1, "" },
/* 49*/ { UNICODE_MODE, -1, -1, -1, { 1, 2, "A" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 549: Structured Append ID not available for MaxiCode", "" }, /* 49*/ { UNICODE_MODE, -1, -1, -1, { 1, 2, "A" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 549: Structured Append ID not available for MaxiCode", 1, 1, "" },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
struct zint_symbol *symbol; struct zint_symbol *symbol;
char escaped[1024]; char escaped[1024];
char cmp_buf[32768];
char cmp_msg[1024];
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); // Only do ZXing-C++ test if asked, too slow otherwise
testStart("test_input"); testStart("test_input");
@ -209,16 +216,48 @@ static void test_input(int index, int generate, int debug) {
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) { if (generate) {
printf(" /*%3d*/ { %s, %d, %d, %d, { %d, %d, \"%s\" }, \"%s\", %d, \"%s\", %s, %d, \"%s\", \"%s\" },\n", printf(" /*%3d*/ { %s, %d, %d, %d, { %d, %d, \"%s\" }, \"%s\", %d, \"%s\", %s, %d, \"%s\", %d, %d, \"%s\" },\n",
i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, data[i].option_2, i, testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, data[i].option_2,
data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, data[i].structapp.index, data[i].structapp.count, data[i].structapp.id,
testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length, data[i].primary, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), data[i].length, data[i].primary,
testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].comment); testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].bwipp_cmp, data[i].zxingcpp_cmp, data[i].comment);
} else { } else {
if (ret < ZINT_ERROR) { if (ret < ZINT_ERROR) {
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data);
} }
assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected);
if (ret < ZINT_ERROR) {
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
char modules_dump[33 * 33 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, symbol->primary, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, modules_dump);
}
}
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) {
if (!data[i].zxingcpp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not ZXing-C++ compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
int cmp_len, ret_len;
char modules_dump[33 * 33 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, symbol->primary, escaped, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %.*s\nexpected: %.*s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped);
}
}
}
} }
ZBarcode_Delete(symbol); ZBarcode_Delete(symbol);
@ -928,7 +967,7 @@ static void test_encode(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, data[i].primary, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, data[i].primary, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
@ -956,6 +995,437 @@ static void test_encode(int index, int generate, int debug) {
testFinish(); testFinish();
} }
static void test_encode_segs(int index, int generate, int debug) {
struct item {
int input_mode;
int option_1;
int option_2;
struct zint_structapp structapp;
struct zint_seg segs[3];
char *primary;
int ret;
int expected_rows;
int expected_width;
int bwipp_cmp;
char *comment;
char *expected;
};
struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, "", 0, 33, 30, 1, "ISO 16023:2000 4.15.4 example",
"010101010101010101010101010111"
"000000000000000000000000000000"
"101010101010101010101010101010"
"010101010101010101010101010110"
"000000000000000000000000000001"
"101010101010101010101010101000"
"010101010101010101010101010110"
"000000000000000000000000000010"
"101010101010101010101010101001"
"010101010011010100000101010100"
"000000000011111110001000000000"
"101010101110000000101010101010"
"010101110110000000110101010110"
"000000110000000000100100000000"
"101010011000000000010010101000"
"010101111000000000001001010110"
"000000001000000000001000000010"
"101010001000000000001110101000"
"010101111100000000000001010111"
"000000010000000000110100000010"
"101010000110000000010110101011"
"010101011010000001110001010100"
"000000000010110101000100000011"
"101010100111110001001110101010"
"010101010101010101011111010111"
"000000000000000000001111010110"
"101010101010101010100000000010"
"111111110000111100000101000000"
"010110101111000011110101010100"
"101010100000010101011111101010"
"111101011010000011110101101010"
"010110101111010110101010111100"
"010100000000010110101010010100"
},
/* 1*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 0 }, { TU(""), 0, 0 } }, "", ZINT_WARN_USES_ECI, 33, 30, 1, "ISO 16023:2000 4.15.4 example auto-ECI",
"010101010101010101010101010111"
"000000000000000000000000000000"
"101010101010101010101010101010"
"010101010101010101010101010110"
"000000000000000000000000000001"
"101010101010101010101010101000"
"010101010101010101010101010110"
"000000000000000000000000000010"
"101010101010101010101010101001"
"010101010011010100000101010100"
"000000000011111110001000000000"
"101010101110000000101010101010"
"010101110110000000110101010110"
"000000110000000000100100000000"
"101010011000000000010010101000"
"010101111000000000001001010110"
"000000001000000000001000000010"
"101010001000000000001110101000"
"010101111100000000000001010111"
"000000010000000000110100000010"
"101010000110000000010110101011"
"010101011010000001110001010100"
"000000000010110101000100000011"
"101010100111110001001110101010"
"010101010101010101011111010111"
"000000000000000000001111010110"
"101010101010101010100000000010"
"111111110000111100000101000000"
"010110101111000011110101010100"
"101010100000010101011111101010"
"111101011010000011110101101010"
"010110101111010110101010111100"
"010100000000010110101010010100"
},
/* 2*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 7 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, "", 0, 33, 30, 1, "ISO 16023:2000 4.15.4 example inverted",
"010101010101010101010101010111"
"000000000000000000000000000000"
"101010101010101010101010101010"
"010101010101010101010101010110"
"000000000000000000000000000001"
"101010101010101010101010101000"
"010101010101010101010101010110"
"000000000000000000000000000010"
"101010101010101010101010101001"
"010101010011000000110101010100"
"000000000111100010011000000000"
"101010100110000000011010101010"
"010101010110000000110101010110"
"000000000000000000111100000000"
"101010101000000000001110101000"
"010101110000000000001101010110"
"000000001000000000001000000010"
"101010111000000000001110101000"
"010101101000000000010101010111"
"000000100100000000111000000010"
"101010011010000000110110101011"
"010101010110000001111001010100"
"000000001010101111101100000011"
"101010101110010101110010101010"
"010101010101010101011111010111"
"000000000000000000001111010110"
"101010101010101010100000000010"
"111111110000111100000101000000"
"010110101111000011110101010100"
"101010100000010101011111101010"
"111101011010000011110101101010"
"010110101111010110101010111100"
"010100000000010110101010010100"
},
/* 3*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, "", ZINT_WARN_USES_ECI, 33, 30, 1, "ISO 16023:2000 4.15.4 example inverted auto-ECI",
"010101010101010101010101010111"
"000000000000000000000000000000"
"101010101010101010101010101010"
"010101010101010101010101010110"
"000000000000000000000000000001"
"101010101010101010101010101000"
"010101010101010101010101010110"
"000000000000000000000000000010"
"101010101010101010101010101001"
"010101010011000000110101010100"
"000000000111100010011000000000"
"101010100110000000011010101010"
"010101010110000000110101010110"
"000000000000000000111100000000"
"101010101000000000001110101000"
"010101110000000000001101010110"
"000000001000000000001000000010"
"101010111000000000001110101000"
"010101101000000000010101010111"
"000000100100000000111000000010"
"101010011010000000110110101011"
"010101010110000001111001010100"
"000000001010101111101100000011"
"101010101110010101110010101010"
"010101010101010101011111010111"
"000000000000000000001111010110"
"101010101010101010100000000010"
"111111110000111100000101000000"
"010110101111000011110101010100"
"101010100000010101011111101010"
"111101011010000011110101101010"
"010110101111010110101010111100"
"010100000000010110101010010100"
},
/* 4*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Pixel 4a 128 GB:$439.97"), -1, 3 }, { TU("Pixel 4a 128 GB:¥3149.79"), -1, 29 }, { TU("Pixel 4a 128 GB:444,90 €"), -1, 17 } }, "", 0, 33, 30, 0, "AIM ITS/04-023:2022 Annex A example (shortened)",
"011100110111111101000011011111"
"001000110000000100100001101000"
"000010110010010000110101000010"
"110000100011101010111101111100"
"011110010111001101100111010010"
"000010001011001011111001101100"
"011100110111111101000011110111"
"001000110000000100100001111000"
"000010110010010000110101011110"
"011111110011001000000111011100"
"110110000101000110011000011110"
"011000100000000000101011000100"
"111110101110000000011110101100"
"100101100100000000001100001100"
"111011100000000000000110001101"
"011100010000000000000000100010"
"000111001000000000001010010110"
"000000110000000000001010001010"
"110011010100000000011001111111"
"100011101100000000111000000000"
"001011100010000000011000100100"
"111111000010000001111000011110"
"101001000110101011100010000110"
"000001010110011101000111000010"
"110111110111010101010010100001"
"101101000011010000000001011000"
"000010000001001010100100111001"
"101010010101100010111000111000"
"000111001101011101010101101000"
"110111101110001101100111010100"
"101000010100101000011010011110"
"100000110001100001110001101000"
"010000101110100111010101100101"
},
/* 5*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("$439.97"), -1, 3 }, { TU("¥3149.79"), -1, 29 }, { TU("444,90 €"), -1, 17 } }, "", 0, 33, 30, 1, "AIM ITS/04-023:2022 Annex A example price only",
"101011011101111111110111111011"
"011111101101000010011110010100"
"111001110100111000100111101110"
"010101010111011111011111111010"
"000000000111000001111010100011"
"101010100001000010000000001010"
"010101010101010101010101010111"
"000000000000000000000000000010"
"101010101010101010101010101000"
"010101010111001100100001010100"
"000000001001000110011100000010"
"101010100010000000011110101010"
"010101011110000000001101010100"
"000000101000000000010000000000"
"101010001100000000000110101000"
"010101111000000000001001010110"
"000000101000000000001000000010"
"101010011000000000001110101010"
"010101110100000000001101010101"
"000000001000000000011000000000"
"101010010010000000101010101000"
"010101010100000001111101010100"
"000000000110101111101000000011"
"101010100110011101000110101000"
"010101010101010101011001001110"
"000000000000000000000000000100"
"101010101010101010100101100101"
"001001110101111010110011011100"
"001100001100101000100101110110"
"011101100101000100110011000100"
"000100101101010011010011101111"
"010111011011100000011000101000"
"001111010010000100010110011110"
},
/* 6*/ { DATA_MODE, -1, -1, { 0, 0, "" }, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, "", 0, 33, 30, 1, "Standard example + extra seg, data mode",
"010101010101010101010101010111"
"110000000000000000000000000010"
"111010101010101010101010101011"
"010101010101010101010101010110"
"000000000000000000000000000000"
"101010101010101010101010101000"
"010101010101010101010101010110"
"000000000000000000000000000010"
"101010101010101010101010101001"
"010101010011010100111101010110"
"000000000011111110000100000010"
"101010100010000000111010101010"
"010101001110000000110001010100"
"000000001100000000101000000000"
"101010000100000000010010101000"
"010101011000000000001101010110"
"000000001000000000001000000010"
"101010001000000000001010101000"
"010101001000000000000001010101"
"000000111100000000110100000000"
"101010011010000000011010101000"
"010101011010000001010101010100"
"000000001010110101000100000011"
"101010101111110001011110101010"
"010101010101010101010011100111"
"000000000000000000000111010110"
"101010101010101010100100000010"
"110011010010110000000111001110"
"011010011101001011010111010101"
"101010000011010101001111100110"
"001110010010000001111001111010"
"000111101111000100101110001100"
"000100001000100111100110010100"
},
/* 7*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("αβ"), -1, 0 }, { TU("ÿ"), -1, 0 }, { TU("貫やぐ禁"), -1, 20 } }, "", ZINT_WARN_USES_ECI, 33, 30, 1, "Auto-ECI",
"011010110111101111110011111111"
"100110111111001100110011001110"
"001100101100100001100100010111"
"010101010101010101101111110100"
"000000000000000000101100111110"
"101010101010101010010000100110"
"010101010101010101010101010111"
"000000000000000000000000000000"
"101010101010101010101010101000"
"010101010111000000110101010100"
"000000000011010010001100000010"
"101010101100000000111010101010"
"010101101100000000110101010110"
"000000011100000000011100000000"
"101010001000000000011110101000"
"010101011000000000001101010110"
"000000001000000000001000000011"
"101010001000000000001010101010"
"010101010000000000001001010100"
"000000010100000000000000000000"
"101010110010000000110110101000"
"010101010010000001110101010110"
"000000000010101011100100000001"
"101010101011010001100010101000"
"010101010101010101011010000110"
"000000000000000000001001001100"
"101010101010101010100101111110"
"110111000101110010100001011100"
"111110011010010010000011001011"
"111000110110111111111000010100"
"101001001111001011110110101001"
"101010010100011001011101100110"
"111011110000111001101101111000"
},
/* 8*/ { UNICODE_MODE, -1, -1, { 1, 2, "" }, { { TU("αβ"), -1, 9 }, { TU("ÿ"), -1, 3 }, { TU("貫やぐ禁"), -1, 20 } }, "", 0, 33, 30, 1, "Structured Append",
"001101101011011110111111001111"
"001110011011111100110011001110"
"111000110010110010000110010011"
"010101010101011011111101111110"
"000000000000001011001111110011"
"101010101010100100001001010100"
"010101010101010101010101010111"
"000000000000000000000000000010"
"101010101010101010101010101011"
"010101010011000000111101010110"
"000000001101000010010000000011"
"101010101010000000100010101000"
"010101111000000000111101010111"
"000000000100000000100000000000"
"101010001100000000011010101010"
"010101011000000000000101010110"
"000000001000000000001000000000"
"101010001000000000001110101000"
"010101100000000000011001010100"
"000000111000000000001000000010"
"101010100110000000010110101011"
"010101011010000000001001010110"
"000000001010011011100000000010"
"101010101011000001000010101000"
"010101010101010101011111010011"
"000000000000000000000100001000"
"101010101010101010100101111111"
"111101010111011110110011111100"
"000011111110111101111100110001"
"001101101111000110000011100010"
"111110010111110110000111100100"
"101010011010110110110010010100"
"100101010111100011100010101000"
},
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
char escaped[1024];
char cmp_buf[8192];
char cmp_msg[1024];
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); // Only do ZXing-C++ test if asked, too slow otherwise
testStart("test_encode_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, BARCODE_MAXICODE, data[i].input_mode, -1 /*eci*/,
data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, NULL, 0, debug);
if (data[i].structapp.count) {
symbol->structapp = data[i].structapp;
}
strcpy(symbol->primary, data[i].primary);
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
char escaped1[4096];
char escaped2[4096];
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length;
int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length;
printf(" /*%3d*/ { %s, %d, %d, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, \"%s\", %s, %d, %d, %d, \"%s\",\n",
i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2,
data[i].structapp.index, data[i].structapp.count, data[i].structapp.id,
testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci,
testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci,
testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci,
data[i].primary, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment);
testUtilModulesPrint(symbol, " ", "\n");
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) {
if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
ret = testUtilBwippSegs(i, symbol, -1, data[i].option_2, -1, data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf));
assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected);
}
}
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length, debug)) {
if (data[i].input_mode == DATA_MODE) {
if (debug & ZINT_DEBUG_TEST_PRINT) {
printf("i:%d multiple segments in DATA_MODE not currently supported for ZXing-C++ testing (%s)\n",
i, testUtilBarcodeName(symbol->symbology));
}
} else {
int cmp_len, ret_len;
char modules_dump[17984 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length,
modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count,
data[i].primary, escaped, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped);
}
}
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_best_supported_set(int index, int generate, int debug) { static void test_best_supported_set(int index, int generate, int debug) {
struct item { struct item {
@ -1174,6 +1644,7 @@ int main(int argc, char *argv[]) {
{ "test_large", test_large, 1, 0, 1 }, { "test_large", test_large, 1, 0, 1 },
{ "test_input", test_input, 1, 1, 1 }, { "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_encode_segs", test_encode_segs, 1, 1, 1 },
{ "test_best_supported_set", test_best_supported_set, 1, 1, 1 }, { "test_best_supported_set", test_best_supported_set, 1, 1, 1 },
{ "test_fuzz", test_fuzz, 1, 0, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 },
{ "test_perf", test_perf, 1, 0, 1 }, { "test_perf", test_perf, 1, 0, 1 },

View File

@ -294,7 +294,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);

View File

@ -1692,7 +1692,7 @@ static void test_encode(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
@ -1720,6 +1720,382 @@ static void test_encode(int index, int generate, int debug) {
testFinish(); testFinish();
} }
static void test_encode_segs(int index, int generate, int debug) {
struct item {
int symbology;
int input_mode;
int option_1;
int option_2;
int option_3;
struct zint_structapp structapp;
struct zint_seg segs[3];
int ret;
int expected_rows;
int expected_width;
int bwipp_cmp;
char *comment;
char *expected;
};
struct item data[] = {
/* 0*/ { BARCODE_PDF417, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 8, 103, 1, "Standard example",
"1111111101010100011111010101111100110101000011000001111001111001010011110101011110000111111101000101001"
"1111111101010100011111101010001110101000011110010001001111110010110011110101001000000111111101000101001"
"1111111101010100011101010111111000111010100011111101001111110011101011101010001111110111111101000101001"
"1111111101010100011010111100111110110110100010000001000011000110010010101111001111000111111101000101001"
"1111111101010100011101011100001100101110100011111001111000001001001011110101110011100111111101000101001"
"1111111101010100011110101111010000111011111000101101001111100001101011101011111010000111111101000101001"
"1111111101010100011101001110111110101000111011100001000111011100100011010011101111000111111101000101001"
"1111111101010100011111010010110000111000101110110001101011100001000010101111110111000111111101000101001"
},
/* 1*/ { BARCODE_PDF417, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 8, 103, 1, "Standard example auto-ECI",
"1111111101010100011111010101111100110101000011000001111001111001010011110101011110000111111101000101001"
"1111111101010100011111101010001110101000011110010001001111110010110011110101001000000111111101000101001"
"1111111101010100011101010111111000111010100011111101001111110011101011101010001111110111111101000101001"
"1111111101010100011010111100111110110110100010000001000011000110010010101111001111000111111101000101001"
"1111111101010100011101011100001100101110100011111001111000001001001011110101110011100111111101000101001"
"1111111101010100011110101111010000111011111000101101001111100001101011101011111010000111111101000101001"
"1111111101010100011101001110111110101000111011100001000111011100100011010011101111000111111101000101001"
"1111111101010100011111010010110000111000101110110001101011100001000010101111110111000111111101000101001"
},
/* 2*/ { BARCODE_PDF417, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 7 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, 0, 9, 103, 1, "Standard example inverted",
"1111111101010100011111010101111100110101000001100001100011100011001011110101011110000111111101000101001"
"1111111101010100011110101000010000111111010100011101011111100100011011110101001000000111111101000101001"
"1111111101010100011101010111111000110010010111110001000011111011001010101000011110000111111101000101001"
"1111111101010100011010111100111110111010100111000001111001111001010010101111001111000111111101000101001"
"1111111101010100011010111000001000101000011110010001011111101011000011110101110011100111111101000101001"
"1111111101010100011110101111010000111000111111010101100111110100010011110101111101100111111101000101001"
"1111111101010100011101001110111110111110111010111001111001100101110011010011101111000111111101000101001"
"1111111101010100011111101001011100111100100010100001001111101011100010101111110111000111111101000101001"
"1111111101010100011010011011111100100111010011000001100011010011110011111010011101000111111101000101001"
},
/* 3*/ { BARCODE_PDF417, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 9, 103, 1, "Standard example inverted auto-ECI",
"1111111101010100011111010101111100110101000001100001100011100011001011110101011110000111111101000101001"
"1111111101010100011110101000010000111111010100011101011111100100011011110101001000000111111101000101001"
"1111111101010100011101010111111000110010010111110001000011111011001010101000011110000111111101000101001"
"1111111101010100011010111100111110111010100111000001111001111001010010101111001111000111111101000101001"
"1111111101010100011010111000001000101000011110010001011111101011000011110101110011100111111101000101001"
"1111111101010100011110101111010000111000111111010101100111110100010011110101111101100111111101000101001"
"1111111101010100011101001110111110111110111010111001111001100101110011010011101111000111111101000101001"
"1111111101010100011111101001011100111100100010100001001111101011100010101111110111000111111101000101001"
"1111111101010100011010011011111100100111010011000001100011010011110011111010011101000111111101000101001"
},
/* 4*/ { BARCODE_PDF417, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 24, 188, 0, "AIM ITS/04-023:2022 Annex A example; BWIPP different encodation",
"11111111010101000111010100011100001001010000100000011000111000110010111010100111000001000011000110010011000001001011000100110001101000001101000010000110011010100011000000111111101000101001"
"11111111010101000111110101000001101111010011011000011110000011011010100000101111101101111011000011001011110100000100010110100011100001001110000110111010011111101010001110111111101000101001"
"11111111010101000110101000111110001101100010001111011100101011111100110011111011011001001011000111110011111101011100110100111110001100101100011110101100011111101011010000111111101000101001"
"11111111010101000111110100101111101101001111011111010000010100010000111110110100111101100000101001100010011011100001100110000010100110001110011000010011011110100101111000111111101000101001"
"11111111010101000110101111011000001110010000011001011111010100011000110100011100001001001111010001111011000001011101000101011111001100001001001111000001011101011100001100111111101000101001"
"11111111010101000111101011110000101010011101111110010000001100101110111100001011110101001000100001111010010110000111110100110000110111101101000001011111011101011111000100111111101000101001"
"11111111010101000101001111011110001111011000100111010010001110011100110001110001100101010111101111000010000010000100010111011011001110001110110100011000011010011100011110111111101000101001"
"11111111010101000111111010010011101110100000110001011100101111001110101111110101100001111000001101101011101000000110010111101100001100101111010000010001011111010010110000111111101000101001"
"11111111010101000101001100011111001111110010110001011001111110110010100100100111100001011011101111100010110110111100000101100100000111001100011111001001011111010011100100111111101000101001"
"11111111010101000110100011100111101111011110001001011000011010010000110000100011011101100010101100000010000110111101110100000101000001001000001010001000010100011100111000111111101000101001"
"11111111010101000110100111000000101000101111010000011111101001011100110000010111010001101000011110110011011111101011100110010011101000001111110111010010011101001110001100111111101000101001"
"11111111010101000101000110111110001000010100011110011111101011000100110011100010011101100110100111100010111000110011100110110000010111101001100110001111011111010001110100111111101000101001"
"11111111010101000101000001001000001100110000010001010001010000010000110011000001001001101111001110001010100000101000000110110011000011001100100000100011011101000001011100111111101000101001"
"11111111010101000111101000110110001101111101011110011111011001010000101110111111010001111001110011101011110100001001000101111110100110001111101011011100011111010001000110111111101000101001"
"11111111010101000101000001101111101001110011001110011000111110010010101111110011100101110110111111001010000111110110010111111010110001001100011111001001011100101011111100111111101000101001"
"11111111010101000111100101101111101001100110000100010011000110100000110100001000011001011000111000011011100111101100010100000101110011101110111010100000011100101101111000111111101000101001"
"11111111010101000101000111111011101111010000010001011010001110000100111000011011101001001011111101110011110100011011000110000010111010001101000111000001010100011111011000111111101000101001"
"11111111010101000111110010111101101111110101110011010011111000110010110001111010110001111101001110100011001111101101100100100101111000001000111101110111011100101111100100111111101000101001"
"11111111010101000111101101000011101100000100101100011010000010011000101001111011110001010000011000110010000010100010000111011100100000101000001000101000011101101000011000111111101000101001"
"11111111010101000111101000001000101000001011110100011100101100000100111101011001100001111001110011101011101011101100000111100010110011001111010001000010010100001111100110111111101000101001"
"11111111010101000110010010011111001011110010000010010111000100110000101000001001111001011100100011000011111101011100110100111111001110101110010111111011010010010000111100111111101000101001"
"11111111010101000101101110001100001000011000110010010000110001100100100001100011001001000011000110010010000110001100100110011000010010001101110110100000011101101110011110111111101000101001"
"11111111010101000111100101000000101111010000010001010100011110010000101110100111110001110000010110001011101000011000010110110001111001001100010111000100011111001010001100111111101000101001"
"11111111010101000111001001111101001011101100011100011001110010001110110000111110100101001111001100011010110011001111000101100100001110001101111001000011011001001111110010111111101000101001"
},
/* 5*/ { BARCODE_PDF417, DATA_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("\357"), 1, 0 }, { TU("\357"), 1, 7 }, { TU("\357"), 1, 0 } }, 0, 10, 103, 1, "Standard example + extra seg, data mode",
"1111111101010100011101010011100000110101101110000001111001111001010011110101011110000111111101000101001"
"1111111101010100011111010100011000111100101110011101001111110010110011111010100110000111111101000101001"
"1111111101010100011101010111111000111010100011111101001111110011101011010100011111000111111101000101001"
"1111111101010100010101111101111100111011001000110001100011100011001010101111001111000111111101000101001"
"1111111101010100011010111000010000111110101001100001011111100100011011010111000100000111111101000101001"
"1111111101010100011110101111010000101100110011110001100011111001001011110101111000010111111101000101001"
"1111111101010100010100111001110000110101000011000001100100011001110011010011101111000111111101000101001"
"1111111101010100011110100101000000100001011110000101101011111101111011010111111011110111111101000101001"
"1111111101010100011010011011111100110100111111010001001011101111110010100110001111100111111101000101001"
"1111111101010100010100011000001100111100100100111101100011001010000011010001100011100111111101000101001"
},
/* 6*/ { BARCODE_PDF417, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("Τεχτ"), -1, 9 }, { TU("กขฯ"), -1, 0 }, { TU("貫やぐ禁"), -1, 20 } }, ZINT_WARN_USES_ECI, 11, 120, 1, "Auto-ECI",
"111111110101010001110101001110000011010111001111000110001110001100101010100000100000011111010101111100111111101000101001"
"111111110101010001111110101000111011011111101011100111111001010111001111001011000110011111010100110000111111101000101001"
"111111110101010001010100111100000010110011101111100111111001000110101000011111011001011101010001111110111111101000101001"
"111111110101010001010111110111110011101011011110000100000100001000101001011000110000011010111100111110111111101000101001"
"111111110101010001110101110000110011110100001010000111010000001100101001111110010110011010111000100000111111101000101001"
"111111110101010001111101011110110011111101011000010110011111101100101011001000001110011101011111010000111111101000101001"
"111111110101010001010011100111000011001100001100110101100011110011101100111001110011011101001110111110111111101000101001"
"111111110101010001111101001011000011111010001011000110100011101000001111100101001100011010111111011110111111101000101001"
"111111110101010001111110100110010011000111110010010100111010011000001110101111100010010100110000111110111111101000101001"
"111111110101010001010001100000110011001000010011000110011000110011001011110011110010010100011000011000111111101000101001"
"111111110101010001110100111000110011010001111011000110000110111100101101001111000011011010011100100000111111101000101001"
},
/* 7*/ { BARCODE_PDF417, UNICODE_MODE, -1, -1, -1, { 2, 4, "017053" }, { { TU("Τεχτ"), -1, 9 }, { TU("กขฯ"), -1, 13 }, { TU("貫やぐ禁"), -1, 20 } }, 0, 11, 120, 1, "Structured Append",
"111111110101010001110101001110000011010111001111000110001110001100101010100000100000011111010101111100111111101000101001"
"111111110101010001111110101000111011011111101011100111111001010111001111001011000110011111010100110000111111101000101001"
"111111110101010001010100111100000010110011101111100111111001000110101000011111011001011101010001111110111111101000101001"
"111111110101010001010111110111110011101011011110000100000100001000101001011000110000011010111100111110111111101000101001"
"111111110101010001110101110000110011110100001010000111010000001100101001111110010110011010111000100000111111101000101001"
"111111110101010001111101011110110011111101011000010110011111101100101011001000001110011101011111010000111111101000101001"
"111111110101010001010011100111000011001100001100110101100011110011101100111001110011011101001110111110111111101000101001"
"111111110101010001111101001011000011111010001011000110100011101000001111100101001100011010111111011110111111101000101001"
"111111110101010001111110100110010011000111110010010100111010011000001110101111100010010100110000111110111111101000101001"
"111111110101010001010001100000110011001000010011000110011000110011001011110011110010010100011000011000111111101000101001"
"111111110101010001110100111000110011010001111011000110000110111100101101001111000011011010011100100000111111101000101001"
},
/* 8*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, { { TU("¶¶"), -1, 0 }, { TU("ЖЖ"), -1, 7 }, { TU(""), 0, 0 } }, 0, 8, 82, 1, "Standard example (doubled to avoid Byte Shift)",
"1100111010100000100001000101000010110110110100010000001101101000100000011001110101"
"1110111010100111111001011001000010010111111010100011101101111110101110011101110101"
"1110011010110010010111110001000011010110010010111110001100011111001001011100110101"
"1111011010100001100011001001000111010100001011101110001100010000010011011110110101"
"1111001010111001000011010001000110010110111001111101001101000011101000011110010101"
"1110001010101101101111000001000100010100111100001101101011011100011111011100010101"
"1100001010111011100010100001001100010101110001110010001100100111011110011000010101"
"1100011010101111100100111001001110010111010001100010001111000101000001011000110101"
},
/* 9*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, { { TU("¶¶"), -1, 0 }, { TU("ЖЖ"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 8, 82, 1, "Standard example auto-ECI",
"1100111010100000100001000101000010110110110100010000001101101000100000011001110101"
"1110111010100111111001011001000010010111111010100011101101111110101110011101110101"
"1110011010110010010111110001000011010110010010111110001100011111001001011100110101"
"1111011010100001100011001001000111010100001011101110001100010000010011011110110101"
"1111001010111001000011010001000110010110111001111101001101000011101000011110010101"
"1110001010101101101111000001000100010100111100001101101011011100011111011100010101"
"1100001010111011100010100001001100010101110001110010001100100111011110011000010101"
"1100011010101111100100111001001110010111010001100010001111000101000001011000110101"
},
/* 10*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, { { TU("ЖЖ"), -1, 7 }, { TU("¶¶"), -1, 0 }, { TU(""), 0, 0 } }, 0, 8, 82, 1, "Standard example inverted",
"1100111010110001110001100101000010110111010100011100001000001000010001011001110101"
"1110111010101000011110010001000010010101000011110010001001111110010110011101110101"
"1110011010110101001111100001000011010110011111101100101100100101111100011100110101"
"1111011010110110100010000001000111010100000100111011101010000010100000011110110101"
"1111001010110111001111101001000110010110111011111010001011111010011100011110010101"
"1110001010101100010001110001000100010110111110010000101000000110101110011100010101"
"1100001010110100001000110001001100010111010010000111001110001100010011011000010101"
"1100011010111110111011000101001110010111011000111000101110100111000110011000110101"
},
/* 11*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, { { TU("ЖЖ"), -1, 0 }, { TU("¶¶"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 8, 82, 1, "Standard example inverted auto-ECI",
"1100111010110001110001100101000010110111010100011100001000001000010001011001110101"
"1110111010101000011110010001000010010101000011110010001001111110010110011101110101"
"1110011010110101001111100001000011010110011111101100101100100101111100011100110101"
"1111011010110110100010000001000111010100000100111011101010000010100000011110110101"
"1111001010110111001111101001000110010110111011111010001011111010011100011110010101"
"1110001010101100010001110001000100010110111110010000101000000110101110011100010101"
"1100001010110100001000110001001100010111010010000111001110001100010011011000010101"
"1100011010111110111011000101001110010111011000111000101110100111000110011000110101"
},
/* 12*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, 4, -1, { 0, 0, "" }, { { TU("product:Google Pixel 4a 128 GB Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a 128 GB 黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a 128 GB Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 44, 99, 0, "AIM ITS/04-023:2022 Annex A example (shortened); BWIPP different encodation",
"110010001011000111000110010111010100111000001011000010100001100011001001100000100101100011010001001"
"111010001011000100111010000101001111000010001011100010111101001101100001111000001101101011010001101"
"111011001010001111001101100101110001100111001011100110100100100001111001111110010110001011010000101"
"110011001011000001001011000110010001101110001011100100110100000100011001000001010001000011011000101"
"110111001011010001110000010111010110000001001011101100111100000100010101111110100101110011001000101"
"110111101011001111101101100100100101111000001001101100110001111010110001110111111010100011101000101"
"110011101011111010101111100110110000100001001000101100110101100111000001101110011000010011101100101"
"111011101010101111110011100110011110101111101000101000100010011111011001110100111000011011001100101"
"111001101010111101001000000101100110011110001001101000100001111101100101010111000111111011011100101"
"111101101010000010000100010111011011001110001011101000111011010001100001110010010011100011011110101"
"111100101011100101111001110101111110101100001011001000111100000110110101110100000011001011001110101"
"111000101010111000110011100100100100001111001011001100111111001011000101100111111011001011101110101"
"110000101011011010000100000101101100010000001011000100111101101000111001110110010110000011100110101"
"110001101010111111010110000101111001000111101011000110100001101011111101000110100111111011110110101"
"110001001011011101001110000100111110011101101010000110100111110110010001100111110110110011110010101"
"111001001011010111100111110100100011001100001010001110111000111010010001101001100011100011100010101"
"111101001011011111101011100110110111100010001010001100111110100010110001100011001111001011000010101"
"111101011010011001000011100110001111000101101010011100110001000101111101000111001011000011000110101"
"111101010010100010000010000111101000101111001010011000111101110100110001001011000011000011000100101"
"111001010011110100001001000101111110100110001010111000111110101101110001011101011111000011100100101"
"111011010011000111110010010101111110011100101010110000111011011111100101000011111011001011110100101"
"111010010011110101100111110100001100011001001010010000100110011000010001001100011010000011110101101"
"111010011010100111100001000110010011110110001011010000111100000110110101000001011111011011110101001"
"111010111010111000110011100100100100001111001001010000111111001011000101100111110010100011100101001"
"111010110011001000110111000110100000100011001001011000100000101000100001110010100111000011101101001"
"111010100011101011000000100111100000100010101001011100111111010010111001100000101110100011101001001"
"110010100010010010111100000100011110111011101011011100100111110110001001011001000001110011101001101"
"110010110011110101100111110110111100111000101011011110101011100011100001110001000100111011101011101"
"110010111011110100010000100111100010001010001011001110100100001111000101111010001001000011101011001"
"110010011010111001000110000111111010111001101001001110100111111001110101110010111111011011101010001"
"110011011010000110001100100100001100011001001001101110100001100011001001000011000110010011001010001"
"111011011010111111010110000101111110101100001000101110111110101100011101101110011111010011001011001"
"111001011011011110010011000111111000101100101000100110101111011101110001000011010111000011001011101"
"110001011010011000110100000110000100011011101000110110111000110001001101001101111101111011001001101"
"110001010010011111010011100110110011110001001000010110111101100111001101111010000010100011001101101"
"110011010011111001000111010100010000101111001000010010111010001011111101001100001000111011101101101"
"110111010010001100110000010100001100110010001000011010100010001100001101100100000100011011100101101"
"110110010011101111011111010111111011010011001000111010111100010100100001110000110111010011000101101"
"110110011010011001001110000111001111101001101000110010101110010001100001000101100111110011000101001"
"110110111011101101100111000100110001110110001000100010110111100011100101000110110010000011001101001"
"110110110011111011100110100111001000001100101001100010111101100110000101100100000111001011011101001"
"110110100011101110010111100110001111010001101001110010110111111001101001011010000011100011011001001"
"110100100010110011110001110101100001100010001001111010111011000100110001010000011001100011011001101"
"110101100011111011000010100111110100001011001011111010111110111011000101011101111110001011011011101"
},
/* 13*/ { BARCODE_MICROPDF417, DATA_MODE, -1, 3, -1, { 0, 0, "" }, { { TU("\357\357"), 2, 0 }, { TU("\357\357"), 2, 7 }, { TU("\357\357"), 2, 0 } }, 0, 10, 82, 1, "Standard example (doubled) + extra seg, data mode",
"1100010010110011111101100101001111010101100110011110001011001100111100011000100101"
"1110010010110001110001100101011111010111010100011100001000001000010001011100100101"
"1111010010111100101110011101011110010111100101110011101001111110010110011110100101"
"1111010110110101001111100001011110110110011111101100101011001100111100011110101101"
"1111010100111011001000110001001110110100001100011001001100111011001000011110101001"
"1110010100110001000001110101001110100111111011101010001101110111110100011100101001"
"1110110100110100010011111001001100100110010100001111101110011111101010011101101001"
"1110100100110110000010000101001100110101001000001000001110100000100111011101001001"
"1110100110111101000011001101001000110111101001000100001100100111010000011101001101"
"1110101110100000101101111101001000010111010011111000101001110111001111011101011101"
},
/* 14*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("Τεχτ"), -1, 9 }, { TU("กขฯ"), -1, 0 }, { TU("貫やぐ禁"), -1, 20 } }, ZINT_WARN_USES_ECI, 17, 55, 1, "Auto-ECI",
"1100110100100001111101100101101010000111110011001101001"
"1101110100100000100001000101100100110011100011011101001"
"1101100100111100101100011001100101111011000011011001001"
"1101100110111111001000110101000011111011001011011001101"
"1101101110111010110111100001000001000010001011011011101"
"1101101100101000111111011101111010000101000011011011001"
"1101101000100100111011111101000011111011001011011010001"
"1101001000101011000011000001000001000010001011010010001"
"1101011000111001011000001001111011101110100011010110001"
"1101011100110011010011110001101111100010001011010111001"
"1101011110110100001110111101110100000010111011010111101"
"1101001110111110010100110001011111101011000011010011101"
"1101001100101000011001111101000000110100111011010011001"
"1101000100110100110111000001000010000100100011010001001"
"1101000110111001011110011101101101111001000011010001101"
"1101000010110000011010111101100110010001111011010000101"
"1101100010100001001101100001001001110111000011011000101"
},
/* 15*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, -1, -1, { 3, 4, "017053" }, { { TU("Τεχτ"), -1, 9 }, { TU("กขฯ"), -1, 13 }, { TU("貫やぐ禁"), -1, 20 } }, 0, 17, 55, 1, "Structured Append",
"1100110100100001111101100101101010000111110011001101001"
"1101110100100000100001000101100100110011100011011101001"
"1101100100111100101100011001100101111011000011011001001"
"1101100110111111001000110101000011111011001011011001101"
"1101101110111010110111100001000001000010001011011011101"
"1101101100101000111111011101111010000101000011011011001"
"1101101000100100111011111101000011111011001011011010001"
"1101001000101011000011000001000001000010001011010010001"
"1101011000111001011000001001111011101110100011010110001"
"1101011100110011010011110001101111100010001011010111001"
"1101011110110100001110111101110100000010111011010111101"
"1101001110111110010100110001011111101011000011010011101"
"1101001100101000011001111101000000110100111011010011001"
"1101000100110100110111000001000010000100100011010001001"
"1101000110111001011110011101101101111001000011010001101"
"1101000010110000011010111101100110010001111011010000101"
"1101100010100001001101100001001001110111000011011000101"
},
/* 16*/ { BARCODE_PDF417COMP, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 8, 69, 1, "Standard example",
"111111110101010001111101010111110011010100001100000111100111100101001"
"111111110101010001111110101000111010100001111001000100111111001011001"
"111111110101010001110101011111100011101010001111110100111111001110101"
"111111110101010001101011110011111011011010001000000100001100011001001"
"111111110101010001110101110000110010111010001111100111100000100100101"
"111111110101010001111010111101000011101111100010110100111110000110101"
"111111110101010001110100111011111010100011101110000100011101110010001"
"111111110101010001111101001011000011100010111011000110101110000100001"
},
/* 17*/ { BARCODE_HIBC_PDF, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("H123ABC"), -1, 0 }, { TU("012345678"), -1, 0 }, { TU("90D"), -1, 20 } }, ZINT_ERROR_INVALID_OPTION, 0, 0, 1, "HIBC",
""
},
/* 18*/ { BARCODE_HIBC_MICPDF, UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, { { TU("H123ABC"), -1, 0 }, { TU("012345678"), -1, 0 }, { TU("90D"), -1, 20 } }, ZINT_ERROR_INVALID_OPTION, 0, 0, 1, "HIBC",
""
},
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
char escaped[1024];
char cmp_buf[32768];
char cmp_msg[1024];
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); // Only do ZXing-C++ test if asked, too slow otherwise
testStart("test_encode_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/,
data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, NULL, 0, debug);
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
char escaped1[4096];
char escaped2[4096];
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length;
int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length;
printf(" /*%3d*/ { %s, %s, %d, %d, %d, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n",
i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode),
data[i].option_1, data[i].option_2, data[i].option_3,
data[i].structapp.index, data[i].structapp.count, data[i].structapp.id,
testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci,
testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci,
testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci,
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment);
if (data[i].ret < ZINT_ERROR) {
testUtilModulesPrint(symbol, " ", "\n");
} else {
printf(" \"\"\n");
}
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) {
if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
ret = testUtilBwippSegs(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].segs, seg_count, NULL, cmp_buf, sizeof(cmp_buf));
assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected);
}
}
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length, debug)) {
if (data[i].input_mode == DATA_MODE) {
if (debug & ZINT_DEBUG_TEST_PRINT) {
printf("i:%d multiple segments in DATA_MODE not currently supported for ZXing-C++ testing (%s)\n",
i, testUtilBarcodeName(symbol->symbology));
}
} else {
int cmp_len, ret_len;
char modules_dump[2710 * 8 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilZXingCPP(i, symbol, (const char *) data[i].segs[0].source, data[i].segs[0].length,
modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count,
NULL /*primary*/, escaped, &ret_len);
assert_zero(ret, "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped);
}
}
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
// #181 Nico Gunkel OSS-Fuzz // #181 Nico Gunkel OSS-Fuzz
static void test_fuzz(int index, int debug) { static void test_fuzz(int index, int debug) {
@ -2161,6 +2537,7 @@ int main(int argc, char *argv[]) {
{ "test_reader_init", test_reader_init, 1, 1, 1 }, { "test_reader_init", test_reader_init, 1, 1, 1 },
{ "test_input", test_input, 1, 1, 1 }, { "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_encode_segs", test_encode_segs, 1, 1, 1 },
{ "test_fuzz", test_fuzz, 1, 0, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 },
{ "test_perf", test_perf, 1, 0, 1 }, { "test_perf", test_perf, 1, 0, 1 },
}; };

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -303,7 +302,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -436,3 +435,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
// USPS Publication 25 (July 2003) Designing Letter and Reply Mail https://web.archive.org/web/20050118015758/http://www.siemons.com/forms/pdf/designing_letter_reply_mail.pdf // USPS Publication 25 (July 2003) Designing Letter and Reply Mail https://web.archive.org/web/20050118015758/http://www.siemons.com/forms/pdf/designing_letter_reply_mail.pdf
// USPS DMM Domestic Mail Manual https://pe.usps.com/DMM300 // USPS DMM Domestic Mail Manual https://pe.usps.com/DMM300
@ -474,7 +473,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -607,3 +606,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

File diff suppressed because it is too large Load Diff

View File

@ -165,7 +165,7 @@ static void test_binary_div_modulo_divisor(int index, int generate, int debug) {
assert_zero(ret, "i:%d ZBarcode_Buffer_Vector ret %d != 0\n", i, ret); assert_zero(ret, "i:%d ZBarcode_Buffer_Vector ret %d != 0\n", i, ret);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, -1, -1, text, length, symbol->primary, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, -1, -1, text, length, symbol->primary, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmpRow(symbol, symbol->rows - 1, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmpRow(symbol, symbol->rows - 1, cmp_msg, cmp_buf, data[i].expected);
@ -904,7 +904,7 @@ static void test_examples(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -267,7 +266,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -403,3 +402,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -27,7 +27,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h" #include "testcommon.h"
@ -213,7 +212,7 @@ static void test_input(int index, int generate, int debug) {
/* 16*/ { UNICODE_MODE, 0, -1, -1, -1, { 0, 0, "" }, "β", ZINT_WARN_USES_ECI, "Warning (2) 263 226", "" }, /* 16*/ { UNICODE_MODE, 0, -1, -1, -1, { 0, 0, "" }, "β", ZINT_WARN_USES_ECI, "Warning (2) 263 226", "" },
/* 17*/ { UNICODE_MODE, 9, -1, -1, -1, { 0, 0, "" }, "β", 0, "(2) 263 226", "" }, /* 17*/ { UNICODE_MODE, 9, -1, -1, -1, { 0, 0, "" }, "β", 0, "(2) 263 226", "" },
/* 18*/ { UNICODE_MODE, 9, -1, -1, -1, { 0, 0, "" }, "βAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 0, "(253) 263 226 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65", "249 chars EC2" }, /* 18*/ { UNICODE_MODE, 9, -1, -1, -1, { 0, 0, "" }, "βAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 0, "(253) 263 226 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65", "249 chars EC2" },
/* 19*/ { UNICODE_MODE, 9, -1, -1, ULTRA_COMPRESSION, { 0, 0, "" }, "A", 0, "(2) 272 65", "Note ECI ignored and not outputted if ULTRA_COMPRESSION and all ASCII" }, /* 19*/ { UNICODE_MODE, 9, -1, -1, ULTRA_COMPRESSION, { 0, 0, "" }, "A", 0, "(2) 263 65", "Note previously ECI ignored and not outputted if ULTRA_COMPRESSION and all ASCII" },
/* 20*/ { UNICODE_MODE, 15, -1, -1, -1, { 0, 0, "" }, "Ŗ", 0, "(2) 268 170", "" }, /* 20*/ { UNICODE_MODE, 15, -1, -1, -1, { 0, 0, "" }, "Ŗ", 0, "(2) 268 170", "" },
/* 21*/ { DATA_MODE, 898, -1, -1, -1, { 0, 0, "" }, "\001\002\003\004\377", 0, "(7) 278 130 1 2 3 4 255", "" }, /* 21*/ { DATA_MODE, 898, -1, -1, -1, { 0, 0, "" }, "\001\002\003\004\377", 0, "(7) 278 130 1 2 3 4 255", "" },
/* 22*/ { DATA_MODE, 899, -1, -1, -1, { 0, 0, "" }, "\001\002\003\004\377", 0, "(6) 280 1 2 3 4 255", "" }, /* 22*/ { DATA_MODE, 899, -1, -1, -1, { 0, 0, "" }, "\001\002\003\004\377", 0, "(6) 280 1 2 3 4 255", "" },
@ -280,13 +279,15 @@ static void test_input(int index, int generate, int debug) {
symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
length = testUtilSetSymbol(symbol, BARCODE_ULTRA, data[i].input_mode, data[i].eci, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug); length = testUtilSetSymbol(symbol, BARCODE_ULTRA, data[i].input_mode, data[i].eci,
data[i].option_1, data[i].option_2, data[i].option_3,
-1 /*output_options*/, data[i].data, -1, debug);
if (data[i].structapp.count) { if (data[i].structapp.count) {
symbol->structapp = data[i].structapp; symbol->structapp = data[i].structapp;
} }
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) { if (generate) {
printf(" /*%3d*/ { %s, %d, %d, %d, %s, { %d, %d, \"%s\" }, \"%s\", %s, \"%s\", \"%s\" },\n", printf(" /*%3d*/ { %s, %d, %d, %d, %s, { %d, %d, \"%s\" }, \"%s\", %s, \"%s\", \"%s\" },\n",
@ -818,7 +819,7 @@ static void test_encode(int index, int generate, int debug) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else { } else {
ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
@ -835,6 +836,255 @@ static void test_encode(int index, int generate, int debug) {
testFinish(); testFinish();
} }
static void test_encode_segs(int index, int generate, int debug) {
struct item {
int input_mode;
int option_1;
int option_2;
int option_3;
struct zint_structapp structapp;
struct zint_seg segs[3];
int ret;
int expected_rows;
int expected_width;
int bwipp_cmp;
char *comment;
char *expected;
};
// Based on AIMD/TSC15032-43 (v 0.99c), with values updated from BWIPP update 2021-07-14
// https://github.com/bwipp/postscriptbarcode/commit/4255810845fa8d45c6192dd30aee1fdad1aaf0cc
struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, -1, ULTRA_COMPRESSION, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 13, 15, 0, "Standard example; BWIPP no ECI support for Ultracode",
"777777777777777"
"785786131155157"
"773783613563337"
"781786355656167"
"776785561363337"
"783781355651517"
"778787878787877"
"786781665116117"
"771783136335337"
"786785653613557"
"773781536165117"
"781786115333557"
"777777777777777"
},
/* 1*/ { UNICODE_MODE, -1, -1, ULTRA_COMPRESSION, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 13, 15, 0, "Standard example auto-ECI; BWIPP no ECI support for Ultracode",
"777777777777777"
"785786131155157"
"773783613563337"
"781786355656167"
"776785561363337"
"783781355651517"
"778787878787877"
"786781665116117"
"771783136335337"
"786785653613557"
"773781536165117"
"781786115333557"
"777777777777777"
},
/* 2*/ { UNICODE_MODE, -1, -1, ULTRA_COMPRESSION, { 0, 0, "" }, { { TU("Ж"), -1, 7 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, 0, 13, 15, 0, "Standard example inverted; BWIPP no ECI support for Ultracode",
"777777777777777"
"785786351355157"
"773785113663337"
"781781365356167"
"776783136163337"
"783786555651517"
"778787878787877"
"786781356116117"
"771783663335337"
"786785531613157"
"773781353165517"
"781786565333657"
"777777777777777"
},
/* 3*/ { UNICODE_MODE, -1, -1, ULTRA_COMPRESSION, { 0, 0, "" }, { { TU("Ж"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 13, 15, 0, "Standard example inverted auto-ECI; BWIPP no ECI support for Ultracode",
"777777777777777"
"785786351355157"
"773785113663337"
"781781365356167"
"776783136163337"
"783786555651517"
"778787878787877"
"786781356116117"
"771783663335337"
"786785531613157"
"773781353165517"
"781786565333657"
"777777777777777"
},
/* 4*/ { UNICODE_MODE, -1, -1, ULTRA_COMPRESSION, { 0, 0, "" }, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 31, 51, 0, "AIM ITS/04-023:2022 Annex A example; BWIPP no ECI support for Ultracode",
"777777777777777777777777777777777777777777777777777"
"788786553615151313686615635315656568556155565633167"
"778783131336563655375536556151531317365661116315357"
"788786366163615166181363163533665138151555551131667"
"778785631636351311375511615351516667316663165656357"
"788781563115163655581635531513353338163331636363137"
"778787878787878787878787878787878787878787878787877"
"788785515563115631383565335311551158666513631316557"
"778786651356351315575153153566315667555156366135637"
"788781363513515166181666316333666318161633113513317"
"775783635365361331576153163515155637655155661351537"
"781785353136156566383335656633633318536616353136617"
"773787878787878787878787878787878787878787878787877"
"781781331535616631386565316331555568565666316651557"
"776786666356535565175656551655663617153515131366317"
"788783355511663311383331636113116138635136555113557"
"773785516665311566576556353555655567351513361555317"
"781783633336533155181333115131513638536365113131157"
"773787878787878787878787878787878787878787878787877"
"785786636561663636181316366313566618513136611663557"
"771781563655535363573133555551311167331655355551317"
"788783155566111151385315661133633538516533131135557"
"778786516633355666676136356651116667635356516556317"
"788785133151663353583553135516551118156615665661657"
"778787878787878787878787878787878787878787878787877"
"788781353515665533386611351311655558113366366156117"
"778783616631513151171356535556166617531115155365537"
"788785555563336315386533363665613368666653363516367"
"778781366656651133171316155153135557515516515663557"
"788786635535536351685531611336513668663633636555117"
"777777777777777777777777777777777777777777777777777"
},
/* 5*/ { DATA_MODE, -1, -1, ULTRA_COMPRESSION, { 0, 0, "" }, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, 0, 13, 17, 0, "Standard example + extra seg, data mode; BWIPP no ECI support for Ultracode",
"77777777777777777"
"78578616315515157"
"77378361566333337"
"78578633115616167"
"77678566656333337"
"78378131365151517"
"77878787878787877"
"78678136111616117"
"77378361633535337"
"78178513161353157"
"77378656536515517"
"78178135353353657"
"77777777777777777"
},
/* 6*/ { UNICODE_MODE, -1, -1, ULTRA_COMPRESSION, { 0, 0, "" }, { { TU("¿é"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("φχψω"), -1, 0 } }, ZINT_WARN_USES_ECI, 13, 20, 0, "Auto-ECI; BWIPP no ECI support for Ultracode",
"77777777777777777777"
"78578651555561561667"
"77678333166653153337"
"78178655335135635557"
"77578563166556553337"
"78378131655133331167"
"77878787878787878787"
"78678166111615516617"
"77378351653131633337"
"78578663311616515557"
"77378315636535131317"
"78178131363151656557"
"77777777777777777777"
},
/* 7*/ { UNICODE_MODE, -1, -1, ULTRA_COMPRESSION, { 2, 3, "4" }, { { TU("¿é"), -1, 3 }, { TU("กขฯ"), -1, 13 }, { TU("φχψω"), -1, 9 } }, 0, 13, 23, 0, "Structured Append; BWIPP no ECI support for Ultracode",
"77777777777777777777777"
"78578613615616155168657"
"77678335366131316337317"
"78378666635516165158557"
"77578515156665351317317"
"78378163515131516568557"
"77878787878787878787877"
"78678151513156156168617"
"77578366351365315337337"
"78178633513113563558557"
"77378516666355655337317"
"78178133151513333118657"
"77777777777777777777777"
},
/* 8*/ { UNICODE_MODE, -1, -1, ULTRA_COMPRESSION, { 0, 0, "" }, { { TU("çèéêëì"), -1, 0 }, { TU("òóô"), -1, 899 }, { TU("òóô"), -1, 10000 } }, 0, 13, 27, 0, "ECIs >= 899; BWIPP no ECI support for Ultracode",
"777777777777777777777777777"
"785786353555666665585335557"
"771783161616113513373663337"
"783786335335661355686335667"
"771785511666353666171656117"
"786781655535111113385163357"
"778787878787878787878787877"
"783781151511666355586355517"
"771785616353113666675666637"
"783781363635661511183311157"
"775786615561353366676566637"
"781785551653535633383633317"
"777777777777777777777777777"
},
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
char escaped[1024];
char bwipp_buf[32768];
char bwipp_msg[1024];
int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
testStart("test_encode_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
if ((debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) printf("i:%d\n", i);
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, BARCODE_ULTRA, data[i].input_mode, -1 /*eci*/,
data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, NULL, 0, debug);
if (data[i].structapp.count) {
symbol->structapp = data[i].structapp;
}
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
char escaped1[4096];
char escaped2[4096];
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length;
int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length;
printf(" /*%3d*/ { %s, %d, %d, %s, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n",
i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilOption3Name(data[i].option_3),
data[i].structapp.index, data[i].structapp.count, data[i].structapp.id,
testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci,
testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci,
testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci,
testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment);
testUtilModulesPrint(symbol, " ", "\n");
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, debug)) {
if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment);
} else {
ret = testUtilBwippSegs(i, symbol, data[i].option_1, data[i].option_2, data[i].option_3, data[i].segs, seg_count, NULL, bwipp_buf, sizeof(bwipp_buf));
assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected);
}
}
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
@ -842,6 +1092,7 @@ int main(int argc, char *argv[]) {
{ "test_reader_init", test_reader_init, 1, 1, 1 }, { "test_reader_init", test_reader_init, 1, 1, 1 },
{ "test_input", test_input, 1, 1, 1 }, { "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 },
{ "test_encode_segs", test_encode_segs, 1, 1, 1 },
}; };
testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
@ -850,3 +1101,5 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
/* vim: set ts=4 sw=4 et : */

View File

@ -121,7 +121,7 @@ static void test_upce_input(int index, int debug) {
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) {
char modules_dump[8192 + 1]; char modules_dump[8192 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i);
ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].hrt, (int) strlen(data[i].hrt), NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].hrt, (int) strlen(data[i].hrt), NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump);
@ -952,7 +952,7 @@ static void test_encode(int index, int generate, int debug) {
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf)); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);

View File

@ -2010,7 +2010,7 @@ static const char *testUtilBwippName(int index, const struct zint_symbol *symbol
{ "", BARCODE_GRIDMATRIX, 142, 0, 0, 0, 0, 0, }, { "", BARCODE_GRIDMATRIX, 142, 0, 0, 0, 0, 0, },
{ "", BARCODE_UPNQR, 143, 0, 0, 0, 0, 0, }, { "", BARCODE_UPNQR, 143, 0, 0, 0, 0, 0, },
{ "ultracode", BARCODE_ULTRA, 144, 1, 1, 0, 0, 0, }, { "ultracode", BARCODE_ULTRA, 144, 1, 1, 0, 0, 0, },
{ "rectangularmicroqrcode", BARCODE_RMQR, 145, 1, 1, 0, 0, 0, }, { "rectangularmicroqrcode", BARCODE_RMQR, 145, 1, 1, 1, 0, 0, },
}; };
static const int data_size = ARRAY_SIZE(data); static const int data_size = ARRAY_SIZE(data);
@ -2153,14 +2153,13 @@ static void testUtilBwippCvtGS1Data(char *bwipp_data, int upcean, int *addon_pos
/* Convert data to Ghostscript format for passing to bwipp_dump.ps */ /* Convert data to Ghostscript format for passing to bwipp_dump.ps */
static char *testUtilBwippEscape(char *bwipp_data, int bwipp_data_size, const char *data, int length, static char *testUtilBwippEscape(char *bwipp_data, int bwipp_data_size, const char *data, int length,
int zint_escape_mode, int eci, int *parse, int *parsefnc) { int zint_escape_mode, int eci, int *parse, int *parsefnc) {
const int init_parsefnc = *parsefnc == 1;
char *b = bwipp_data; char *b = bwipp_data;
char *be = b + bwipp_data_size; char *be = b + bwipp_data_size;
unsigned char *d = (unsigned char *) data; unsigned char *d = (unsigned char *) data;
unsigned char *de = (unsigned char *) data + length; unsigned char *de = (unsigned char *) data + length;
*parse = *parsefnc = 0; if (eci && !init_parsefnc) {
if (eci) {
sprintf(bwipp_data, "^ECI%06d", eci); sprintf(bwipp_data, "^ECI%06d", eci);
*parsefnc = 1; *parsefnc = 1;
b = bwipp_data + 10; b = bwipp_data + 10;
@ -2169,7 +2168,8 @@ static char *testUtilBwippEscape(char *bwipp_data, int bwipp_data_size, const ch
while (b < be && d < de) { while (b < be && d < de) {
/* Have to escape double quote otherwise Ghostscript gives "Unterminated quote in @-file" for some reason */ /* Have to escape double quote otherwise Ghostscript gives "Unterminated quote in @-file" for some reason */
/* Escape single quote also to avoid having to do proper shell escaping TODO: proper shell escaping */ /* Escape single quote also to avoid having to do proper shell escaping TODO: proper shell escaping */
if (*d < 0x20 || *d >= 0x7F || *d == '^' || *d == '"' || *d == '\'' || (!zint_escape_mode && *d == '\\')) { if (*d < 0x20 || *d >= 0x7F || (*d == '^' && !init_parsefnc) || *d == '"' || *d == '\''
|| (*d == '\\' && !zint_escape_mode)) {
if (b + 4 >= be) { if (b + 4 >= be) {
fprintf(stderr, "testUtilBwippEscape: double quote bwipp_data buffer full (%d)\n", bwipp_data_size); fprintf(stderr, "testUtilBwippEscape: double quote bwipp_data buffer full (%d)\n", bwipp_data_size);
return NULL; return NULL;
@ -2238,11 +2238,53 @@ static void testUtilISBNHyphenate(char *bwipp_data, int addon_posn) {
strcpy(bwipp_data, temp); strcpy(bwipp_data, temp);
} }
/* Helper to convert UTF-8 data */
static char *testUtilBwippUtf8Convert(const int index, const int symbology, const int try_sjis, int *p_eci,
const unsigned char *data, int *p_data_len, unsigned char *converted) {
int eci = *p_eci;
if (eci == 0 && try_sjis
&& (symbology == BARCODE_QRCODE || symbology == BARCODE_MICROQR || symbology == BARCODE_RMQR)) {
if (utf8_to_eci(0, data, converted, p_data_len) != 0) {
if (utf8_to_eci(20, data, converted, p_data_len) != 0) {
fprintf(stderr, "i:%d testUtilBwippUtf8Convert: failed to convert UTF-8 data for %s, ECI 0/20\n",
index, testUtilBarcodeName(symbology));
return NULL;
}
// NOTE: not setting *p_eci = 20
}
return (char *) converted;
}
if (ZBarcode_Cap(symbology, ZINT_CAP_ECI)) {
if (utf8_to_eci(eci, data, converted, p_data_len) != 0) {
if (eci != 0) {
fprintf(stderr, "i:%d testUtilBwippUtf8Convert: failed to convert UTF-8 data for %s, ECI %d\n",
index, testUtilBarcodeName(symbology), eci);
return NULL;
}
*p_eci = eci = get_best_eci(data, *p_data_len);
if (utf8_to_eci(eci, data, converted, p_data_len) != 0) {
fprintf(stderr, "i:%d testUtilBwippUtf8Convert: failed to convert UTF-8 data for %s, ECI %d\n",
index, testUtilBarcodeName(symbology), eci);
return NULL;
}
}
return (char *) converted;
}
if (eci != 0) {
fprintf(stderr, "i:%d testUtilBwippUtf8Convert: ECI %d but not supported for %s\n",
index, eci, testUtilBarcodeName(symbology));
return NULL;
}
return (char *) data;
}
#define GS_INITIAL_LEN 35 /* Length of cmd up to -q */ #define GS_INITIAL_LEN 35 /* Length of cmd up to -q */
/* Create bwipp_dump.ps command and run */ /* Create bwipp_dump.ps command and run */
int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3, int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3,
const char *data, int length, const char *primary, char *buffer, int buffer_size) { const char *data, int length, const char *primary, char *buffer, int buffer_size, int *p_parsefnc) {
static const char cmd_fmt[] = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%s'" static const char cmd_fmt[] = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%s'"
" backend/tests/tools/bwipp_dump.ps"; " backend/tests/tools/bwipp_dump.ps";
static const char cmd_opts_fmt[] = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%s' -so='%s'" static const char cmd_opts_fmt[] = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%s' -so='%s'"
@ -2253,7 +2295,7 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int
static const char cmd_opts_fmt2[] = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%.2043s' -sd2='%s' -so='%s'" static const char cmd_opts_fmt2[] = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%.2043s' -sd2='%s' -so='%s'"
" backend/tests/tools/bwipp_dump.ps"; " backend/tests/tools/bwipp_dump.ps";
int symbology = symbol->symbology; const int symbology = symbol->symbology;
int data_len = length == -1 ? (int) strlen(data) : length; int data_len = length == -1 ? (int) strlen(data) : length;
int primary_len = primary ? (int) strlen(primary) : 0; int primary_len = primary ? (int) strlen(primary) : 0;
/* 4 AI prefix + primary + '|' + leading zero + escaped data + fudge */ /* 4 AI prefix + primary + '|' + leading zero + escaped data + fudge */
@ -2278,7 +2320,7 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int
char *b = buffer; char *b = buffer;
char *be = buffer + buffer_size; char *be = buffer + buffer_size;
int r, h; int r, h;
int parse, parsefnc; int parse = 0, parsefnc = p_parsefnc ? *p_parsefnc : 0;
int upcean = is_extendable(symbology); int upcean = is_extendable(symbology);
int upca = symbology == BARCODE_UPCA || symbology == BARCODE_UPCA_CHK || symbology == BARCODE_UPCA_CC; int upca = symbology == BARCODE_UPCA || symbology == BARCODE_UPCA_CHK || symbology == BARCODE_UPCA_CC;
@ -2311,36 +2353,12 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int
eci = symbol->eci >= 3 && ZBarcode_Cap(symbology, ZINT_CAP_ECI) ? symbol->eci : 0; eci = symbol->eci >= 3 && ZBarcode_Cap(symbology, ZINT_CAP_ECI) ? symbol->eci : 0;
if ((symbol->input_mode & 0x07) == UNICODE_MODE && is_eci_convertible(eci)) { if ((symbol->input_mode & 0x07) == UNICODE_MODE && is_eci_convertible(eci)
if (eci == 0 && (symbology == BARCODE_QRCODE || symbology == BARCODE_MICROQR || symbology == BARCODE_RMQR)) { && (data = testUtilBwippUtf8Convert(index, symbology, 1 /*try_sjis*/, &eci, (const unsigned char *) data,
if (utf8_to_eci(0, (const unsigned char *) data, (unsigned char *) converted, &data_len) != 0 &data_len, (unsigned char *) converted)) == NULL) {
&& utf8_to_eci(20, (const unsigned char *) data, (unsigned char *) converted, &data_len) != 0) { fprintf(stderr, "i:%d testUtilBwipp: failed to convert UTF-8 data for %s\n",
fprintf(stderr, "i:%d testUtilBwipp: failed to convert Unicode data for %s, ECI 0/20\n", index, testUtilBarcodeName(symbology));
index, testUtilBarcodeName(symbology)); return -1;
return -1;
}
data = converted;
} else if (ZBarcode_Cap(symbology, ZINT_CAP_ECI)) {
if (utf8_to_eci(eci, (const unsigned char *) data, (unsigned char *) converted, &data_len) != 0) {
if (eci != 0) {
eci = get_best_eci((const unsigned char *) data, data_len);
if (utf8_to_eci(eci, (const unsigned char *) data, (unsigned char *) converted, &data_len) != 0) {
fprintf(stderr, "i:%d testUtilBwipp: failed to convert Unicode data for %s, ECI %d\n",
index, testUtilBarcodeName(symbology), eci);
return -1;
}
} else {
fprintf(stderr, "i:%d testUtilBwipp: failed to convert Unicode data for %s, no ECI specified\n",
index, testUtilBarcodeName(symbology));
return -1;
}
}
data = converted;
} else if (eci != 0) {
fprintf(stderr, "i:%d testUtilBwipp: ECI %d but not supported for %s\n",
index, eci, testUtilBarcodeName(symbology));
return -1;
}
} }
if (is_composite(symbology)) { if (is_composite(symbology)) {
@ -2638,7 +2656,7 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int
len += 4; len += 4;
} }
} }
if (symbol->eci == 0) { /* If not already done for ECI */ if (!parsefnc) { /* If not already done for ECI */
sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%sparsefnc", sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%sparsefnc",
strlen(bwipp_opts_buf) ? " " : ""); strlen(bwipp_opts_buf) ? " " : "");
bwipp_opts = bwipp_opts_buf; bwipp_opts = bwipp_opts_buf;
@ -2785,6 +2803,20 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int
bwipp_opts = bwipp_opts_buf; bwipp_opts = bwipp_opts_buf;
} }
} }
/* Hack to place ECI after Macro header */
if (eci && length > 5 && memcmp("[)>\036", data, 4) == 0) {
char macro_eci_buf[13];
if (length > 6 && data[6] == 29 /*GS*/ && ((data[4] == '0' && data[5] == '5')
|| (data[4] == '0' && data[5] == '6') || (data[4] == '1' && data[5] == '2'))) {
memcpy(macro_eci_buf, bwipp_data + 10, 13); /* Macro */
memcpy(bwipp_data + 13, bwipp_data, 10); /* ECI */
memcpy(bwipp_data, macro_eci_buf, 13);
} else if (data[4] >= '0' && data[4] <= '9' && data[5] >= '0' && data[5] <= '9') {
memcpy(macro_eci_buf, bwipp_data, 10); /* ECI */
memcpy(bwipp_data, bwipp_data + 10, 9); /* Macro */
memcpy(bwipp_data + 9, macro_eci_buf, 10);
}
}
} else if (symbology == BARCODE_QRCODE || symbology == BARCODE_HIBC_QR || symbology == BARCODE_MICROQR } else if (symbology == BARCODE_QRCODE || symbology == BARCODE_HIBC_QR || symbology == BARCODE_MICROQR
|| symbology == BARCODE_RMQR) { || symbology == BARCODE_RMQR) {
if (option_1 >= 1 && option_1 <= 4) { if (option_1 >= 1 && option_1 <= 4) {
@ -2972,6 +3004,94 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int
return 0; return 0;
} }
int testUtilBwippSegs(int index, struct zint_symbol *symbol, int option_1, int option_2, int option_3,
const struct zint_seg segs[], const int seg_count, const char *primary, char *buffer, int buffer_size) {
const int symbology = symbol->symbology;
const int unicode_mode = (symbol->input_mode & 0x7) == UNICODE_MODE;
const int symbol_eci = symbol->eci;
struct zint_seg *local_segs = (struct zint_seg *) testutil_alloca(sizeof(struct zint_seg) * seg_count);
int total_len = 0;
char *data, *d;
int parsefnc = 1;
int ret;
int i;
assert(ZBarcode_Cap(symbology, ZINT_CAP_ECI));
for (i = 0; i < seg_count; i++) {
local_segs[i] = segs[i];
if (local_segs[i].length == -1) {
local_segs[i].length = (int) ustrlen(local_segs[i].source);
}
if (unicode_mode) {
total_len += get_eci_length(local_segs[i].eci, local_segs[i].source, local_segs[i].length);
} else {
total_len += local_segs[i].length;
}
}
total_len += 10 * seg_count;
d = data = (char *) testutil_alloca(total_len + 1);
for (i = 0; i < seg_count; i++) {
if (unicode_mode && is_eci_convertible(local_segs[i].eci)) {
char *converted = testUtilBwippUtf8Convert(index, symbology, 0 /*try_sjis*/, &local_segs[i].eci,
local_segs[i].source, &local_segs[i].length, (unsigned char *) d);
if (converted == NULL) {
return -1;
}
if (converted == d) {
/* Ensure default ECI set if follows non-default ECI */
if (i != 0 && local_segs[i].eci == 0 && local_segs[i - 1].eci > 3) {
local_segs[i].eci = 3;
}
if (local_segs[i].eci) { /* Note this will fail if have DotCode macro */
char eci_str[10 + 1];
sprintf(eci_str, "^ECI%06d", local_segs[i].eci);
memmove(d + 10, d, local_segs[i].length);
memcpy(d, eci_str, 10);
d += 10;
}
d += local_segs[i].length;
} else {
/* Ensure default ECI set if follows non-default ECI */
if (i != 0 && local_segs[i].eci == 0 && local_segs[i - 1].eci > 3) {
local_segs[i].eci = 3;
}
if (local_segs[i].eci) {
d += sprintf(d, "^ECI%06d", local_segs[i].eci);
}
memcpy(d, local_segs[i].source, local_segs[i].length);
d += local_segs[i].length;
}
} else {
/* Ensure default ECI set if follows non-default ECI */
if (i != 0 && local_segs[i].eci == 0 && local_segs[i - 1].eci > 3) {
local_segs[i].eci = 3;
}
if (local_segs[i].eci) {
d += sprintf(d, "^ECI%06d", local_segs[i].eci);
}
memcpy(d, local_segs[i].source, local_segs[i].length);
d += local_segs[i].length;
}
}
total_len = d - data;
if (unicode_mode) {
symbol->input_mode = DATA_MODE;
}
symbol->eci = 0;
ret = testUtilBwipp(index, symbol, option_1, option_2, option_3, data, total_len, primary, buffer, buffer_size, &parsefnc);
if (unicode_mode) {
symbol->input_mode = UNICODE_MODE;
}
symbol->eci = symbol_eci;
return ret;
}
/* Compare bwipp_dump.ps output to test suite module dump */ /* Compare bwipp_dump.ps output to test suite module dump */
int testUtilBwippCmp(const struct zint_symbol *symbol, char *msg, char *cmp_buf, const char *expected) { int testUtilBwippCmp(const struct zint_symbol *symbol, char *msg, char *cmp_buf, const char *expected) {
int cmp_len = (int) strlen(cmp_buf); int cmp_len = (int) strlen(cmp_buf);
@ -3039,7 +3159,7 @@ int testUtilBwippCmpRow(const struct zint_symbol *symbol, int row, char *msg, co
/* Whether ZXing-C++ Decoder available on system */ /* Whether ZXing-C++ Decoder available on system */
/* Requires the "diagnostics2" branch from https://github.com/gitlost/zxing-cpp built with BUILD_EXAMPLE_DECODER /* Requires the "diagnostics2" branch from https://github.com/gitlost/zxing-cpp built with BUILD_EXAMPLE_DECODER
and "zintcppdecoder" placed in PATH, e.g.: and "zxingcppdecoder" placed in PATH, e.g.:
git clone --branch diagnostics2 https://github.com/gitlost/zxing-cpp zxing-cpp-diagnostics2 git clone --branch diagnostics2 https://github.com/gitlost/zxing-cpp zxing-cpp-diagnostics2
cd zxing-cpp-diagnostics2 cd zxing-cpp-diagnostics2
mkdir build; cd build mkdir build; cd build
@ -3261,9 +3381,9 @@ int testUtilCanZXingCPP(int index, const struct zint_symbol *symbol, const char
int testUtilZXingCPP(int index, struct zint_symbol *symbol, const char *source, const int length, char *bits, int testUtilZXingCPP(int index, struct zint_symbol *symbol, const char *source, const int length, char *bits,
char *buffer, const int buffer_size, int *p_cmp_len) { char *buffer, const int buffer_size, int *p_cmp_len) {
static const char cmd_fmt[] = "zxingcppdecoder -width %d -textonly -format %s -zint '%d,%d' -bits '%s'"; static const char cmd_fmt[] = "zxingcppdecoder -width %d -textonly -format %s -bits '%s'";
static const char cs_cmd_fmt[] = "zxingcppdecoder -width %d -textonly -format %s -zint '%d,%d' -bits '%s'" static const char hint_cmd_fmt[] = "zxingcppdecoder -width %d -textonly -format %s -hint '%s' -bits '%s'";
" -charset %s"; static const char cs_cmd_fmt[] = "zxingcppdecoder -width %d -textonly -format %s -bits '%s' -charset %s";
const int bits_len = (int) strlen(bits); const int bits_len = (int) strlen(bits);
const int width = symbol->width; const int width = symbol->width;
@ -3272,6 +3392,7 @@ int testUtilZXingCPP(int index, struct zint_symbol *symbol, const char *source,
const char *zxingcpp_barcode = NULL; const char *zxingcpp_barcode = NULL;
const int data_mode = (symbol->input_mode & 0x07) == DATA_MODE; const int data_mode = (symbol->input_mode & 0x07) == DATA_MODE;
int set_charset = 0; int set_charset = 0;
const char *hint = NULL;
FILE *fp = NULL; FILE *fp = NULL;
int cnt; int cnt;
@ -3284,16 +3405,38 @@ int testUtilZXingCPP(int index, struct zint_symbol *symbol, const char *source,
return -1; return -1;
} }
if (symbol->eci == 0 && symbol->symbology == BARCODE_HANXIN) { if (symbology == BARCODE_EXCODE39) {
if (symbol->option_2 == 1) {
hint = "tryCode39ExtendedMode,validateCode39CheckSum";
} else {
hint = "tryCode39ExtendedMode";
}
} else if ((symbology == BARCODE_CODE39 || symbology == BARCODE_LOGMARS) && symbol->option_2 == 1) {
hint = "validateCode39CheckSum";
}
if ((symbol->input_mode & 0x07) == UNICODE_MODE && symbol->eci == 0
&& (symbology == BARCODE_QRCODE || symbology == BARCODE_HANXIN)) {
int converted_len = length; int converted_len = length;
unsigned char *converted_buf = (unsigned char *) testutil_alloca(converted_len + 1); unsigned char *converted_buf = (unsigned char *) testutil_alloca(converted_len + 1);
set_charset = utf8_to_eci(0, (const unsigned char *) source, converted_buf, &converted_len) != 0; if (symbology == BARCODE_HANXIN) {
set_charset = utf8_to_eci(0, (const unsigned char *) source, converted_buf, &converted_len) != 0;
} else {
set_charset = utf8_to_eci(0, (const unsigned char *) source, converted_buf, &converted_len) == 0;
}
} }
if (set_charset) { if (set_charset) {
static const char charset[] = "GB18030"; const char *charset;
sprintf(cmd, cs_cmd_fmt, width, zxingcpp_barcode, symbology, symbol->option_2, bits, charset); if (symbology == BARCODE_HANXIN) {
charset = "GB18030";
} else {
charset = "ISO8859_1";
}
sprintf(cmd, cs_cmd_fmt, width, zxingcpp_barcode, bits, charset);
} else if (hint) {
sprintf(cmd, hint_cmd_fmt, width, zxingcpp_barcode, hint, bits);
} else { } else {
sprintf(cmd, cmd_fmt, width, zxingcpp_barcode, symbology, symbol->option_2, bits); sprintf(cmd, cmd_fmt, width, zxingcpp_barcode, bits);
} }
if (symbol->debug & ZINT_DEBUG_TEST_PRINT) { if (symbol->debug & ZINT_DEBUG_TEST_PRINT) {
@ -3313,7 +3456,6 @@ int testUtilZXingCPP(int index, struct zint_symbol *symbol, const char *source,
testutil_pclose(fp); testutil_pclose(fp);
return -1; return -1;
} }
buffer[cnt] = '\0';
if (fgetc(fp) != EOF) { if (fgetc(fp) != EOF) {
fprintf(stderr, "i:%d testUtilZXingCPP: failed to read full stream (%s)\n", index, cmd); fprintf(stderr, "i:%d testUtilZXingCPP: failed to read full stream (%s)\n", index, cmd);
@ -3323,8 +3465,8 @@ int testUtilZXingCPP(int index, struct zint_symbol *symbol, const char *source,
testutil_pclose(fp); testutil_pclose(fp);
if (data_mode && (is_eci_convertible(symbol->eci) || symbol->eci == 899)) { if (data_mode && (is_eci_convertible(symbol->eci) || symbol->eci >= 899)) {
const int eci = symbol->eci == 899 ? 3 : symbol->eci; const int eci = symbol->eci >= 899 ? 3 : symbol->eci;
int error_number; int error_number;
const int eci_length = get_eci_length(eci, (const unsigned char *) buffer, cnt); const int eci_length = get_eci_length(eci, (const unsigned char *) buffer, cnt);
unsigned char *preprocessed = (unsigned char *) testutil_alloca(eci_length + 1); unsigned char *preprocessed = (unsigned char *) testutil_alloca(eci_length + 1);
@ -3338,8 +3480,8 @@ int testUtilZXingCPP(int index, struct zint_symbol *symbol, const char *source,
if (error_number == 0) { if (error_number == 0) {
memcpy(buffer, preprocessed, cnt); memcpy(buffer, preprocessed, cnt);
} else { } else {
if (eci != 0) { if (eci != 0 && symbol->eci < 899) {
fprintf(stderr, "i:%d testUtilZXingCPP: utf8_to_eci == %d (%s)\n", index, error_number, cmd); fprintf(stderr, "i:%d testUtilZXingCPP: utf8_to_eci(%d) == %d (%s)\n", index, eci, error_number, cmd);
return -1; return -1;
} else { } else {
int i; int i;
@ -3383,17 +3525,17 @@ int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, in
const int is_dbar_exp = symbology == BARCODE_DBAR_EXP || symbology == BARCODE_DBAR_EXPSTK; const int is_dbar_exp = symbology == BARCODE_DBAR_EXP || symbology == BARCODE_DBAR_EXPSTK;
const int is_upcean = is_extendable(symbology); const int is_upcean = is_extendable(symbology);
char *reduced = gs1 ? (char *) alloca(expected_len + 1) : NULL; char *reduced = gs1 ? (char *) testutil_alloca(expected_len + 1) : NULL;
char *escaped = is_escaped ? (char *) alloca(expected_len + 1) : NULL; char *escaped = is_escaped ? (char *) testutil_alloca(expected_len + 1) : NULL;
char *hibc = is_hibc ? (char *) alloca(expected_len + 2 + 1) : NULL; char *hibc = is_hibc ? (char *) testutil_alloca(expected_len + 2 + 1) : NULL;
char *maxi = symbology == BARCODE_MAXICODE && primary char *maxi = symbology == BARCODE_MAXICODE && primary
? (char *) alloca(expected_len + strlen(primary) + 6 + 9 + 1) : NULL; ? (char *) testutil_alloca(expected_len + strlen(primary) + 6 + 9 + 1) : NULL;
char *vin = symbology == BARCODE_VIN && (symbol->option_2 & 1) ? (char *) alloca(expected_len + 1 + 1) : NULL; char *vin = symbology == BARCODE_VIN && (symbol->option_2 & 1) ? (char *) testutil_alloca(expected_len + 1 + 1) : NULL;
char *c25inter = have_c25inter ? (char *) alloca(expected_len + 13 + 1 + 1) : NULL; char *c25inter = have_c25inter ? (char *) testutil_alloca(expected_len + 13 + 1 + 1) : NULL;
char *dbar_exp = is_dbar_exp ? (char *) alloca(expected_len + 1) : NULL; char *dbar_exp = is_dbar_exp ? (char *) testutil_alloca(expected_len + 1) : NULL;
char *upcean = is_upcean ? (char *) alloca(expected_len + 1 + 1) : NULL; char *upcean = is_upcean ? (char *) testutil_alloca(expected_len + 1 + 1) : NULL;
char *ean14_nve18 = symbology == BARCODE_EAN14 || symbology == BARCODE_NVE18 char *ean14_nve18 = symbology == BARCODE_EAN14 || symbology == BARCODE_NVE18
? (char *) alloca(expected_len + 3 + 1) : NULL; ? (char *) testutil_alloca(expected_len + 3 + 1) : NULL;
int ret; int ret;
int ret_memcmp; int ret_memcmp;
@ -3417,7 +3559,7 @@ int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, in
} }
if (gs1 && symbology != BARCODE_EAN14 && symbology != BARCODE_NVE18) { if (gs1 && symbology != BARCODE_EAN14 && symbology != BARCODE_NVE18) {
ret = gs1_verify(symbol, (const unsigned char *) expected, expected_len, (unsigned char *) reduced); ret = gs1_verify(symbol, (const unsigned char *) expected, expected_len, (unsigned char *) reduced);
if (ret != 0) { if (ret >= ZINT_ERROR) {
sprintf(msg, "gs1_verify %d != 0", ret); sprintf(msg, "gs1_verify %d != 0", ret);
return 4; return 4;
} }
@ -3451,15 +3593,26 @@ int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, in
expected = hibc; expected = hibc;
} }
if (symbology == BARCODE_MAXICODE) { if (symbology == BARCODE_MAXICODE) {
if (symbol->primary && symbol->primary[0]) { if (primary && primary[0]) {
int primary_len = (int) strlen(primary); int primary_len = (int) strlen(primary);
int maxi_len = 0; int maxi_len = 0;
if (symbol->option_2 >= 1 && symbol->option_2 <= 100) { if (symbol->option_2 >= 1 && symbol->option_2 <= 100) {
sprintf(maxi, "[)>\03601\035%02d", symbol->option_2 - 1); sprintf(maxi, "[)>\03601\035%02d", symbol->option_2 - 1);
maxi_len = (int) strlen(maxi); maxi_len = (int) strlen(maxi);
} }
sprintf(maxi + maxi_len, "%-6.*s\035%.*s\035%.*s\035", primary_len - 6, primary, #if 1
if (primary[0] > '9') {
sprintf(maxi + maxi_len, "%-6.*s\035%.*s\035%.*s\035", primary_len - 6, primary,
3, primary + primary_len - 6, 3, primary + primary_len - 3);
} else {
sprintf(maxi + maxi_len, "%.*s\035%.*s\035%.*s\035", primary_len - 6, primary,
3, primary + primary_len - 6, 3, primary + primary_len - 3);
}
#else
sprintf(maxi + maxi_len, "%.*s\035%.*s\035%.*s\035", primary_len - 6, primary,
3, primary + primary_len - 6, 3, primary + primary_len - 3); 3, primary + primary_len - 6, 3, primary + primary_len - 3);
#endif
printf("primary %s, primary_len %d\n", primary, primary_len);
maxi_len = (int) strlen(maxi); maxi_len = (int) strlen(maxi);
memcpy(maxi + maxi_len, expected, expected_len); memcpy(maxi + maxi_len, expected, expected_len);
expected = maxi; expected = maxi;
@ -3683,4 +3836,21 @@ int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, in
return 0; return 0;
} }
int testUtilZXingCPPCmpSegs(struct zint_symbol *symbol, char *msg, char *cmp_buf, int cmp_len,
const struct zint_seg segs[], const int seg_count, const char *primary, char *ret_buf, int *p_ret_len) {
int expected_len = segs_length(segs, seg_count);
char *expected = (char *) testutil_alloca(expected_len + 1);
char *s = expected;
int i;
for (i = 0; i < seg_count; i++) {
int len = segs[i].length == -1 ? (int) ustrlen(segs[i].source) : segs[i].length;
memcpy(s, segs[i].source, len);
s += len;
}
*s = '\0';
return testUtilZXingCPPCmp(symbol, msg, cmp_buf, cmp_len, expected, expected_len, primary, ret_buf, p_ret_len);
}
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */

View File

@ -111,6 +111,8 @@ void assert_notequal(int e1, int e2, ...);
#define assert_notequal(__e1__, __e2__, ...) assert_exp((__e1__) != (__e2__), __VA_ARGS__) #define assert_notequal(__e1__, __e2__, ...) assert_exp((__e1__) != (__e2__), __VA_ARGS__)
#endif #endif
#define TU(p) ((unsigned char *) (p))
INTERNAL void vector_free(struct zint_symbol *symbol); /* Free vector structures */ INTERNAL void vector_free(struct zint_symbol *symbol); /* Free vector structures */
int testUtilSetSymbol(struct zint_symbol *symbol, int symbology, int input_mode, int eci, int testUtilSetSymbol(struct zint_symbol *symbol, int symbology, int input_mode, int eci,
@ -170,7 +172,9 @@ int testUtilVerifyTiffInfo(const char *filename, int debug);
int testUtilCanBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3, int testUtilCanBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3,
int debug); int debug);
int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3, int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3,
const char *data, int length, const char *primary, char *buffer, int buffer_size); const char *data, int length, const char *primary, char *buffer, int buffer_size, int *p_parsefnc);
int testUtilBwippSegs(int index, struct zint_symbol *symbol, int option_1, int option_2, int option_3,
const struct zint_seg segs[], const int seg_count, const char *primary, char *buffer, int buffer_size);
int testUtilBwippCmp(const struct zint_symbol *symbol, char *msg, char *cmp_buf, const char *expected); int testUtilBwippCmp(const struct zint_symbol *symbol, char *msg, char *cmp_buf, const char *expected);
int testUtilBwippCmpRow(const struct zint_symbol *symbol, int row, char *msg, const char *cmp_buf, int testUtilBwippCmpRow(const struct zint_symbol *symbol, int row, char *msg, const char *cmp_buf,
const char *expected); const char *expected);
@ -180,8 +184,12 @@ int testUtilCanZXingCPP(int index, const struct zint_symbol *symbol, const char
const int debug); const int debug);
int testUtilZXingCPP(int index, struct zint_symbol *symbol, const char *source, const int length, char *bits, int testUtilZXingCPP(int index, struct zint_symbol *symbol, const char *source, const int length, char *bits,
char *buffer, const int buffer_size, int *p_cmp_len); char *buffer, const int buffer_size, int *p_cmp_len);
int testUtilZXingCPPSegs(int index, struct zint_symbol *symbol, const struct zint_seg segs[], const int seg_count, char *bits,
char *buffer, const int buffer_size, int *p_cmp_len);
int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, int cmp_len, int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, int cmp_len,
const char *expected, int expected_len, const char *primary, char *ret_buf, int *p_ret_len); const char *expected, int expected_len, const char *primary, char *ret_buf, int *p_ret_len);
int testUtilZXingCPPCmpSegs(struct zint_symbol *symbol, char *msg, char *cmp_buf, int cmp_len,
const struct zint_seg segs[], const int seg_count, const char *primary, char *ret_buf, int *p_ret_len);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,5 +1,5 @@
--- /home/mburke/code/bwipp/postscriptbarcode/build/monolithic/barcode.ps 2022-04-04 14:55:50.742795871 +0100 --- /home/mburke/code/bwipp/postscriptbarcode/build/monolithic/barcode.ps 2022-05-09 17:52:29.878548024 +0100
+++ backend/tests/tools/bwipp_dump.ps 2022-04-09 18:28:15.057483295 +0100 +++ backend/tests/tools/bwipp_dump.ps 2022-05-09 18:09:55.849954110 +0100
@@ -15187,8 +15187,8 @@ @@ -15187,8 +15187,8 @@
} bind } bind
/fime { /fime {
@ -11,7 +11,7 @@
} bind } bind
>> def >> def
@@ -26445,34 +26445,80 @@ @@ -26479,34 +26479,80 @@
pop pop
} ifelse } ifelse
@ -111,7 +111,7 @@
end end
@@ -26531,7 +26577,7 @@ @@ -26565,7 +26611,7 @@
pop pop
} ifelse } ifelse
@ -120,7 +120,7 @@
% Get the result of encoding with ean8 and gs1-cc % Get the result of encoding with ean8 and gs1-cc
options (lintype) (ean8) put options (lintype) (ean8) put
@@ -26539,29 +26585,75 @@ @@ -26573,29 +26619,75 @@
options (dontdraw) true put options (dontdraw) true put
% Plot the linear part % Plot the linear part
@ -216,7 +216,7 @@
end end
@@ -26620,34 +26712,80 @@ @@ -26654,34 +26746,80 @@
pop pop
} ifelse } ifelse
@ -316,7 +316,7 @@
end end
@@ -26721,34 +26859,80 @@ @@ -26755,34 +26893,80 @@
/opt options /opt options
>> def >> def
@ -416,7 +416,7 @@
end end
@@ -26807,7 +26991,7 @@ @@ -26841,7 +27025,7 @@
pop pop
} ifelse } ifelse
@ -425,7 +425,7 @@
options (lintype) (databaromni) put options (lintype) (databaromni) put
options (linkage) true put options (linkage) true put
@@ -26818,7 +27002,7 @@ @@ -26852,7 +27036,7 @@
linear options //databaromni exec linear options //databaromni exec
dup (sbs) get /linsbs exch def dup (sbs) get /linsbs exch def
dup (bhs) get 0 get 72 mul /linheight exch def dup (bhs) get 0 get 72 mul /linheight exch def
@ -434,7 +434,7 @@
% Plot the separator % Plot the separator
/sepfinder { /sepfinder {
@@ -26849,20 +27033,66 @@ @@ -26883,20 +27067,66 @@
sep 0 [0 0 0] putinterval sep 0 [0 0 0] putinterval
sep sep length 4 sub [0 0 0 0] putinterval sep sep length 4 sub [0 0 0 0] putinterval
18 sepfinder 64 sepfinder 18 sepfinder 64 sepfinder
@ -513,7 +513,7 @@
end end
@@ -26920,7 +27150,7 @@ @@ -26954,7 +27184,7 @@
pop pop
} ifelse } ifelse
@ -522,7 +522,7 @@
options (lintype) (databarstacked) put options (lintype) (databarstacked) put
options (linkage) true put options (linkage) true put
@@ -26931,7 +27161,7 @@ @@ -26965,7 +27195,7 @@
linear options //databarstacked exec linear options //databarstacked exec
dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def
dup (pixy) get /linheight exch def dup (pixy) get /linheight exch def
@ -531,7 +531,7 @@
% Plot the separator % Plot the separator
/sepfinder { /sepfinder {
@@ -26959,20 +27189,52 @@ @@ -26993,20 +27223,52 @@
sep 0 [ 0 0 0 0 ] putinterval sep 0 [ 0 0 0 0 ] putinterval
sep sep length 4 sub [ 0 0 0 0 ] putinterval sep sep length 4 sub [ 0 0 0 0 ] putinterval
18 sepfinder 18 sepfinder
@ -596,7 +596,7 @@
end end
@@ -27030,7 +27292,7 @@ @@ -27064,7 +27326,7 @@
pop pop
} ifelse } ifelse
@ -605,7 +605,7 @@
options (lintype) (databarstackedomni) put options (lintype) (databarstackedomni) put
options (linkage) true put options (linkage) true put
@@ -27041,7 +27303,7 @@ @@ -27075,7 +27337,7 @@
linear options //databarstackedomni exec linear options //databarstackedomni exec
dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def
dup (pixy) get /linheight exch def dup (pixy) get /linheight exch def
@ -614,7 +614,7 @@
% Plot the separator % Plot the separator
/sepfinder { /sepfinder {
@@ -27069,20 +27331,52 @@ @@ -27103,20 +27365,52 @@
sep 0 [ 0 0 0 0 ] putinterval sep 0 [ 0 0 0 0 ] putinterval
sep sep length 4 sub [ 0 0 0 0 ] putinterval sep sep length 4 sub [ 0 0 0 0 ] putinterval
18 sepfinder 18 sepfinder
@ -679,7 +679,7 @@
end end
@@ -27255,7 +27549,7 @@ @@ -27289,7 +27583,7 @@
pop pop
} ifelse } ifelse
@ -688,7 +688,7 @@
options (lintype) (databarlimited) put options (lintype) (databarlimited) put
options (linkage) true put options (linkage) true put
@@ -27266,7 +27560,7 @@ @@ -27300,7 +27594,7 @@
linear options //databarlimited exec linear options //databarlimited exec
dup (sbs) get /linsbs exch def dup (sbs) get /linsbs exch def
dup (bhs) get 0 get 72 mul /linheight exch def dup (bhs) get 0 get 72 mul /linheight exch def
@ -697,7 +697,7 @@
% Plot the separator % Plot the separator
mark mark
@@ -27274,22 +27568,68 @@ @@ -27308,22 +27602,68 @@
counttomark 1 sub array astore /sep exch def pop pop counttomark 1 sub array astore /sep exch def pop pop
sep 0 [0 0 0] putinterval sep 0 [0 0 0] putinterval
sep sep length 9 sub [0 0 0 0 0 0 0 0 0] putinterval % 4 + 5 right guard spaces sep sep length 9 sub [0 0 0 0 0 0 0 0 0] putinterval % 4 + 5 right guard spaces
@ -780,7 +780,7 @@
end end
@@ -27348,7 +27688,7 @@ @@ -27382,7 +27722,7 @@
pop pop
} ifelse } ifelse
@ -789,7 +789,7 @@
options (lintype) (databarexpanded) put options (lintype) (databarexpanded) put
options (linkage) true put options (linkage) true put
@@ -27359,7 +27699,7 @@ @@ -27393,7 +27733,7 @@
linear options //databarexpanded exec linear options //databarexpanded exec
dup (sbs) get /linsbs exch def dup (sbs) get /linsbs exch def
dup (bhs) get 0 get 72 mul /linheight exch def dup (bhs) get 0 get 72 mul /linheight exch def
@ -798,7 +798,7 @@
% Plot the separator % Plot the separator
/sepfinder { /sepfinder {
@@ -27388,20 +27728,60 @@ @@ -27422,20 +27762,60 @@
18 98 bot length 13 sub {} for 18 98 bot length 13 sub {} for
69 98 bot length 13 sub {} for 69 98 bot length 13 sub {} for
] {sepfinder} forall ] {sepfinder} forall
@ -871,7 +871,7 @@
end end
@@ -27459,7 +27839,7 @@ @@ -27493,7 +27873,7 @@
pop pop
} ifelse } ifelse
@ -880,7 +880,7 @@
options (lintype) (databarexpandedstacked) put options (lintype) (databarexpandedstacked) put
options (linkage) true put options (linkage) true put
@@ -27470,7 +27850,7 @@ @@ -27504,7 +27884,7 @@
linear options //databarexpandedstacked exec linear options //databarexpandedstacked exec
dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def
dup (pixy) get /linheight exch def dup (pixy) get /linheight exch def
@ -889,7 +889,7 @@
% Plot the separator % Plot the separator
/sepfinder { /sepfinder {
@@ -27496,21 +27876,49 @@ @@ -27530,21 +27910,49 @@
19 98 bot length 13 sub {} for 19 98 bot length 13 sub {} for
70 98 bot length 13 sub {} for 70 98 bot length 13 sub {} for
] {sepfinder} forall ] {sepfinder} forall
@ -952,7 +952,7 @@
end end
@@ -27569,7 +27977,7 @@ @@ -27603,7 +28011,7 @@
pop pop
} ifelse } ifelse
@ -961,7 +961,7 @@
options (inkspread) (0) put options (inkspread) (0) put
options (dontdraw) true put options (dontdraw) true put
@@ -27596,35 +28004,87 @@ @@ -27630,35 +28038,87 @@
linear << options {} forall >> //gs1-128 exec linear << options {} forall >> //gs1-128 exec
dup (sbs) get /linsbs exch def dup (sbs) get /linsbs exch def
dup (bhs) get 0 get 72 mul /linheight exch def dup (bhs) get 0 get 72 mul /linheight exch def
@ -1063,7 +1063,7 @@
end end
@@ -29057,3 +29517,189 @@ @@ -29091,3 +29551,189 @@
% --END ENCODER hibcazteccode-- % --END ENCODER hibcazteccode--
% --END TEMPLATE-- % --END TEMPLATE--

View File

@ -16,27 +16,33 @@ function run_bwipp_test() {
run_bwipp_test "test_2of5" "encode" run_bwipp_test "test_2of5" "encode"
run_bwipp_test "test_auspost" "encode" run_bwipp_test "test_auspost" "encode"
run_bwipp_test "test_aztec" "encode" run_bwipp_test "test_aztec" "encode"
run_bwipp_test "test_aztec" "encode_segs"
run_bwipp_test "test_channel" "encode" run_bwipp_test "test_channel" "encode"
run_bwipp_test "test_codablock" "encode" run_bwipp_test "test_codablock" "encode"
run_bwipp_test "test_code" "encode" run_bwipp_test "test_code" "encode"
run_bwipp_test "test_code1" "encode" run_bwipp_test "test_code1" "encode"
run_bwipp_test "test_code1" "encode_segs"
run_bwipp_test "test_code128" "encode" run_bwipp_test "test_code128" "encode"
run_bwipp_test "test_code16k" "encode" run_bwipp_test "test_code16k" "encode"
run_bwipp_test "test_code49" "encode" run_bwipp_test "test_code49" "encode"
run_bwipp_test "test_composite" run_bwipp_test "test_composite"
run_bwipp_test "test_dmatrix" "input" run_bwipp_test "test_dmatrix" "input"
run_bwipp_test "test_dmatrix" "encode" run_bwipp_test "test_dmatrix" "encode"
run_bwipp_test "test_dmatrix" "encode_segs"
run_bwipp_test "test_dotcode" "input"
run_bwipp_test "test_dotcode" "encode" run_bwipp_test "test_dotcode" "encode"
run_bwipp_test "test_dotcode" "encode_segs"
run_bwipp_test "test_gs1" "gs1_reduce" run_bwipp_test "test_gs1" "gs1_reduce"
run_bwipp_test "test_imail" "encode" run_bwipp_test "test_imail" "encode"
run_bwipp_test "test_maxicode" "input"
run_bwipp_test "test_maxicode" "encode" run_bwipp_test "test_maxicode" "encode"
run_bwipp_test "test_maxicode" "encode_segs"
run_bwipp_test "test_medical" "encode" run_bwipp_test "test_medical" "encode"
run_bwipp_test "test_pdf417" "encode" run_bwipp_test "test_pdf417" "encode"
run_bwipp_test "test_pdf417" "encode_segs"
run_bwipp_test "test_plessey" "encode" run_bwipp_test "test_plessey" "encode"
run_bwipp_test "test_postal" "encode" run_bwipp_test "test_postal" "encode"
run_bwipp_test "test_qr" "qr_encode" run_bwipp_test "test_qr"
run_bwipp_test "test_qr" "microqr_encode"
run_bwipp_test "test_qr" "rmqr_encode"
run_bwipp_test "test_rss" run_bwipp_test "test_rss"
run_bwipp_test "test_telepen" "encode" run_bwipp_test "test_telepen" "encode"
run_bwipp_test "test_upcean" "upce_input" run_bwipp_test "test_upcean" "upce_input"

View File

@ -10,16 +10,28 @@ function run_zxingcpp_test() {
run_zxingcpp_test "test_2of5" "encode" run_zxingcpp_test "test_2of5" "encode"
run_zxingcpp_test "test_aztec" "encode" run_zxingcpp_test "test_aztec" "encode"
run_zxingcpp_test "test_aztec" "encode_segs"
run_zxingcpp_test "test_code" "encode" run_zxingcpp_test "test_code" "encode"
run_zxingcpp_test "test_code128" "encode" run_zxingcpp_test "test_code128" "encode"
run_zxingcpp_test "test_dmatrix" "input" run_zxingcpp_test "test_dmatrix" "input"
run_zxingcpp_test "test_dmatrix" "encode" run_zxingcpp_test "test_dmatrix" "encode"
run_zxingcpp_test "test_dmatrix" "encode_segs"
run_zxingcpp_test "test_dotcode" "input"
run_zxingcpp_test "test_dotcode" "encode" run_zxingcpp_test "test_dotcode" "encode"
run_zxingcpp_test "test_dotcode" "encode_segs"
run_zxingcpp_test "test_hanxin" "input"
run_zxingcpp_test "test_hanxin" "encode" run_zxingcpp_test "test_hanxin" "encode"
run_zxingcpp_test "test_hanxin" "encode_segs"
run_zxingcpp_test "test_maxicode" "input"
run_zxingcpp_test "test_maxicode" "encode" run_zxingcpp_test "test_maxicode" "encode"
run_zxingcpp_test "test_maxicode" "encode_segs"
run_zxingcpp_test "test_medical" "encode" run_zxingcpp_test "test_medical" "encode"
run_zxingcpp_test "test_pdf417" "encode" run_zxingcpp_test "test_pdf417" "encode"
run_zxingcpp_test "test_pdf417" "encode_segs"
run_zxingcpp_test "test_qr" "qr_input"
run_zxingcpp_test "test_qr" "qr_optimize"
run_zxingcpp_test "test_qr" "qr_encode" run_zxingcpp_test "test_qr" "qr_encode"
run_zxingcpp_test "test_qr" "qr_encode_segs"
run_zxingcpp_test "test_rss" "binary_div_modulo_divisor" run_zxingcpp_test "test_rss" "binary_div_modulo_divisor"
run_zxingcpp_test "test_rss" "examples" run_zxingcpp_test "test_rss" "examples"
run_zxingcpp_test "test_upcean" "upce_input" run_zxingcpp_test "test_upcean" "upce_input"

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* zint.h - definitions for libzint /* zint.h - definitions for libzint
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009-2021 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -28,7 +28,6 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
/* vim: set ts=4 sw=4 et : */
/* /*
* For version, see "zintconfig.h" * For version, see "zintconfig.h"
* For documentation, see "../docs/manual.txt" * For documentation, see "../docs/manual.txt"
@ -83,7 +82,7 @@ extern "C" {
/* Structured Append info - ignored unless `zint_structapp.count` is set to non-zero value */ /* Structured Append info - ignored unless `zint_structapp.count` is set to non-zero value */
struct zint_structapp { struct zint_structapp {
int index; /* Position in Structured Append sequence, 1-based. Must be <= count */ int index; /* Position in Structured Append sequence, 1-based. Must be <= `count` */
int count; /* Number of symbols in Structured Append sequence. Set >= 2 to add SA Info */ int count; /* Number of symbols in Structured Append sequence. Set >= 2 to add SA Info */
char id[32]; /* Optional ID to distinguish sequence, ASCII, NUL-terminated unless max 32 long */ char id[32]; /* Optional ID to distinguish sequence, ASCII, NUL-terminated unless max 32 long */
}; };
@ -129,6 +128,13 @@ extern "C" {
struct zint_vector *vector; /* Pointer to vector header (vector output only) */ struct zint_vector *vector; /* Pointer to vector header (vector output only) */
}; };
/* Segment for use with `ZBarcode_Encode_Segs()` below */
struct zint_seg {
unsigned char *source; /* Data to encode */
int length; /* Length of `source`. If 0, `source` must be NUL-terminated */
int eci; /* Extended Channel Interpretation */
};
/* Symbologies (`symbol->symbology`) */ /* Symbologies (`symbol->symbology`) */
/* Tbarcode 7 codes */ /* Tbarcode 7 codes */
#define BARCODE_CODE11 1 /* Code 11 */ #define BARCODE_CODE11 1 /* Code 11 */
@ -163,7 +169,7 @@ extern "C" {
#define BARCODE_UPCA_CHK 35 /* UPC-A + Check Digit */ #define BARCODE_UPCA_CHK 35 /* UPC-A + Check Digit */
#define BARCODE_UPCE 37 /* UPC-E */ #define BARCODE_UPCE 37 /* UPC-E */
#define BARCODE_UPCE_CHK 38 /* UPC-E + Check Digit */ #define BARCODE_UPCE_CHK 38 /* UPC-E + Check Digit */
#define BARCODE_POSTNET 40 /* USPS POSTNET */ #define BARCODE_POSTNET 40 /* USPS (U.S. Postal Service) POSTNET */
#define BARCODE_MSI_PLESSEY 47 /* MSI Plessey */ #define BARCODE_MSI_PLESSEY 47 /* MSI Plessey */
#define BARCODE_FIM 49 /* Facing Identification Mark */ #define BARCODE_FIM 49 /* Facing Identification Mark */
#define BARCODE_LOGMARS 50 /* LOGMARS */ #define BARCODE_LOGMARS 50 /* LOGMARS */
@ -211,7 +217,7 @@ extern "C" {
#define BARCODE_MICROQR 97 /* Micro QR Code */ #define BARCODE_MICROQR 97 /* Micro QR Code */
/* Tbarcode 9 codes */ /* Tbarcode 9 codes */
#define BARCODE_HIBC_128 98 /* HIBC Code 128 */ #define BARCODE_HIBC_128 98 /* HIBC (Health Industry Barcode) Code 128 */
#define BARCODE_HIBC_39 99 /* HIBC Code 39 */ #define BARCODE_HIBC_39 99 /* HIBC Code 39 */
#define BARCODE_HIBC_DM 102 /* HIBC Data Matrix */ #define BARCODE_HIBC_DM 102 /* HIBC Data Matrix */
#define BARCODE_HIBC_QR 104 /* HIBC QR Code */ #define BARCODE_HIBC_QR 104 /* HIBC QR Code */
@ -333,6 +339,8 @@ extern "C" {
/* The largest amount of data that can be encoded is 4350 4-byte UTF-8 chars in Han Xin Code */ /* The largest amount of data that can be encoded is 4350 4-byte UTF-8 chars in Han Xin Code */
#define ZINT_MAX_DATA_LEN 17400 #define ZINT_MAX_DATA_LEN 17400
/* Maximum number of segments allowed for (`seg_count`) */
#define ZINT_MAX_SEG_COUNT 256
/* Debug flags (debug) */ /* Debug flags (debug) */
#define ZINT_DEBUG_PRINT 0x0001 /* Print debug info (if any) to stdout */ #define ZINT_DEBUG_PRINT 0x0001 /* Print debug info (if any) to stdout */
@ -360,9 +368,13 @@ extern "C" {
ZINT_EXTERN void ZBarcode_Delete(struct zint_symbol *symbol); ZINT_EXTERN void ZBarcode_Delete(struct zint_symbol *symbol);
/* Encode a barcode. If `length` is 0, `source` must be NUL-terminated. */ /* Encode a barcode. If `length` is 0, `source` must be NUL-terminated */
ZINT_EXTERN int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int length); ZINT_EXTERN int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int length);
/* Encode a barcode with multiple ECI segments */
ZINT_EXTERN int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[],
const int seg_count);
/* Encode a barcode using input data from file `filename` */ /* Encode a barcode using input data from file `filename` */
ZINT_EXTERN int ZBarcode_Encode_File(struct zint_symbol *symbol, const char *filename); ZINT_EXTERN int ZBarcode_Encode_File(struct zint_symbol *symbol, const char *filename);
@ -374,6 +386,10 @@ extern "C" {
ZINT_EXTERN int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, const unsigned char *source, int length, ZINT_EXTERN int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, const unsigned char *source, int length,
int rotate_angle); int rotate_angle);
/* Encode a symbol with multiple ECI segments and output to file `symbol->outfile` */
ZINT_EXTERN int ZBarcode_Encode_Segs_and_Print(struct zint_symbol *symbol, const struct zint_seg segs[],
const int seg_count, int rotate_angle);
/* Encode a symbol using input data from file `filename` and output to file `symbol->outfile` */ /* Encode a symbol using input data from file `filename` and output to file `symbol->outfile` */
ZINT_EXTERN int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, const char *filename, ZINT_EXTERN int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, const char *filename,
int rotate_angle); int rotate_angle);
@ -386,6 +402,10 @@ extern "C" {
ZINT_EXTERN int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, const unsigned char *source, int length, ZINT_EXTERN int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, const unsigned char *source, int length,
int rotate_angle); int rotate_angle);
/* Encode a symbol with multiple ECI segments and output to memory as raster (`symbol->bitmap`) */
ZINT_EXTERN int ZBarcode_Encode_Segs_and_Buffer(struct zint_symbol *symbol, const struct zint_seg segs[],
const int seg_count, int rotate_angle);
/* Encode a symbol using input data from file `filename` and output to memory as raster (`symbol->bitmap`) */ /* Encode a symbol using input data from file `filename` and output to memory as raster (`symbol->bitmap`) */
ZINT_EXTERN int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, const char *filename, ZINT_EXTERN int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, const char *filename,
int rotate_angle); int rotate_angle);
@ -398,6 +418,10 @@ extern "C" {
ZINT_EXTERN int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol, const unsigned char *source, ZINT_EXTERN int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol, const unsigned char *source,
int length, int rotate_angle); int length, int rotate_angle);
/* Encode a symbol with multiple ECI segments and output to memory as vector (`symbol->vector`) */
ZINT_EXTERN int ZBarcode_Encode_Segs_and_Buffer_Vector(struct zint_symbol *symbol, const struct zint_seg segs[],
const int seg_count, int rotate_angle);
/* Encode a symbol using input data from file `filename` and output to memory as vector (`symbol->vector`) */ /* Encode a symbol using input data from file `filename` and output to memory as vector (`symbol->vector`) */
ZINT_EXTERN int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol, const char *filename, ZINT_EXTERN int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol, const char *filename,
int rotate_angle); int rotate_angle);
@ -420,4 +444,5 @@ extern "C" {
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
/* vim: set ts=4 sw=4 et : */
#endif /* ZINT_H */ #endif /* ZINT_H */

View File

@ -34,10 +34,36 @@
#define QSL QStringLiteral #define QSL QStringLiteral
namespace Zint { namespace Zint {
static const char *fontStyle = "Helvetica"; static const char fontStyle[] = "Helvetica";
static const char *fontStyleError = "Helvetica"; static const char fontStyleError[] = "Helvetica";
static const int fontSizeError = 14; /* Point size */ static const int fontSizeError = 14; /* Point size */
static const int maxSegs = 256;
static const int maxCLISegs = 10; /* CLI restricted to 10 segments (including main data) */
/* Helper to convert ECI combo index to ECI value */
static int ECIIndexToECI(const int ECIIndex) {
int ret;
if (ECIIndex >= 1 && ECIIndex <= 11) {
ret = ECIIndex + 2;
} else if (ECIIndex >= 12 && ECIIndex <= 15) {
ret = ECIIndex + 3;
} else if (ECIIndex >= 16 && ECIIndex <= 31) {
ret = ECIIndex + 4;
} else if (ECIIndex == 32) {
ret = 170; /* ISO 646 Invariant */
} else if (ECIIndex == 33) {
ret = 899; /* 8-bit binary data */
} else {
ret = 0;
}
return ret;
}
/* Segment constructors */
QZintSeg::QZintSeg() : m_eci(0) {}
QZintSeg::QZintSeg(const QString& text, const int ECIIndex) : m_text(text), m_eci(ECIIndexToECI(ECIIndex)) {}
QZint::QZint() QZint::QZint()
: m_zintSymbol(NULL), m_symbol(BARCODE_CODE128), m_input_mode(UNICODE_MODE), : m_zintSymbol(NULL), m_symbol(BARCODE_CODE128), m_input_mode(UNICODE_MODE),
m_height(0.0f), m_height(0.0f),
@ -139,9 +165,17 @@ namespace Zint {
void QZint::encode() { void QZint::encode() {
resetSymbol(); resetSymbol();
QByteArray bstr = m_text.toUtf8(); if (m_segs.empty()) {
/* Note do our own rotation */ QByteArray bstr = m_text.toUtf8();
m_error = ZBarcode_Encode_and_Buffer_Vector(m_zintSymbol, (unsigned char *) bstr.data(), bstr.length(), 0); /* Note do our own rotation */
m_error = ZBarcode_Encode_and_Buffer_Vector(m_zintSymbol, (unsigned char *) bstr.data(), bstr.length(), 0);
} else {
struct zint_seg segs[maxSegs];
std::vector<QByteArray> bstrs;
int seg_count = convertSegs(segs, bstrs);
/* Note do our own rotation */
m_error = ZBarcode_Encode_Segs_and_Buffer_Vector(m_zintSymbol, segs, seg_count, 0);
}
m_lastError = m_zintSymbol->errtxt; m_lastError = m_zintSymbol->errtxt;
if (m_error < ZINT_ERROR) { if (m_error < ZINT_ERROR) {
@ -182,6 +216,19 @@ namespace Zint {
void QZint::setText(const QString& text) { void QZint::setText(const QString& text) {
m_text = text; m_text = text;
m_segs.clear();
}
std::vector<QZintSeg> QZint::segs() const {
return m_segs;
}
void QZint::setSegs(const std::vector<QZintSeg>& segs) {
m_segs = segs;
m_text.clear();
if (m_segs.size()) { /* Make sure `symbol->eci` synced */
m_eci = m_segs[0].m_eci;
}
} }
QString QZint::primaryMessage() const { QString QZint::primaryMessage() const {
@ -454,19 +501,7 @@ namespace Zint {
} }
void QZint::setECI(int ECIIndex) { // Sets from comboBox index void QZint::setECI(int ECIIndex) { // Sets from comboBox index
if (ECIIndex >= 1 && ECIIndex <= 11) { m_eci = ECIIndexToECI(ECIIndex);
m_eci = ECIIndex + 2;
} else if (ECIIndex >= 12 && ECIIndex <= 15) {
m_eci = ECIIndex + 3;
} else if (ECIIndex >= 16 && ECIIndex <= 31) {
m_eci = ECIIndex + 4;
} else if (ECIIndex == 32) {
m_eci = 170; /* ISO 646 Invariant */
} else if (ECIIndex == 33) {
m_eci = 899; /* 8-bit binary data */
} else {
m_eci = 0;
}
} }
void QZint::setECIValue(int eci) { // Sets literal value void QZint::setECIValue(int eci) { // Sets literal value
@ -611,12 +646,19 @@ namespace Zint {
return ZBarcode_Version(); return ZBarcode_Version();
} }
bool QZint::save_to_file(const QString &filename) { bool QZint::save_to_file(const QString& filename) {
resetSymbol(); resetSymbol();
strcpy(m_zintSymbol->outfile, filename.toLatin1().left(255)); strcpy(m_zintSymbol->outfile, filename.toLatin1().left(255));
QByteArray bstr = m_text.toUtf8(); if (m_segs.empty()) {
m_error = ZBarcode_Encode_and_Print(m_zintSymbol, (unsigned char *) bstr.data(), bstr.length(), QByteArray bstr = m_text.toUtf8();
m_rotate_angle); m_error = ZBarcode_Encode_and_Print(m_zintSymbol, (unsigned char *) bstr.data(), bstr.length(),
m_rotate_angle);
} else {
struct zint_seg segs[maxSegs];
std::vector<QByteArray> bstrs;
int seg_count = convertSegs(segs, bstrs);
m_error = ZBarcode_Encode_Segs_and_Print(m_zintSymbol, segs, seg_count, m_rotate_angle);
}
if (m_error >= ZINT_ERROR) { if (m_error >= ZINT_ERROR) {
m_lastError = m_zintSymbol->errtxt; m_lastError = m_zintSymbol->errtxt;
m_encodedWidth = 0; m_encodedWidth = 0;
@ -657,6 +699,19 @@ namespace Zint {
} }
} }
/* Helper to convert `m_segs` to `struct zint_seg[]` */
int QZint::convertSegs(struct zint_seg segs[], std::vector<QByteArray>& bstrs) {
bstrs.reserve(m_segs.size());
int i;
for (i = 0; i < (int) m_segs.size() && i < maxSegs && !m_segs[i].m_text.isEmpty(); i++) {
segs[i].eci = m_segs[i].m_eci;
bstrs.push_back(m_segs[i].m_text.toUtf8());
segs[i].source = (unsigned char *) bstrs.back().data();
segs[i].length = bstrs.back().length();
}
return i;
}
/* Note: legacy argument `mode` is not used */ /* Note: legacy argument `mode` is not used */
void QZint::render(QPainter& painter, const QRectF& paintRect, AspectRatioMode /*mode*/) { void QZint::render(QPainter& painter, const QRectF& paintRect, AspectRatioMode /*mode*/) {
struct zint_vector_rect *rect; struct zint_vector_rect *rect;
@ -824,7 +879,7 @@ namespace Zint {
If HEIGHTPERROW_MODE set and non-zero `heightPerRow` given then use that for height instead of internal If HEIGHTPERROW_MODE set and non-zero `heightPerRow` given then use that for height instead of internal
height */ height */
QString QZint::getAsCLI(const bool win, const bool longOptOnly, const bool barcodeNames, QString QZint::getAsCLI(const bool win, const bool longOptOnly, const bool barcodeNames,
const bool autoHeight, const float heightPerRow, const QString &outfile) const { const bool autoHeight, const float heightPerRow, const QString& outfile) const {
QString cmd(win ? QSL("zint.exe") : QSL("zint")); QString cmd(win ? QSL("zint.exe") : QSL("zint"));
char name_buf[32]; char name_buf[32];
@ -859,7 +914,18 @@ namespace Zint {
arg_bool(cmd, "--compliantheight", hasCompliantHeight() && compliantHeight()); arg_bool(cmd, "--compliantheight", hasCompliantHeight() && compliantHeight());
arg_data(cmd, longOptOnly ? "--data=" : "-d ", text(), win); if (m_segs.empty()) {
if (supportsECI()) {
arg_int(cmd, "--eci=", eci());
}
arg_data(cmd, longOptOnly ? "--data=" : "-d ", m_text, win);
} else {
arg_int(cmd, "--eci=", m_segs.front().m_eci);
arg_data(cmd, longOptOnly ? "--data=" : "-d ", m_segs.front().m_text, win);
for (int i = 1; i < (int) m_segs.size() && i < maxCLISegs && !m_segs[i].m_text.isEmpty(); i++) {
arg_seg(cmd, i, m_segs[i], win);
}
}
if (m_symbol == BARCODE_DATAMATRIX || m_symbol == BARCODE_HIBC_DM) { if (m_symbol == BARCODE_DATAMATRIX || m_symbol == BARCODE_HIBC_DM) {
arg_bool(cmd, "--dmre", option3() == DM_DMRE); arg_bool(cmd, "--dmre", option3() == DM_DMRE);
@ -872,10 +938,6 @@ namespace Zint {
arg_bool(cmd, "--dotty", dotty()); arg_bool(cmd, "--dotty", dotty());
} }
if (supportsECI()) {
arg_int(cmd, "--eci=", eci());
}
arg_bool(cmd, "--esc", inputMode() & ESCAPE_MODE); arg_bool(cmd, "--esc", inputMode() & ESCAPE_MODE);
arg_bool(cmd, "--fast", inputMode() & FAST_MODE); arg_bool(cmd, "--fast", inputMode() & FAST_MODE);
@ -992,26 +1054,26 @@ namespace Zint {
} }
/* `getAsCLI()` helpers */ /* `getAsCLI()` helpers */
void QZint::arg_str(QString &cmd, const char *const opt, const QString &val) { void QZint::arg_str(QString& cmd, const char *const opt, const QString& val) {
if (!val.isEmpty()) { if (!val.isEmpty()) {
QByteArray bstr = val.toUtf8(); QByteArray bstr = val.toUtf8();
cmd += QString::asprintf(" %s%.*s", opt, bstr.length(), bstr.data()); cmd += QString::asprintf(" %s%.*s", opt, bstr.length(), bstr.data());
} }
} }
void QZint::arg_int(QString &cmd, const char *const opt, const int val, const bool allowZero) { void QZint::arg_int(QString& cmd, const char *const opt, const int val, const bool allowZero) {
if (val > 0 || (val == 0 && allowZero)) { if (val > 0 || (val == 0 && allowZero)) {
cmd += QString::asprintf(" %s%d", opt, val); cmd += QString::asprintf(" %s%d", opt, val);
} }
} }
void QZint::arg_bool(QString &cmd, const char *const opt, const bool val) { void QZint::arg_bool(QString& cmd, const char *const opt, const bool val) {
if (val) { if (val) {
cmd += QString::asprintf(" %s", opt); cmd += QString::asprintf(" %s", opt);
} }
} }
void QZint::arg_color(QString &cmd, const char *const opt, const QColor val) { void QZint::arg_color(QString& cmd, const char *const opt, const QColor val) {
if (val.alpha() != 0xFF) { if (val.alpha() != 0xFF) {
cmd += QString::asprintf(" %s%02X%02X%02X%02X", opt, val.red(), val.green(), val.blue(), val.alpha()); cmd += QString::asprintf(" %s%02X%02X%02X%02X", opt, val.red(), val.green(), val.blue(), val.alpha());
} else { } else {
@ -1019,33 +1081,43 @@ namespace Zint {
} }
} }
void QZint::arg_data(QString &cmd, const char *const opt, const QString &val, const bool win) { void QZint::arg_data(QString& cmd, const char *const opt, const QString& val, const bool win) {
if (!val.isEmpty()) { if (!val.isEmpty()) {
QString text(val); QString text(val);
const char delim = win ? '"' : '\''; arg_data_esc(cmd, opt, text, win);
if (win) {
// Difficult (impossible?) to fully escape strings on Windows, e.g. "blah%PATH%" will substitute
// env var PATH, so just doing basic escaping here
text.replace("\\\\", "\\\\\\\\"); // Double-up backslashed backslash `\\` -> `\\\\`
text.replace("\"", "\\\""); // Backslash quote `"` -> `\"`
QByteArray bstr = text.toUtf8();
cmd += QString::asprintf(" %s%c%.*s%c", opt, delim, bstr.length(), bstr.data(), delim);
} else {
text.replace("'", "'\\''"); // Single quote `'` -> `'\''`
QByteArray bstr = text.toUtf8();
cmd += QString::asprintf(" %s%c%.*s%c", opt, delim, bstr.length(), bstr.data(), delim);
}
} }
} }
void QZint::arg_float(QString &cmd, const char *const opt, const float val, const bool allowZero) { void QZint::arg_seg(QString& cmd, const int seg_no, const QZintSeg& val, const bool win) {
QString text(val.m_text);
QString opt = QString::asprintf("--seg%d=%d,", seg_no, val.m_eci);
arg_data_esc(cmd, opt.toUtf8(), text, win);
}
void QZint::arg_data_esc(QString& cmd, const char *const opt, QString& text, const bool win) {
const char delim = win ? '"' : '\'';
if (win) {
// Difficult (impossible?) to fully escape strings on Windows, e.g. "blah%PATH%" will substitute
// env var PATH, so just doing basic escaping here
text.replace("\\\\", "\\\\\\\\"); // Double-up backslashed backslash `\\` -> `\\\\`
text.replace("\"", "\\\""); // Backslash quote `"` -> `\"`
QByteArray bstr = text.toUtf8();
cmd += QString::asprintf(" %s%c%.*s%c", opt, delim, bstr.length(), bstr.data(), delim);
} else {
text.replace("'", "'\\''"); // Single quote `'` -> `'\''`
QByteArray bstr = text.toUtf8();
cmd += QString::asprintf(" %s%c%.*s%c", opt, delim, bstr.length(), bstr.data(), delim);
}
}
void QZint::arg_float(QString& cmd, const char *const opt, const float val, const bool allowZero) {
if (val > 0 || (val == 0 && allowZero)) { if (val > 0 || (val == 0 && allowZero)) {
cmd += QString::asprintf(" %s%g", opt, val); cmd += QString::asprintf(" %s%g", opt, val);
} }
} }
void QZint::arg_structapp(QString &cmd, const char *const opt, const int count, const int index, void QZint::arg_structapp(QString& cmd, const char *const opt, const int count, const int index,
const QString &id, const bool win) { const QString& id, const bool win) {
if (count >= 2 && index >= 1) { if (count >= 2 && index >= 1) {
if (id.isEmpty()) { if (id.isEmpty()) {
cmd += QString::asprintf(" %s%d,%d", opt, index, count); cmd += QString::asprintf(" %s%d,%d", opt, index, count);

View File

@ -1,7 +1,7 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2008 by BogDan Vatra * * Copyright (C) 2008 by BogDan Vatra *
* bogdan@licentia.eu * * bogdan@licentia.eu *
* Copyright (C) 2010-2021 Robin Stuart * * Copyright (C) 2010-2022 Robin Stuart *
* * * *
* This program is free software: you can redistribute it and/or modify * * This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
@ -14,7 +14,6 @@
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. * * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/
/* vim: set ts=4 sw=4 et : */
#ifndef QZINT_H #ifndef QZINT_H
#define QZINT_H #define QZINT_H
@ -26,6 +25,17 @@
namespace Zint namespace Zint
{ {
/* QString version of `struct zint_seg` */
class QZintSeg {
public:
QString m_text;
int m_eci;
QZintSeg();
QZintSeg(const QString& text, const int ECIIndex = 0); // `ECIIndex` is comboBox index (not ECI value)
};
/* Interface */
class QZint : public QObject class QZint : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -44,7 +54,10 @@ public:
void setInputMode(int input_mode); void setInputMode(int input_mode);
QString text() const; QString text() const;
void setText(const QString& text); void setText(const QString& text); // Clears segs
std::vector<QZintSeg> segs() const;
void setSegs(const std::vector<QZintSeg>& segs); // Clears text and sets eci
QString primaryMessage() const; QString primaryMessage() const;
void setPrimaryMessage(const QString& primaryMessage); void setPrimaryMessage(const QString& primaryMessage);
@ -177,7 +190,7 @@ public:
const QString& lastError() const; const QString& lastError() const;
bool hasErrors() const; bool hasErrors() const;
bool save_to_file(const QString &filename); bool save_to_file(const QString& filename);
/* Note: legacy argument `mode` is not used */ /* Note: legacy argument `mode` is not used */
void render(QPainter& painter, const QRectF& paintRect, AspectRatioMode mode = IgnoreAspectRatio); void render(QPainter& painter, const QRectF& paintRect, AspectRatioMode mode = IgnoreAspectRatio);
@ -189,7 +202,7 @@ public:
If HEIGHTPERROW_MODE set and non-zero `heightPerRow` given then use that for height instead of internal If HEIGHTPERROW_MODE set and non-zero `heightPerRow` given then use that for height instead of internal
height */ height */
QString getAsCLI(const bool win, const bool longOptOnly = false, const bool barcodeNames = false, QString getAsCLI(const bool win, const bool longOptOnly = false, const bool barcodeNames = false,
const bool autoHeight = false, const float heightPerRow = 0.0f, const QString &outfile = "") const; const bool autoHeight = false, const float heightPerRow = 0.0f, const QString& outfile = "") const;
signals: signals:
void encoded(); void encoded();
@ -198,17 +211,22 @@ signals:
private: private:
void resetSymbol(); void resetSymbol();
void encode(); void encode();
int convertSegs(struct zint_seg segs[], std::vector<QByteArray>& bstrs);
static Qt::GlobalColor colourToQtColor(int colour); static Qt::GlobalColor colourToQtColor(int colour);
/* `getAsCLI()` helpers */ /* `getAsCLI()` helpers */
static void arg_str(QString &cmd, const char *const opt, const QString &val); static void arg_str(QString& cmd, const char *const opt, const QString& val);
static void arg_int(QString &cmd, const char *const opt, const int val, const bool allowZero = false); static void arg_int(QString& cmd, const char *const opt, const int val, const bool allowZero = false);
static void arg_bool(QString &cmd, const char *const opt, const bool val); static void arg_bool(QString& cmd, const char *const opt, const bool val);
static void arg_color(QString &cmd, const char *const opt, const QColor val); static void arg_color(QString& cmd, const char *const opt, const QColor val);
static void arg_data(QString &cmd, const char *const opt, const QString &val, const bool win); static void arg_data(QString& cmd, const char *const opt, const QString& val, const bool win);
static void arg_float(QString &cmd, const char *const opt, const float val, const bool allowZero = false); static void arg_seg(QString& cmd, const int seg_no, const QZintSeg& val, const bool win);
static void arg_structapp(QString &cmd, const char *const opt, const int count, const int index, static void arg_data_esc(QString& cmd, const char *const opt, QString& text, const bool win);
const QString &id, const bool win); static void arg_float(QString& cmd, const char *const opt, const float val, const bool allowZero = false);
static void arg_structapp(QString& cmd, const char *const opt, const int count, const int index,
const QString& id, const bool win);
private: private:
zint_symbol *m_zintSymbol; zint_symbol *m_zintSymbol;
@ -216,6 +234,7 @@ private:
int m_input_mode; int m_input_mode;
QString m_text; QString m_text;
QString m_primaryMessage; QString m_primaryMessage;
std::vector<QZintSeg> m_segs;
float m_height; float m_height;
int m_option_1; int m_option_1;
int m_option_2; int m_option_2;
@ -256,4 +275,5 @@ private:
} /* namespace Zint */ } /* namespace Zint */
/* vim: set ts=4 sw=4 et : */
#endif /* QZINT_H */ #endif /* QZINT_H */

View File

@ -60,6 +60,35 @@ private slots:
QString text("text"); QString text("text");
bc.setText(text); bc.setText(text);
QCOMPARE(bc.text(), text); QCOMPARE(bc.text(), text);
QCOMPARE(bc.segs().empty(), true);
std::vector<QString> segTexts;
std::vector<int> segECIs;
segTexts.push_back(QString("Τεχτ"));
segECIs.push_back(9);
segTexts.push_back(QString("貫やぐ禁"));
segECIs.push_back(20);
segTexts.push_back(QString("กขฯ"));
segECIs.push_back(13);
std::vector<Zint::QZintSeg> segs;
for (int i = 0; i < (int) segTexts.size(); i++) {
segs.push_back(Zint::QZintSeg(segTexts[i]));
segs.back().m_eci = segECIs[i];
}
bc.setSegs(segs);
QCOMPARE(bc.segs().size(), segs.size());
for (int i = 0; i < (int) segs.size(); i++) {
QCOMPARE(bc.segs()[i].m_text, segTexts[i]);
QCOMPARE(bc.segs()[i].m_eci, segECIs[i]);
}
QCOMPARE(bc.text().isEmpty(), true);
QCOMPARE(bc.eci(), segECIs[0]);
bc.setText(text);
QCOMPARE(bc.text(), text);
QCOMPARE(bc.segs().empty(), true);
QString primaryMessage("primary message"); QString primaryMessage("primary message");
bc.setPrimaryMessage(primaryMessage); bc.setPrimaryMessage(primaryMessage);
@ -343,7 +372,7 @@ private slots:
QTest::newRow("BARCODE_QRCODE") << BARCODE_QRCODE << "1234" << 0 << "" << 21 << 21; QTest::newRow("BARCODE_QRCODE") << BARCODE_QRCODE << "1234" << 0 << "" << 21 << 21;
if (!m_skipIfFontUsed) { if (!m_skipIfFontUsed) {
QTest::newRow("BARCODE_QRCODE no text") << BARCODE_QRCODE << "" << ZINT_ERROR_INVALID_DATA << "Error 205: No input data" << 0 << 0; QTest::newRow("BARCODE_QRCODE no text") << BARCODE_QRCODE << "" << ZINT_ERROR_INVALID_DATA << "Error 773: Input segment 0 length zero" << 0 << 0;
} }
} }
@ -499,9 +528,9 @@ private slots:
<< true << 0 << 0 << 2 << 3 << 0 // cmyk-fontSetting << true << 0 << 0 << 2 << 3 << 0 // cmyk-fontSetting
<< true << false << false << false << false << 0 // showText-rotateAngle << true << false << false << false << false << 0 // showText-rotateAngle
<< 7 << false << false << false << WARN_DEFAULT << false // eci-debug << 7 << false << false << false << WARN_DEFAULT << false // eci-debug
<< "zint -b 92 --cmyk -d '12345678Ж0%var%' --dotsize=0.9 --dotty --eci=7 --fg=0000FF --scale=4" << "zint -b 92 --cmyk --eci=7 -d '12345678Ж0%var%' --dotsize=0.9 --dotty --fg=0000FF --scale=4"
" --secure=1 --structapp='1,2,as\"dfa'\\''sdf' --vwhitesp=3 -w 2" " --secure=1 --structapp='1,2,as\"dfa'\\''sdf' --vwhitesp=3 -w 2"
<< "zint.exe -b 92 --cmyk -d \"12345678Ж0%var%\" --dotsize=0.9 --dotty --eci=7 --fg=0000FF --scale=4" << "zint.exe -b 92 --cmyk --eci=7 -d \"12345678Ж0%var%\" --dotsize=0.9 --dotty --fg=0000FF --scale=4"
" --secure=1 --structapp=\"1,2,as\\\"dfa'sdf\" --vwhitesp=3 -w 2" " --secure=1 --structapp=\"1,2,as\\\"dfa'sdf\" --vwhitesp=3 -w 2"
<< "" << ""; << "" << "";
@ -679,8 +708,8 @@ private slots:
<< false << 0 << 0 << 0 << 0 << 0 // cmyk-fontSetting << false << 0 << 0 << 0 << 0 << 0 // cmyk-fontSetting
<< true << false << false << false << true << 0 // showText-rotateAngle << true << false << false << false << true << 0 // showText-rotateAngle
<< 29 << false << false << false << WARN_DEFAULT << false // eci-debug << 29 << false << false << false << WARN_DEFAULT << false // eci-debug
<< "zint -b 116 -d 'éβÿ啊\\e\"'\\''' --eci=29 --esc --mask=0 --secure=2 --vers=5" << "zint -b 116 --eci=29 -d 'éβÿ啊\\e\"'\\''' --esc --mask=0 --secure=2 --vers=5"
<< "zint.exe -b 116 -d \"éβÿ啊\\e\\\"'\" --eci=29 --esc --mask=0 --secure=2 --vers=5" << "zint.exe -b 116 --eci=29 -d \"éβÿ啊\\e\\\"'\" --esc --mask=0 --secure=2 --vers=5"
<< "" << ""; << "" << "";
QTest::newRow("BARCODE_HIBC_DM") << false << 10.0f << "" QTest::newRow("BARCODE_HIBC_DM") << false << 10.0f << ""
@ -770,8 +799,8 @@ private slots:
<< false << 0 << 0 << 0 << 0 << 0 // cmyk-fontSetting << false << 0 << 0 << 0 << 0 << 0 // cmyk-fontSetting
<< true << false << false << false << true << 180 // showText-rotateAngle << true << false << false << false << true << 180 // showText-rotateAngle
<< 20 << false << false << false << WARN_DEFAULT << false // eci-debug << 20 << false << false << false << WARN_DEFAULT << false // eci-debug
<< "zint -b 145 -d 'テ' --eci=20 --rotate=180 --vers=8" << "zint -b 145 --eci=20 -d 'テ' --rotate=180 --vers=8"
<< "zint.exe -b 145 -d \"\" --eci=20 --rotate=180 --vers=8" << "zint.exe -b 145 --eci=20 -d \"\" --rotate=180 --vers=8"
<< "" << ""; << "" << "";
QTest::newRow("BARCODE_ULTRA") << false << 0.0f << "" QTest::newRow("BARCODE_ULTRA") << false << 0.0f << ""
@ -926,6 +955,44 @@ private slots:
} }
} }
void getAsCLISegsTest()
{
Zint::QZint bc;
QString cmd;
QString expected_cmd;
QString expected_win;
std::vector<QString> segTexts;
std::vector<int> segECIs;
segTexts.push_back(QString("Τεχτ"));
segECIs.push_back(9);
segTexts.push_back(QString("Téxt"));
segECIs.push_back(3);
segTexts.push_back(QString("กขฯ"));
segECIs.push_back(13);
segTexts.push_back(QString("貫やぐ禁"));
segECIs.push_back(20);
std::vector<Zint::QZintSeg> segs;
for (int i = 0; i < (int) segTexts.size(); i++) {
segs.push_back(Zint::QZintSeg(segTexts[i]));
segs.back().m_eci = segECIs[i];
}
bc.setSymbol(BARCODE_QRCODE);
bc.setSegs(segs);
bc.setDotty(true);
expected_cmd = "zint -b 58 --eci=9 -d 'Τεχτ' --seg1=3,'Téxt' --seg2=13,'กขฯ' --seg3=20,'貫やぐ禁' --dotty";
cmd = bc.getAsCLI(false /*win*/);
QCOMPARE(cmd, expected_cmd);
expected_win = "zint.exe -b 58 --eci=9 -d \"Τεχτ\" --seg1=3,\"Téxt\" --seg2=13,\"กขฯ\" --seg3=20,\"貫やぐ禁\" --dotty";
cmd = bc.getAsCLI(true /*win*/);
QCOMPARE(cmd, expected_win);
}
void qZintAndLibZintEqual_data() void qZintAndLibZintEqual_data()
{ {
QTest::addColumn<int>("symbology"); QTest::addColumn<int>("symbology");

View File

@ -141,6 +141,10 @@
2022-04-08 GL 2022-04-08 GL
- Updated ECIs to AIM ITS/04-023:2022 - Updated ECIs to AIM ITS/04-023:2022
Note changed names "unicode" -> "utf-16be", "euc-cn" -> "gb2312" Note changed names "unicode" -> "utf-16be", "euc-cn" -> "gb2312"
2022-04-24 GL
- Added -segN options
- Added "invariant" and "binary" ECIs
- Tcl_GetIndexFromObj() flags arg -> 0
*/ */
#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
@ -431,7 +435,7 @@ static const char *s_eci_list[] = {
"cp1256", /*24: Windows-1256*/ "cp1256", /*24: Windows-1256*/
"utf-16be", /*25: UTF-16BE (High order byte first) Unicode*/ "utf-16be", /*25: UTF-16BE (High order byte first) Unicode*/
"utf-8", /*26: Unicode (UTF-8)*/ "utf-8", /*26: Unicode (UTF-8)*/
"ascii", /*27: ISO-646:1991 7-bit character set*/ "ascii", /*27: ISO-646:1991 7-bit character set ASCII*/
"big5", /*28: Big5 (Taiwan) Chinese Character Set*/ "big5", /*28: Big5 (Taiwan) Chinese Character Set*/
"gb2312", /*29: GB 2312 (PRC) Chinese Character Set*/ "gb2312", /*29: GB 2312 (PRC) Chinese Character Set*/
"iso2022-kr", /*30: Korean Character Set EUC-KR (KS X 1001:2002)*/ "iso2022-kr", /*30: Korean Character Set EUC-KR (KS X 1001:2002)*/
@ -440,13 +444,15 @@ static const char *s_eci_list[] = {
"utf-16le", /*33: UTF-16LE (Low order byte first) Unicode*/ "utf-16le", /*33: UTF-16LE (Low order byte first) Unicode*/
"utf-32be", /*34: UTF-32BE (High order byte first) Unicode*/ "utf-32be", /*34: UTF-32BE (High order byte first) Unicode*/
"utf-32le", /*35: UTF-32BE (Low order byte first) Unicode*/ "utf-32le", /*35: UTF-32BE (Low order byte first) Unicode*/
"invariant", /*170: ISO-646:1991 7-bit character set invariant*/
"binary", /*899: 8-bit binary*/
NULL NULL
}; };
/* The ECI numerical number to pass to ZINT */ /* The ECI numerical number to pass to ZINT */
static const int s_eci_number[] = { static const int s_eci_number[] = {
3,4,5,6,7,8,9,10,11,12,13,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30, 3,4,5,6,7,8,9,10,11,12,13,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35 31,32,33,34,35,170,899
}; };
/* Version information */ /* Version information */
@ -460,7 +466,7 @@ static const char help_message[] = "zint tcl(stub,obj) dll\n"
" photo: a tcl photo image handle ('p' after 'image create photo p')\n" " photo: a tcl photo image handle ('p' after 'image create photo p')\n"
" Available options:\n" " Available options:\n"
" -barcode choice: symbology, use 'zint symbology' to get a list\n" " -barcode choice: symbology, use 'zint symbology' to get a list\n"
" -addongap number: (7..12, default: 9) set add-on gap in multiple of module size (UPC/EAN-CC)\n" " -addongap integer: (7..12, default: 9) set add-on gap in multiple of module size (UPC/EAN-CC)\n"
" -bg color: set background color as 6 or 8 hex rrggbbaa\n" " -bg color: set background color as 6 or 8 hex rrggbbaa\n"
/* cli option --binary internally handled */ /* cli option --binary internally handled */
" -bind bool: bars above/below the code, size set by -border\n" " -bind bool: bars above/below the code, size set by -border\n"
@ -476,7 +482,7 @@ static const char help_message[] = "zint tcl(stub,obj) dll\n"
" -dotty bool: use dots instead of boxes for matrix codes\n" " -dotty bool: use dots instead of boxes for matrix codes\n"
/* cli option --dump not supported */ /* cli option --dump not supported */
/* cli option --ecinos not supported */ /* cli option --ecinos not supported */
" -eci number: ECI to use\n" " -eci choice: ECI to use\n"
/* cli option --esc not supported */ /* cli option --esc not supported */
" -fast bool: use fast encodation (Data Matrix)\n" " -fast bool: use fast encodation (Data Matrix)\n"
" -fg color: set foreground color as 6 or 8 hex rrggbbaa\n" " -fg color: set foreground color as 6 or 8 hex rrggbbaa\n"
@ -492,9 +498,9 @@ static const char help_message[] = "zint tcl(stub,obj) dll\n"
" -heightperrow bool: treat height as per-row\n" " -heightperrow bool: treat height as per-row\n"
/* cli option --input not supported */ /* cli option --input not supported */
" -init bool: Create reader initialisation symbol (Code 128, Data Matrix)\n" " -init bool: Create reader initialisation symbol (Code 128, Data Matrix)\n"
" -mask number: set masking pattern to use (QR/MicroQR/HanXin/DotCode)\n" " -mask integer: set masking pattern to use (QR/MicroQR/HanXin/DotCode)\n"
/* cli option --mirror not supported */ /* cli option --mirror not supported */
" -mode number: set encoding mode (MaxiCode, Composite)\n" " -mode integer: set encoding mode (MaxiCode, Composite)\n"
" -nobackground bool: set background transparent\n" " -nobackground bool: set background transparent\n"
" -noquietzones bool: disable default quiet zones\n" " -noquietzones bool: disable default quiet zones\n"
" -notext bool: no interpretation line\n" " -notext bool: no interpretation line\n"
@ -505,8 +511,9 @@ static const char help_message[] = "zint tcl(stub,obj) dll\n"
" -rotate angle: Image rotation by 0,90 or 270 degrees\n" " -rotate angle: Image rotation by 0,90 or 270 degrees\n"
" -rows integer: Codablock F, PDF417: number of rows\n" " -rows integer: Codablock F, PDF417: number of rows\n"
" -scale double: Scale the image to this factor\n" " -scale double: Scale the image to this factor\n"
" -scmvv number: Prefix SCM with [)>\\R01\\Gvv (vv is NUMBER) (MaxiCode)\n" " -scmvv integer: Prefix SCM with [)>\\R01\\Gvv (vv is integer) (MaxiCode)\n"
" -secure integer: EC Level (Aztec, GridMatrix, HanXin, PDF417, QR, UltraCode)\n" " -secure integer: EC Level (Aztec, GridMatrix, HanXin, PDF417, QR, UltraCode)\n"
" -segN {eci data}: Set the ECI & data content for segment N where N is 1 to 9\n"
" -separator 0..4 (default: 1) : Stacked symbologies: separator width\n" " -separator 0..4 (default: 1) : Stacked symbologies: separator width\n"
/* cli option --small replaced by -smalltext */ /* cli option --small replaced by -smalltext */
" -smalltext bool: tiny interpretation line font\n" " -smalltext bool: tiny interpretation line font\n"
@ -710,6 +717,11 @@ static int Encode(Tcl_Interp *interp, int objc,
int Mask = 0; int Mask = 0;
int rows = 0; int rows = 0;
unsigned int cap; unsigned int cap;
int seg_count = 0;
int seg_no;
Tcl_Obj *pSegDataObjs[10] = {0};
Tcl_DString segInputs[10];
struct zint_seg segs[10];
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* >> Check if at least data and object is given and a pair number of */ /* >> Check if at least data and object is given and a pair number of */
/* >> options */ /* >> options */
@ -741,8 +753,9 @@ static int Encode(Tcl_Interp *interp, int objc,
"-gs1nocheck", "-gs1parens", "-gssep", "-guarddescent", "-gs1nocheck", "-gs1parens", "-gssep", "-guarddescent",
"-height", "-heightperrow", "-init", "-mask", "-mode", "-height", "-heightperrow", "-init", "-mask", "-mode",
"-nobackground", "-noquietzones", "-notext", "-primary", "-quietzones", "-nobackground", "-noquietzones", "-notext", "-primary", "-quietzones",
"-reverse", "-rotate", "-rows", "-scale", "-scmvv", "-reverse", "-rotate", "-rows", "-scale", "-scmvv", "-secure",
"-secure", "-separator", "-smalltext", "-square", "-structapp", "-seg1", "-seg2", "-seg3", "-seg4", "-seg5", "-seg6", "-seg7", "-seg8", "-seg9",
"-separator", "-smalltext", "-square", "-structapp",
"-to", "-vers", "-vwhitesp", "-werror", "-whitesp", "-to", "-vers", "-vwhitesp", "-werror", "-whitesp",
NULL}; NULL};
enum iOption { enum iOption {
@ -752,8 +765,9 @@ static int Encode(Tcl_Interp *interp, int objc,
iGS1NoCheck, iGS1Parens, iGSSep, iGuardDescent, iGS1NoCheck, iGS1Parens, iGSSep, iGuardDescent,
iHeight, iHeightPerRow, iInit, iMask, iMode, iHeight, iHeightPerRow, iInit, iMask, iMode,
iNoBackground, iNoQuietZones, iNoText, iPrimary, iQuietZones, iNoBackground, iNoQuietZones, iNoText, iPrimary, iQuietZones,
iReverse, iRotate, iRows, iScale, iSCMvv, iReverse, iRotate, iRows, iScale, iSCMvv, iSecure,
iSecure, iSeparator, iSmallText, iSquare, iStructApp, iSeg1, iSeg2, iSeg3, iSeg4, iSeg5, iSeg6, iSeg7, iSeg8, iSeg9,
iSeparator, iSmallText, iSquare, iStructApp,
iTo, iVers, iVWhiteSp, iWError, iWhiteSp iTo, iVers, iVWhiteSp, iWError, iWhiteSp
}; };
int optionIndex; int optionIndex;
@ -762,7 +776,7 @@ static int Encode(Tcl_Interp *interp, int objc,
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
if(Tcl_GetIndexFromObj(interp, objv[optionPos], if(Tcl_GetIndexFromObj(interp, objv[optionPos],
(const char **) optionList, (const char **) optionList,
"zint option", optionPos-1, &optionIndex) "zint option", 0, &optionIndex)
== TCL_ERROR) == TCL_ERROR)
{ {
fError = 1; fError = 1;
@ -852,6 +866,38 @@ static int Encode(Tcl_Interp *interp, int objc,
fError = 1; fError = 1;
} }
break; break;
case iSeg1: case iSeg2: case iSeg3: case iSeg4: case iSeg5:
case iSeg6: case iSeg7: case iSeg8: case iSeg9:
seg_no = optionIndex - iSeg1 + 1;
if (pSegDataObjs[seg_no]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("duplicate segment", -1));
fError = 1;
} else {
Tcl_Obj *poParam;
if (TCL_OK != Tcl_ListObjLength(interp, objv[optionPos+1], &lStr)) {
Tcl_SetObjResult(interp, Tcl_Format(interp, "option %s not a list", 1, objv + optionPos));
fError = 1;
} else if (lStr != 2) {
Tcl_SetObjResult(interp, Tcl_Format(interp, "option %s not a list of 2", 1, objv + optionPos));
fError = 1;
} else if (TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1],
0, &poParam)
|| TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1],
1, &pSegDataObjs[seg_no])) {
Tcl_SetObjResult(interp, Tcl_Format(interp, "option %s list format is {eci data}", 1, objv + optionPos));
fError = 1;
} else if (Tcl_GetIndexFromObj(interp, poParam,
(const char **) s_eci_list, Tcl_GetString(objv[optionPos]), 0, &ECIIndex)
== TCL_ERROR) {
fError = 1;
} else {
segs[seg_no].eci = s_eci_number[ECIIndex];
if (seg_no >= seg_count) {
seg_count = seg_no + 1;
}
}
}
break;
} }
if (fError) { if (fError) {
break; break;
@ -944,7 +990,7 @@ static int Encode(Tcl_Interp *interp, int objc,
break; break;
case iECI: case iECI:
if(Tcl_GetIndexFromObj(interp, objv[optionPos+1], if(Tcl_GetIndexFromObj(interp, objv[optionPos+1],
(const char **) s_eci_list,"-eci", optionPos, &ECIIndex) (const char **) s_eci_list, "-eci", 0, &ECIIndex)
== TCL_ERROR) == TCL_ERROR)
{ {
fError = 1; fError = 1;
@ -1129,7 +1175,7 @@ static int Encode(Tcl_Interp *interp, int objc,
/*------------------------------------------------------------*/ /*------------------------------------------------------------*/
if(Tcl_GetIndexFromObj(interp, objv[optionPos+1], if(Tcl_GetIndexFromObj(interp, objv[optionPos+1],
(const char **) rotateList, (const char **) rotateList,
"rotate", optionPos, &intValue) "-rotate", 0, &intValue)
== TCL_ERROR) == TCL_ERROR)
{ {
fError = 1; fError = 1;
@ -1145,7 +1191,7 @@ static int Encode(Tcl_Interp *interp, int objc,
break; break;
case iBarcode: case iBarcode:
if(Tcl_GetIndexFromObj(interp, objv[optionPos+1], if(Tcl_GetIndexFromObj(interp, objv[optionPos+1],
(const char **) s_code_list,"-barcode", optionPos, &intValue) (const char **) s_code_list, "-barcode", 0, &intValue)
== TCL_ERROR) == TCL_ERROR)
{ {
fError = 1; fError = 1;
@ -1255,7 +1301,7 @@ static int Encode(Tcl_Interp *interp, int objc,
/*------------------------------------------------------------*/ /*------------------------------------------------------------*/
if(Tcl_GetIndexFromObj(interp, objv[optionPos+1], if(Tcl_GetIndexFromObj(interp, objv[optionPos+1],
(const char **) formatList, (const char **) formatList,
"format", optionPos, &intValue) "-format", 0, &intValue)
== TCL_ERROR) == TCL_ERROR)
{ {
fError = 1; fError = 1;
@ -1325,6 +1371,32 @@ static int Encode(Tcl_Interp *interp, int objc,
pStr = Tcl_DStringValue( &dsInput ); pStr = Tcl_DStringValue( &dsInput );
lStr = Tcl_DStringLength( &dsInput ); lStr = Tcl_DStringLength( &dsInput );
} }
if (seg_count) {
segs[0].source = (unsigned char *) pStr;
segs[0].length = lStr;
segs[0].eci = my_symbol->eci;
for (seg_no = 1; seg_no < seg_count; seg_no++) {
if (!pSegDataObjs[seg_no]) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("Segments must be consecutive", -1));
fError = 1;
break;
}
}
if (!fError) {
for (seg_no = 1; seg_no < seg_count; seg_no++) {
if ((my_symbol->input_mode & 0x07) == DATA_MODE) {
segs[seg_no].source = (unsigned char *) Tcl_GetByteArrayFromObj(pSegDataObjs[seg_no],
&segs[seg_no].length);
} else {
pStr = Tcl_GetStringFromObj(pSegDataObjs[seg_no], &lStr);
Tcl_DStringInit(& segInputs[seg_no]);
Tcl_UtfToExternalDString( hZINTEncoding, pStr, lStr, &segInputs[seg_no]);
segs[seg_no].source = (unsigned char *) Tcl_DStringValue( &segInputs[seg_no] );
segs[seg_no].length = Tcl_DStringLength( &segInputs[seg_no] );
}
}
}
}
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* >>> Build symbol graphic */ /* >>> Build symbol graphic */
@ -1333,8 +1405,13 @@ static int Encode(Tcl_Interp *interp, int objc,
Tk_PhotoHandle hPhoto; Tk_PhotoHandle hPhoto;
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/* call zint graphic creation to buffer */ /* call zint graphic creation to buffer */
ErrorNumber = ZBarcode_Encode_and_Buffer(my_symbol, if (seg_count) {
(unsigned char *) pStr, lStr, rotate_angle); ErrorNumber = ZBarcode_Encode_Segs_and_Buffer(my_symbol,
segs, seg_count, rotate_angle);
} else {
ErrorNumber = ZBarcode_Encode_and_Buffer(my_symbol,
(unsigned char *) pStr, lStr, rotate_angle);
}
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/* >> Show a message */ /* >> Show a message */
if( 0 != ErrorNumber ) if( 0 != ErrorNumber )

View File

@ -40,7 +40,7 @@ symbol: A symbol is an image which encodes data according to one of the
symbology: A method of encoding data to create a certain type of symbol. symbology: A method of encoding data to create a certain type of symbol.
linear: A linear symbol is one which consists of bars and spaces, and is what linear: A linear symbol is one which consists of bars and spaces, and is what
most people associate with the term "barcode". Examples include EAN. most people associate with the term 'barcode'. Examples include EAN.
stacked: A stacked symbol consists of multiple linear symbols placed one above stacked: A stacked symbol consists of multiple linear symbols placed one above
another and which together hold the message, usually alongside some another and which together hold the message, usually alongside some
@ -58,12 +58,12 @@ X-dimension: The X-dimension of a symbol is the size (usually the width) of the
composite: A composite symbology is one which is made up of elements which are composite: A composite symbology is one which is made up of elements which are
both linear and stacked. Those currently supported are made up of a both linear and stacked. Those currently supported are made up of a
linear "primary" message above which is printed a stacked component linear 'primary' message above which is printed a stacked component
based on the PDF417 symbology. These symbols also have a separator based on the PDF417 symbology. These symbols also have a separator
which separates the linear and the stacked components. which separates the linear and the stacked components.
GS1 data: This is a structured way of representing information which consists GS1 data: This is a structured way of representing information which consists
of "chunks" of data, each of which starts with an Application of 'chunks' of data, each of which starts with an Application
Identifier. The AI identifies what type of information is being Identifier. The AI identifies what type of information is being
encoded. encoded.
@ -136,7 +136,7 @@ qtZint.exe - Zint Barcode Studio
zint.exe - Command Line Interface zint.exe - Command Line Interface
For fresh releases you will get a warning message from Microsoft Defender For fresh releases you will get a warning message from Microsoft Defender
SmartScreen that this is an "unrecognised app". This happens because Zint is SmartScreen that this is an 'unrecognised app'. This happens because Zint is
a free and open-source software project with no advertising and hence no a free and open-source software project with no advertising and hence no
income, meaning we are not able to afford the $664 per year to have the income, meaning we are not able to afford the $664 per year to have the
application digitally signed by Microsoft. application digitally signed by Microsoft.
@ -559,8 +559,8 @@ The maximum scale for both raster and vector is 100.
4.9.1 Scaling Example 4.9.1 Scaling Example
--------------------- ---------------------
The GS1 General Specifications Section 5.2.6.6 "Symbol dimensions at nominal The GS1 General Specifications Section 5.2.6.6 'Symbol dimensions at nominal
size" gives an example of an EAN-13 barcode using the X-dimension of 0.33mm. size' gives an example of an EAN-13 barcode using the X-dimension of 0.33mm.
To print that example as a PNG at 12 dots per mm (dpmm), the equivalent of 300 To print that example as a PNG at 12 dots per mm (dpmm), the equivalent of 300
dots per inch (dpi = dpmm * 25.4), specify a scale of 2, since 0.33 * 12 = 3.96 dots per inch (dpi = dpmm * 25.4), specify a scale of 2, since 0.33 * 12 = 3.96
pixels, or 4 pixels rounding to the nearest pixel: pixels, or 4 pixels rounding to the nearest pixel:
@ -641,7 +641,7 @@ Health Industry Barcode (HIBC) data may also be encoded in the symbologies Code
Code. Within this mode, the leading '+' and the check character are Code. Within this mode, the leading '+' and the check character are
automatically added, conforming to HIBC Labeler Identification Code (HIBC LIC). automatically added, conforming to HIBC Labeler Identification Code (HIBC LIC).
For HIBC Provider Applications Standard (HIBC PAS), preface the data with a For HIBC Provider Applications Standard (HIBC PAS), preface the data with a
slash "/". slash '/'.
The --binary option encodes the input data as given. Automatic code page The --binary option encodes the input data as given. Automatic code page
translation to an ECI page is disabled, and no validation of the data's encoding translation to an ECI page is disabled, and no validation of the data's encoding
@ -650,25 +650,35 @@ switch plays together with the built-in ECI logic and examples may be found
below. below.
The --fullmultibyte option uses the multibyte modes of QR Code, Micro QR Code, The --fullmultibyte option uses the multibyte modes of QR Code, Micro QR Code,
Rectangular Micro QR Code, Han Xin Code and Grid Matrix for binary and Latin Rectangular Micro QR Code (rMQR), Han Xin Code and Grid Matrix for binary and
data, maximizing density. This is achieved by using compression designed for Latin data, maximizing density. This is achieved by using compression designed
Kanji/Hanzi characters, however some decoders take blocks which are encoded this for Kanji/Hanzi characters, however some decoders take blocks which are encoded
way and interpret them as Kanji/Hanzi characters, typically by applying a this way and interpret them as Kanji/Hanzi characters, typically by applying a
transformation to UTF-8 and thus causing data corruption. Symbols encoded with transformation to UTF-8 and thus causing data corruption. Symbols encoded with
this option should be checked against decoders before they are used. The popular this option should be checked against decoders before they are used. The popular
open-source ZXing decoder is known to exhibit this behaviour. open-source ZXing decoder is known to exhibit this behaviour.
If your data contains non-Latin-1 characters, you may encode it using an If your data contains non-Latin-1 characters, you may encode it using an
ECI-aware symbology and an ECI value from the table below. The ECI information ECI-aware symbology and an ECI value from the table below. The ECI information
is added to your code symbol as prefix data. is added to your code symbol as prefix data. The symbologies that support ECI
are Aztec Code, Code One, Data Matrix, DotCode, Grid Matrix, Han Xin Code,
MaxiCode, PDF417 and MicroPDF417, QR Code and rMQR, and Ultracode.
The ECI value may be specified with the --eci switch, followed by the value in The ECI value may be specified with the --eci switch, followed by the value in
the column "ECI Code". The input data should be UTF-8 formatted. Zint the column "ECI Code". The input data should be UTF-8 formatted. Zint
automatically translates the data into the target encoding. automatically translates the data into the target encoding.
The ECI value of 0 does not encode any ECI information in the code symbol. In An ECI value of 0 does not encode any ECI information in the code symbol (unless
this case, the default encoding applies for the data which is "ISO/IEC 8859-1 - the data contains non-Latin-1 characters). In this case, the default encoding
Latin alphabet No. 1". applies, which is "ISO/IEC 8859-1 - Latin alphabet No. 1".
If no ECI is specified or a value of 0 is given, and the data does contain
characters other than Latin-1, then Zint will automatically insert the
appropriate single-byte ECI if possible (ECIs 4 to 24, excluding ECI 20), or
failing that ECI 26 (UTF-8). A warning will be generated. This mechanism is not
applied if the --binary option is given.
Multiple ECIs can be specified using the --segN= options - see section 4.15.
Note: the "--eci=3" specification should only be used for special purposes. Note: the "--eci=3" specification should only be used for special purposes.
Using this parameter, the ECI information is explicitly added to the code Using this parameter, the ECI information is explicitly added to the code
@ -775,7 +785,7 @@ Input Character | Interpretation
--------------------------------------------- ---------------------------------------------
~ | Insert a number or '0' ~ | Insert a number or '0'
# | Insert a number or space # | Insert a number or space
@ | Insert a number or "*" @ | Insert a number or '*'
Any other | Insert literally Any other | Insert literally
--------------------------------------------- ---------------------------------------------
@ -847,7 +857,26 @@ minimum dot size is 0.01, the maximum is 20. The default size is 0.8.
The default and minimum scale for raster output in dotty mode is 1. The default and minimum scale for raster output in dotty mode is 1.
4.15 Structured Append 4.15 Multiple Segments
----------------------
If you need to specify different ECIs for different sections of the input data,
the --seg1= to --seg9= options can be used. Each option is of the form
--segN=ECI,data where "ECI" is the ECI code (see table in section 4.10) and
"data" is the data to which this applies. This is in addition to the ECI and
data specified using the --eci= and -d options which must still be present and
which in effect constitute segment 0. For instance
zint -b AZTEC_CODE --eci=9 -d "Κείμενο" --seg1=13,"Текст" --seg2=20,"文章"
specifies 3 segments: segment 0 with ECI 9 (Greek), segment 1 with ECI 7
(Cyrillic), and segment 2 with ECI 20 (Shift JIS). Segments must be consecutive.
ECIs of zero may be given, in which case Zint will automatically determine an
ECI if necessary, as described in section 4.10.
Multiple segments are not currently supported for use with GS1 data.
4.16 Structured Append
---------------------- ----------------------
Structured Append is a method of splitting data among several symbols so that Structured Append is a method of splitting data among several symbols so that
they form a sequence that can be scanned and re-assembled in the correct order they form a sequence that can be scanned and re-assembled in the correct order
@ -1557,7 +1586,62 @@ For HEIGHTPERROW_MODE, see --heightperrow in section 4.4. The height variable
should be set to the desired per-row value on input (it will be set to the should be set to the desired per-row value on input (it will be set to the
overall height on output). overall height on output).
5.11 Verifying Symbology Availability 5.11 Multiple Segments
----------------------
For input data requiring multiple ECIs, the following functions may be used:
int ZBarcode_Encode_Segs(struct zint_symbol *symbol,
const struct zint_seg segs[], const int seg_count);
int ZBarcode_Encode_Segs_and_Print(struct zint_symbol *symbol,
const struct zint_seg segs[], const int seg_count, int rotate_angle);
int ZBarcode_Encode_Segs_and_Buffer(struct zint_symbol *symbol,
const struct zint_seg segs[], const int seg_count, int rotate_angle);
int ZBarcode_Encode_Segs_and_Buffer_Vector(struct zint_symbol *symbol,
const struct zint_seg segs[], const int seg_count, int rotate_angle);
These are direct analogues of ZBarcode_Encode(), ZBarcode_Encode_and_Print(),
ZBarcode_Encode_and_Buffer() and ZBarcode_Encode_and_Buffer_Vector()
respectively, where in place of a "source, length" pair you have a "segs,
seg_count" pair, with "segs" being an array of zint_seg structures and
"seg_count" being the number of elements it contains. The zint_seg structure is
of the form:
struct zint_seg {
unsigned char *source; /* Data to encode */
int length; /* Length of `source`. If 0, `source` must be
NUL-terminated */
int eci; /* Extended Channel Interpretation */
};
The symbology must of course support ECIs, i.e. be Aztec Code, Code One, Data
Matrix, DotCode, Grid Matrix, Han Xin Code, MaxiCode, PDF417, MicroPDF417, QR
Code, rMQR, or Ultracode. For example:
#include <zint.h>
int main(int argc, char **argv)
{
struct zint_seg segs[] = {
{ "Κείμενο", 0, 9 },
{ "Текст", 0, 7 },
{ "文章", 0, 20 }
};
struct zint_symbol *my_symbol;
my_symbol = ZBarcode_Create();
my_symbol->symbology = BARCODE_AZTEC;
my_symbol->input_mode = UNICODE_MODE;
ZBarcode_Encode_Segs(my_symbol, segs, 3);
ZBarcode_Print(my_symbol, 0);
ZBarcode_Delete(my_symbol);
return 0;
}
A maximum of 256 segments may be specified. Use of multiple segments with GS1
data is not currently supported.
5.12 Verifying Symbology Availability
------------------------------------- -------------------------------------
An additional function available in the API is defined as: An additional function available in the API is defined as:
@ -1588,7 +1672,7 @@ if (ZBarcode_BarcodeName(BARCODE_PDF417, name) == 0) {
will print "BARCODE_PDF417". will print "BARCODE_PDF417".
5.12 Checking Symbology Capabilities 5.13 Checking Symbology Capabilities
------------------------------------ ------------------------------------
It can be useful for frontend programs to know the capabilities of a symbology. It can be useful for frontend programs to know the capabilities of a symbology.
This can be determined using another additional function: This can be determined using another additional function:
@ -1600,7 +1684,7 @@ see which are set.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Value | Meaning Value | Meaning
--------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ZINT_CAP_HRT | Can the symbology print Human Readable Text? ZINT_CAP_HRT | Can the symbology print Human Readable Text?
ZINT_CAP_STACKABLE | Is the symbology stackable? ZINT_CAP_STACKABLE | Is the symbology stackable?
ZINT_CAP_EXTENDABLE | Is the symbology extendable with add-on data? ZINT_CAP_EXTENDABLE | Is the symbology extendable with add-on data?
@ -1635,7 +1719,7 @@ if (cap & ZINT_CAP_ECI) {
printf("PDF417 does not support ECI\n"); printf("PDF417 does not support ECI\n");
} }
5.13 Zint Version 5.14 Zint Version
----------------- -----------------
Lastly, the version of the Zint library linked to is returned by: Lastly, the version of the Zint library linked to is returned by:
@ -2003,7 +2087,7 @@ required. The GTIN check digit and AI (01) are added by Zint.
6.1.11.5 NVE-18 (SSCC-18) 6.1.11.5 NVE-18 (SSCC-18)
------------------------- -------------------------
A variation of Code 128 the "Nummer der Versandeinheit" standard, also known as A variation of Code 128 the 'Nummer der Versandeinheit' standard, also known as
SSCC-18 (Serial Shipping Container Code), includes both modulo-10 and modulo-103 SSCC-18 (Serial Shipping Container Code), includes both modulo-10 and modulo-103
check digits. NVE-18 requires a 17 digit numerical input. Check digits and AI check digits. NVE-18 requires a 17 digit numerical input. Check digits and AI
(00) are added by Zint. (00) are added by Zint.
@ -2149,23 +2233,25 @@ or by setting option_1, with values from 2 to 16.
Heavily used in the parcel industry, the PDF417 symbology can encode a vast Heavily used in the parcel industry, the PDF417 symbology can encode a vast
amount of data into a small space. Zint supports encoding up to the ISO amount of data into a small space. Zint supports encoding up to the ISO
standard maximum symbol size of 925 codewords which (at error correction level standard maximum symbol size of 925 codewords which (at error correction level
0) allows a maximum data size of 1850 text characters, or 2710 digits. The 0) allows a maximum data size of 1850 text characters, or 2710 digits.
width of the generated PDF417 symbol can be specified at the command line using
the --cols switch followed by a number between 1 and 30, the number of rows The width of the generated PDF417 symbol can be specified at the command line
using the --rows switch followed by a number between 3 and 90, and the amount of using the --cols switch followed by a number between 1 and 30, the number of
error correction information can be specified by using the --secure switch rows using the --rows switch followed by a number between 3 and 90, and the
followed by a number between 0 and 8 where the number of codewords used for amount of error correction information can be specified by using the --secure
error correction is determined by 2^(value + 1). If using the API these values switch followed by a number between 0 and 8 where the number of codewords used
are assigned to option_2, option_3 and option_1 respectively. The default level for error correction is determined by 2^(value + 1). If using the API these
of error correction is determined by the amount of data being encoded. This values are assigned to option_2, option_3 and option_1 respectively. The default
symbology uses Latin-1 character encoding by default but also supports the ECI level of error correction is determined by the amount of data being encoded.
encoding mechanism. A separate symbology ID can be used to encode Health
This symbology uses Latin-1 character encoding by default but also supports the
ECI encoding mechanism. A separate symbology ID can be used to encode Health
Industry Barcode (HIBC) data which adds a leading '+' character and a modulo-49 Industry Barcode (HIBC) data which adds a leading '+' character and a modulo-49
check digit to the encoded data. check digit to the encoded data.
PDF417 supports Structured Append of up to a 99,999 symbols and an optional PDF417 supports Structured Append of up to a 99,999 symbols and an optional
numeric ID of up to 30 digits, which can be set by using the --structapp option numeric ID of up to 30 digits, which can be set by using the --structapp option
(see section 4.15) or the API structapp variable. The ID consists of up to 10 (see section 4.16) or the API structapp variable. The ID consists of up to 10
triplets, each ranging from "000" to "899". For instance "123456789" would be a triplets, each ranging from "000" to "899". For instance "123456789" would be a
valid ID of 3 triplets. However "123456900" would not, as the last triplet "900" valid ID of 3 triplets. However "123456900" would not, as the last triplet "900"
exceeds "899". The triplets are 0-filled, for instance "1234" becomes "123004". exceeds "899". The triplets are 0-filled, for instance "1234" becomes "123004".
@ -2184,9 +2270,10 @@ where symbol size needs to be kept to a minimum. 34 predefined symbol sizes are
available with 1 - 4 columns and 4 - 44 rows. The maximum size a MicroPDF417 available with 1 - 4 columns and 4 - 44 rows. The maximum size a MicroPDF417
symbol can hold is 250 alphanumeric characters or 366 digits. The amount of symbol can hold is 250 alphanumeric characters or 366 digits. The amount of
error correction used is dependent on symbol size. The number of columns used error correction used is dependent on symbol size. The number of columns used
can be determined using the --cols switch or option_2 as with PDF417. This can be determined using the --cols switch or option_2 as with PDF417.
symbology uses Latin-1 character encoding by default but also supports the ECI
encoding mechanism. A separate symbology ID can be used to encode Health This symbology uses Latin-1 character encoding by default but also supports the
ECI encoding mechanism. A separate symbology ID can be used to encode Health
Industry Barcode (HIBC) data which adds a leading '+' character and a modulo-49 Industry Barcode (HIBC) data which adds a leading '+' character and a modulo-49
check digit to the encoded data. MicroPDF417 supports Structured Append the same check digit to the encoded data. MicroPDF417 supports Structured Append the same
as PDF417, for which see details. as PDF417, for which see details.
@ -2440,40 +2527,20 @@ Barcode (HIBC) data which adds a leading '+' character and a modulo-49 check
digit to the encoded data. Note that only ECC200 encoding is supported, the digit to the encoded data. Note that only ECC200 encoding is supported, the
older standards have now been removed from Zint. older standards have now been removed from Zint.
--------------------- -------------------------------------------------------------------------------
Input | Symbol Size Input | Symbol Size | Input | Symbol Size | Input | Symbol Size
--------------------- -------------------------------------------------------------------------------
1 | 10 x 10 1 | 10 x 10 | 11 | 36 x 36 | 21 | 104 x 104
2 | 12 x 12 2 | 12 x 12 | 12 | 40 x 40 | 22 | 120 x 120
3 | 14 x 14 3 | 14 x 14 | 13 | 44 x 44 | 23 | 132 x 132
4 | 16 x 16 4 | 16 x 16 | 14 | 48 x 48 | 24 | 144 x 144
5 | 18 x 18 5 | 18 x 18 | 15 | 52 x 52 | 25 | 8 x 18
6 | 20 x 20 6 | 20 x 20 | 16 | 64 x 64 | 26 | 8 x 32
7 | 22 x 22 7 | 22 x 22 | 17 | 72 x 72 | 28 | 12 x 26
8 | 24 x 24 8 | 24 x 24 | 18 | 80 x 80 | 28 | 12 x 36
9 | 26 x 26 9 | 26 x 26 | 19 | 88 x 88 | 29 | 16 x 36
10 | 32 x 32 10 | 32 x 32 | 20 | 96 x 96 | 30 | 16 x 48
11 | 36 x 36 -------------------------------------------------------------------------------
12 | 40 x 40
13 | 44 x 44
14 | 48 x 48
15 | 52 x 52
16 | 64 x 64
17 | 72 x 72
18 | 80 x 80
19 | 88 x 88
20 | 96 x 96
21 | 104 x 104
22 | 120 x 120
23 | 132 x 132
24 | 144 x 144
25 | 8 x 18
26 | 8 x 32
28 | 12 x 26
28 | 12 x 36
29 | 16 x 36
30 | 16 x 48
---------------------
When using automatic symbol sizes you can force Zint to use square symbols When using automatic symbol sizes you can force Zint to use square symbols
(versions 1-24) at the command line by using the option --square and when (versions 1-24) at the command line by using the option --square and when
@ -2482,28 +2549,19 @@ using the API by setting the value option_3 = DM_SQUARE.
Data Matrix Rectangular Extension (ISO/IEC 21471) codes may be generated with Data Matrix Rectangular Extension (ISO/IEC 21471) codes may be generated with
the following values as before: the following values as before:
--------------------- ---------------------------------------------------
Input | Symbol Size Input | Symbol Size | Input | Symbol Size
--------------------- ---------------------------------------------------
31 | 8 x 48 31 | 8 x 48 | 40 | 20 x 36
32 | 8 x 64 32 | 8 x 64 | 41 | 20 x 44
33 | 8 x 80 33 | 8 x 80 | 42 | 20 x 64
34 | 8 x 96 34 | 8 x 96 | 43 | 22 x 48
35 | 8 x 120 35 | 8 x 120 | 44 | 24 x 48
36 | 8 x 144 36 | 8 x 144 | 45 | 24 x 64
37 | 12 x 64 37 | 12 x 64 | 46 | 26 x 40
38 | 12 x 88 38 | 12 x 88 | 47 | 26 x 48
39 | 16 x 64 39 | 16 x 64 | 48 | 26 x 64
40 | 20 x 36 ---------------------------------------------------
41 | 20 x 44
42 | 20 x 64
43 | 22 x 48
44 | 24 x 48
45 | 24 x 64
46 | 26 x 40
47 | 26 x 48
48 | 26 x 64
---------------------
DMRE symbol sizes may be activated in automatic size mode using the option DMRE symbol sizes may be activated in automatic size mode using the option
--dmre or by the API option_3 = DM_DMRE --dmre or by the API option_3 = DM_DMRE
@ -2516,7 +2574,7 @@ FAST_MODE) may be used.
Data Matrix supports Structured Append of up to 16 symbols and a numeric ID Data Matrix supports Structured Append of up to 16 symbols and a numeric ID
(file identifications), which can be set by using the --structapp option (see (file identifications), which can be set by using the --structapp option (see
section 4.15) or the API structapp variable. The ID consists of 2 numbers ID1 section 4.16) or the API structapp variable. The ID consists of 2 numbers ID1
and ID2, each of which can range from 1 to 254, and is specified as the single and ID2, each of which can range from 1 to 254, and is specified as the single
number ID1 * 1000 + ID2, so for instance ID1 "123" and ID2 "234" would be given number ID1 * 1000 + ID2, so for instance ID1 "123" and ID2 "234" would be given
as "123234". Note that both ID1 and ID2 must be non-zero, so e.g. "123000" or as "123234". Note that both ID1 and ID2 must be non-zero, so e.g. "123000" or
@ -2528,63 +2586,37 @@ Also known as Quick Response Code this symbology was developed by Denso. Four
levels of error correction are available using the --secure= option or by levels of error correction are available using the --secure= option or by
setting option_1 as shown in the following table. setting option_1 as shown in the following table.
------------------------------------------------------------------------- -----------------------------------------------------------------------
Input | ECC Level | Error Correction Capacity | Recovery Capacity Input | ECC Level | Error Correction Capacity | Recovery Capacity
------------------------------------------------------------------------- -----------------------------------------------------------------------
1 | L (default) | Approx 20% of symbol | Approx 7% 1 | L | Approx 20% of symbol | Approx 7%
2 | M | Approx 37% of symbol | Approx 15% 2 | M | Approx 37% of symbol | Approx 15%
3 | Q | Approx 55% of symbol | Approx 25% 3 | Q | Approx 55% of symbol | Approx 25%
4 | H | Approx 65% of symbol | Approx 30% 4 | H | Approx 65% of symbol | Approx 30%
------------------------------------------------------------------------- -----------------------------------------------------------------------
The size of the symbol can be set by using the --vers= option or setting The size of the symbol can be set by using the --vers= option or setting
option_2 to the QR Code version required (1-40). The size of symbol generated option_2 to the QR Code version required (1-40). The size of symbol generated
is shown in the table below. is shown in the table below.
--------------------- -------------------------------------------------------------------------------
Input | Symbol Size Input | Symbol Size | Input | Symbol Size | Input | Symbol Size
--------------------- -------------------------------------------------------------------------------
1 | 21 x 21 1 | 21 x 21 | 15 | 77 x 77 | 29 | 133 x 133
2 | 25 x 25 2 | 25 x 25 | 16 | 81 x 81 | 30 | 137 x 137
3 | 29 x 29 3 | 29 x 29 | 17 | 85 x 85 | 31 | 141 x 141
4 | 33 x 33 4 | 33 x 33 | 18 | 89 x 89 | 32 | 145 x 145
5 | 37 x 37 5 | 37 x 37 | 19 | 93 x 93 | 33 | 149 x 149
6 | 41 x 41 6 | 41 x 41 | 20 | 97 x 97 | 34 | 153 x 153
7 | 45 x 45 7 | 45 x 45 | 21 | 101 x 101 | 35 | 157 x 157
8 | 49 x 49 8 | 49 x 49 | 22 | 105 x 105 | 36 | 161 x 161
9 | 53 x 53 9 | 53 x 53 | 23 | 109 x 109 | 37 | 165 x 165
10 | 57 x 57 10 | 57 x 57 | 24 | 113 x 113 | 38 | 169 x 169
11 | 61 x 61 11 | 61 x 61 | 25 | 117 x 117 | 39 | 173 x 173
12 | 65 x 65 12 | 65 x 65 | 26 | 121 x 121 | 40 | 177 x 177
13 | 69 x 69 13 | 69 x 69 | 27 | 125 x 125 |
14 | 73 x 73 14 | 73 x 73 | 28 | 129 x 129 |
15 | 77 x 77 -------------------------------------------------------------------------------
16 | 81 x 81
17 | 85 x 85
18 | 89 x 89
19 | 93 x 93
20 | 97 x 97
21 | 101 x 101
22 | 105 x 105
23 | 109 x 109
24 | 113 x 113
25 | 117 x 117
26 | 121 x 121
28 | 125 x 125
28 | 129 x 129
29 | 133 x 133
30 | 137 x 137
31 | 141 x 141
32 | 145 x 145
33 | 149 x 149
34 | 153 x 153
35 | 157 x 157
36 | 161 x 161
38 | 165 x 165
38 | 169 x 169
39 | 173 x 173
40 | 177 x 177
---------------------
The maximum capacity of a (version 40) QR Code symbol is 7089 numeric digits, The maximum capacity of a (version 40) QR Code symbol is 7089 numeric digits,
4296 alphanumeric characters or 2953 bytes of data. QR Code symbols can also be 4296 alphanumeric characters or 2953 bytes of data. QR Code symbols can also be
@ -2607,7 +2639,7 @@ by using the --mask= switch with values 0-7, or by setting option_3 to
ZINT_FULL_MULTIBYTE | (N + 1) << 8. ZINT_FULL_MULTIBYTE | (N + 1) << 8.
QR Code supports Structured Append of up to 16 symbols and a numeric ID QR Code supports Structured Append of up to 16 symbols and a numeric ID
(parity), which can be set by using the --structapp option (see section 4.15) or (parity), which can be set by using the --structapp option (see section 4.16) or
the API structapp variable. The parity ID ranges from 0 (default) to 255, and the API structapp variable. The parity ID ranges from 0 (default) to 255, and
for full compliance should be set to the value obtained by XOR-ing together each for full compliance should be set to the value obtained by XOR-ing together each
byte of the complete data forming the sequence. Currently this calculation must byte of the complete data forming the sequence. Currently this calculation must
@ -2615,23 +2647,40 @@ be done outside of Zint.
6.6.3 Micro QR Code (ISO 18004) 6.6.3 Micro QR Code (ISO 18004)
------------------------------- -------------------------------
A miniature version of the QR Code symbol for short messages. ECC levels can be A miniature version of the QR Code symbol for short messages, Micro QR Code
selected as for QR Code (above). QR Code symbols can encode characters in the symbols can encode characters in the Latin-1 set and Kanji characters which are
Latin-1 set and Kanji characters which are members of the Shift JIS encoding members of the Shift JIS encoding scheme. Input should be entered as a UTF-8
scheme. Input should be entered as a UTF-8 stream with conversion to Shift JIS stream with conversion to Latin-1 or Shift JIS being carried out automatically
being carried out automatically by Zint. A preferred symbol size can be by Zint. A preferred symbol size can be selected by using the --vers= option or
selected by using the --vers= option or by setting option_2 although the actual by setting option_2, as shown in the table below. Note that versions M1 and M2
version used by Zint may be different if required by the input data. The table have restrictions on what characters can be encoded.
below shows the possible sizes:
--------------------------------- ------------------------------------------------------------------------
Input | Version | Symbol Size Input | Version | Symbol Size | Allowed Characters
--------------------------------- ------------------------------------------------------------------------
1 | M1 | 11 x 11 1 | M1 | 11 x 11 | Numeric only
2 | M2 | 13 x 13 2 | M2 | 13 x 13 | Numeric, uppercase letters, space,
3 | M3 | 15 x 15 | | | and the characters "$%*+-./:"
4 | M4 | 17 x 17 3 | M3 | 15 x 15 | Latin-1 and Kanji
--------------------------------- 4 | M4 | 17 x 17 | Latin-1 and Kanji
------------------------------------------------------------------------
Except for version M1, which is always ECC level L, the amount of ECC codewords
can be adjusted using the --secure= option (API option_1); however ECC level H
is not available for any version, and ECC level Q is only available for version
M4:
----------------------------------------------------------------------------
Input | ECC | Error Correction | Recovery | Available for
| Level | Capacity | Capacity | Versions
----------------------------------------------------------------------------
1 | L | Approx 20% of symbol | Approx 7% | M1, M2, M3, M4
2 | M | Approx 37% of symbol | Approx 15% | M2, M3, M4
3 | Q | Approx 55% of symbol | Approx 25% | M4
---------------------------------------------------------------------------
The defaults for symbol size and ECC level depend on the input and whether
either of them is specified.
For barcode readers that support it, non-ASCII data density may be maximized by For barcode readers that support it, non-ASCII data density may be maximized by
using the --fullmultibyte switch or by setting option_3 to ZINT_FULL_MULTIBYTE. using the --fullmultibyte switch or by setting option_3 to ZINT_FULL_MULTIBYTE.
@ -2653,60 +2702,40 @@ entered as UTF-8 with conversion being handled by Zint. The amount of ECC
codewords can be adjusted using the --secure= option (API option_1), however codewords can be adjusted using the --secure= option (API option_1), however
only ECC levels M and H are valid for this type of symbol. only ECC levels M and H are valid for this type of symbol.
------------------------------------------------------------------------- -----------------------------------------------------------------------
Input | ECC Level | Error Correction Capacity | Recovery Capacity Input | ECC Level | Error Correction Capacity | Recovery Capacity
------------------------------------------------------------------------- -----------------------------------------------------------------------
2 | M (default) | Approx 37% of symbol | Approx 15% 2 | M | Approx 37% of symbol | Approx 15%
4 | H | Approx 65% of symbol | Approx 30% 4 | H | Approx 65% of symbol | Approx 30%
------------------------------------------------------------------------- -----------------------------------------------------------------------
The preferred symbol sizes can be selected using the --vers= option (API The preferred symbol sizes can be selected using the --vers= option (API
option_2) as shown in the table below. Input values between 33 and 38 fix the option_2) as shown in the table below. Input values between 33 and 38 fix the
height of the symbol while allowing Zint to determine the minimum symbol width. height of the symbol while allowing Zint to determine the minimum symbol width.
--------------------------------------- --------------------------------------------------------------------------------
Input | Version | Symbol Size (HxW) Input | Version | Symbol Size (HxW) | Input | Version | Symbol Size (HxW)
--------------------------------------- --------------------------------------------------------------------------------
1 | R7x43 | 7 x 73 1 | R7x43 | 7 x 73 | 20 | R13x77 | 13 x 77
2 | R7x59 | 7 x 59 2 | R7x59 | 7 x 59 | 21 | R13x99 | 13 x 99
3 | R7x77 | 7 x 77 3 | R7x77 | 7 x 77 | 22 | R13x139 | 13 x 139
4 | R7x99 | 7 x 99 4 | R7x99 | 7 x 99 | 23 | R15x43 | 15 x 43
5 | R7x139 | 7 x 139 5 | R7x139 | 7 x 139 | 24 | R15x59 | 15 x 59
6 | R9x43 | 9 x 43 6 | R9x43 | 9 x 43 | 25 | R15x77 | 15 x 77
7 | R9x59 | 9 x 59 7 | R9x59 | 9 x 59 | 26 | R15x99 | 15 x 99
8 | R9x77 | 9 x 77 8 | R9x77 | 9 x 77 | 27 | R15x139 | 15 x 139
9 | R9x99 | 9 x 99 9 | R9x99 | 9 x 99 | 28 | R17x43 | 17 x 43
10 | R9x139 | 9 x 139 10 | R9x139 | 9 x 139 | 29 | R17x59 | 17 x 59
11 | R11x27 | 11 x 27 11 | R11x27 | 11 x 27 | 30 | R17x77 | 17 x 77
12 | R11x43 | 11 x 43 12 | R11x43 | 11 x 43 | 31 | R17x99 | 17 x 99
13 | R11x59 | 11 x 59 13 | R11x59 | 11 x 59 | 32 | R17x139 | 17 x 139
14 | R11x77 | 11 x 77 14 | R11x77 | 11 x 77 | 33 | R7xW | 7 x automatic width
15 | R11x99 | 11 x 99 15 | R11x99 | 11 x 99 | 34 | R9xW | 9 x automatic width
16 | R11x139 | 11 x 139 16 | R11x139 | 11 x 139 | 35 | R11xW | 11 x automatic width
17 | R13x27 | 13 x 27 17 | R13x27 | 13 x 27 | 36 | R13xW | 13 x automatic width
18 | R13x43 | 13 x 43 18 | R13x43 | 13 x 43 | 37 | R15xW | 15 x automatic width
19 | R13x59 | 13 x 59 19 | R13x59 | 13 x 59 | 38 | R17xW | 17 x automatic width
20 | R13x77 | 13 x 77 --------------------------------------------------------------------------------
21 | R13x99 | 13 x 99
22 | R13x139 | 13 x 139
23 | R15x43 | 15 x 43
24 | R15x59 | 15 x 59
25 | R15x77 | 15 x 77
26 | R15x99 | 15 x 99
27 | R15x139 | 15 x 139
28 | R17x43 | 17 x 43
29 | R17x59 | 17 x 59
30 | R17x77 | 17 x 77
31 | R17x99 | 17 x 99
32 | R17x139 | 17 x 139
---------------------------------------
33 | R7 x automatic width
34 | R9 x automatic width
35 | R11 x automatic width
36 | R13 x automatic width
37 | R15 x automatic width
38 | R17 x automatic width
---------------------------------------
For barcode readers that support it, non-ASCII data density may be maximized by For barcode readers that support it, non-ASCII data density may be maximized by
using the --fullmultibyte switch or by setting option_3 to ZINT_FULL_MULTIBYTE. using the --fullmultibyte switch or by setting option_3 to ZINT_FULL_MULTIBYTE.
@ -2797,7 +2826,7 @@ Mode | Maximum Data Length | Maximum Data Length | Number of Error
* - secondary only * - secondary only
MaxiCode supports Structured Append of up to 8 symbols, which can be set by MaxiCode supports Structured Append of up to 8 symbols, which can be set by
using the --structapp option (see section 4.15) or the API structapp variable. using the --structapp option (see section 4.16) or the API structapp variable.
It does not support specifying an ID. It does not support specifying an ID.
MaxiCode uses a different scaling than other symbols for raster output, see MaxiCode uses a different scaling than other symbols for raster output, see
@ -2808,7 +2837,7 @@ instead of 2.
---------------------------- ----------------------------
Invented by Andrew Longacre at Welch Allyn Inc in 1995 the Aztec Code symbol is Invented by Andrew Longacre at Welch Allyn Inc in 1995 the Aztec Code symbol is
a matrix symbol with a distinctive bulls-eye finder pattern. Zint can generate a matrix symbol with a distinctive bulls-eye finder pattern. Zint can generate
Compact Aztec Code (sometimes called Small Aztec Code) as well as "full-range" Compact Aztec Code (sometimes called Small Aztec Code) as well as 'full-range'
Aztec Code symbols and by default will automatically select symbol type and Aztec Code symbols and by default will automatically select symbol type and
size dependent on the length of the data to be encoded. Error correction size dependent on the length of the data to be encoded. Error correction
codewords will normally be generated to fill at least 23% of the symbol. Two codewords will normally be generated to fill at least 23% of the symbol. Two
@ -2816,49 +2845,25 @@ options are available to change this behaviour:
The size of the symbol can be specified using the --vers= option or setting The size of the symbol can be specified using the --vers= option or setting
option_2 to a value between 1 and 36 according to the following table. The option_2 to a value between 1 and 36 according to the following table. The
symbols marked with an asterisk (*) in the table below are "compact" symbols, symbols marked with an asterisk (*) in the table below are 'compact' symbols,
meaning they have a smaller bulls-eye pattern at the centre of the symbol. meaning they have a smaller bulls-eye pattern at the centre of the symbol.
--------------------- -------------------------------------------------------------------------------
Input | Symbol Size Input | Symbol Size | Input | Symbol Size | Input | Symbol Size
--------------------- -------------------------------------------------------------------------------
1 | 15 x 15* 1 | 15 x 15* | 13 | 53 x 53 | 25 | 105 x 105
2 | 19 x 19* 2 | 19 x 19* | 14 | 57 x 57 | 26 | 109 x 109
3 | 23 x 23* 3 | 23 x 23* | 15 | 61 x 61 | 27 | 113 x 113
4 | 27 x 27* 4 | 27 x 27* | 16 | 67 x 67 | 28 | 117 x 117
5 | 19 x 19 5 | 19 x 19 | 17 | 71 x 71 | 29 | 121 x 121
6 | 23 x 23 6 | 23 x 23 | 18 | 75 x 75 | 30 | 125 x 125
7 | 27 x 27 7 | 27 x 27 | 19 | 79 x 79 | 31 | 131 x 131
8 | 31 x 31 8 | 31 x 31 | 20 | 83 x 83 | 32 | 135 x 135
9 | 37 x 37 9 | 37 x 37 | 21 | 87 x 87 | 33 | 139 x 139
10 | 41 x 41 10 | 41 x 41 | 22 | 91 x 91 | 34 | 143 x 143
11 | 45 x 45 11 | 45 x 45 | 23 | 95 x 95 | 35 | 147 x 147
12 | 49 x 49 12 | 49 x 49 | 24 | 101 x 101 | 36 | 151 x 151
13 | 53 x 53 -------------------------------------------------------------------------------
14 | 57 x 57
15 | 61 x 61
16 | 67 x 67
17 | 71 x 71
18 | 75 x 75
19 | 79 x 79
20 | 83 x 83
21 | 87 x 87
22 | 91 x 91
23 | 95 x 95
24 | 101 x 101
25 | 105 x 105
26 | 109 x 109
27 | 113 x 113
28 | 117 x 117
29 | 121 x 121
30 | 125 x 125
31 | 131 x 131
32 | 135 x 135
33 | 139 x 139
34 | 143 x 143
35 | 147 x 147
36 | 151 x 151
---------------------
Note that in symbols which have a specified size the amount of error correction Note that in symbols which have a specified size the amount of error correction
is dependent on the length of the data input and Zint will allow error is dependent on the length of the data input and Zint will allow error
@ -2888,7 +2893,7 @@ encoded data.
Aztec Code supports Structured Append of up to 26 symbols and an optional Aztec Code supports Structured Append of up to 26 symbols and an optional
alphanumeric ID of up to 32 characters, which can be set by using the alphanumeric ID of up to 32 characters, which can be set by using the
--structapp option (see section 4.15) or the API structapp variable. The ID --structapp option (see section 4.16) or the API structapp variable. The ID
cannot contain spaces. If an ID is not given, no ID is encoded. cannot contain spaces. If an ID is not given, no ID is encoded.
6.6.8 Aztec Runes 6.6.8 Aztec Runes
@ -2926,7 +2931,7 @@ Version S symbols can only encode numeric data. The width of version S and
version T symbols is determined by the length of the input data. version T symbols is determined by the length of the input data.
Code One supports Structured Append of up to 128 symbols, which can be set by Code One supports Structured Append of up to 128 symbols, which can be set by
using the --structapp option (see section 4.15) or the API structapp variable. using the --structapp option (see section 4.16) or the API structapp variable.
It does not support specifying an ID. Structured Append is not supported with It does not support specifying an ID. Structured Append is not supported with
GS1 data nor for Version S symbols. GS1 data nor for Version S symbols.
@ -2945,23 +2950,17 @@ option or by setting option_2, and the error correction capacity can be
specified by using the --secure= option or by setting option_1 according to specified by using the --secure= option or by setting option_1 according to
the following tables: the following tables:
--------------------- ----------------------------------------------------
Input | Symbol Size Input | Symbol Size | Input | Symbol Size
--------------------- ----------------------------------------------------
1 | 18 x 18 1 | 18 x 18 | 8 | 102 x 102
2 | 30 x 30 2 | 30 x 30 | 9 | 114 x 114
3 | 42 x 42 3 | 42 x 42 | 10 | 126 x 126
4 | 54 x 54 4 | 54 x 54 | 11 | 138 x 138
5 | 66 x 66 5 | 66 x 66 | 12 | 150 x 150
6 | 78 x 78 6 | 78 x 78 | 13 | 162 x 162
7 | 90 x 90 7 | 90 x 90
8 | 102 x 102 ----------------------------------------------------
9 | 114 x 114
10 | 126 x 126
11 | 138 x 138
12 | 150 x 150
13 | 162 x 162
---------------------
---------------------------------- ----------------------------------
Mode | Error Correction Capacity Mode | Error Correction Capacity
@ -2979,7 +2978,7 @@ supports this before using.
Grid Matrix supports Structured Append of up to 16 symbols and a numeric ID Grid Matrix supports Structured Append of up to 16 symbols and a numeric ID
(file signature), which can be set by using the --structapp option (see section (file signature), which can be set by using the --structapp option (see section
4.15) or the API structapp variable. The ID ranges from 0 (default) to 255. 4.16) or the API structapp variable. The ID ranges from 0 (default) to 255.
6.6.11 DotCode 6.6.11 DotCode
-------------- --------------
@ -2993,116 +2992,58 @@ setting the scale of the image to a larger value than the default (e.g. approx
10) for the dots to be plotted correctly. Approximately 33% of the resulting 10) for the dots to be plotted correctly. Approximately 33% of the resulting
symbol is comprised of error correction codewords. symbol is comprised of error correction codewords.
DotCode has two sets of 4 masks, designated 0-3 and 0'-3', the second "prime" DotCode has two sets of 4 masks, designated 0-3 and 0'-3', the second 'prime'
set being the same as the first with corners lit. The best mask to use is set being the same as the first with corners lit. The best mask to use is
selected automatically by Zint but may be manually specified by using the selected automatically by Zint but may be manually specified by using the
--mask= switch with values 0-7, where 4-7 denote 0'-3', or by setting option_3 --mask= switch with values 0-7, where 4-7 denote 0'-3', or by setting option_3
to (N + 1) << 8 where N is 0-7. to (N + 1) << 8 where N is 0-7.
DotCode supports Structured Append of up to 35 symbols, which can be set by DotCode supports Structured Append of up to 35 symbols, which can be set by
using the --structapp option (see section 4.15) or the API structapp variable. using the --structapp option (see section 4.16) or the API structapp variable.
It does not support specifying an ID. It does not support specifying an ID.
6.6.12 Han Xin Code 6.6.12 Han Xin Code
------------------- -------------------
Also known as Chinese Sensible Code, Han Xin is a symbology which is still under Also known as Chinese Sensible Code, Han Xin is capable of encoding characters
development, so it is recommended it should not yet be used for a production in the GB 18030 character set (which includes all Unicode characters) and is
environment. The symbology is capable of encoding characters in the GB 18030 also able to support the ECI mechanism. Support for the encoding of GS1 data has
character set (which includes all Unicode characters) and is also able to not yet been implemented.
support the ECI mechanism. Support for the encoding of GS1 data has not yet been
implemented.
The size of the symbol can be specified using the --vers= option or setting The size of the symbol can be specified using the --vers= option or setting
option_2 to a value between 1 and 84 according to the following table. option_2 to a value between 1 and 84 according to the following table.
--------------------- -------------------------------------------------------------------------------
Input | Symbol Size Input | Symbol Size | Input | Symbol Size | Input | Symbol Size
--------------------- -------------------------------------------------------------------------------
1 | 23 x 23 1 | 23 x 23 | 29 | 79 x 79 | 57 | 135 x 135
2 | 25 x 25 2 | 25 x 25 | 30 | 81 x 81 | 58 | 137 x 137
3 | 27 x 27 3 | 27 x 27 | 31 | 83 x 83 | 59 | 139 x 139
4 | 29 x 29 4 | 29 x 29 | 32 | 85 x 85 | 60 | 141 x 141
5 | 31 x 31 5 | 31 x 31 | 33 | 87 x 87 | 61 | 143 x 143
6 | 33 x 33 6 | 33 x 33 | 34 | 89 x 89 | 62 | 145 x 145
7 | 35 x 35 7 | 35 x 35 | 35 | 91 x 91 | 63 | 147 x 147
8 | 37 x 37 8 | 37 x 37 | 36 | 93 x 93 | 64 | 149 x 149
9 | 39 x 39 9 | 39 x 39 | 37 | 95 x 95 | 65 | 151 x 151
10 | 41 x 41 10 | 41 x 41 | 38 | 97 x 97 | 66 | 153 x 153
11 | 43 x 43 11 | 43 x 43 | 39 | 99 x 99 | 67 | 155 x 155
12 | 45 x 45 12 | 45 x 45 | 40 | 101 x 101 | 68 | 157 x 157
13 | 47 x 47 13 | 47 x 47 | 41 | 103 x 103 | 69 | 159 x 159
14 | 49 x 49 14 | 49 x 49 | 42 | 105 x 105 | 70 | 161 x 161
15 | 51 x 51 15 | 51 x 51 | 43 | 107 x 107 | 71 | 163 x 163
16 | 53 x 53 16 | 53 x 53 | 44 | 109 x 109 | 72 | 165 x 165
17 | 55 x 55 17 | 55 x 55 | 45 | 111 x 111 | 73 | 167 x 167
18 | 57 x 57 18 | 57 x 57 | 46 | 113 x 113 | 74 | 169 x 169
19 | 59 x 59 19 | 59 x 59 | 47 | 115 x 115 | 75 | 171 x 171
20 | 61 x 61 20 | 61 x 61 | 48 | 117 x 117 | 76 | 173 x 173
21 | 63 x 63 21 | 63 x 63 | 49 | 119 x 119 | 77 | 175 x 175
22 | 65 x 65 22 | 65 x 65 | 50 | 121 x 121 | 78 | 177 x 177
23 | 67 x 67 23 | 67 x 67 | 51 | 123 x 123 | 79 | 179 x 179
24 | 69 x 69 24 | 69 x 69 | 52 | 125 x 125 | 80 | 181 x 181
25 | 71 x 71 25 | 71 x 71 | 53 | 127 x 127 | 81 | 183 x 183
26 | 73 x 73 26 | 73 x 73 | 54 | 129 x 129 | 82 | 185 x 185
28 | 75 x 75 27 | 75 x 75 | 55 | 131 x 131 | 83 | 187 x 187
28 | 77 x 77 28 | 77 x 77 | 56 | 133 x 133 | 84 | 189 x 189
29 | 79 x 79 -------------------------------------------------------------------------------
30 | 81 x 81
31 | 83 x 83
32 | 85 x 85
33 | 87 x 87
34 | 89 x 89
35 | 91 x 91
36 | 93 x 93
37 | 95 x 95
38 | 97 x 97
39 | 99 x 99
40 | 101 x 101
41 | 103 x 103
42 | 105 x 105
43 | 107 x 107
44 | 109 x 109
45 | 111 x 111
46 | 113 x 113
47 | 115 x 115
48 | 117 x 117
49 | 119 x 119
50 | 121 x 121
51 | 123 x 123
52 | 125 x 125
53 | 127 x 127
54 | 129 x 129
55 | 131 x 131
56 | 133 x 133
57 | 135 x 135
58 | 137 x 137
59 | 139 x 139
60 | 141 x 141
61 | 143 x 143
62 | 145 x 145
63 | 147 x 147
64 | 149 x 149
65 | 151 x 151
66 | 153 x 153
67 | 155 x 155
68 | 157 x 157
69 | 159 x 159
70 | 161 x 161
71 | 163 x 163
72 | 165 x 165
73 | 167 x 167
74 | 169 x 169
75 | 171 x 171
76 | 173 x 173
77 | 175 x 175
78 | 177 x 177
79 | 179 x 179
80 | 181 x 181
81 | 183 x 183
82 | 185 x 185
83 | 187 x 187
84 | 189 x 189
---------------------
There are four levels of error correction capacity available for Han Xin Code There are four levels of error correction capacity available for Han Xin Code
which can be set by using the --secure= option or by setting option_1 to a value which can be set by using the --secure= option or by setting option_1 to a value
@ -3159,7 +3100,7 @@ option_2 to 2.
Ultracode supports Structured Append of up to 8 symbols and an optional numeric Ultracode supports Structured Append of up to 8 symbols and an optional numeric
ID (File Number), which can be set by using the --structapp option (see section ID (File Number), which can be set by using the --structapp option (see section
4.15) or the API structapp variable. The ID ranges from 1 to 80088. If an ID is 4.16) or the API structapp variable. The ID ranges from 1 to 80088. If an ID is
not given, no ID is encoded. not given, no ID is encoded.
6.7 Other Barcode-Like Markings 6.7 Other Barcode-Like Markings

View File

@ -127,14 +127,14 @@ static void usage(void) {
" --cmyk Use CMYK colour space in EPS/TIF symbols\n" " --cmyk Use CMYK colour space in EPS/TIF symbols\n"
" --cols=NUMBER Set the number of data columns in symbol\n" " --cols=NUMBER Set the number of data columns in symbol\n"
" --compliantheight Warn if height not compliant, and use standard default\n" " --compliantheight Warn if height not compliant, and use standard default\n"
" -d, --data=DATA Set the symbol content\n" " -d, --data=DATA Set the symbol data content (segment 0)\n"
" --direct Send output to stdout\n" " --direct Send output to stdout\n"
" --dmre Allow Data Matrix Rectangular Extended\n" " --dmre Allow Data Matrix Rectangular Extended\n"
" --dotsize=NUMBER Set radius of dots in dotty mode\n" " --dotsize=NUMBER Set radius of dots in dotty mode\n"
" --dotty Use dots instead of squares for matrix symbols\n" " --dotty Use dots instead of squares for matrix symbols\n"
" --dump Dump hexadecimal representation to stdout\n" " --dump Dump hexadecimal representation to stdout\n"
" -e, --ecinos Display table of ECI character encodings\n" " -e, --ecinos Display ECI (Extended Channel Interpretation) table\n"
" --eci=NUMBER Set the ECI (Extended Channel Interpretation) code\n" " --eci=NUMBER Set the ECI code for the data (segment 0)\n"
" --esc Process escape characters in input data\n" " --esc Process escape characters in input data\n"
" --fast Use faster encodation (Data Matrix)\n" " --fast Use faster encodation (Data Matrix)\n"
" --fg=COLOUR Specify a foreground colour (in hex RGB/RGBA)\n" " --fg=COLOUR Specify a foreground colour (in hex RGB/RGBA)\n"
@ -165,6 +165,7 @@ static void usage(void) {
" --scale=NUMBER Adjust size of X-dimension\n" " --scale=NUMBER Adjust size of X-dimension\n"
" --scmvv=NUMBER Prefix SCM with \"[)>\\R01\\Gvv\" (vv is NUMBER) (MaxiCode)\n" " --scmvv=NUMBER Prefix SCM with \"[)>\\R01\\Gvv\" (vv is NUMBER) (MaxiCode)\n"
" --secure=NUMBER Set error correction level (ECC)\n" " --secure=NUMBER Set error correction level (ECC)\n"
" --segN=ECI,DATA Set the ECI & data content for segment N where N is 1 to 9\n"
" --separator=NUMBER Set height of row separator bars (stacked symbologies)\n" " --separator=NUMBER Set height of row separator bars (stacked symbologies)\n"
" --small Use small text\n" " --small Use small text\n"
" --square Force Data Matrix symbols to be square\n" " --square Force Data Matrix symbols to be square\n"
@ -561,6 +562,28 @@ int validate_structapp(const char *optarg, struct zint_structapp *structapp) {
return 1; return 1;
} }
/* Parse and validate the segment argument "ECI,DATA" to "--segN" */
static int validate_seg(const char *optarg, const int N, struct zint_seg segs[10]) {
char eci[10] = {0};
const char *comma = strchr(optarg, ',');
if (!comma || comma == optarg || comma - optarg > 9 || *(comma + 1) == '\0') {
fprintf(stderr, "Error 166: Invalid segment argument, expect \"ECI,DATA\"\n");
return 0;
}
strncpy(eci, optarg, comma - optarg);
if (!validate_int(eci, &segs[N].eci)) {
fprintf(stderr, "Error 167: Invalid segment ECI (digits only)\n");
return 0;
}
if (segs[N].eci > 999999) {
fprintf(stderr, "Error 168: Segment ECI code out of range (0 to 999999)\n");
return 0;
}
segs[N].length = (int) strlen(comma + 1);
segs[N].source = (unsigned char *) (comma + 1);
return 1;
}
/* Batch mode - output symbol for each line of text in `filename` */ /* Batch mode - output symbol for each line of text in `filename` */
static int batch_process(struct zint_symbol *symbol, const char *filename, const int mirror_mode, static int batch_process(struct zint_symbol *symbol, const char *filename, const int mirror_mode,
const char *filetype, const int rotate_angle) { const char *filetype, const int rotate_angle) {
@ -819,6 +842,7 @@ typedef struct { char *arg; int opt; } arg_opt;
int main(int argc, char **argv) { int main(int argc, char **argv) {
struct zint_symbol *my_symbol; struct zint_symbol *my_symbol;
struct zint_seg segs[10] = {0};
int error_number = 0; int error_number = 0;
int rotate_angle = 0; int rotate_angle = 0;
int help = 0; int help = 0;
@ -839,6 +863,7 @@ int main(int argc, char **argv) {
int ret; int ret;
char *outfile_extension; char *outfile_extension;
int data_arg_num = 0; int data_arg_num = 0;
int seg_count = 0;
float float_opt; float float_opt;
#ifndef _MSC_VER #ifndef _MSC_VER
arg_opt arg_opts[argc]; arg_opt arg_opts[argc];
@ -872,8 +897,9 @@ int main(int argc, char **argv) {
OPT_GS1, OPT_GS1NOCHECK, OPT_GS1PARENS, OPT_GSSEP, OPT_GUARDDESCENT, OPT_GS1, OPT_GS1NOCHECK, OPT_GS1PARENS, OPT_GSSEP, OPT_GUARDDESCENT,
OPT_HEIGHT, OPT_HEIGHTPERROW, OPT_INIT, OPT_MIRROR, OPT_MASK, OPT_MODE, OPT_HEIGHT, OPT_HEIGHTPERROW, OPT_INIT, OPT_MIRROR, OPT_MASK, OPT_MODE,
OPT_NOBACKGROUND, OPT_NOQUIETZONES, OPT_NOTEXT, OPT_PRIMARY, OPT_QUIETZONES, OPT_NOBACKGROUND, OPT_NOQUIETZONES, OPT_NOTEXT, OPT_PRIMARY, OPT_QUIETZONES,
OPT_ROTATE, OPT_ROWS, OPT_SCALE, OPT_SCMVV, OPT_ROTATE, OPT_ROWS, OPT_SCALE, OPT_SCMVV, OPT_SECURE,
OPT_SECURE, OPT_SEPARATOR, OPT_SMALL, OPT_SQUARE, OPT_STRUCTAPP, OPT_SEG1, OPT_SEG2, OPT_SEG3, OPT_SEG4, OPT_SEG5, OPT_SEG6, OPT_SEG7, OPT_SEG8, OPT_SEG9,
OPT_SEPARATOR, OPT_SMALL, OPT_SQUARE, OPT_STRUCTAPP,
OPT_VERBOSE, OPT_VERS, OPT_VWHITESP, OPT_WERROR, OPT_VERBOSE, OPT_VERS, OPT_VWHITESP, OPT_WERROR,
}; };
int option_index = 0; int option_index = 0;
@ -929,6 +955,15 @@ int main(int argc, char **argv) {
{"scale", 1, NULL, OPT_SCALE}, {"scale", 1, NULL, OPT_SCALE},
{"scmvv", 1, NULL, OPT_SCMVV}, {"scmvv", 1, NULL, OPT_SCMVV},
{"secure", 1, NULL, OPT_SECURE}, {"secure", 1, NULL, OPT_SECURE},
{"seg1", 1, NULL, OPT_SEG1},
{"seg2", 1, NULL, OPT_SEG2},
{"seg3", 1, NULL, OPT_SEG3},
{"seg4", 1, NULL, OPT_SEG4},
{"seg5", 1, NULL, OPT_SEG5},
{"seg6", 1, NULL, OPT_SEG6},
{"seg7", 1, NULL, OPT_SEG7},
{"seg8", 1, NULL, OPT_SEG8},
{"seg9", 1, NULL, OPT_SEG9},
{"separator", 1, NULL, OPT_SEPARATOR}, {"separator", 1, NULL, OPT_SEPARATOR},
{"small", 0, NULL, OPT_SMALL}, {"small", 0, NULL, OPT_SMALL},
{"square", 0, NULL, OPT_SQUARE}, {"square", 0, NULL, OPT_SQUARE},
@ -1241,6 +1276,32 @@ int main(int argc, char **argv) {
fflush(stderr); fflush(stderr);
} }
break; break;
case OPT_SEG1:
case OPT_SEG2:
case OPT_SEG3:
case OPT_SEG4:
case OPT_SEG5:
case OPT_SEG6:
case OPT_SEG7:
case OPT_SEG8:
case OPT_SEG9:
if (batch_mode == 0) {
val = c - OPT_SEG1 + 1; /* Segment number */
if (segs[val].source) {
fprintf(stderr, "Error 164: Duplicate segment %d\n", val);
return do_exit(1);
}
if (!validate_seg(optarg, c - OPT_SEG1 + 1, segs)) {
return do_exit(1);
}
if (val >= seg_count) {
seg_count = val + 1;
}
} else {
fprintf(stderr, "Warning 165: Can't define segments in batch mode, ignoring '%s'\n", optarg);
fflush(stderr);
}
break;
case OPT_SEPARATOR: case OPT_SEPARATOR:
if (!validate_int(optarg, &val)) { if (!validate_int(optarg, &val)) {
fprintf(stderr, "Error 128: Invalid separator value (digits only)\n"); fprintf(stderr, "Error 128: Invalid separator value (digits only)\n");
@ -1419,6 +1480,10 @@ int main(int argc, char **argv) {
fprintf(stderr, "Warning 144: Processing first input file '%s' only\n", arg_opts[0].arg); fprintf(stderr, "Warning 144: Processing first input file '%s' only\n", arg_opts[0].arg);
fflush(stderr); fflush(stderr);
} }
if (seg_count) {
fprintf(stderr, "Warning 169: Ignoring segment arguments\n");
fflush(stderr);
}
if (filetype[0] == '\0') { if (filetype[0] == '\0') {
outfile_extension = get_extension(my_symbol->outfile); outfile_extension = get_extension(my_symbol->outfile);
if (outfile_extension && supported_filetype(outfile_extension, no_png, NULL)) { if (outfile_extension && supported_filetype(outfile_extension, no_png, NULL)) {
@ -1440,6 +1505,25 @@ int main(int argc, char **argv) {
fflush(stderr); fflush(stderr);
} }
} else { } else {
if (seg_count) {
if (data_arg_num > 1) {
fprintf(stderr, "Error 170: Cannot specify segments and multiple data arguments together\n");
return do_exit(1);
}
if (arg_opts[0].opt != 'd') { /* For simplicity disallow input args for now */
fprintf(stderr, "Error 171: Cannot use input argument with segment arguments\n");
return do_exit(1);
}
segs[0].eci = my_symbol->eci;
segs[0].source = (unsigned char *) arg_opts[0].arg;
segs[0].length = (int) strlen(arg_opts[0].arg);
for (i = 0; i < seg_count; i++) {
if (segs[i].source == NULL) {
fprintf(stderr, "Error 172: Segments must be consecutive - segment %d missing\n", i);
return do_exit(1);
}
}
}
if (filetype[0] != '\0') { if (filetype[0] != '\0') {
set_extension(my_symbol->outfile, filetype); set_extension(my_symbol->outfile, filetype);
} }
@ -1452,8 +1536,12 @@ int main(int argc, char **argv) {
} }
for (i = 0; i < data_arg_num; i++) { for (i = 0; i < data_arg_num; i++) {
if (arg_opts[i].opt == 'd') { if (arg_opts[i].opt == 'd') {
ret = ZBarcode_Encode(my_symbol, (unsigned char *) arg_opts[i].arg, if (seg_count) {
(int) strlen(arg_opts[i].arg)); ret = ZBarcode_Encode_Segs(my_symbol, segs, seg_count);
} else {
ret = ZBarcode_Encode(my_symbol, (unsigned char *) arg_opts[i].arg,
(int) strlen(arg_opts[i].arg));
}
} else { } else {
ret = ZBarcode_Encode_File(my_symbol, arg_opts[i].arg); ret = ZBarcode_Encode_File(my_symbol, arg_opts[i].arg);
} }

View File

@ -150,6 +150,14 @@ static void arg_data(char *cmd, const char *opt, const char *data) {
} }
} }
static void arg_seg(char *cmd, const char *opt, const char *data, const int eci) {
if (data != NULL) {
sprintf(cmd + (int) strlen(cmd), "%s%s%d,\"%s\"", strlen(cmd) ? " " : "", opt, eci, data);
} else {
sprintf(cmd + (int) strlen(cmd), "%s%s%d", strlen(cmd) ? " " : "", opt, eci);
}
}
static int arg_input(char *cmd, const char *filename, const char *input) { static int arg_input(char *cmd, const char *filename, const char *input) {
FILE *fp; FILE *fp;
int cnt; int cnt;
@ -369,6 +377,77 @@ static void test_dump_args(int index, int debug) {
testFinish(); testFinish();
} }
// Tests segs
static void test_dump_segs(int index, int debug) {
struct item {
int b;
char *data;
char *data_seg1;
char *data_seg2;
int eci;
int eci_seg1;
int eci_seg2;
char *expected;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { -1, "123", NULL, NULL, -1, -1, -1, "D2 13 9B 39 65 C8 C9 8E B" },
/* 1*/ { -1, "123", NULL, NULL, -1, 3, -1, "Error 166: Invalid segment argument, expect \"ECI,DATA\"" },
/* 2*/ { -1, "123", "456", NULL, -1, -1, -1, "Error 167: Invalid segment ECI (digits only)" },
/* 3*/ { -1, "123", "456", NULL, -1, 1000000, -1, "Error 168: Segment ECI code out of range (0 to 999999)" },
/* 4*/ { -1, "123", "456", NULL, -1, 3, -1, "Error 775: Symbology does not support multiple segments" },
/* 5*/ { BARCODE_AZTEC, "123", "456", NULL, -1, 3, -1, "2B 7A\nC7 02\nF0 6E\n3F FE\n70 1C\nB7 D6\nB4 58\n15 54\n94 56\nB7 DC\n30 1A\n1F FC\n4C 66\n22 DA\n1E C6" },
/* 6*/ { BARCODE_AZTEC, "123", NULL, "789", -1, -1, 3, "Error 172: Segments must be consecutive - segment 1 missing" },
};
int data_size = ARRAY_SIZE(data);
int i;
char cmd[4096];
char buf[4096];
testStart("test_dump_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
strcpy(cmd, "zint --dump");
if (debug & ZINT_DEBUG_PRINT) {
strcat(cmd, " --verbose");
}
arg_int(cmd, "-b ", data[i].b);
if (data[i].data && data[i].data[0]) {
arg_data(cmd, "-d ", data[i].data);
}
if (data[i].eci > 0) {
arg_int(cmd, "--eci=", data[i].eci);
}
if (data[i].data_seg1 && data[i].data_seg1[0]) {
arg_seg(cmd, "--seg1=", data[i].data_seg1, data[i].eci_seg1);
} else if (data[i].eci_seg1 >= 0) {
arg_seg(cmd, "--seg1=", NULL, data[i].eci_seg1);
}
if (data[i].data_seg2 && data[i].data_seg2[0]) {
arg_seg(cmd, "--seg2=", data[i].data_seg2, data[i].eci_seg2);
} else if (data[i].eci_seg2 >= 0) {
arg_seg(cmd, "--seg2=", NULL, data[i].eci_seg2);
}
strcat(cmd, " 2>&1");
assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i), "i:%d exec(%s) NULL\n", i, cmd);
assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd);
}
testFinish();
}
static void test_input(int index, int debug) { static void test_input(int index, int debug) {
#define TEST_INPUT_LONG "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" #define TEST_INPUT_LONG "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
@ -997,6 +1076,7 @@ int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_dump_args", test_dump_args, 1, 0, 1 }, { "test_dump_args", test_dump_args, 1, 0, 1 },
{ "test_dump_segs", test_dump_segs, 1, 0, 1 },
{ "test_input", test_input, 1, 0, 1 }, { "test_input", test_input, 1, 0, 1 },
{ "test_stdin_input", test_stdin_input, 1, 0, 1 }, { "test_stdin_input", test_stdin_input, 1, 0, 1 },
{ "test_batch_input", test_batch_input, 1, 0, 1 }, { "test_batch_input", test_batch_input, 1, 0, 1 },

View File

@ -1,6 +1,6 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2008 by BogDan Vatra <bogdan@licentia.eu> * * Copyright (C) 2008 by BogDan Vatra <bogdan@licentia.eu> *
* Copyright (C) 2009-2021 by Robin Stuart <rstuart114@gmail.com> * * Copyright (C) 2009-2022 by Robin Stuart <rstuart114@gmail.com> *
* * * *
* This program is free software: you can redistribute it and/or modify * * This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
@ -13,7 +13,6 @@
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. * * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/
/* vim: set ts=4 sw=4 et : */
#include <QApplication> #include <QApplication>
#include "mainwindow.h" #include "mainwindow.h"
@ -38,3 +37,5 @@ int main(int argc, char *argv[])
w.show(); w.show();
return app.exec(); return app.exec();
} }
/* vim: set ts=4 sw=4 et : */

File diff suppressed because it is too large Load Diff

View File

@ -171,10 +171,12 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl)
bstyle->setCurrentIndex(settings.value(QSL("studio/symbology"), 10).toInt()); bstyle->setCurrentIndex(settings.value(QSL("studio/symbology"), 10).toInt());
txtData->setText(settings.value(QSL("studio/data"), tr("Your Data Here!")).toString()); txtData->setText(settings.value(QSL("studio/data"), tr("Your Data Here!")).toString());
/* Don't save seg data */
txtComposite->setText(settings.value(QSL("studio/composite_text"), tr("Your Data Here!")).toString()); txtComposite->setText(settings.value(QSL("studio/composite_text"), tr("Your Data Here!")).toString());
chkComposite->setChecked(settings.value(QSL("studio/chk_composite")).toInt() ? true : false); chkComposite->setChecked(settings.value(QSL("studio/chk_composite")).toInt() ? true : false);
cmbCompType->setCurrentIndex(settings.value(QSL("studio/comp_type"), 0).toInt()); cmbCompType->setCurrentIndex(settings.value(QSL("studio/comp_type"), 0).toInt());
cmbECI->setCurrentIndex(settings.value(QSL("studio/appearance/eci"), 0).toInt()); cmbECI->setCurrentIndex(settings.value(QSL("studio/eci"), 0).toInt());
/* Don't save seg ECIs */
chkEscape->setChecked(settings.value(QSL("studio/chk_escape")).toInt() ? true : false); chkEscape->setChecked(settings.value(QSL("studio/chk_escape")).toInt() ? true : false);
chkData->setChecked(settings.value(QSL("studio/chk_data")).toInt() ? true : false); chkData->setChecked(settings.value(QSL("studio/chk_data")).toInt() ? true : false);
chkRInit->setChecked(settings.value(QSL("studio/chk_rinit")).toInt() ? true : false); chkRInit->setChecked(settings.value(QSL("studio/chk_rinit")).toInt() ? true : false);
@ -209,11 +211,20 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl)
connect(btype, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(btype, SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(cmbFontSetting, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(cmbFontSetting, SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(txtData, SIGNAL(textChanged( const QString& )), SLOT(update_preview())); connect(txtData, SIGNAL(textChanged( const QString& )), SLOT(update_preview()));
connect(txtDataSeg1, SIGNAL(textChanged( const QString& )), SLOT(data_ui_set()));
connect(txtDataSeg1, SIGNAL(textChanged( const QString& )), SLOT(update_preview()));
connect(txtDataSeg2, SIGNAL(textChanged( const QString& )), SLOT(data_ui_set()));
connect(txtDataSeg2, SIGNAL(textChanged( const QString& )), SLOT(update_preview()));
connect(txtDataSeg3, SIGNAL(textChanged( const QString& )), SLOT(data_ui_set()));
connect(txtDataSeg3, SIGNAL(textChanged( const QString& )), SLOT(update_preview()));
connect(txtComposite, SIGNAL(textChanged()), SLOT(update_preview())); connect(txtComposite, SIGNAL(textChanged()), SLOT(update_preview()));
connect(chkComposite, SIGNAL(toggled( bool )), SLOT(composite_ui_set())); connect(chkComposite, SIGNAL(toggled( bool )), SLOT(composite_ui_set()));
connect(chkComposite, SIGNAL(toggled( bool )), SLOT(update_preview())); connect(chkComposite, SIGNAL(toggled( bool )), SLOT(update_preview()));
connect(cmbCompType, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(cmbCompType, SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(cmbECI, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(cmbECI, SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(cmbECISeg1, SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(cmbECISeg2, SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(cmbECISeg3, SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(chkEscape, SIGNAL(toggled( bool )), SLOT(update_preview())); connect(chkEscape, SIGNAL(toggled( bool )), SLOT(update_preview()));
connect(chkData, SIGNAL(toggled( bool )), SLOT(update_preview())); connect(chkData, SIGNAL(toggled( bool )), SLOT(update_preview()));
connect(chkRInit, SIGNAL(toggled( bool )), SLOT(update_preview())); connect(chkRInit, SIGNAL(toggled( bool )), SLOT(update_preview()));
@ -227,6 +238,9 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl)
connect(btnExit, SIGNAL(clicked( bool )), SLOT(quit_now())); connect(btnExit, SIGNAL(clicked( bool )), SLOT(quit_now()));
connect(btnReset, SIGNAL(clicked( bool )), SLOT(reset_colours())); connect(btnReset, SIGNAL(clicked( bool )), SLOT(reset_colours()));
connect(btnMoreData, SIGNAL(clicked( bool )), SLOT(open_data_dialog())); connect(btnMoreData, SIGNAL(clicked( bool )), SLOT(open_data_dialog()));
connect(btnMoreDataSeg1, SIGNAL(clicked( bool )), SLOT(open_data_dialog_seg1()));
connect(btnMoreDataSeg2, SIGNAL(clicked( bool )), SLOT(open_data_dialog_seg2()));
connect(btnMoreDataSeg3, SIGNAL(clicked( bool )), SLOT(open_data_dialog_seg3()));
connect(btnSequence, SIGNAL(clicked( bool )), SLOT(open_sequence_dialog())); connect(btnSequence, SIGNAL(clicked( bool )), SLOT(open_sequence_dialog()));
connect(chkAutoHeight, SIGNAL(toggled( bool )), SLOT(autoheight_ui_set())); connect(chkAutoHeight, SIGNAL(toggled( bool )), SLOT(autoheight_ui_set()));
connect(chkAutoHeight, SIGNAL(toggled( bool )), SLOT(update_preview())); connect(chkAutoHeight, SIGNAL(toggled( bool )), SLOT(update_preview()));
@ -258,6 +272,9 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags fl)
createActions(); createActions();
createMenu(); createMenu();
bstyle->setFocus();
tabMain->installEventFilter(this);
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@ -279,10 +296,12 @@ MainWindow::~MainWindow()
settings.setValue(QSL("studio/paper/blue"), m_bgcolor.blue()); settings.setValue(QSL("studio/paper/blue"), m_bgcolor.blue());
settings.setValue(QSL("studio/paper/alpha"), m_bgcolor.alpha()); settings.setValue(QSL("studio/paper/alpha"), m_bgcolor.alpha());
settings.setValue(QSL("studio/data"), txtData->text()); settings.setValue(QSL("studio/data"), txtData->text());
/* Seg data not saved so don't restore */
settings.setValue(QSL("studio/composite_text"), txtComposite->toPlainText()); settings.setValue(QSL("studio/composite_text"), txtComposite->toPlainText());
settings.setValue(QSL("studio/chk_composite"), chkComposite->isChecked() ? 1 : 0); settings.setValue(QSL("studio/chk_composite"), chkComposite->isChecked() ? 1 : 0);
settings.setValue(QSL("studio/comp_type"), cmbCompType->currentIndex()); settings.setValue(QSL("studio/comp_type"), cmbCompType->currentIndex());
settings.setValue(QSL("studio/eci"), cmbECI->currentIndex()); settings.setValue(QSL("studio/eci"), cmbECI->currentIndex());
/* Seg ECIs not saved so don't restore */
settings.setValue(QSL("studio/chk_escape"), chkEscape->isChecked() ? 1 : 0); settings.setValue(QSL("studio/chk_escape"), chkEscape->isChecked() ? 1 : 0);
settings.setValue(QSL("studio/chk_data"), chkData->isChecked() ? 1 : 0); settings.setValue(QSL("studio/chk_data"), chkData->isChecked() ? 1 : 0);
settings.setValue(QSL("studio/chk_rinit"), chkRInit->isChecked() ? 1 : 0); settings.setValue(QSL("studio/chk_rinit"), chkRInit->isChecked() ? 1 : 0);
@ -350,6 +369,20 @@ bool MainWindow::event(QEvent *event)
return QWidget::event(event); return QWidget::event(event);
} }
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::ShortcutOverride) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->modifiers().testFlag(Qt::AltModifier) && keyEvent->key() == 'O') {
event->ignore();
txtData->setFocus();
return true;
}
}
return QWidget::eventFilter(watched, event);
}
void MainWindow::reset_colours() void MainWindow::reset_colours()
{ {
m_fgcolor.setRgb(0, 0, 0, 0xff); m_fgcolor.setRgb(0, 0, 0, 0xff);
@ -471,11 +504,11 @@ void MainWindow::about()
"<p><table border=1><tr><td><small>Currently supported standards include:<br>" "<p><table border=1><tr><td><small>Currently supported standards include:<br>"
"EN 797:1996, EN 798:1996, EN 12323:2005, ISO/IEC 15417:2007,<br>" "EN 797:1996, EN 798:1996, EN 12323:2005, ISO/IEC 15417:2007,<br>"
"ISO/IEC 15438:2015, ISO/IEC 16022:2006, ISO/IEC 16023:2000,<br>" "ISO/IEC 15438:2015, ISO/IEC 16022:2006, ISO/IEC 16023:2000,<br>"
"ISO/IEC 16388:2007, ISO/IEC 18004:2015, ISO/IEC 24723:2010,<br>" "ISO/IEC 16388:2007, ISO/IEC 18004:2015, ISO/IEC 20830:2021,<br>"
"ISO/IEC 24724:2011, ISO/IEC 24728:2006, ISO/IEC 24778:2008,<br>" "ISO/IEC 24723:2010, ISO/IEC 24724:2011, ISO/IEC 24728:2006,<br>"
"ISO/IEC 16390:2007, ISO/IEC 21471:2019, ANSI-HIBC 2.6-2016,<br>" "ISO/IEC 24778:2008, ISO/IEC 16390:2007, ISO/IEC 21471:2019,<br>"
"ANSI/AIM BC6-2000, ANSI/AIM BC12-1998, ANSI/AIM BC5-1995,<br>" "ANSI-HIBC 2.6-2016, ANSI/AIM BC12-1998, ANSI/AIM BC6-2000,<br>"
"AIM ISS-X-24, AIMD014 (v 1.63), USPS-B-3200" "ANSI/AIM BC5-1995, AIM ISS-X-24, AIMD014 (v 1.63), USPS-B-3200"
"</small></td></tr></table></p>").arg(zint_version).arg(QT_VERSION_STR)); "</small></td></tr></table></p>").arg(zint_version).arg(QT_VERSION_STR));
} }
@ -484,24 +517,62 @@ void MainWindow::help()
QDesktopServices::openUrl(QSL("https://zint.org.uk/manual")); // TODO: manual.md QDesktopServices::openUrl(QSL("https://zint.org.uk/manual")); // TODO: manual.md
} }
void MainWindow::open_data_dialog() void MainWindow::open_data_dialog_seg(const int seg_no)
{ {
DataWindow dlg(txtData->text(), chkEscape->isChecked()); if (seg_no < 0 || seg_no > 3) {
return;
}
static QLineEdit *edits[4] = {
txtData, txtDataSeg1, txtDataSeg2, txtDataSeg3
};
DataWindow dlg(edits[seg_no]->text(), chkEscape->isChecked());
(void) dlg.exec(); (void) dlg.exec();
if (dlg.Valid) { if (dlg.Valid) {
const bool updated = txtData->text() != dlg.DataOutput; const bool updated = edits[seg_no]->text() != dlg.DataOutput;
txtData->setText(dlg.DataOutput); edits[seg_no]->setText(dlg.DataOutput);
if (updated) { if (updated) {
static const QString updatedEscTxts[4] = {
tr("Set \"Parse Escapes\", updated data"),
tr("Set \"Parse Escapes\", updated segment 1 data"),
tr("Set \"Parse Escapes\", updated segment 2 data"),
tr("Set \"Parse Escapes\", updated segment 3 data"),
};
static const QString updatedTxts[4] = {
tr("Updated data"),
tr("Updated segment 1 data"),
tr("Updated segment 2 data"),
tr("Updated segment 3 data"),
};
if (dlg.Escaped && !chkEscape->isChecked()) { if (dlg.Escaped && !chkEscape->isChecked()) {
chkEscape->setChecked(true); chkEscape->setChecked(true);
statusBar->showMessage(tr("Set \"Parse Escapes\", updated data"), tempMessageTimeout); statusBar->showMessage(updatedEscTxts[seg_no], tempMessageTimeout);
} else { } else {
statusBar->showMessage(tr("Updated data"), tempMessageTimeout); statusBar->showMessage(updatedTxts[seg_no], tempMessageTimeout);
} }
} }
} }
} }
void MainWindow::open_data_dialog()
{
open_data_dialog_seg(0);
}
void MainWindow::open_data_dialog_seg1()
{
open_data_dialog_seg(1);
}
void MainWindow::open_data_dialog_seg2()
{
open_data_dialog_seg(2);
}
void MainWindow::open_data_dialog_seg3()
{
open_data_dialog_seg(3);
}
void MainWindow::open_sequence_dialog() void MainWindow::open_sequence_dialog()
{ {
SequenceWindow dlg(&m_bc); SequenceWindow dlg(&m_bc);
@ -1523,9 +1594,27 @@ void MainWindow::change_options()
case BARCODE_DBAR_OMNSTK: case BARCODE_DBAR_OMNSTK:
case BARCODE_DBAR_EXPSTK: case BARCODE_DBAR_EXPSTK:
grpComposite->show(); grpComposite->show();
grpSegs->hide();
break;
case BARCODE_AZTEC:
case BARCODE_DATAMATRIX:
case BARCODE_MAXICODE:
case BARCODE_MICROPDF417:
case BARCODE_PDF417:
case BARCODE_PDF417COMP:
case BARCODE_QRCODE:
case BARCODE_DOTCODE:
case BARCODE_CODEONE:
case BARCODE_GRIDMATRIX:
case BARCODE_HANXIN:
case BARCODE_ULTRA:
case BARCODE_RMQR:
grpComposite->hide();
grpSegs->show();
break; break;
default: default:
grpComposite->hide(); grpComposite->hide();
grpSegs->hide();
break; break;
} }
@ -1536,6 +1625,7 @@ void MainWindow::change_options()
chkQuietZones->setEnabled(!m_bc.bc.hasDefaultQuietZones(symbology)); chkQuietZones->setEnabled(!m_bc.bc.hasDefaultQuietZones(symbology));
chkDotty->setEnabled(m_bc.bc.isDotty(symbology)); chkDotty->setEnabled(m_bc.bc.isDotty(symbology));
data_ui_set();
composite_ui_set(); composite_ui_set();
autoheight_ui_set(); autoheight_ui_set();
HRTShow_ui_set(); HRTShow_ui_set();
@ -1552,6 +1642,46 @@ void MainWindow::change_options()
} }
} }
void MainWindow::data_ui_set()
{
if (grpSegs->isHidden()) {
return;
}
if (txtDataSeg1->text().isEmpty()) {
cmbECISeg1->setEnabled(false);
lblSeg2->setEnabled(false);
cmbECISeg2->setEnabled(false);
txtDataSeg2->setEnabled(false);
btnMoreDataSeg2->setEnabled(false);
lblSeg3->setEnabled(false);
cmbECISeg3->setEnabled(false);
txtDataSeg3->setEnabled(false);
btnMoreDataSeg3->setEnabled(false);
} else {
cmbECISeg1->setEnabled(true);
lblSeg2->setEnabled(true);
txtDataSeg2->setEnabled(true);
btnMoreDataSeg2->setEnabled(true);
if (txtDataSeg2->text().isEmpty()) {
cmbECISeg2->setEnabled(false);
lblSeg3->setEnabled(false);
cmbECISeg3->setEnabled(false);
txtDataSeg3->setEnabled(false);
btnMoreDataSeg3->setEnabled(false);
} else {
cmbECISeg2->setEnabled(true);
lblSeg3->setEnabled(true);
txtDataSeg3->setEnabled(true);
btnMoreDataSeg3->setEnabled(true);
if (txtDataSeg3->text().isEmpty()) {
cmbECISeg3->setEnabled(false);
} else {
cmbECISeg3->setEnabled(true);
}
}
}
}
void MainWindow::composite_ui_set() void MainWindow::composite_ui_set()
{ {
bool enabled = !grpComposite->isHidden() && chkComposite->isChecked(); bool enabled = !grpComposite->isHidden() && chkComposite->isChecked();
@ -1715,7 +1845,20 @@ void MainWindow::update_preview()
m_bc.bc.setPrimaryMessage(txtData->text()); m_bc.bc.setPrimaryMessage(txtData->text());
m_bc.bc.setText(txtComposite->toPlainText()); m_bc.bc.setText(txtComposite->toPlainText());
} else { } else {
m_bc.bc.setText(txtData->text()); if (!grpSegs->isHidden() && !txtDataSeg1->text().isEmpty()) {
std::vector<Zint::QZintSeg> segs;
segs.push_back(Zint::QZintSeg(txtData->text(), cmbECI->currentIndex()));
segs.push_back(Zint::QZintSeg(txtDataSeg1->text(), cmbECISeg1->currentIndex()));
if (!txtDataSeg2->text().isEmpty()) {
segs.push_back(Zint::QZintSeg(txtDataSeg2->text(), cmbECISeg2->currentIndex()));
if (!txtDataSeg3->text().isEmpty()) {
segs.push_back(Zint::QZintSeg(txtDataSeg3->text(), cmbECISeg3->currentIndex()));
}
}
m_bc.bc.setSegs(segs);
} else {
m_bc.bc.setText(txtData->text());
}
} }
m_bc.bc.setOption1(-1); m_bc.bc.setOption1(-1);
m_bc.bc.setOption2(0); m_bc.bc.setOption2(0);
@ -2689,6 +2832,11 @@ void MainWindow::save_sub_settings(QSettings &settings, int symbology)
QString name = get_setting_name(symbology); QString name = get_setting_name(symbology);
if (!name.isEmpty()) { if (!name.isEmpty()) {
settings.setValue(QSL("studio/bc/%1/data").arg(name), txtData->text()); settings.setValue(QSL("studio/bc/%1/data").arg(name), txtData->text());
if (!grpSegs->isHidden()) {
settings.setValue(QSL("studio/bc/%1/data_seg1").arg(name), txtDataSeg1->text());
settings.setValue(QSL("studio/bc/%1/data_seg2").arg(name), txtDataSeg2->text());
settings.setValue(QSL("studio/bc/%1/data_seg3").arg(name), txtDataSeg3->text());
}
if (!grpComposite->isHidden()) { if (!grpComposite->isHidden()) {
settings.setValue(QSL("studio/bc/%1/composite_text").arg(name), txtComposite->toPlainText()); settings.setValue(QSL("studio/bc/%1/composite_text").arg(name), txtComposite->toPlainText());
settings.setValue(QSL("studio/bc/%1/chk_composite").arg(name), chkComposite->isChecked() ? 1 : 0); settings.setValue(QSL("studio/bc/%1/chk_composite").arg(name), chkComposite->isChecked() ? 1 : 0);
@ -2696,6 +2844,9 @@ void MainWindow::save_sub_settings(QSettings &settings, int symbology)
} }
if (cmbECI->isEnabled()) { if (cmbECI->isEnabled()) {
settings.setValue(QSL("studio/bc/%1/eci").arg(name), cmbECI->currentIndex()); settings.setValue(QSL("studio/bc/%1/eci").arg(name), cmbECI->currentIndex());
settings.setValue(QSL("studio/bc/%1/eci_seg1").arg(name), cmbECISeg1->currentIndex());
settings.setValue(QSL("studio/bc/%1/eci_seg2").arg(name), cmbECISeg2->currentIndex());
settings.setValue(QSL("studio/bc/%1/eci_seg3").arg(name), cmbECISeg3->currentIndex());
} }
settings.setValue(QSL("studio/bc/%1/chk_escape").arg(name), chkEscape->isChecked() ? 1 : 0); settings.setValue(QSL("studio/bc/%1/chk_escape").arg(name), chkEscape->isChecked() ? 1 : 0);
settings.setValue(QSL("studio/bc/%1/chk_data").arg(name), chkData->isChecked() ? 1 : 0); settings.setValue(QSL("studio/bc/%1/chk_data").arg(name), chkData->isChecked() ? 1 : 0);
@ -3050,6 +3201,11 @@ void MainWindow::load_sub_settings(QSettings &settings, int symbology)
if (!tdata.isEmpty()) { if (!tdata.isEmpty()) {
txtData->setText(tdata); txtData->setText(tdata);
} }
if (!grpSegs->isHidden()) {
txtDataSeg1->setText(settings.value(QSL("studio/bc/%1/data_seg1").arg(name), QSL("")).toString());
txtDataSeg2->setText(settings.value(QSL("studio/bc/%1/data_seg2").arg(name), QSL("")).toString());
txtDataSeg3->setText(settings.value(QSL("studio/bc/%1/data_seg3").arg(name), QSL("")).toString());
}
if (!grpComposite->isHidden()) { if (!grpComposite->isHidden()) {
const QString &composite_text = settings.value( const QString &composite_text = settings.value(
QSL("studio/bc/%1/composite_text").arg(name), QSL("")).toString(); QSL("studio/bc/%1/composite_text").arg(name), QSL("")).toString();
@ -3062,6 +3218,9 @@ void MainWindow::load_sub_settings(QSettings &settings, int symbology)
} }
if (cmbECI->isEnabled()) { if (cmbECI->isEnabled()) {
cmbECI->setCurrentIndex(settings.value(QSL("studio/bc/%1/eci").arg(name), 0).toInt()); cmbECI->setCurrentIndex(settings.value(QSL("studio/bc/%1/eci").arg(name), 0).toInt());
cmbECISeg1->setCurrentIndex(settings.value(QSL("studio/bc/%1/eci_seg1").arg(name), 0).toInt());
cmbECISeg2->setCurrentIndex(settings.value(QSL("studio/bc/%1/eci_seg2").arg(name), 0).toInt());
cmbECISeg3->setCurrentIndex(settings.value(QSL("studio/bc/%1/eci_seg3").arg(name), 0).toInt());
} }
chkEscape->setChecked(settings.value(QSL("studio/bc/%1/chk_escape").arg(name)).toInt() ? true : false); chkEscape->setChecked(settings.value(QSL("studio/bc/%1/chk_escape").arg(name)).toInt() ? true : false);
chkData->setChecked(settings.value(QSL("studio/bc/%1/chk_data").arg(name)).toInt() ? true : false); chkData->setChecked(settings.value(QSL("studio/bc/%1/chk_data").arg(name)).toInt() ? true : false);

View File

@ -47,6 +47,7 @@ public slots:
void change_options(); void change_options();
void on_fgcolor_clicked(); void on_fgcolor_clicked();
void on_bgcolor_clicked(); void on_bgcolor_clicked();
void data_ui_set();
void composite_ui_set(); void composite_ui_set();
void composite_ean_check(); void composite_ean_check();
void maxi_scm_ui_set(); void maxi_scm_ui_set();
@ -70,6 +71,9 @@ public slots:
void reset_colours(); void reset_colours();
void open_data_dialog(); void open_data_dialog();
void open_data_dialog_seg1();
void open_data_dialog_seg2();
void open_data_dialog_seg3();
void open_sequence_dialog(); void open_sequence_dialog();
void open_cli_dialog(); void open_cli_dialog();
@ -98,6 +102,7 @@ public slots:
protected: protected:
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
bool event(QEvent *event) override; bool event(QEvent *event) override;
bool eventFilter(QObject *watched, QEvent *event);
void combobox_item_enabled(QComboBox *comboBox, int index, bool enabled); void combobox_item_enabled(QComboBox *comboBox, int index, bool enabled);
void upcean_addon_gap(const QString &comboBoxName, const QString &labelName, int base); void upcean_addon_gap(const QString &comboBoxName, const QString &labelName, int base);
@ -106,6 +111,8 @@ protected:
void set_gs1_mode(bool gs1_mode); void set_gs1_mode(bool gs1_mode);
void set_smaller_font(const QString &labelName); void set_smaller_font(const QString &labelName);
void open_data_dialog_seg(const int seg_no);
void createActions(); void createActions();
void createMenu(); void createMenu();
void enableActions(bool enabled); void enableActions(bool enabled);