diff --git a/ChangeLog b/ChangeLog index 28ad4318..f64680b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -Version 2.13.0.9 (dev) not released yet (2024-11-18) +Version 2.13.0.9 (dev) not released yet (2024-11-23) ==================================================== **Incompatible changes** @@ -14,7 +14,7 @@ Version 2.13.0.9 (dev) not released yet (2024-11-18) - Add-ons for UPC-A and UPC-E now descend to be level with the main symbol guard bars, and the righthand outside digit is now placed 1X less from main symbol to avoid touching any add-on -- GS1_128 now warns if READER_INIT option used +- GS1-128 symbols now warn if READER_INIT option used Changes ------- @@ -41,8 +41,7 @@ Changes return warning if ECC < 5% (due to bit-stuffing when version given) - MAXICODE: zero-pad US postcodes that lack "+4" (Annex B.1.4a), from OkapiBarcode, props Daniel Gredler; - use code set E for padding as well, saves codeword, props Bue Jensen (BWIPP PR - #279) + add minimal encodation algorithm, props Bue Jensen (BWIPP) - GUI: use X11 (xcb) as platform instead of Wayland on Linux to avoid various weird behaviours; in "grpDATF.ui" use "PlainText" rather than "RichText" for tracker ratio diff --git a/backend/auspost.c b/backend/auspost.c index b27a2fd0..b45fc518 100644 --- a/backend/auspost.c +++ b/backend/auspost.c @@ -90,8 +90,8 @@ static char *aus_rs_error(char data_pattern[], char *d) { rs_init_code(&rs, 4, 1); rs_encode(&rs, triple_writer, triple, result); - for (reader = 4; reader > 0; reader--, d += 3) { - memcpy(d, AusBarTable[result[reader - 1]], 3); + for (reader = 0; reader < 4; reader++, d += 3) { + memcpy(d, AusBarTable[result[reader]], 3); } return d; diff --git a/backend/aztec.c b/backend/aztec.c index 38c50329..ce364a9f 100644 --- a/backend/aztec.c +++ b/backend/aztec.c @@ -1159,7 +1159,7 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int break; } - for (i = (ecc_blocks - 1); i >= 0; i--) { + for (i = 0; i < ecc_blocks; i++) { adjusted_length = bin_append_posn(ecc_part[i], codeword_size, adjusted_string, adjusted_length); } @@ -1214,19 +1214,19 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int rs_init_code(&rs, 5, 1); rs_encode(&rs, 2, desc_data, desc_ecc); for (i = 0; i < 5; i++) { - descriptor[(i * 4) + 8] = (desc_ecc[4 - i] & 0x08) ? '1' : '0'; - descriptor[(i * 4) + 9] = (desc_ecc[4 - i] & 0x04) ? '1' : '0'; - descriptor[(i * 4) + 10] = (desc_ecc[4 - i] & 0x02) ? '1' : '0'; - descriptor[(i * 4) + 11] = (desc_ecc[4 - i] & 0x01) ? '1' : '0'; + descriptor[(i * 4) + 8] = (desc_ecc[i] & 0x08) ? '1' : '0'; + descriptor[(i * 4) + 9] = (desc_ecc[i] & 0x04) ? '1' : '0'; + descriptor[(i * 4) + 10] = (desc_ecc[i] & 0x02) ? '1' : '0'; + descriptor[(i * 4) + 11] = (desc_ecc[i] & 0x01) ? '1' : '0'; } } else { rs_init_code(&rs, 6, 1); rs_encode(&rs, 4, desc_data, desc_ecc); for (i = 0; i < 6; i++) { - descriptor[(i * 4) + 16] = (desc_ecc[5 - i] & 0x08) ? '1' : '0'; - descriptor[(i * 4) + 17] = (desc_ecc[5 - i] & 0x04) ? '1' : '0'; - descriptor[(i * 4) + 18] = (desc_ecc[5 - i] & 0x02) ? '1' : '0'; - descriptor[(i * 4) + 19] = (desc_ecc[5 - i] & 0x01) ? '1' : '0'; + descriptor[(i * 4) + 16] = (desc_ecc[i] & 0x08) ? '1' : '0'; + descriptor[(i * 4) + 17] = (desc_ecc[i] & 0x04) ? '1' : '0'; + descriptor[(i * 4) + 18] = (desc_ecc[i] & 0x02) ? '1' : '0'; + descriptor[(i * 4) + 19] = (desc_ecc[i] & 0x01) ? '1' : '0'; } } @@ -1320,7 +1320,7 @@ INTERNAL int azrune(struct zint_symbol *symbol, unsigned char source[], int leng rs_encode(&rs, 2, data_codewords, ecc_codewords); for (i = 0; i < 5; i++) { - bp = bin_append_posn(ecc_codewords[4 - i], 4, binary_string, bp); + bp = bin_append_posn(ecc_codewords[i], 4, binary_string, bp); } for (i = 0; i < 28; i += 2) { diff --git a/backend/code1.c b/backend/code1.c index 2878cc94..d4b113af 100644 --- a/backend/code1.c +++ b/backend/code1.c @@ -1106,7 +1106,7 @@ INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const i rs_encode_uint(&rs, codewords, target, ecc); for (i = 0; i < codewords; i++) { - target[i + codewords] = ecc[codewords - i - 1]; + target[i + codewords] = ecc[i]; } if (debug_print) { @@ -1195,7 +1195,7 @@ INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const i rs_encode_uint(&rs, data_cw, target, ecc); for (i = 0; i < ecc_cw; i++) { - target[data_cw + i] = ecc[ecc_cw - i - 1]; + target[data_cw + i] = ecc[i]; } if (debug_print) { @@ -1285,7 +1285,7 @@ INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const i } rs_encode_uint(&rs, data_blocks, sub_data, sub_ecc); for (j = 0; j < ecc_blocks; j++) { - target[data_cw + j * blocks + i] = sub_ecc[ecc_blocks - 1 - j]; + target[data_cw + j * blocks + i] = sub_ecc[j]; } } diff --git a/backend/common.c b/backend/common.c index 9f887216..ceb6f560 100644 --- a/backend/common.c +++ b/backend/common.c @@ -154,7 +154,7 @@ INTERNAL int not_sane_lookup(const char test_string[], const int test_length, co return 0; } -/* Returns the position of `data` in `set_string` */ +/* Returns the position of `data` in `set_string`, or -1 if not found */ INTERNAL int posn(const char set_string[], const char data) { const char *s; diff --git a/backend/common.h b/backend/common.h index e419aa73..6017dbb2 100644 --- a/backend/common.h +++ b/backend/common.h @@ -195,7 +195,7 @@ INTERNAL int not_sane(const unsigned int flg, const unsigned char source[], cons INTERNAL int not_sane_lookup(const char test_string[], const int test_length, const unsigned char source[], const int length, int *posns); -/* Returns the position of `data` in `set_string` */ +/* Returns the position of `data` in `set_string`, or -1 if not found */ INTERNAL int posn(const char set_string[], const char data); diff --git a/backend/dmatrix.c b/backend/dmatrix.c index 30e0e7fc..997d24ea 100644 --- a/backend/dmatrix.c +++ b/backend/dmatrix.c @@ -179,19 +179,20 @@ static void dm_ecc(unsigned char *binary, const int bytes, const int datablock, for (n = b; n < bytes; n += blocks) buf[p++] = binary[n]; rs_encode(&rs, p, buf, ecc); - p = rsblock - 1; /* comes back reversed */ - for (n = b; n < rsblocks; n += blocks) { - if (skew) { - /* Rotate ecc data to make 144x144 size symbols acceptable */ - /* See http://groups.google.com/group/postscriptbarcode/msg/5ae8fda7757477da - or https://github.com/nu-book/zxing-cpp/issues/259 */ + if (skew) { + /* Rotate ecc data to make 144x144 size symbols acceptable */ + /* See http://groups.google.com/group/postscriptbarcode/msg/5ae8fda7757477da + or https://github.com/nu-book/zxing-cpp/issues/259 */ + for (n = b, p = 0; n < rsblocks; n += blocks, p++) { if (b < 8) { - binary[bytes + n + 2] = ecc[p--]; + binary[bytes + n + 2] = ecc[p]; } else { - binary[bytes + n - 8] = ecc[p--]; + binary[bytes + n - 8] = ecc[p]; } - } else { - binary[bytes + n] = ecc[p--]; + } + } else { + for (n = b, p = 0; n < rsblocks; n += blocks, p++) { + binary[bytes + n] = ecc[p]; } } } diff --git a/backend/gridmtx.c b/backend/gridmtx.c index 7ab4b9b6..fa87d4da 100644 --- a/backend/gridmtx.c +++ b/backend/gridmtx.c @@ -886,12 +886,12 @@ static void gm_add_ecc(const char binary[], const int data_posn, const int layer rs_init_code(&rs, ecc_size, 1); rs_encode(&rs, data_size, data_block, ecc_block); - /* Correct error correction data but in reverse order */ + /* Add error correction data */ for (j = 0; j < data_size; j++) { block[j] = data_block[j]; } for (j = 0; j < ecc_size; j++) { - block[(j + data_size)] = ecc_block[ecc_size - j - 1]; + block[j + data_size] = ecc_block[j]; } for (j = 0; j < n2; j++) { diff --git a/backend/gs1_lint.h b/backend/gs1_lint.h index 1db351eb..1571771a 100644 --- a/backend/gs1_lint.h +++ b/backend/gs1_lint.h @@ -751,7 +751,8 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len, return n3_iso3166(data, data_len, p_err_no, p_err_posn, err_msg); } if (ai == 423 || ai == 425) { - return n3_iso3166__n3__iso3166__n3__iso3166__n3__iso3166__n3__iso3166(data, data_len, p_err_no, p_err_posn, err_msg); + return n3_iso3166__n3__iso3166__n3__iso3166__n3__iso3166__n3__iso3166(data, + data_len, p_err_no, p_err_posn, err_msg); } if (ai == 427) { return x__3(data, data_len, p_err_no, p_err_posn, err_msg); diff --git a/backend/hanxin.c b/backend/hanxin.c index 790504be..c76b507c 100644 --- a/backend/hanxin.c +++ b/backend/hanxin.c @@ -1118,8 +1118,8 @@ static void hx_add_ecc(unsigned char fullstream[], const unsigned char datastrea unsigned char data_block[180]; unsigned char ecc_block[36]; int i, j, block; - int input_position = -1; - int output_position = -1; + int input_position = 0; + int output_position = 0; const int table_d1_pos = ((version - 1) * 36) + ((ecc_level - 1) * 9); rs_t rs; @@ -1134,17 +1134,15 @@ static void hx_add_ecc(unsigned char fullstream[], const unsigned char datastrea for (block = 0; block < batch_size; block++) { for (j = 0; j < data_length; j++) { - input_position++; - output_position++; data_block[j] = input_position < data_codewords ? datastream[input_position] : 0; - fullstream[output_position] = data_block[j]; + fullstream[output_position++] = data_block[j]; + input_position++; } rs_encode(&rs, data_length, data_block, ecc_block); for (j = 0; j < ecc_length; j++) { - output_position++; - fullstream[output_position] = ecc_block[ecc_length - j - 1]; + fullstream[output_position++] = ecc_block[j]; } } } @@ -1177,7 +1175,7 @@ static void hx_set_function_info(unsigned char *grid, const int size, const int rs_init_code(&rs, 4, 1); rs_encode(&rs, 3, fi_cw, fi_ecc); - for (i = 3; i >= 0; i--) { + for (i = 0; i < 4; i++) { bp = bin_append_posn(fi_ecc[i], 4, function_information, bp); } diff --git a/backend/mailmark.c b/backend/mailmark.c index bb7b9ab6..c91263e1 100644 --- a/backend/mailmark.c +++ b/backend/mailmark.c @@ -402,16 +402,15 @@ INTERNAL int mailmark_4s(struct zint_symbol *symbol, unsigned char source[], int /* Generation of Reed-Solomon Check Numbers */ rs_init_gf(&rs, 0x25); rs_init_code(&rs, check_count, 1); - rs_encode(&rs, (data_top + 1), data, check); + data_top++; + rs_encode(&rs, data_top, data, check); /* Append check digits to data */ - for (i = 1; i <= check_count; i++) { - data[data_top + i] = check[check_count - i]; - } + memcpy(data + data_top, check, check_count); if (symbol->debug & ZINT_DEBUG_PRINT) { fputs("Codewords:", stdout); - for (i = 0; i <= data_top + check_count; i++) { + for (i = 0; i < data_top + check_count; i++) { printf(" %d", (int) data[i]); } fputc('\n', stdout); @@ -421,7 +420,7 @@ INTERNAL int mailmark_4s(struct zint_symbol *symbol, unsigned char source[], int for (i = 0; i <= data_step; i++) { data[i] = mailmark_data_symbol_even[data[i]]; } - for (i = data_step + 1; i <= (data_top + check_count); i++) { + for (i = data_step + 1; i < (data_top + check_count); i++) { data[i] = mailmark_data_symbol_odd[data[i]]; } diff --git a/backend/maxicode.c b/backend/maxicode.c index 99cfd6b7..4f18d409 100644 --- a/backend/maxicode.c +++ b/backend/maxicode.c @@ -37,510 +37,498 @@ #include "maxicode.h" #include "reedsol.h" -/* Handles error correction of primary message */ -static void maxi_do_primary_check(unsigned char maxi_codeword[144]) { - unsigned char results[15]; - int j; - int datalen = 10; - int ecclen = 10; - rs_t rs; +/* Code Set states. Those with PAD (i.e. A, B and E) are first pick */ +#define MX_A 0 +#define MX_B 1 +#define MX_E 2 +#define MX_C 3 +#define MX_D 4 +#define MX_STATES 5 - rs_init_gf(&rs, 0x43); - rs_init_code(&rs, ecclen, 1); +/* Prior:A B E C D Later */ +static const char mx_latch_seq[MX_STATES][MX_STATES][2] = { + { { 0 }, {63 }, {58 }, {58 }, {58 } }, /* A */ + { {63 }, { 0 }, {63 }, {63 }, {63 } }, /* B */ + { {62,62}, {62,62}, { 0 }, {62,62}, {62,62} }, /* E */ + { {60,60}, {60,60}, {60,60}, { 0 }, {60,60} }, /* C */ + { {61,61}, {61,61}, {61,61}, {61,61}, { 0 } }, /* D */ - rs_encode(&rs, datalen, maxi_codeword, results); +}; +static const char mx_latch_len[MX_STATES][MX_STATES] = { /* Lengths of above */ + { 0, 1, 1, 1, 1 }, /* A */ + { 1, 0, 1, 1, 1 }, /* B */ + { 2, 2, 0, 2, 2 }, /* E */ + { 2, 2, 2, 0, 2 }, /* C */ + { 2, 2, 2, 2, 0 }, /* D */ +}; - for (j = 0; j < ecclen; j += 1) - maxi_codeword[ datalen + j] = results[ecclen - 1 - j]; -} +/* Op */ +struct mx_op { + unsigned char op; + unsigned char intake; /* `output` calculated from this */ +}; -/* Handles error correction of odd characters in secondary */ -static void maxi_do_secondary_chk_odd(unsigned char maxi_codeword[144], const int ecclen) { - unsigned char data[100]; - unsigned char results[30]; - int j; - int datalen = 68; - rs_t rs; +/* Op table ops */ +#define MX_OP_DGTS 0 +#define MX_OP_SETA 0x01 /* If change these, must change `maxiCodeSet` */ +#define MX_OP_SETB 0x02 +#define MX_OP_SETE 0x04 +#define MX_OP_SETC 0x08 +#define MX_OP_SETD 0x10 +#define MX_OP_SHA (0x20 | MX_OP_SETA) +#define MX_OP_2SHA (0x40 | MX_OP_SETA) +#define MX_OP_3SHA (0x80 | MX_OP_SETA) +#define MX_OP_SHB (0x20 | MX_OP_SETB) +#define MX_OP_SHE (0x20 | MX_OP_SETE) +#define MX_OP_SHC (0x20 | MX_OP_SETC) +#define MX_OP_SHD (0x20 | MX_OP_SETD) - rs_init_gf(&rs, 0x43); - rs_init_code(&rs, ecclen, 1); +/* Op table indexes */ +#define MX_OP_DGTS_IDX 0 +#define MX_OP_SETA_IDX 1 +#define MX_OP_SETB_IDX 2 +#define MX_OP_SETE_IDX 3 +#define MX_OP_SETC_IDX 4 +#define MX_OP_SETD_IDX 5 +#define MX_OP_SHA_IDX 6 +#define MX_OP_2SHA_IDX 7 +#define MX_OP_3SHA_IDX 8 +#define MX_OP_SHB_IDX 9 +#define MX_OP_SHE_IDX 10 +#define MX_OP_SHC_IDX 11 +#define MX_OP_SHD_IDX 12 +#define MX_OP_IDXS 13 - if (ecclen == 20) - datalen = 84; +/* Op table (order must match indexes above) */ +static const struct mx_op mx_op_tab[MX_OP_IDXS] = { + /* op intake */ + { MX_OP_DGTS, 9 }, + { MX_OP_SETA, 1 }, + { MX_OP_SETB, 1 }, + { MX_OP_SETE, 1 }, + { MX_OP_SETC, 1 }, + { MX_OP_SETD, 1 }, + { MX_OP_SHA, 1 }, + { MX_OP_2SHA, 2 }, + { MX_OP_3SHA, 3 }, + { MX_OP_SHB, 1 }, + { MX_OP_SHE, 1 }, + { MX_OP_SHC, 1 }, + { MX_OP_SHD, 1 }, +}; - for (j = 1; j < datalen; j += 2) - data[(j - 1) / 2] = maxi_codeword[j + 20]; +/* Indexes of op sets relevant to each state - MX_OP_DGTS dealt with separately */ +static const signed char mx_code_set_op_idxs[MX_STATES][8] = { + { MX_OP_SETA_IDX, MX_OP_SHB_IDX, MX_OP_SHE_IDX, MX_OP_SHC_IDX, MX_OP_SHD_IDX, -1 }, /* MX_A */ + { MX_OP_SETB_IDX, MX_OP_SHA_IDX, MX_OP_2SHA_IDX, MX_OP_3SHA_IDX, MX_OP_SHE_IDX, MX_OP_SHC_IDX, /* MX_B */ + MX_OP_SHD_IDX, -1 }, + { MX_OP_SETE_IDX, MX_OP_SHC_IDX, MX_OP_SHD_IDX, -1 }, /* MX_E */ + { MX_OP_SETC_IDX, MX_OP_SHE_IDX, MX_OP_SHD_IDX, -1 }, /* MX_C */ + { MX_OP_SETD_IDX, MX_OP_SHE_IDX, MX_OP_SHC_IDX, -1 }, /* MX_D */ +}; - rs_encode(&rs, datalen / 2, data, results); - - for (j = 0; j < (ecclen); j += 1) - maxi_codeword[ datalen + (2 * j) + 1 + 20 ] = results[ecclen - 1 - j]; -} - -/* Handles error correction of even characters in secondary */ -static void maxi_do_secondary_chk_even(unsigned char maxi_codeword[144], const int ecclen) { - unsigned char data[100]; - unsigned char results[30]; - int j; - int datalen = 68; - rs_t rs; - - if (ecclen == 20) - datalen = 84; - - rs_init_gf(&rs, 0x43); - rs_init_code(&rs, ecclen, 1); - - for (j = 0; j < datalen + 1; j += 2) - data[j / 2] = maxi_codeword[j + 20]; - - rs_encode(&rs, datalen / 2, data, results); - - for (j = 0; j < (ecclen); j += 1) - maxi_codeword[ datalen + (2 * j) + 20] = results[ecclen - 1 - j]; -} - -/* Moves everything up so that a shift or latch can be inserted */ -static void maxi_bump(unsigned char set[], unsigned char character[], const int bump_posn, int *p_length) { - - if (bump_posn < 143) { - memmove(set + bump_posn + 1, set + bump_posn, 143 - bump_posn); - memmove(character + bump_posn + 1, character + bump_posn, 143 - bump_posn); +/* Whether can encode character `ch` with `op` - MX_OP_DGTS dealt with separately */ +static int mx_can(const unsigned char op, const unsigned char ch, const int num_a) { + if (op == MX_OP_2SHA || op == MX_OP_3SHA) { + return num_a >= 2 + (op == MX_OP_3SHA); } - (*p_length)++; /* Increment length regardless to make sure too long always triggered */ + return maxiCodeSet[ch] & op; } -/* If the value is present in array, return the value, else return badvalue */ -static int maxi_value_in_array(const unsigned char val, const unsigned char arr[], const int badvalue, - const int arrLength) { - int i; - for (i = 0; i < arrLength; i++) { - if (arr[i] == val) return val; +/* Get the symbol value for `ch` in Code Set of `op`, accounting for chars in multiple Code Sets */ +static int mx_symbol_ch(const unsigned char op, const unsigned char ch) { + if (maxiCodeSet[ch] == (op & 0x1F) || (op & MX_OP_SETA)) { /* Non-multiple or Code Set A */ + return maxiSymbolChar[ch]; } - return badvalue; -} - -/* 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] */ -static int maxi_bestSurroundingSet(const int index, const int length, const unsigned char set[], const int sp, - const unsigned char setval[], const int setLength) { - int badValue = -1; - int option1 = maxi_value_in_array(set[sp + index - 1], setval, badValue, setLength); - if (index + 1 < length) { - /* we have two options to check (previous & next) */ - int option2 = maxi_value_in_array(set[sp + index + 1], setval, badValue, setLength); - if (option2 != badValue && option1 > option2) { - return option2; + if (op & MX_OP_SETB) { + const int p = posn(" ,./:", ch); + if (p >= 0) { + return 47 + p; } } - - if (option1 != badValue) { - return option1; + if (op & MX_OP_SETE) { + if (ch >= 28 && ch <= 30) { /* FS GS RS */ + return ch + 4; + } } - return setval[0]; + return ch == ' ' ? 59 : ch; /* SP CR FS GS RS */ } -/* Format text according to Appendix A */ -static int maxi_text_process(unsigned char set[144], unsigned char character[144], const unsigned char in_source[], - int length, const int eci, const int scm_vv, int *p_sp, int current_set, const int debug_print) { +/* Encode according to operation `op` (note done backwards) */ +static int mx_enc(unsigned char codewords[144], int ci, const unsigned char source[], const int i, + const unsigned char op) { + if (op == MX_OP_DGTS) { + const int value = (source[i] - '0') * 100000000 + (source[i + 1] - '0') * 10000000 + + (source[i + 2] - '0') * 1000000 + (source[i + 3] - '0') * 100000 + + (source[i + 4] - '0') * 10000 + (source[i + 5] - '0') * 1000 + + (source[i + 6] - '0') * 100 + (source[i + 7] - '0') * 10 + source[i + 8] - '0'; + assert(ci >= 6); + codewords[--ci] = (value & 0x3F); + codewords[--ci] = (value & 0xFC0) >> 6; + codewords[--ci] = (value & 0x3F000) >> 12; + codewords[--ci] = (value & 0xFC0000) >> 18; + codewords[--ci] = (value & 0x3F000000) >> 24; + codewords[--ci] = 31; /* NS */ + } else if (op == MX_OP_2SHA) { + assert(ci >= 3); + codewords[--ci] = mx_symbol_ch(op, source[i + 1]); + codewords[--ci] = mx_symbol_ch(op, source[i]); + codewords[--ci] = 56; + } else if (op == MX_OP_3SHA) { + assert(ci >= 4); + codewords[--ci] = mx_symbol_ch(op, source[i + 2]); + codewords[--ci] = mx_symbol_ch(op, source[i + 1]); + codewords[--ci] = mx_symbol_ch(op, source[i]); + codewords[--ci] = 57; + } else { + assert(ci >= 1); + codewords[--ci] = mx_symbol_ch(op, source[i]); - int sp = *p_sp; - int i, count; -#ifndef NDEBUG - int ns_count1 = 0, ns_count2 = 0; -#endif - - static const unsigned char set15[2] = { 1, 5 }; - static const unsigned char set12[2] = { 1, 2 }; - static const unsigned char set12345[5] = { 1, 2, 3, 4, 5 }; - - const unsigned char *source = in_source; - unsigned char *source_buf = (unsigned char *) z_alloca(length + 9); /* For prefixing 9-character SCM sequence */ - - if (sp + length > 144) { - return 0; + if (op & 0x20) { /* Shift */ + assert(ci >= 1); + codewords[--ci] = 59 + 1 * (op == MX_OP_SHC) + 2 * (op == MX_OP_SHD) + 3 * (op == MX_OP_SHE); + } } + return ci; +} - /* 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 0; - character[sp++] = 27; /* ECI */ - if (eci <= 31) { - if (sp + 1 + length > 144) return 0; - character[sp++] = eci; - } else if (eci <= 1023) { - if (sp + 2 + length > 144) return 0; - character[sp++] = 0x20 | ((eci >> 6) & 0x0F); - character[sp++] = eci & 0x3F; - } else if (eci <= 32767) { - if (sp + 3 + length > 144) return 0; - character[sp++] = 0x30 | ((eci >> 12) & 0x07); - character[sp++] = (eci >> 6) & 0x3F; - character[sp++] = eci & 0x3F; +/* Encoding length of ECI */ +static int mx_eci_len(const int eci) { + return eci == 0 ? 0 : 2 + (eci > 31) + (eci > 1023) + (eci > 32767); +} + +/* Encode ECI (`eci` non-zero) */ +static int mx_enc_eci(const int eci, unsigned char codewords[144], int ci) { + codewords[--ci] = eci & 0x3F; + if (eci > 31) { + if (eci > 1023) { + codewords[--ci] = (eci & 0xFC0) >> 6; + if (eci > 32767) { + codewords[--ci] = (eci & 0x3F000) >> 12; + codewords[--ci] = 0x38 | ((eci & 0xC0000) >> 18); + } else { + codewords[--ci] = 0x30 | ((eci & 0x7000) >> 12); + } } else { - if (sp + 4 + length > 144) return 0; - character[sp++] = 0x38 | ((eci >> 18) & 0x03); - character[sp++] = (eci >> 12) & 0x3F; - character[sp++] = (eci >> 6) & 0x3F; - character[sp++] = eci & 0x3F; + codewords[--ci] = 0x20 | ((eci & 0x3C0) >> 6); } } + codewords[--ci] = 27; /* ECI */ + + return ci; +} + +/* Get the shortest encoded length for the Code Set (state) and plot the path */ +static int mx_get_best_length(const int state, const int i, const unsigned char ch, const int digits, const int num_a, + const int best_lengths[16][MX_STATES], const char best_origins[16][MX_STATES], + unsigned char *const path_op, char *const prior_code_set) { + const char *const latch_length_s = mx_latch_len[state]; + int min_len = 999999; + int j; + + if (digits >= 9) { /* Nothing can beat digits */ + const int m = (i - 9) & 0x0F; + const int org = best_origins[m][state]; + const int len = best_lengths[m][org] + latch_length_s[org] + 6; + if (len < min_len) { + path_op[state] = MX_OP_DGTS_IDX; + prior_code_set[state] = org; + min_len = len; + } + } else { + const signed char *const op_idx_s = mx_code_set_op_idxs[state]; + for (j = 0; op_idx_s[j] != -1; j++) { + const int op_idx = op_idx_s[j]; + const struct mx_op *const op = &mx_op_tab[op_idx]; + if (mx_can(op->op, ch, num_a)) { + const int m = (i - op->intake) & 0x0F; + const int org = best_origins[m][state]; + const int len = best_lengths[m][org] + latch_length_s[org] + op->intake + (op_idx >= MX_OP_SHA_IDX); + if (len < min_len) { + path_op[state] = op_idx; + prior_code_set[state] = org; + min_len = len; + } + } + } + } + return min_len; +} + +/* Loop to get the best prior Code Set using a row of best encoded lengths */ +static int mx_get_best_origin(const int state, const int *const best_length) { + + const char *const latch_length_s = mx_latch_len[state]; + int orglen = best_length[0] + latch_length_s[0]; + int best_org = 0; + int org; + + for (org = 1; org < MX_STATES; org++) { + const int len = best_length[org] + latch_length_s[org]; + if (len < orglen) { + best_org = org; + orglen = len; + } + } + return best_org; +} + +/* Minimal encoding using backtracking by Bue Jensen, taken from BWIPP - see + https://github.com/bwipp/postscriptbarcode/pull/279 */ +static int mx_text_process_segs(unsigned char codewords[144], const int mode, struct zint_seg segs[], + const int seg_count, const int structapp_cw, const int scm_vv, const int debug_print) { + + /* The encoder needs 10 history rows. The circular history buffers are 16 long for convenience */ + int best_lengths[16][MX_STATES] = {0}; + char best_origins[16][MX_STATES] = {0}; + int *best_length = NULL; /* Suppress clang-tidy-20 warning */ + + int cp = 20 - 9 * (mode > 3); /* Offset the initial codewords index to minimize copying */ + const int max_len = (mode == 5 ? 77 : 93) + 11; /* 11 added to adjust for above offset */ + int ci, ci_top; + + /* Backtracking information */ + const int segs_len = segs_length(segs, seg_count); + char (*prior_code_sets)[MX_STATES] = (char (*)[MX_STATES]) z_alloca(sizeof(*prior_code_sets) * (segs_len + 9)); + unsigned char (*path_ops)[MX_STATES] + = (unsigned char (*)[MX_STATES]) z_alloca(sizeof(*path_ops) * (segs_len + 9)); + + int digits = 0; + int num_a = 0; + + int min_len = 999999; + int min_state = 0; + int state; + + unsigned char *source_scm_vv; /* For SCM prefix `scm_vv` if any */ + int have_eci_scm = 0; /* Set if have ECI and SCM prefix */ + + int seg; + int si = 0; /* Segment offset to `source` position */ + int i, j; if (scm_vv != -1) { /* Add SCM prefix */ - if (sp + length > 135) { - return 0; - } - sprintf((char *) source_buf, "[)>\03601\035%02d", scm_vv); /* [)>\R01\Gvv */ - memcpy(source_buf + 9, in_source, length); - source = source_buf; - length += 9; + source_scm_vv = (unsigned char *) z_alloca(segs[0].length + 9); + sprintf((char *) source_scm_vv, "[)>\03601\035%02d", scm_vv); /* [)>\R01\Gvv */ + memcpy(source_scm_vv + 9, segs[0].source, segs[0].length); + segs[0].source = source_scm_vv; + segs[0].length += 9; + have_eci_scm = segs[0].eci; + } else if (segs[0].length >= 9 && memcmp(segs[0].source, "[)>\03601\035", 7) == 0 + && z_isdigit(segs[0].source[7]) && z_isdigit(segs[0].source[8])) { + have_eci_scm = segs[0].eci; } - for (i = 0; i < length; i++) { - /* Look up characters in table from Appendix A - this gives - value and code set for most characters */ - set[sp + i] = maxiCodeSet[source[i]]; - character[sp + i] = maxiSymbolChar[source[i]]; - } - - /* If a character can be represented in more than one code set, - pick which version to use */ - if (set[sp + 0] == 0) { - if (character[sp + 0] == 13) { - character[sp + 0] = 0; - } - set[sp + 0] = 1; - } - - for (i = 1; i < length; i++) { - if (set[sp + i] == 0) { - /* Special character */ - if (character[sp + i] == 13) { - /* Carriage Return */ - set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set15, 2); - if (set[sp + i] == 5) { - character[sp + i] = 13; - } else { - character[sp + i] = 0; - } - - } else if (character[sp + i] == 28) { - /* FS */ - set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5); - if (set[sp + i] == 5) { - character[sp + i] = 32; - } - - } else if (character[sp + i] == 29) { - /* GS */ - set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5); - if (set[sp + i] == 5) { - character[sp + i] = 33; - } - - } else if (character[sp + i] == 30) { - /* RS */ - set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5); - if (set[sp + i] == 5) { - character[sp + i] = 34; - } - - } else if (character[sp + i] == 32) { - /* Space */ - set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5); - if (set[sp + i] == 1) { - character[sp + i] = 32; - } else if (set[sp + i] == 2) { - character[sp + i] = 47; - } else { - character[sp + i] = 59; - } - - } else if (character[sp + i] == 44) { - /* Comma */ - set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2); - if (set[sp + i] == 2) { - character[sp + i] = 48; - } - - } else if (character[sp + i] == 46) { - /* Full Stop */ - set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2); - if (set[sp + i] == 2) { - character[sp + i] = 49; - } - - } else if (character[sp + i] == 47) { - /* Slash */ - set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2); - if (set[sp + i] == 2) { - character[sp + i] = 50; - } - - } else if (character[sp + i] == 58) { - /* Colon */ - set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2); - if (set[sp + i] == 2) { - character[sp + i] = 51; - } - } - } - } - - /* Find candidates for number compression */ - /* Note the prohibition on number compression in the primary message in ISO/IEC 16023:2000 B.1 (1) - applies to modes 2 & 3 only */ - count = 0; - for (i = 0; sp + i < 144 && sp + i < length; i++) { - if ((set[sp + i] == 1) && ((character[sp + i] >= 48) && (character[sp + i] <= 57))) { - /* Character is a number */ - count++; - if (count == 9) { - /* Nine digits in a row can be compressed */ - memset(set + sp + i - 8, 6, 9); /* Set set of nine digits to 6 */ - count = 0; -#ifndef NDEBUG - ns_count1++; -#endif - } - } else { - count = 0; - } - } - - /* Add shift and latch characters */ - for (i = 0; sp + i < 144 && set[sp + i] != 255; i++) { - - if ((set[sp + i] != current_set) && (set[sp + i] != 6)) { - switch (set[sp + i]) { - case 1: - if (current_set == 2) { /* Set B */ - if (sp + i + 1 < 144 && set[sp + i + 1] == 1) { - if (sp + i + 2 < 144 && set[sp + i + 2] == 1) { - if (sp + i + 3 < 144 && set[sp + i + 3] == 1) { - /* Latch A */ - maxi_bump(set, character, sp + i, &length); - character[sp + i] = 63; /* Set B Latch A */ - current_set = 1; - i += 3; /* Next 3 Set A so skip over */ - if (debug_print) fputs("LCHA ", stdout); - } else { - /* 3 Shift A */ - maxi_bump(set, character, sp + i, &length); - character[sp + i] = 57; /* Set B triple shift A */ - i += 2; /* Next 2 Set A so skip over */ - if (debug_print) fputs("3SHA ", stdout); - } - } else { - /* 2 Shift A */ - maxi_bump(set, character, sp + i, &length); - character[sp + i] = 56; /* Set B double shift A */ - i++; /* Next Set A so skip over */ - if (debug_print) fputs("2SHA ", stdout); - } - } else { - /* Shift A */ - maxi_bump(set, character, sp + i, &length); - character[sp + i] = 59; /* Set A Shift B */ - if (debug_print) fputs("SHA ", stdout); - } - } else { /* All sets other than B only have latch */ - /* Latch A */ - maxi_bump(set, character, sp + i, &length); - character[sp + i] = 58; /* Sets C,D,E Latch A */ - current_set = 1; - if (debug_print) fputs("LCHA ", stdout); - } - break; - case 2: /* 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 */ - maxi_bump(set, character, sp + i, &length); - character[sp + i] = 63; /* Sets A,C,D,E Latch B */ - current_set = 2; - if (debug_print) fputs("LCHB ", stdout); - } else { /* Only available from Set A */ - /* Shift B */ - maxi_bump(set, character, sp + i, &length); - character[sp + i] = 59; /* Set B Shift A */ - if (debug_print) fputs("SHB ", stdout); - } - break; - case 3: /* Set C */ - case 4: /* Set D */ - case 5: /* Set E */ - /* If first and next 3 same set, or not first and previous and next 2 same set */ - if ((sp + i == 0 && sp + i + 3 < 144 && set[sp + i + 1] == set[sp + i] - && set[sp + i + 2] == set[sp + i] && set[sp + i + 3] == set[sp + i]) - || (sp + i > 0 && set[sp + i - 1] == set[sp + i] && sp + i + 2 < 144 - && set[sp + i + 1] == set[sp + i] && set[sp + i + 2] == set[sp + i])) { - /* Lock in C/D/E */ - if (sp + i == 0) { - maxi_bump(set, character, sp + i, &length); - character[sp + i] = 60 + set[sp + i] - 3; - i++; /* Extra bump */ - maxi_bump(set, character, sp + i, &length); - character[sp + i] = 60 + set[sp + i] - 3; - i += 3; /* Next 3 same set so skip over */ - } else { - /* Add single Shift to previous Shift */ - maxi_bump(set, character, sp + i - 1, &length); - character[sp + i - 1] = 60 + set[sp + i] - 3; - i += 2; /* Next 2 same set so skip over */ - } - current_set = set[sp + i]; - if (debug_print) printf("LCK%c ", 'C' + set[sp + i] - 3); - } else { - /* Shift C/D/E */ - maxi_bump(set, character, sp + i, &length); - character[sp + i] = 60 + set[sp + i] - 3; - if (debug_print) printf("SH%c ", 'C' + set[sp + i] - 3); - } - break; - } - i++; /* Allow for bump */ - } - } - - /* Number compression has not been forgotten! - It's handled below */ - for (i = 0; sp + i < 144 && sp + i <= length - 9; i++) { - if (set[sp + i] == 6) { - /* Number compression */ - int value = to_int(character + sp + i, 9); - - character[sp + i] = 31; /* NS */ - character[sp + i + 1] = (value & 0x3f000000) >> 24; - character[sp + i + 2] = (value & 0xfc0000) >> 18; - character[sp + i + 3] = (value & 0x3f000) >> 12; - character[sp + i + 4] = (value & 0xfc0) >> 6; - character[sp + i + 5] = (value & 0x3f); - - memmove(set + sp + i + 6, set + sp + i + 9, 144 - (sp + i + 9)); - memmove(character + sp + i + 6, character + sp + i + 9, 144 - (sp + i + 9)); - i += 5; - length -= 3; -#ifndef NDEBUG - ns_count2++; -#endif - } - } - assert(ns_count1 == ns_count2); - - *p_sp = sp + length; - - return current_set; -} - -/* 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 sp = 0; - int current_set = 1; /* Initial Code Set A */ - int padding_set = 0, padding_char = 0; /* Suppress clang-tidy-20 warnings */ - const int max_length = mode == 5 ? 77 : mode <= 3 ? 84 : 93; - - memset(set, 255, 144); - /* Insert Structured Append at beginning if needed */ if (structapp_cw) { - character[sp++] = 33; /* PAD */ - character[sp++] = structapp_cw; + codewords[cp++] = 33; /* PAD */ + codewords[cp++] = structapp_cw; } - for (i = 0; i < seg_count; i++) { - current_set = maxi_text_process(set, character, segs[i].source, segs[i].length, segs[i].eci, scm_vv, &sp, - current_set, debug_print); - if (current_set == 0) { - return ZINT_ERROR_TOO_LONG; + /* Make a table of best path options */ + ci = cp; + for (seg = 0; seg < seg_count; seg++) { + /* Suppress NS compaction for SCM prefix if have ECI so can place ECI after it when encoding */ + const int no_eci_scm_check = !have_eci_scm || seg != 0; + const unsigned char *const source = segs[seg].source; + const int length = segs[seg].length; + const int eci_len = mx_eci_len(segs[seg].eci); + if (eci_len) { + ci += eci_len; + if (ci > max_len) { + return ZINT_ERROR_TOO_LONG; + } + digits = 0; } - scm_vv = -1; - } - /* If end in Code Set C or D, switch to A for padding */ - if (sp < max_length && (current_set == 3 || current_set == 4)) { - set[sp] = 1; - character[sp] = 58; /* Sets C,D Latch A */ - sp++; - current_set = 1; - if (debug_print) fputs("LCHA ", stdout); - } + for (i = 0; i < length; i++) { + const unsigned char ch = source[i]; + const int si_i = i + si; - if (debug_print) { - if (sp < max_length) { - printf("\nPads (%d)\n", max_length - sp); - } else { - fputs("\nNo Pads\n", stdout); + /* Get rows of interest */ + unsigned char *const path_op = path_ops[si_i]; + char *const prior_code_set = prior_code_sets[si_i]; + char *const best_origin = best_origins[(si_i) & 0x0F]; + best_length = best_lengths[(si_i) & 0x0F]; + + /* Keep tabs on digits and characters in Code Set A */ + digits = z_isdigit(ch) && (no_eci_scm_check || i >= 9) ? digits + 1 : 0; + num_a = maxiCodeSet[ch] & MX_OP_SETA ? num_a + 1 : 0; + + /* Get best encoded lengths, then best prior Code Sets */ + for (state = 0; state < MX_STATES; state++) { + best_length[state] = mx_get_best_length(state, si_i, ch, digits, num_a, best_lengths, best_origins, + path_op, prior_code_set); + } + for (state = 0; state < MX_STATES; state++) { + best_origin[state] = mx_get_best_origin(state, best_length); + } + } + si += length; + } + assert(best_length == best_lengths[(segs_len + 9 * (scm_vv != -1) - 1) & 0x0F]); /* Set to last char */ + + /* Get the best Code Set to end with */ + for (state = 0; state < MX_STATES; state++) { + const int len = best_length[state]; + if (len < min_len) { + min_state = state; + min_len = len; } } - - if (sp < max_length) { - padding_set = current_set == 5 ? 5 : current_set == 2 ? 2 : 1; - padding_char = current_set == 5 ? 28 : 33; - for (; sp < max_length; sp++) { - /* Add the padding */ - set[sp] = padding_set; - character[sp] = padding_char; - } - } - - if (debug_print) printf("Length: %d\n", sp); - - if (sp > max_length) { + if (ci + min_len > max_len) { return ZINT_ERROR_TOO_LONG; } - /* Copy the encoded text into the codeword array */ - if ((mode == 2) || (mode == 3)) { - for (i = 0; i < 84; i++) { /* secondary only */ - maxi_codeword[i + 20] = character[i]; - } + /* Follow the best path back to the start of the message */ + ci += min_len; + ci_top = ci; + state = min_state; + for (seg = seg_count - 1; seg >= 0; seg--) { + const unsigned char *const source = segs[seg].source; + const int length = segs[seg].length; + const int eci_scm_check = have_eci_scm && seg == 0; - } else if ((mode == 4) || (mode == 6)) { - for (i = 0; i < 9; i++) { /* primary */ - maxi_codeword[i + 1] = character[i]; - } - for (i = 0; i < 84; i++) { /* secondary */ - maxi_codeword[i + 20] = character[i + 9]; - } + si -= length; + assert(si >= 0); - } else { /* Mode 5 */ - for (i = 0; i < 9; i++) { /* primary */ - maxi_codeword[i + 1] = character[i]; + i = length; + while (i > 0) { + const int ch_i = (i + si) - 1; + const int pcs = prior_code_sets[ch_i][state]; + const int op_idx = path_ops[ch_i][state]; + const struct mx_op *const op = &mx_op_tab[op_idx]; + + if (eci_scm_check && i == 9) { /* Place ECI after SCM prefix */ + assert(ci >= cp + mx_eci_len(segs[0].eci)); + ci = mx_enc_eci(segs[0].eci, codewords, ci); + segs[0].eci = 0; + } + + i -= op->intake; + assert(i >= 0); + ci = mx_enc(codewords, ci, source, i, op->op); + + if (state != pcs) { + const int latch_len = mx_latch_len[state][pcs]; + assert(ci >= cp + latch_len); + for (j = 0; j < latch_len; j++) { + codewords[--ci] = mx_latch_seq[state][pcs][j]; + } + state = pcs; + } } - for (i = 0; i < 68; i++) { /* secondary */ - maxi_codeword[i + 20] = character[i + 9]; + if (segs[seg].eci) { + assert(ci >= cp + mx_eci_len(segs[seg].eci)); + ci = mx_enc_eci(segs[seg].eci, codewords, ci); } } + assert(ci == cp); + + cp = ci_top; + + /* If end in Code Set C or D, switch to A for padding */ + if (cp < max_len && (min_state == MX_C || min_state == MX_D)) { + codewords[cp++] = 58; /* Latch A */ + } + + if (debug_print) { + if (cp < max_len) { + printf("Pads: %d\n", max_len - cp); + } else { + fputs("No Pads\n", stdout); + } + } + + if (cp < max_len) { + /* Add the padding */ + memset(codewords + cp, min_state == MX_E ? 28 : 33, max_len - cp); + } + + if (debug_print) printf("Length: %d\n", cp); + + if (cp > max_len) { + return ZINT_ERROR_TOO_LONG; + } + + /* Adjust the codeword array */ + if (mode > 3) { + memcpy(codewords + 1, codewords + 20 - 9, 9); /* Primary */ + } return 0; } +/* Handles error correction of primary message */ +static void mx_do_primary_ecc(unsigned char codewords[144]) { + const int datalen = 10, eclen = 10; + unsigned char ecc[10]; + int j; + rs_t rs; + + rs_init_gf(&rs, 0x43); + rs_init_code(&rs, eclen, 1); + + rs_encode(&rs, datalen, codewords, ecc); + + for (j = 0; j < eclen; j++) { + codewords[datalen + j] = ecc[j]; + } +} + +/* Handles error correction of characters in secondary */ +static void mx_do_secondary_ecc(unsigned char codewords[144], const int datalen, const int eclen) { + unsigned char data[42]; /* Half max `datalen` (84) */ + unsigned char ecc[28]; /* Half max `eclen` (56) */ + int j; + rs_t rs; + + rs_init_gf(&rs, 0x43); + rs_init_code(&rs, eclen, 1); + + /* Even */ + for (j = 0; j < datalen; j += 2) { + data[j >> 1] = codewords[j + 20]; + } + + rs_encode(&rs, datalen >> 1, data, ecc); + + for (j = 0; j < eclen; j++) { + codewords[datalen + (j << 1) + 20] = ecc[j]; + } + + /* Odd */ + for (j = 0; j < datalen; j += 2) { + data[j >> 1] = codewords[j + 1 + 20]; + } + + rs_encode(&rs, datalen >> 1, data, ecc); + + for (j = 0; j < eclen; j++) { + codewords[datalen + (j << 1) + 1 + 20] = ecc[j]; + } +} + /* Format structured primary for Mode 2 */ -static void maxi_do_primary_2(unsigned char maxi_codeword[144], const unsigned char postcode[], +static void mx_do_primary_2(unsigned char codewords[144], const unsigned char postcode[], const int postcode_length, const int country, const int service) { - int postcode_num; - postcode_num = to_int(postcode, postcode_length); + const int postcode_num = to_int(postcode, postcode_length); - maxi_codeword[0] = ((postcode_num & 0x03) << 4) | 2; - maxi_codeword[1] = ((postcode_num & 0xfc) >> 2); - maxi_codeword[2] = ((postcode_num & 0x3f00) >> 8); - maxi_codeword[3] = ((postcode_num & 0xfc000) >> 14); - maxi_codeword[4] = ((postcode_num & 0x3f00000) >> 20); - maxi_codeword[5] = ((postcode_num & 0x3c000000) >> 26) | ((postcode_length & 0x3) << 4); - maxi_codeword[6] = ((postcode_length & 0x3c) >> 2) | ((country & 0x3) << 4); - maxi_codeword[7] = (country & 0xfc) >> 2; - maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2); - maxi_codeword[9] = ((service & 0x3f0) >> 4); + codewords[0] = ((postcode_num & 0x03) << 4) | 2; + codewords[1] = ((postcode_num & 0xFC) >> 2); + codewords[2] = ((postcode_num & 0x3F00) >> 8); + codewords[3] = ((postcode_num & 0xFC000) >> 14); + codewords[4] = ((postcode_num & 0x3F00000) >> 20); + codewords[5] = ((postcode_num & 0x3C000000) >> 26) | ((postcode_length & 0x03) << 4); + codewords[6] = ((postcode_length & 0x3C) >> 2) | ((country & 0x03) << 4); + codewords[7] = (country & 0xFC) >> 2; + codewords[8] = ((country & 0x300) >> 8) | ((service & 0x0F) << 2); + codewords[9] = ((service & 0x3F0) >> 4); } /* Format structured primary for Mode 3 */ -static void maxi_do_primary_3(unsigned char maxi_codeword[144], unsigned char postcode[], const int country, +static void mx_do_primary_3(unsigned char codewords[144], unsigned char postcode[], const int country, const int service) { int i; @@ -549,22 +537,22 @@ static void maxi_do_primary_3(unsigned char maxi_codeword[144], unsigned char po postcode[i] = maxiSymbolChar[postcode[i]]; } - maxi_codeword[0] = ((postcode[5] & 0x03) << 4) | 3; - maxi_codeword[1] = ((postcode[4] & 0x03) << 4) | ((postcode[5] & 0x3c) >> 2); - maxi_codeword[2] = ((postcode[3] & 0x03) << 4) | ((postcode[4] & 0x3c) >> 2); - maxi_codeword[3] = ((postcode[2] & 0x03) << 4) | ((postcode[3] & 0x3c) >> 2); - maxi_codeword[4] = ((postcode[1] & 0x03) << 4) | ((postcode[2] & 0x3c) >> 2); - maxi_codeword[5] = ((postcode[0] & 0x03) << 4) | ((postcode[1] & 0x3c) >> 2); - maxi_codeword[6] = ((postcode[0] & 0x3c) >> 2) | ((country & 0x3) << 4); - maxi_codeword[7] = (country & 0xfc) >> 2; - maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2); - maxi_codeword[9] = ((service & 0x3f0) >> 4); + codewords[0] = ((postcode[5] & 0x03) << 4) | 3; + codewords[1] = ((postcode[4] & 0x03) << 4) | ((postcode[5] & 0x3C) >> 2); + codewords[2] = ((postcode[3] & 0x03) << 4) | ((postcode[4] & 0x3C) >> 2); + codewords[3] = ((postcode[2] & 0x03) << 4) | ((postcode[3] & 0x3C) >> 2); + codewords[4] = ((postcode[1] & 0x03) << 4) | ((postcode[2] & 0x3C) >> 2); + codewords[5] = ((postcode[0] & 0x03) << 4) | ((postcode[1] & 0x3C) >> 2); + codewords[6] = ((postcode[0] & 0x3C) >> 2) | ((country & 0x03) << 4); + codewords[7] = (country & 0xFC) >> 2; + codewords[8] = ((country & 0x300) >> 8) | ((service & 0x0F) << 2); + codewords[9] = ((service & 0x3F0) >> 4); } INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { - int i, j, block, shift, mode, lp = 0; - int error_number, eclen; - unsigned char maxi_codeword[144] = {0}; + int i, j, mode, lp = 0; + int error_number; + unsigned char codewords[144]; int scm_vv = -1; int structapp_cw = 0; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; @@ -589,11 +577,11 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const } } - if ((mode < 2) || (mode > 6)) { /* Only codes 2 to 6 supported */ + if (mode < 2 || mode > 6) { /* Only codes 2 to 6 supported */ return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 550, "Mode '%d' out of range (2 to 6)", mode); } - if ((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */ + if (mode <= 3) { /* Modes 2 and 3 need data in symbol->primary */ unsigned char postcode[10]; int countrycode; int service; @@ -613,7 +601,7 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const countrycode = to_int((const unsigned char *) (symbol->primary + postcode_len), 3); service = to_int((const unsigned char *) (symbol->primary + postcode_len + 3), 3); - if (countrycode == -1 || service == -1) { /* check that country code and service are numeric */ + if (countrycode == -1 || service == -1) { /* Check that country code and service are numeric */ return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 552, "Non-numeric country code or service class in Primary Message"); } @@ -627,7 +615,8 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const postcode[i] = '\0'; postcode_len = i; break; - } else if (!z_isdigit(postcode[i])) { + } + if (!z_isdigit(postcode[i])) { return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 555, "Non-numeric postcode in Primary Message"); } } @@ -637,7 +626,7 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const memcpy(postcode + 5, "0000", 5); /* Include NUL char */ postcode_len = 9; } - maxi_do_primary_2(maxi_codeword, postcode, postcode_len, countrycode, service); + mx_do_primary_2(codewords, postcode, postcode_len, countrycode, service); } else { /* Just truncate and space-pad */ postcode[6] = '\0'; @@ -647,13 +636,13 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const /* Upper-case and check for Code Set A characters only */ to_upper(postcode, postcode_len); for (i = 0; i < 6; i++) { - /* Don't allow Code Set A control characters CR, RS, GS and RS */ - if (postcode[i] < ' ' || maxiCodeSet[postcode[i]] > 1) { + /* Don't allow control chars (CR FS GS RS for Code Set A) */ + if (postcode[i] < ' ' || !(maxiCodeSet[postcode[i]] & MX_OP_SETA)) { return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 556, "Invalid character in postcode in Primary Message"); } } - maxi_do_primary_3(maxi_codeword, postcode, countrycode, service); + mx_do_primary_3(codewords, postcode, countrycode, service); } if (symbol->option_2) { /* Check for option_2 = vv + 1, where vv is version of SCM prefix "[)>\R01\Gvv" */ @@ -661,6 +650,10 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 557, "SCM prefix version '%d' out of range (1 to 100)", symbol->option_2); } + if (symbol->eci == 25 || (symbol->eci >= 33 && symbol->eci <= 35)) { /* UTF-16/32 */ + return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 547, + "SCM prefix can not be used with ECI %d (ECI must be ASCII compatible)", symbol->eci); + } scm_vv = symbol->option_2 - 1; } @@ -668,7 +661,7 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const printf("Postcode: %s, Country Code: %d, Service Class: %d\n", postcode, countrycode, service); } } else { - maxi_codeword[0] = mode; + codewords[0] = mode; } if (debug_print) { @@ -691,42 +684,41 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const structapp_cw = (symbol->structapp.count - 1) | ((symbol->structapp.index - 1) << 3); } - error_number = maxi_text_process_segs(maxi_codeword, mode, segs, seg_count, structapp_cw, scm_vv, debug_print); + error_number = mx_text_process_segs(codewords, mode, segs, seg_count, structapp_cw, scm_vv, debug_print); if (error_number == ZINT_ERROR_TOO_LONG) { return errtxt(error_number, symbol, 553, "Input too long, requires too many codewords (maximum 144)"); } /* All the data is sorted - now do error correction */ - maxi_do_primary_check(maxi_codeword); /* always EEC */ + mx_do_primary_ecc(codewords); /* Always Enhanced ECC (EEC) 10 data + 10 error correction */ - if (mode == 5) - eclen = 56; /* 68 data codewords , 56 error corrections */ - else - eclen = 40; /* 84 data codewords, 40 error corrections */ - - maxi_do_secondary_chk_even(maxi_codeword, eclen / 2); /* do error correction of even */ - maxi_do_secondary_chk_odd(maxi_codeword, eclen / 2); /* do error correction of odd */ + if (mode == 5) { + /* Enhanced ECC (EEC) 68 data + 56 error correction */ + mx_do_secondary_ecc(codewords, 68, 28); /* ECC halved for even/odd */ + } else { + /* Standard ECC (SEC) 84 data + 40 error correction */ + mx_do_secondary_ecc(codewords, 84, 20); /* ECC halved for even/odd */ + } if (debug_print) { fputs("Codewords:", stdout); - for (i = 0; i < 144; i++) printf(" %d", maxi_codeword[i]); + for (i = 0; i < 144; i++) printf(" %d", codewords[i]); fputc('\n', stdout); } #ifdef ZINT_TEST if (symbol->debug & ZINT_DEBUG_TEST) { - debug_test_codeword_dump(symbol, maxi_codeword, 144); + debug_test_codeword_dump(symbol, codewords, 144); } #endif /* Copy data into symbol grid */ for (i = 0; i < 33; i++) { for (j = 0; j < 30; j++) { - block = (MaxiGrid[(i * 30) + j] + 5) / 6; + const int mod_seq = maxiGrid[(i * 30) + j] + 5; + const int block = mod_seq / 6; if (block != 0) { - shift = 5 - ((MaxiGrid[(i * 30) + j] + 5) % 6); - - if ((maxi_codeword[block - 1] >> shift) & 0x1) { + if ((codewords[block - 1] >> (5 - (mod_seq % 6))) & 1) { set_module(symbol, i, j); } } diff --git a/backend/maxicode.h b/backend/maxicode.h index f280a607..aefa8046 100644 --- a/backend/maxicode.h +++ b/backend/maxicode.h @@ -1,7 +1,7 @@ /* maxicode.h - Handles Maxicode */ /* libzint - the open source barcode library - Copyright (C) 2008-2022 Robin Stuart + Copyright (C) 2008-2024 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -33,9 +33,9 @@ #ifndef Z_MAXICODE_H #define Z_MAXICODE_H -static const unsigned short MaxiGrid[] = { - /* ISO/IEC 16023 Figure 5 - MaxiCode Module Sequence */ /* 30 x 33 data grid */ - 122, 121, 128, 127, 134, 133, 140, 139, 146, 145, 152, 151, 158, 157, 164, 163, 170, 169, 176, 175, 182, 181, 188, 187, 194, 193, 200, 199, 0, 0, +/* ISO/IEC 16023 Figure 5 - MaxiCode Module Sequence */ +static const unsigned short maxiGrid[] = { /* 33 x 30 data grid */ + 122, 121, 128, 127, 134, 133, 140, 139, 146, 145, 152, 151, 158, 157, 164, 163, 170, 169, 176, 175, 182, 181, 188, 187, 194, 193, 200, 199, 0, 0, 124, 123, 130, 129, 136, 135, 142, 141, 148, 147, 154, 153, 160, 159, 166, 165, 172, 171, 178, 177, 184, 183, 190, 189, 196, 195, 202, 201, 817, 0, 126, 125, 132, 131, 138, 137, 144, 143, 150, 149, 156, 155, 162, 161, 168, 167, 174, 173, 180, 179, 186, 185, 192, 191, 198, 197, 204, 203, 819, 818, 284, 283, 278, 277, 272, 271, 266, 265, 260, 259, 254, 253, 248, 247, 242, 241, 236, 235, 230, 229, 224, 223, 218, 217, 212, 211, 206, 205, 820, 0, @@ -70,39 +70,49 @@ static const unsigned short MaxiGrid[] = { 738, 737, 744, 743, 750, 749, 756, 755, 762, 761, 768, 767, 774, 773, 780, 779, 786, 785, 792, 791, 798, 797, 804, 803, 810, 809, 816, 815, 864, 863 }; +/* From Appendix A - ASCII character to Code Set bit flag (MX_OP_SETX): A 0x01; B 0x02; E 0x04; C 0x08; D 0x10 */ +/* Chars that fit in more than one set have flags OR-ed together: A/E "CR"; All "FS GS RS SP"; A/B ",./:" */ static const char maxiCodeSet[256] = { - /* from Appendix A - ASCII character to Code Set (e.g. 2 = Set B) */ - /* set 0 refers to special characters that fit into more than one set (e.g. GS) */ - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 0, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, - 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 4, 5, 5, 5, 5, 5, 5, 4, 5, 3, 4, 3, 5, 5, 4, 4, 3, 3, 3, - 4, 3, 5, 4, 4, 3, 3, 4, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 + /* CR */ + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, /* 0- 15 */ + /* FS GS RS */ + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1F, 0x1F, 0x1F, 0x04, /* 16- 31 */ + /*SP , . / */ + 0x1F, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x03, 0x03, /* 32- 47 */ + /* : */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48- 63 */ + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* 64- 79 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, /* 80- 95 */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 96-111 */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 112-127 */ + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, /* 128-143 */ + 0x10, 0x10, 0x10, 0x10, 0x10, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 144-159 */ + 0x04, 0x10, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x10, 0x04, 0x08, 0x10, 0x08, 0x04, 0x04, 0x10, /* 160-175 */ + 0x10, 0x08, 0x08, 0x08, 0x10, 0x08, 0x04, 0x10, 0x10, 0x08, 0x08, 0x10, 0x08, 0x08, 0x08, 0x10, /* 176-191 */ + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 192-207 */ + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 208-223 */ + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, /* 224-249 */ + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 /* 250-255 */ }; +/* From Appendix A - ASCII character to symbol value. For those in multiple sets, Code A value */ static const char maxiSymbolChar[256] = { - /* from Appendix A - ASCII character to symbol value */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 30, 28, 29, 30, 35, 32, 53, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 37, - 38, 39, 40, 41, 52, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 42, 43, 44, 45, 46, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 32, 54, 34, 35, 36, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 36, - 37, 37, 38, 39, 40, 41, 42, 43, 38, 44, 37, 39, 38, 45, 46, 40, 41, 39, 40, 41, - 42, 42, 47, 43, 44, 43, 44, 45, 45, 46, 47, 46, 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, - 33, 34, 35, 36, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 33, 34, 35, 36 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 14, 15, /* 0- 15 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 30, 28, 29, 30, 35, /* 16- 31 */ + 32, 53, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 32- 47 */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 37, 38, 39, 40, 41, /* 48- 63 */ + 52, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 64- 79 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 42, 43, 44, 45, 46, /* 80- 95 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 96-111 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 54, 34, 35, 36, /* 112-127 */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 47, 48, 49, 50, 51, 52, /* 128-143 */ + 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 36, /* 144-159 */ + 37, 37, 38, 39, 40, 41, 42, 43, 38, 44, 37, 39, 38, 45, 46, 40, /* 160-175 */ + 41, 39, 40, 41, 42, 42, 47, 43, 44, 43, 44, 45, 45, 46, 47, 46, /* 176-191 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 192-207 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 33, 34, 35, 36, /* 208-223 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 224-249 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 33, 34, 35, 36 /* 250-255 */ }; /* vim: set ts=4 sw=4 et : */ diff --git a/backend/qr.c b/backend/qr.c index 39425e2b..4671c2b6 100644 --- a/backend/qr.c +++ b/backend/qr.c @@ -839,7 +839,7 @@ static void qr_add_ecc(unsigned char fullstream[], const unsigned char datastrea } fputs(" // ", stdout); for (j = 0; j < ecc_block_length; j++) { - printf("%2X ", ecc_block[ecc_block_length - j - 1]); + printf("%2X ", ecc_block[j]); } fputc('\n', stdout); } @@ -855,7 +855,7 @@ static void qr_add_ecc(unsigned char fullstream[], const unsigned char datastrea } for (j = 0; j < ecc_block_length; j++) { - interleaved_ecc[(j * blocks) + i] = ecc_block[ecc_block_length - j - 1]; + interleaved_ecc[(j * blocks) + i] = ecc_block[j]; } in_posn += length_this_block; @@ -1955,7 +1955,7 @@ static int microqr_end(struct zint_symbol *symbol, char binary_data[], int bp, c /* Add Reed-Solomon codewords to binary data */ for (i = 0; i < ecc_codewords; i++) { - bp = bin_append_posn(ecc_blocks[ecc_codewords - i - 1], 8, binary_data, bp); + bp = bin_append_posn(ecc_blocks[i], 8, binary_data, bp); } return bp; diff --git a/backend/reedsol.c b/backend/reedsol.c index 5a0da23d..de8e47df 100644 --- a/backend/reedsol.c +++ b/backend/reedsol.c @@ -132,8 +132,7 @@ INTERNAL void rs_init_code(rs_t *rs, const int nsym, int index) { } } -/* rs_encode(&rs, datalen, data, res) generates nsym Reed-Solomon codes (nsym as given in rs_init_code()) - * and places them in reverse order in res */ +/* rs_encode(&rs, datalen, data, res) generates nsym Reed-Solomon codes (nsym as given in rs_init_code()) */ INTERNAL void rs_encode(const rs_t *rs, const int datalen, const unsigned char *data, unsigned char *res) { int i, k; const unsigned char *const logt = rs->logt; @@ -141,6 +140,7 @@ INTERNAL void rs_encode(const rs_t *rs, const int datalen, const unsigned char * const unsigned char *const rspoly = rs->rspoly; const unsigned char *const log_rspoly = rs->log_rspoly; const int nsym = rs->nsym; + const int nsym_halved = nsym >> 1; memset(res, 0, nsym); if (rs->zero) { /* Poly has a zero coeff so need to check in inner loop */ @@ -175,6 +175,12 @@ INTERNAL void rs_encode(const rs_t *rs, const int datalen, const unsigned char * } } } + /* Reverse the result */ + for (i = 0; i < nsym_halved; i++) { + const unsigned char tmp = res[i]; + res[i] = res[nsym - 1 - i]; + res[nsym - 1 - i] = tmp; + } } /* The same as above but for unsigned int data and result - Aztec code compatible */ @@ -186,6 +192,7 @@ INTERNAL void rs_encode_uint(const rs_t *rs, const int datalen, const unsigned i const unsigned char *const rspoly = rs->rspoly; const unsigned char *const log_rspoly = rs->log_rspoly; const int nsym = rs->nsym; + const int nsym_halved = nsym >> 1; memset(res, 0, sizeof(unsigned int) * nsym); if (rs->zero) { /* Poly has a zero coeff so need to check in inner loop */ @@ -220,6 +227,12 @@ INTERNAL void rs_encode_uint(const rs_t *rs, const int datalen, const unsigned i } } } + /* Reverse the result */ + for (i = 0; i < nsym_halved; i++) { + const unsigned int tmp = res[i]; + res[i] = res[nsym - 1 - i]; + res[nsym - 1 - i] = tmp; + } } /* Versions of the above for bitlengths > 8 and <= 30 and unsigned int data and results - Aztec code compatible */ @@ -303,6 +316,7 @@ INTERNAL void rs_uint_encode(const rs_uint_t *rs_uint, const int datalen, const const unsigned short *const rspoly = rs_uint->rspoly; const unsigned int *const log_rspoly = rs_uint->log_rspoly; const int nsym = rs_uint->nsym; + const int nsym_halved = nsym >> 1; memset(res, 0, sizeof(unsigned int) * nsym); if (logt == NULL || alog == NULL) { @@ -340,6 +354,12 @@ INTERNAL void rs_uint_encode(const rs_uint_t *rs_uint, const int datalen, const } } } + /* Reverse the result */ + for (i = 0; i < nsym_halved; i++) { + const unsigned int tmp = res[i]; + res[i] = res[nsym - 1 - i]; + res[nsym - 1 - i] = tmp; + } } INTERNAL void rs_uint_free(rs_uint_t *rs_uint) { diff --git a/backend/tests/test_library.c b/backend/tests/test_library.c index aadab815..276fa2a9 100644 --- a/backend/tests/test_library.c +++ b/backend/tests/test_library.c @@ -620,7 +620,7 @@ static void test_escape_char_process(const testCtx *const p_ctx) { /* 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, "" }, /* 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 3F 1D 1E 3C 31", 0, "" }, /* 7*/ { BARCODE_PDF417, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", "", 0, 120, "(24) 16 901 0 23 655 318 98 18 461 639 893 122 129 92 900 900 872 438 359 646 522 773 831", 0, "" }, /* 8*/ { BARCODE_ULTRA, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", "", 0, 20, "(15) 257 0 4 7 8 9 10 11 12 13 27 29 30 129 92", 0, "" }, /* 9*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\d129\\o201\\\\", "", 0, 18, "(32) 01 05 08 09 0A 0B 0C 0D 0E 1C 1E 1F E7 32 45 DB 70 5D E3 16 7B 2B 44 60 E1 55 F7 08", 0, "" }, diff --git a/backend/tests/test_maxicode.c b/backend/tests/test_maxicode.c index 29e143ed..1e099ac3 100644 --- a/backend/tests/test_maxicode.c +++ b/backend/tests/test_maxicode.c @@ -48,7 +48,7 @@ static void test_large(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { -1, -1, "1", 138, "", 0, 33, 30, 0, "Mode 4 (138 agrees with ISO/IEC 16023:2000); BWIPP different encodation (begins with ASCII digits then NSes)" }, + /* 0*/ { -1, -1, "1", 138, "", 0, 33, 30, 1, "Mode 4 (138 agrees with ISO/IEC 16023:2000)" }, /* 1*/ { -1, -1, "1", 139, "", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, /* 2*/ { -1, -1, "1", 144, "", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, /* 3*/ { -1, -1, "1", 145, "", ZINT_ERROR_TOO_LONG, -1, -1, 1, "Absolute max" }, @@ -62,24 +62,24 @@ static void test_large(const testCtx *const p_ctx) { /* 11*/ { 2, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, /* 12*/ { 2, -1, "A", 84, "123456789123123", 0, 33, 30, 1, "" }, /* 13*/ { 2, -1, "A", 85, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, - /* 14*/ { 2, 96 + 1, "1", 109, "123456789123123", 0, 33, 30, 0, "BWIPP different encodation (begins with ASCII digits then NSes)" }, + /* 14*/ { 2, 96 + 1, "1", 109, "123456789123123", 0, 33, 30, 1, "" }, /* 15*/ { 2, 96 + 1, "1", 110, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, /* 16*/ { 2, 96 + 1, "1", 136, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1, 1, "Absolute max with SCM vv" }, /* 17*/ { 3, -1, "1", 126, "ABCDEF123123", 0, 33, 30, 1, "" }, /* 18*/ { 3, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, /* 19*/ { 3, -1, "A", 84, "ABCDEF123123", 0, 33, 30, 1, "" }, /* 20*/ { 3, -1, "A", 85, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, - /* 21*/ { 3, 96 + 1, "1", 109, "ABCDEF123123", 0, 33, 30, 0, "BWIPP different encodation" }, + /* 21*/ { 3, 96 + 1, "1", 109, "ABCDEF123123", 0, 33, 30, 1, "" }, /* 22*/ { 3, 96 + 1, "1", 110, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, - /* 23*/ { 0, -1, "1", 126, "123456789123123", 0, 33, 30, 0, "Mode 2; BWIPP requires mode" }, + /* 23*/ { 0, -1, "1", 126, "123456789123123", 0, 33, 30, 1, "Mode 2" }, /* 24*/ { 0, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, /* 25*/ { 0, -1, "1", 126, "ABCDEF123123", 0, 33, 30, 1, "Mode 3" }, /* 26*/ { 0, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, - /* 27*/ { 5, -1, "1", 113, "", 0, 33, 30, 0, "Extra EEC; BWIPP different encodation (begins with ASCII digits then NSes)" }, + /* 27*/ { 5, -1, "1", 113, "", 0, 33, 30, 1, "Extra EEC" }, /* 28*/ { 5, -1, "1", 114, "", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, /* 29*/ { 5, -1, "A", 77, "", 0, 33, 30, 1, "" }, /* 30*/ { 5, -1, "A", 78, "", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, - /* 31*/ { 6, -1, "1", 138, "", 0, 33, 30, 0, "BWIPP different encodation (begins with ASCII digits then NSes)" }, + /* 31*/ { 6, -1, "1", 138, "", 0, 33, 30, 1, "" }, /* 32*/ { 6, -1, "1", 139, "", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, /* 33*/ { 6, -1, "A", 93, "", 0, 33, 30, 1, "" }, /* 34*/ { 6, -1, "A", 94, "", ZINT_ERROR_TOO_LONG, -1, -1, 1, "" }, @@ -176,6 +176,7 @@ static void test_input(const testCtx *const p_ctx) { int zxingcpp_cmp; char *comment; }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const 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", 1, 1, "" }, /* 1*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 548: Primary Message empty", 1, 1, "" }, @@ -184,11 +185,11 @@ static void test_input(const testCtx *const p_ctx) { /* 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, 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", 1, 1, "9-digit postcode" }, /* 6*/ { UNICODE_MODE, -1, 2, -1, { 0, 0, "" }, "A", -1, "1234567890123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Primary Message length 16 wrong (7 to 15 only)", 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", 0, 1, "1-digit postcode; BWIPP requires mode" }, - /* 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; BWIPP requires mode" }, + /* 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, 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", 1, 1, "9-digit postcode" }, /* 9*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "1234567890123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Primary Message length 16 wrong (7 to 15 only)", 1, 1, "10-digit postcode" }, /* 10*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A", -1, "123456", ZINT_ERROR_INVALID_DATA, 0, "Error 551: Primary Message length 6 wrong (7 to 15 only)", 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", 0, 1, "8-digit postcode; BWIPP requires mode" }, + /* 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", 1, 1, "8-digit postcode" }, /* 12*/ { UNICODE_MODE, -1, 2, -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", 1, 1, "8-digit postcode" }, /* 13*/ { UNICODE_MODE, -1, 3, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_DATA, 0, "Error 548: Primary Message empty", 1, 1, "" }, /* 14*/ { 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" }, @@ -203,36 +204,51 @@ static void test_input(const testCtx *const p_ctx) { /* 23*/ { 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" }, /* 24*/ { 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" }, /* 25*/ { 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" }, - /* 26*/ { 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; BWIPP requires mode for mode 2" }, + /* 26*/ { 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", 1, 1, "Auto-determine mode 2" }, /* 27*/ { 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" }, /* 28*/ { 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" }, - /* 29*/ { 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, 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", 1, 1, "SCM prefix version" }, /* 30*/ { UNICODE_MODE, -1, -1, 101, { 0, 0, "" }, "A", -1, "123456123456", ZINT_ERROR_INVALID_OPTION, 0, "Error 557: SCM prefix version '101' out of range (1 to 100)", 1, 1, "SCM prefix version" }, - /* 31*/ { 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, "" }, - /* 32*/ { 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" }, - /* 33*/ { 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" }, - /* 34*/ { 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" }, - /* 35*/ { 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" }, - /* 36*/ { 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" }, - /* 37*/ { 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" }, - /* 38*/ { 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" }, - /* 39*/ { 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" }, - /* 40*/ { 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" }, - /* 41*/ { 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" }, - /* 42*/ { UNICODE_MODE, -1, 1, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 550: Mode '1' out of range (2 to 6)", 1, 1, "" }, - /* 43*/ { UNICODE_MODE, -1, 7, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 550: Mode '7' out of range (2 to 6)", 1, 1, "" }, - /* 44*/ { 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" }, - /* 45*/ { 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, "" }, - /* 46*/ { 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, "" }, - /* 47*/ { UNICODE_MODE, -1, -1, -1, { 0, 2, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 559: Structured Append index '0' out of range (1 to count 2)", 1, 1, "" }, - /* 48*/ { UNICODE_MODE, -1, -1, -1, { 1, 1, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 558: Structured Append count '1' out of range (2 to 8)", 1, 1, "" }, - /* 49*/ { UNICODE_MODE, -1, -1, -1, { 1, 9, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 558: Structured Append count '9' out of range (2 to 8)", 1, 1, "" }, - /* 50*/ { UNICODE_MODE, -1, -1, -1, { 3, 2, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 559: Structured Append index '3' out of range (1 to count 2)", 1, 1, "" }, - /* 51*/ { 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, "" }, - /* 52*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "b..A", -1, "", 0, 30, "(144) 04 3F 02 31 38 2E 01 21 21 21 23 2F 04 2C 34 3B 28 25 2C 11 21 21 21 21 21 21 21 21", 0, 1, "BWIPP PR #279 (BWIPP 1 shorter)" }, - /* 53*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A123456789b123456789bbbA", -1, "", 0, 30, "(144) 04 01 1F 07 16 3C 34 15 3B 02 08 28 3C 0E 06 03 34 25 3C 1E 1F 07 16 3C 34 15 3F 02", 0, 1, "BWIPP PR #279 (BWIPP 1 shorter)" }, - /* 54*/ { ESCAPE_MODE, -1, -1, -1, { 0, 0, "" }, "\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192", -1, "", 0, 30, "(144) 04 3C 00 3D 00 3D 00 3D 00 3C 32 10 27 30 09 0B 06 16 3D 0D 00 3D 00 3D 00 3D 00 3C", 0, 1, "BWIPP PR #279 (BWIPP 1 shorter)" }, - /* 55*/ { ESCAPE_MODE, -1, 2, -1, { 0, 0, "" }, "1Z34567890\\GUPSN\\G102562\\G034\\G\\G1/1\\G\\GY\\G2201 Second St\\GFt Myers\\GFL\\R\\E", -1, "339010000840001", 0, 30, "(144) 02 34 21 13 03 15 02 12 07 00 0C 03 00 38 24 04 0B 1F 2F 21 31 1A 33 34 35 36 37 38", 0, 1, "BWIPP different encodation" }, + /* 31*/ { UNICODE_MODE, 25, -1, 96 + 1, { 0, 0, "" }, "A", -1, "123456123456", ZINT_ERROR_INVALID_OPTION, 0, "Error 547: SCM prefix can not be used with ECI 25 (ECI must be ASCII compatible)", 1, 1, "SCM prefix version UTF-16BE" }, + /* 32*/ { UNICODE_MODE, 33, -1, 96 + 1, { 0, 0, "" }, "A", -1, "123456123456", ZINT_ERROR_INVALID_OPTION, 0, "Error 547: SCM prefix can not be used with ECI 33 (ECI must be ASCII compatible)", 1, 1, "SCM prefix version UTF-16LE" }, + /* 33*/ { UNICODE_MODE, 34, -1, 96 + 1, { 0, 0, "" }, "A", -1, "123456123456", ZINT_ERROR_INVALID_OPTION, 0, "Error 547: SCM prefix can not be used with ECI 34 (ECI must be ASCII compatible)", 1, 1, "SCM prefix version UTF-32BE" }, + /* 34*/ { UNICODE_MODE, 35, -1, 96 + 1, { 0, 0, "" }, "A", -1, "123456123456", ZINT_ERROR_INVALID_OPTION, 0, "Error 547: SCM prefix can not be used with ECI 35 (ECI must be ASCII compatible)", 1, 1, "SCM prefix version UTF-32LE" }, + /* 35*/ { UNICODE_MODE, 3, 2, 96 + 1, { 0, 0, "" }, "A", -1, "999999999840333", 0, 30, "(144) 32 3F 09 2B 39 1E 02 12 37 14 2F 1E 03 29 3E 1B 2D 2A 06 20 3B 2A 29 3B 28 1E 30 31", 1, 1, "SCM prefix version ISO/IEC 8859-1" }, + /* 36*/ { UNICODE_MODE, 170, 2, 96 + 1, { 0, 0, "" }, "A", -1, "1234567123456", 0, 30, "(144) 32 21 16 0B 01 30 31 1E 20 1C 13 22 04 28 0E 21 13 1E 3A 14 3B 2A 29 3B 28 1E 30 31", 1, 1, "SCM prefix version ASCII Invariant" }, + /* 37*/ { UNICODE_MODE, 20, 2, 96 + 1, { 0, 0, "" }, "テ", -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 3B 2A 29 3B 28 1E 30 31", 1, 1, "SCM prefix version Shift JIS" }, + /* 38*/ { UNICODE_MODE | ESCAPE_MODE, 3, 2, -1, { 0, 0, "" }, "[)>\\R01\\G96A", -1, "999999999840333", 0, 30, "(144) 32 3F 09 2B 39 1E 02 12 37 14 2F 1E 03 29 3E 1B 2D 2A 06 20 3B 2A 29 3B 28 1E 30 31", 1, 1, "Manual SCM prefix ISO/IEC 8859-1" }, + /* 39*/ { 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, "" }, + /* 40*/ { 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" }, + /* 41*/ { 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" }, + /* 42*/ { 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" }, + /* 43*/ { 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" }, + /* 44*/ { 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" }, + /* 45*/ { 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" }, + /* 46*/ { 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" }, + /* 47*/ { 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" }, + /* 48*/ { 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" }, + /* 49*/ { 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" }, + /* 50*/ { UNICODE_MODE, -1, 1, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 550: Mode '1' out of range (2 to 6)", 1, 1, "" }, + /* 51*/ { UNICODE_MODE, -1, 7, -1, { 0, 0, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 550: Mode '7' out of range (2 to 6)", 1, 1, "" }, + /* 52*/ { 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, 1, "" }, + /* 53*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "\015\034\035\036 ", -1, "", 0, 30, "(144) 04 00 1C 1D 1E 20 21 21 21 21 3E 18 0B 14 22 27 2D 3A 18 22 21 21 21 21 21 21 21 21", 1, 1, "Code Set A" }, + /* 54*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "abc\034\035\036 ,./:", -1, "", 0, 30, "(144) 04 3F 01 02 03 1C 1D 1E 2F 30 21 1F 2B 2A 35 0A 00 10 36 1D 31 32 33 21 21 21 21 21", 1, 1, "Code Set B" }, + /* 55*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "\001\002\003\015\034\035\036 ", -1, "", 0, 30, "(144) 04 3E 3E 01 02 03 0D 20 21 22 3D 0F 31 3A 0C 0C 34 26 27 31 3B 1C 1C 1C 1C 1C 1C 1C", 1, 1, "Code Set E" }, + /* 56*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "ÀÀÀ\034\035\036 ", -1, "", 0, 30, "(144) 04 3C 3C 00 00 00 1C 1D 1E 3B 3C 05 39 07 18 15 25 36 28 11 3A 21 21 21 21 21 21 21", 1, 1, "Code Set C" }, + /* 57*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "ààà\034\035\036 ", -1, "", 0, 30, "(144) 04 3D 3D 00 00 00 1C 1D 1E 3B 06 26 23 19 32 1E 0C 1A 05 11 3A 21 21 21 21 21 21 21", 1, 1, "Code Set D" }, + /* 58*/ { 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, "" }, + /* 59*/ { 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, "" }, + /* 60*/ { UNICODE_MODE, -1, -1, -1, { 0, 2, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 559: Structured Append index '0' out of range (1 to count 2)", 1, 1, "" }, + /* 61*/ { UNICODE_MODE, -1, -1, -1, { 1, 1, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 558: Structured Append count '1' out of range (2 to 8)", 1, 1, "" }, + /* 62*/ { UNICODE_MODE, -1, -1, -1, { 1, 9, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 558: Structured Append count '9' out of range (2 to 8)", 1, 1, "" }, + /* 63*/ { UNICODE_MODE, -1, -1, -1, { 3, 2, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 559: Structured Append index '3' out of range (1 to count 2)", 1, 1, "" }, + /* 64*/ { 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, "" }, + /* 65*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "b..A", -1, "", 0, 30, "(144) 04 3B 02 2E 2E 01 21 21 21 21 11 1C 30 14 2D 3E 16 0E 0C 31 21 21 21 21 21 21 21 21", 1, 1, "" }, + /* 66*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A123456789b123456789bbbA", -1, "", 0, 30, "(144) 04 01 1F 07 16 3C 34 15 3F 02 10 1B 28 22 20 32 37 0C 0B 2A 1F 07 16 3C 34 15 02 02", 1, 1, "" }, + /* 67*/ { ESCAPE_MODE, -1, -1, -1, { 0, 0, "" }, "\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192", -1, "", 0, 30, "(144) 04 3C 00 3D 3D 00 00 00 3C 00 34 39 0E 35 1D 25 00 1B 28 03 00 00 00 3C 00 00 00 00", 1, 1, "BWIPP PR #279" }, + /* 68*/ { ESCAPE_MODE, -1, 2, -1, { 0, 0, "" }, "1Z34567890\\GUPSN\\G102562\\G034\\G\\G1/1\\G\\GY\\G2201 Second St\\GFt Myers\\GFL\\R\\E", -1, "339010000840001", 0, 30, "(144) 02 34 21 13 03 15 02 12 07 00 0C 03 00 38 24 04 0B 1F 2F 21 31 1A 33 34 35 36 37 38", 1, 1, "" }, + /* 69*/ { DATA_MODE | ESCAPE_MODE, -1, -1, -1, { 0, 0, "" }, "ABabcdeAabcdABCabcdABabc\\d192\\d192 \\d192\\d224\\d224\\d028\\d224\\d001\\d001\\d001\\d029\\d00112345678a123456789aABCDa\\d192\\d224\\d001\\d192\\d001\\d224\\d030\\d004", -1, "", 0, 30, "(144) 04 01 02 3F 01 02 03 04 05 3B 25 28 3F 32 0D 10 0D 0F 35 11 01 01 02 03 04 39 01 02", 1, 1, "Exercises all latches & no. of shifts" }, + /* 70*/ { UNICODE_MODE, 1023, 3, 96 + 1, { 2, 3, "" }, "A", -1, "P144275001", 0, 30, "(144) 03 08 08 0D 1D 0C 34 04 05 00 13 29 0C 17 0F 15 2E 38 00 0B 21 0A 3B 2A 29 3B 28 1E", 1, 1, "ECI, Structured Append, SCM" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -371,42 +387,42 @@ static void test_encode(const testCtx *const p_ctx) { "001001101111101101101010011100" "001011000000111101100100001000" }, - /* 1*/ { -1, 4, -1, { 0, 0, "" }, "MaxiCode (19 chars)", -1, "", 0, 33, 30, 0, "ISO/IEC 16023:2000 Figure H1 **NOT SAME** different encodation (figure uses '3 Shift A' among other differences); BWIPP different encodation again", - "001101011111011100000010101111" - "101100010001001100010000000100" - "101100001010001111001001111101" + /* 1*/ { -1, 4, -1, { 0, 0, "" }, "MaxiCode (19 chars)", -1, "", 0, 33, 30, 1, "ISO/IEC 16023:2000 Figure H1 **NOT SAME** different encodation (figure uses '3 Shift A' among other differences)", + "000111011111010000001010110111" + "101101010001110001000000110110" + "101110001010111100100111111011" "010101010101010101010101010100" - "000000000000000000000000000111" - "101010101010101010101010101000" - "010101010101010101010101010111" - "000000000000000000000000000000" + "000000000000000000000000000011" "101010101010101010101010101010" + "010101010101010101010101010111" + "000000000000000000000000000010" + "101010101010101010101010101011" "010101011111111100000001010100" - "000000000011110110001000000000" - "101010101110000000111010101000" - "010101100010000000001101010101" - "000000101000000000001000000000" - "101010000000000000011010101011" + "000000000011110110001000000001" + "101010101110000000111010101010" + "010101100010000000001101010110" + "000000101000000000001000000010" + "101010000000000000011010101001" "010101010000000000001101010110" - "000000001000000000001000000001" + "000000001000000000001000000010" "101010110000000000001010101010" "010101101100000000010101010111" "000000100000000000000000000000" "101010010110000000000110101011" "010101010110000000001001010110" - "000000000110001011000000000001" - "101010100110111001010010101000" - "010101010101010101010001100101" - "000000000000000000001111101000" - "101010101010101010100100001101" - "100011000111000111100000110000" - "011011110010111100011100111111" - "110010110110010000110001100100" - "001111010001000111111010011010" - "010010010101001010100000011010" - "010011010001000101110111100100" + "000000000110001011000000000011" + "101010100110111001010010101010" + "010101010101010101011100100010" + "000000000000000000000000101100" + "101010101010101010101010101101" + "011000111100100001011011100100" + "001010011100001010001111100100" + "111010000011101011110001010100" + "000111001100100000010011000110" + "100000101101100000001000111110" + "011101000100000001001111101001" }, - /* 2*/ { ESCAPE_MODE, 2, 96 + 1, { 0, 0, "" }, "1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G634 ALPHA DR\\GPITTSBURGH\\GPA\\R\\E", -1, "152382802840001", 0, 33, 30, 0, "ISO/IEC 16023:2000 Figure B2 **NOT SAME** uses different encodation (figure precedes PAD chars with Latch B); BWIPP different encodation again", + /* 2*/ { ESCAPE_MODE, 2, 96 + 1, { 0, 0, "" }, "1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G634 ALPHA DR\\GPITTSBURGH\\GPA\\R\\E", -1, "152382802840001", 0, 33, 30, 1, "ISO/IEC 16023:2000 Figure B2 **NOT SAME** uses different encodation (figure precedes PAD chars with Latch B)", "110101110110111110111111101111" "010101010111000011011000010010" "110110110001001010100110010001" @@ -441,7 +457,7 @@ static void test_encode(const testCtx *const p_ctx) { "000111101001100001111000010110" "000100101000110000000111110011" }, - /* 3*/ { ESCAPE_MODE, 2, 96 + 1, { 0, 0, "" }, "1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G634 ALPHA DR\\GPITTSBURGH\\GPA\\R\\E", -1, "15238840001", 0, 33, 30, 0, "OkapiBarcode zero-pad postcode lacking +4 (US 840 only), ISO/IEC 16023:2000 Annex B.1.4a; BWIPP different encodation", + /* 3*/ { ESCAPE_MODE, 2, 96 + 1, { 0, 0, "" }, "1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G634 ALPHA DR\\GPITTSBURGH\\GPA\\R\\E", -1, "15238840001", 0, 33, 30, 1, "OkapiBarcode zero-pad postcode lacking +4 (US 840 only), ISO/IEC 16023:2000 Annex B.1.4a", "110101110110111110111111101111" "010101010111000011011000010010" "110110110001001010100110010001" @@ -511,77 +527,77 @@ static void test_encode(const testCtx *const p_ctx) { "010010001001110010000101000010" "010001011010000011010010011100" }, - /* 5*/ { UNICODE_MODE | ESCAPE_MODE, -1, -1, { 0, 0, "" }, "Comité Européen de Normalisation\034rue de Stassart 36\034B-1050 BRUXELLES\034TEL +3225196811", -1, "", 0, 33, 30, 0, "ISO/IEC 16023:2000 Example F.5 **NOT SAME** uses different encodation (2 Shift A among other things); BWIPP different encodation again", - "010010100010110000000100001111" - "001010001100110110111110100110" - "001010011100101010011100100000" - "000000100010000000001000000110" - "111101100000011100110011110001" - "011110001011100010100111010010" - "101010000100001101101000101001" - "110010101110100100001000000000" - "000110101100100000110010111110" - "111101111111111000110110100000" - "100000111001111010010010000011" - "011100111100000000101100011010" - "100001101110000000101111111101" - "110011000100000000111100001010" - "000110010000000000010110001010" + /* 5*/ { UNICODE_MODE | ESCAPE_MODE, -1, -1, { 0, 0, "" }, "Comité Européen de Normalisation\034rue de Stassart 36\034B-1050 BRUXELLES\034TEL +3225196811", -1, "", 0, 33, 30, 1, "ISO/IEC 16023:2000 Example F.5 **NOT SAME** uses different encodation (2 Shift A among other things)", + "110010100010110000000100000111" + "011010001100110110111110101100" + "111010011100101010011100101101" + "000000100010000000001000001100" + "111101100000011100110011110110" + "011110001011100010100111011110" + "101010000100000111101000101010" + "110010101110101101001000000010" + "000110101100101111110010111111" + "111101111011111000111110100000" + "100000110101111010011110000000" + "011100110100000000101100011000" + "100001000110000000101011111100" + "110011101100000000111000001000" + "000110111100000000011010001011" "101010010000000000001000011100" - "011000001000000000001000000010" - "001001010000000000001101000000" - "000000010000000000010100101000" - "101111110100000000011110001100" - "100000000010000000011010110011" - "101001010010000001011100001010" - "001101000010001011110111101010" - "111111001010000001100100100000" - "001000001101010101010010111001" - "111001000000000000001010100000" - "010001101010101010101010110001" - "011011000011100001011001101100" - "101100000001111010000001100011" - "110001001100011100110111011010" - "011110010010101101110100000100" - "001011110011100001001001101100" - "000010111011111010110011000011" + "011000001000000000001000000000" + "001001010000000000001101000010" + "000000100100000000010000101010" + "101111101100000000010010001110" + "100000101110000000011110110000" + "101101011010000001110000001010" + "110001000110001011000111101001" + "111111000110000001110000100010" + "001000010001010101010111010000" + "110100110100000000000010001010" + "101111001110101010101101100111" + "011010000110010001100100101010" + "011100000011000100100111111110" + "010100011110011011111011000100" + "000000100010100101010010010010" + "001111010001110000011001100110" + "000100001011101000111010000010" }, - /* 6*/ { -1, -1, -1, { 0, 0, "" }, "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", -1, "", 0, 33, 30, 0, "Numeric compaction, verified manually against TEC-IT; BWIPP different encodation", - "010111101101010111101101010111" - "111011110110111011110110111010" - "001111111101001111111101001100" - "101101010111101101010111101100" - "111110111001111110111001111100" - "111111000111111111000111111110" - "110101011110110101011110110110" - "011011101111011011101111011000" - "110100111111110100111111110101" - "010111101111111100110111010100" - "111001111011011110011111101100" - "000111111110000000111011110000" - "011110100110000000000111010101" - "101111001000000000110101101110" - "111111110100000000000011010001" - "010111111000000000001110110110" - "111001101000000000001011111001" - "000111010000000000001011111100" - "011110011000000000011011010101" - "101111000100000000010001101100" - "111111100110000000100111010010" - "010101110100000001010110110110" - "101110011010101111111011111011" - "110001110111110101111011111110" - "111011010101111111110000111011" - "111101101110110101010001001000" - "111111010011111010101111110011" - "000101011000111100010001000010" - "011110001101100001011010110010" - "101110000100010011000001001000" - "100000001010110100100110001100" - "111010101011001101111001011010" - "011110011111000011101011111011" + /* 6*/ { -1, -1, -1, { 0, 0, "" }, "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", -1, "", 0, 33, 30, 1, "Numeric compaction, verified manually against TEC-IT", + "101101010111101101010111101111" + "110110111011110110111011110100" + "111101001111111101001111111100" + "010111101101010111101101010110" + "111001111110111001111110111000" + "000111111111000111111111000110" + "011110110101011110110101011111" + "101111011011101111011011101100" + "111111110100111111110100111101" + "101101011111110100101001111010" + "111110111111011010010110011111" + "111111000000000000000101111100" + "110101001100000000110001111010" + "011011101100000000001110111100" + "110100101100000000010111111110" + "101101111000000000001101011110" + "111110001000000000001011100100" + "111111101000000000001100011110" + "110101111000000000011001111000" + "011011001100000000111010111110" + "110100110110000000111011111110" + "111011010010000000100101011100" + "011111101110111111111011100101" + "111111110110011001111000011100" + "010101111011010101111010001110" + "101110111101101110110110000000" + "010011111111010011110011000000" + "101010001001110111000101100100" + "110111101010011001100011111000" + "111000110011011001001101000110" + "111010010010001000101000010101" + "101111000100011110110011011100" + "011111000110100011001101000000" }, - /* 7*/ { -1, 5, -1, { 0, 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\037\237\240\242\243\244\245\246\247\251\255\256\266\225\226\227\230\231\232\233\234\235\236", 51, "", 0, 33, 30, 0, "Mode 5 set E; BWIPP different encodation", + /* 7*/ { -1, 5, -1, { 0, 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\037\237\240\242\243\244\245\246\247\251\255\256\266\225\226\227\230\231\232\233\234\235\236", 51, "", 0, 33, 30, 1, "Mode 5 set E", "000000000000000000101010101011" "100101010111111111000000001000" "110010011100100111001001110011" @@ -721,40 +737,40 @@ static void test_encode(const testCtx *const p_ctx) { "100100110011010101001011100100" "001000101111010000111000010101" }, - /* 11*/ { UNICODE_MODE | ESCAPE_MODE, 4, -1, { 0, 0, "" }, "\\rABCDEFGHIJKLMNOPQRSTUVWXYZ\034\\G\\R \"#$%&'()*+,-./0123456789:", -1, "", 0, 33, 30, 0, "Mode 4 Set A; BWIPP different encodation", + /* 11*/ { UNICODE_MODE | ESCAPE_MODE, 4, -1, { 0, 0, "" }, "\\rABCDEFGHIJKLMNOPQRSTUVWXYZ\034\\G\\R \"#$%&'()*+,-./0123456789:", -1, "", 0, 33, 30, 1, "Mode 4 Set A", "000000000000001010101010101011" "010101111111110000000010101010" "100111001001110010011100100101" - "010101010101011010101010101010" + "010101010101011010101010101000" "101010100000001111110101011011" - "110110001101000110000110001110" - "010101010101010110000100000011" - "010101011111111111001110101100" - "001001110010011111001101100110" - "010101010011000000000001111100" - "000000001001001010010100010100" + "110110001101000110000110001100" + "010101010101010111100010111101" + "010101011111111100111010111000" + "001001110010011100111101000000" + "010101010011000000000001111000" + "000000001001001010010100011001" "101010100010000000010010011010" - "010101000000000000000001010100" - "000000110100000000100100000000" - "101010110000000000001010101011" - "010101010000000000001101010100" - "000000001000000000001000000010" + "010101000000000000000001010111" + "000000110100000000100100000010" + "101010110000000000001010101001" + "010101010000000000001101010110" + "000000001000000000001000000000" "101010100000000000001010101000" "010101001100000000001101010100" "000000111000000000101100000000" "101010000010000000011110101001" "010101010000000000100101010110" - "000000001110000001101000000001" + "000000001110000001101000000000" "101010100011000001001110101000" - "010101010101010101010011100001" - "000000000000000000000100010110" - "101010101010101010100100011110" - "101100000000000010001010010000" - "110010011000011000011011011001" - "111000110101100100110110101000" - "001001100010110011111101010101" - "110111010000000001010000100110" - "101001001010011101111100111011" + "010101010101010101011100010100" + "000000000000000000001011000100" + "101010101010101010101011110001" + "100101110110110010101111111100" + "101101011111001110100110100100" + "010001101100100011100111010100" + "010000101010001111010111011001" + "010010011001101010010001111100" + "100111100111001110011000011011" }, /* 12*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "ABCDabcdAabcABabcABCabcABCDaABCabABCabcABCéa", -1, "", 0, 33, 30, 1, "Mode 4 LCHB SHA 2SHA 3SHA LCHA SHB LCHB 3SHA 3SHA SHD", "110000000011000000000011000011" @@ -931,7 +947,7 @@ static void test_encode(const testCtx *const p_ctx) { "010110101111010110101010111100" "010100000000010110101010010100" }, - /* 17*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "¢£¤¥123456789", -1, "", 0, 33, 30, 0, "Mode 4 LCKE NS; BWIPP different encodation (1 codeword longer)", + /* 17*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "¢£¤¥123456789", -1, "", 0, 33, 30, 1, "Mode 4 LCKE NS", "111110101010101010101010101011" "111010111111111111111111111100" "000010000000000000000000000011" @@ -966,19 +982,19 @@ static void test_encode(const testCtx *const p_ctx) { "011100101001010011011100111100" "101101110111011101011010011101" }, - /* 18*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "ABCDE12abcde1ÀÁÂ⣤¥1àáâãabcde123A123456789àáâ㢣¤¥abc", -1, "", 0, 33, 30, 0, "Mode 4 mixed sets; BWIPP different encodation", + /* 18*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "ABCDE12abcde1ÀÁÂ⣤¥1àáâãabcde123A123456789àáâ㢣¤¥abc", -1, "", 0, 33, 30, 1, "Mode 4 mixed sets", "000000001111111100000000111111" - "000010100100111100000000111100" - "011100101110000000100111010100" + "000010101100111100000000111100" + "011100101110000000100111010111" "001100000000111111110101010110" - "001100000000111100010101101001" + "001100000000111100010101101010" "101111011000101010011000110110" "000000001111111100100010111110" "000010101100000000111010111000" "011100101110011110111101000010" "000000001011001100010111111010" "000000000001000010000111111000" - "110110001110000000011110101010" + "110110001110000000011110101000" "111101000010000000001101010101" "111110110000000000100110010100" "010101101000000000010111001001" @@ -986,20 +1002,20 @@ static void test_encode(const testCtx *const p_ctx) { "000000101000000000001000001110" "101011110000000000001101101110" "010101101000000000000001010101" - "000000000100000000010000000000" - "101010100000000000000110101000" + "000000000100000000010000000010" + "101010100000000000000110101001" "010101010100000000000101010100" "000000001010001011100000000011" "101010101011000001011010101000" - "010101010101010101010101001001" - "000000000000000000000010100000" - "101010101010101010101111110001" - "001110011111110100100011111000" - "011001101011100100010000010101" - "010000011110010110000011110010" - "110111100111000100111111001011" - "100011000001110011101110101000" - "001001110010111101100100010001" + "010101010101010101011001101001" + "000000000000000000001010110000" + "101010101010101010100111000000" + "001010111101110100110011111010" + "011101101010101100110000010101" + "011100101111011110010010111010" + "100101101011010111110011101011" + "100010001001110010101010111000" + "111010110110001100101000010001" }, /* 19*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789MNO123456789", -1, "", 0, 33, 30, 1, "Mode 4 spaced NSs", "001011111000100010111110001011" @@ -1106,6 +1122,41 @@ static void test_encode(const testCtx *const p_ctx) { "011111110000111010001010001100" "110010001001001011011111100111" }, + /* 22*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, "am.//ab,\034TA# z\015!", -1, "", 0, 33, 30, 1, "Was test_best_supported_set", + "101110000101101100110101010111" + "110110000011010100100000000010" + "001000101111011100101010101010" + "010101010101010101010101010110" + "000000000000000000000000000001" + "101010101010101010101010101010" + "010101010101010101010101010100" + "000000000000000000000000000010" + "101010101010101010101010101011" + "010101010111001100000101010110" + "000000001011000010000000000001" + "101010101100000000100110101010" + "010101001100000000101101010110" + "000000100000000000010000000010" + "101010110000000000010010101011" + "010101011000000000000101010100" + "000000001000000000001000000000" + "101010001000000000001010101000" + "010101010000000000001101010101" + "000000001100000000000000000010" + "101010110010000000010110101011" + "010101010100000001111001010110" + "000000001110110111111100000000" + "101010100110111101011010101000" + "010101010101010101011101100010" + "000000000000000000000101101000" + "101010101010101010100011011000" + "000000100000111000011101111100" + "110001011111000111110010001000" + "001011000001011000000110100000" + "110010000110011010101100011010" + "011011001001000010000110011100" + "000010111111111111001110001110" + }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -1345,40 +1396,40 @@ static void test_encode_segs(const testCtx *const p_ctx) { "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); BWIPP different encodation, same codeword count", - "011100110111111101000011011111" - "001000110000000100100001101000" - "000010110010010000110101000010" - "110000100011101010111101111100" - "011110010111001101100111010010" - "000010001011001011111001101100" - "011100110111111101000011110111" - "001000110000000100100001111000" - "000010110010010000110101011110" - "011111110011001000000111011100" - "110110000101000110011000011110" - "011000100000000000101011000100" - "111110101110000000011110101100" - "100101100100000000001100001100" - "111011100000000000000110001101" + /* 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, 1, "AIM ITS/04-023:2022 Annex A example (shortened)", + "011111000111111101000011011111" + "001001000000000100100001101010" + "000011100010010000110101000001" + "110000100011101010111101111110" + "111110010111001101100111010000" + "110010001011001011111001101110" + "011111000111111101000011110110" + "001001000000000100100001111000" + "000011100010010000110101011100" + "011111111011001000000111011110" + "110110000101000110011000011100" + "011000101100000000100011000100" + "111110001110000000011010101110" + "100101101100000000001000001110" + "111011001100000000001110001100" "011100010000000000000000100010" - "000111001000000000001010010110" - "000000110000000000001010001010" - "110011010100000000011001111111" - "100011101100000000111000000000" - "001011100010000000011000100100" - "111111000010000001111000011110" - "101001000110101011100010000110" - "000001010110011101000111000010" - "110111110111010101010010100001" - "101101000011010000000001011000" - "000010000001001010100100111001" - "101010010101100010111000111000" - "000111001101011101010101101000" - "110111101110001101100111010100" - "101000010100101000011010011110" - "100000110001100001110001101000" - "010000101110100111010101100101" + "001111001000000000001010010111" + "001100110000000000001010001000" + "111100011100000000011001111110" + "100100110000000000110100000010" + "001110000110000000011100100110" + "111111001110000001011000011100" + "101001000110101011001110000100" + "000001010110011101111011000000" + "110111110111010101011111010000" + "101101000011010000000101101100" + "000010000001001010100001001111" + "001010001101110010110101001000" + "111110111100101100111101000110" + "010000000001111110111001010000" + "110101000010011011010111000110" + "100010110010010000000010010100" + "100011010011101111001011000001" }, /* 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" @@ -1415,112 +1466,112 @@ static void test_encode_segs(const testCtx *const p_ctx) { "010111011011100000011000101000" "001111010010000100010110011110" }, - /* 6*/ { DATA_MODE, -1, -1, { 0, 0, "" }, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, "", 0, 33, 30, 0, "Standard example + extra seg, data mode; BWIPP different encodation", - "010101010101010101010101010111" - "110000000000000000000000000010" - "111010101010101010101010101011" - "010101010101010101010101010110" + /* 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", + "101010101010101010101010101011" + "111111111111111111111111111100" + "000000000000000000000000000011" + "101010101010101010101010101010" + "111111111111111111111111111111" "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" + "101010101010101010101010101011" + "111111111111111111111111111110" + "000000000000000000000000000011" + "101010100011110100111010101000" + "111111110011111110000011111111" + "000000001110000000111000000010" + "101010110110000000101110101010" + "111111111100000000110011111100" + "000000001100000000010100000011" + "101010010000000000001110101010" + "111111001000000000001011111110" + "000000000000000000001000000010" + "101010101000000000010010101001" + "111111110100000000100011111110" + "000000110000000000111100000010" + "101010100100000001110110101010" + "111111111110111101101111111101" + "000000000011111001100100000010" + "101010101010101010101010010110" + "111111111111111111110101111110" + "000000000000000000000101101010" + "000001010101000010100101111110" + "101001011111101011111010000010" + "111111110000101011110101101010" + "000000001111111101011111000010" + "111100001111010101010101111110" + "000010100101010111111010101010" }, - /* 7*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("αβ"), -1, 0 }, { TU("ÿ"), -1, 0 }, { TU("貫やぐ禁"), -1, 20 } }, "", ZINT_WARN_USES_ECI, 33, 30, 0, "Auto-ECI; BWIPP different encodation", - "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, 0, "Structured Append; BWIPP different encodation", - "001101101011011110111111001111" - "001110011011111100110011001110" - "111000110010110010000110010011" - "010101010101011011111101111110" - "000000000000001011001111110011" - "101010101010100100001001010100" - "010101010101010101010101010111" + /* 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", + "101001111110111100111101111111" + "011011111100001100001111110010" + "110011000010011001010101100010" + "010101010101010101010101111000" + "000000000000000000000000011010" + "101010101010101010101010010100" + "010101010101010101010101010101" "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" + "010101010111000000110101010110" + "000000001011010010000000000000" + "101010100000000000111010101000" + "010101100100000000110101010111" + "000000011000000000011100000000" + "101010010000000000010010101010" + "010101010000000000001101010110" + "000000001000000000001000000011" + "101010000000000000001010101010" + "010101100000000000010001010100" + "000000000000000000010100000010" + "101010110010000000110010101000" + "010101011000000001001001010110" + "000000000010101011101100000000" + "101010100010011101101110101000" + "010101010101010101011111011101" + "000000000000000000000110001000" + "101010101010101010100100010011" + "001001001011101100110001101010" + "100011101101100100001001100101" + "110000000110011111100001111000" + "000011110000100000101100001100" + "101111001101000010111111110000" + "001001000010100001000011101011" }, - /* 9*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("ab"), -1, 3 }, { TU("ABCD"), -1, 4 }, { TU(""), 0, 0 } }, "", 0, 33, 30, 0, "Code Set B then A; BWIPP different encodation", + /* 8*/ { UNICODE_MODE, -1, -1, { 1, 2, "" }, { { TU("αβ"), -1, 9 }, { TU("ÿ"), -1, 3 }, { TU("貫やぐ禁"), -1, 20 } }, "", 0, 33, 30, 1, "Structured Append", + "000110100111111011110011110111" + "001001101111110000110000111100" + "110011001100001001100101010101" + "010101010101010101011110111110" + "000000000000000000000110001101" + "101010101010101010100101001010" + "010101010101010101010101010111" + "000000000000000000000000000010" + "101010101010101010101010101000" + "010101010011001100000001010110" + "000000000101001110001000000011" + "101010101010000000101110101000" + "010101111000000000110001010101" + "000000110100000000100000000010" + "101010001100000000011010101011" + "010101011000000000000101010100" + "000000001000000000001000000010" + "101010001000000000001010101000" + "010101100000000000011101010110" + "000000001000000000001000000010" + "101010101110000000011010101001" + "010101010110000000010101010110" + "000000001110011011011000000010" + "101010100011000001100010101010" + "010101010101010101011010110111" + "000000000000000000001111011010" + "101010101010101010101101010010" + "111001010001101011001010011100" + "001101001101101110010010110011" + "101000100011001111100000101000" + "100000000110100010001110000100" + "101000101011101111110001101000" + "000010101010000010000100110100" + }, + /* 9*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("ab"), -1, 3 }, { TU("ABCD"), -1, 4 }, { TU(""), 0, 0 } }, "", 0, 33, 30, 1, "Code Set B then A", "000000010101010101010101010111" "000010000000000000000000000010" "011100101010101010101010101001" @@ -1530,21 +1581,21 @@ static void test_encode_segs(const testCtx *const p_ctx) { "010101010101010101010101010100" "000000000000000000000000000000" "101010101010101010101010101011" - "010101010111001000000001010100" - "000000000111000110010000000000" - "101010100010000000001010101010" - "010101010010000000110001010110" - "000000110000000000110100000010" - "101010001000000000011110101011" - "010101110000000000001101010110" - "000000101000000000001000000001" - "101010110000000000001010101000" - "010101001100000000000101010101" - "000000101100000000000000000010" - "101010011010000000110110101001" - "010101010000000001111101010100" - "000000001010100111000100000010" - "101010101010010001001110101010" + "010101010111000000110001010100" + "000000001011000010000100000000" + "101010100000000000111110101010" + "010101110010000000111001010110" + "000000000000000000101000000010" + "101010011000000000010110101011" + "010101011000000000000001010110" + "000000001000000000001000000001" + "101010101000000000001010101000" + "010101000000000000001001010101" + "000000001000000000001100000010" + "101010001110000000111010101001" + "010101010010000001111101010100" + "000000000110101111011000000010" + "101010101010010001101010101010" "010101010101010101011110000100" "000000000000000000001100111010" "101010101010101010101100000000" @@ -1555,7 +1606,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { "011011011101010101001101001000" "001010010110100000100111101000" }, - /* 10*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("\004\004\004\004"), -1, 3 }, { TU("ABCD"), -1, 4 }, { TU("abcd"), -1, 5 } }, "", 0, 33, 30, 0, "Code Set E then A then B; BWIPP different encodation", + /* 10*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("\004\004\004\004"), -1, 3 }, { TU("ABCD"), -1, 4 }, { TU("abcd"), -1, 5 } }, "", 0, 33, 30, 0, "Code Set E then A then B; BWIPP different encodation, LCHA before 2nd ECI not after, same codeword count, same result", "001100000000100011000000000111" "100100000010011011000000100000" "000110011100111011100111001010" @@ -1590,6 +1641,111 @@ static void test_encode_segs(const testCtx *const p_ctx) { "111010100101000101001011011000" "011111000111001010010000111100" }, + /* 11*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("12345678"), -1, 3 }, { TU("91234567901"), -1, 4 }, { TU("12345678"), -1, 5 } }, "", 0, 33, 30, 1, "Digits spanning ECIs", + "111000111110001111011010001111" + "010110010011111100001101100010" + "001100101011100111111011101001" + "010101010101011111111111111110" + "000000000000000110101010000010" + "101010101010100011011000110110" + "010101010101010101010101010111" + "000000000000000000000000000010" + "101010101010101010101010101001" + "010101011111001100010001010100" + "000000000001001010011000000010" + "101010100000000000101010101000" + "010101011110000000011001010110" + "000000011000000000001100000010" + "101010101100000000011110101010" + "010101111000000000000101010100" + "000000101000000000001000000000" + "101010101000000000001110101000" + "010101010100000000000101010110" + "000000001100000000100000000000" + "101010001110000000101110101001" + "010101011100000001010101010110" + "000000001010101111111000000011" + "101010101010011101101110101000" + "010101010101010101011010001010" + "000000000000000000000110111110" + "101010101010101010100011111111" + "011111100011010101000000000110" + "111111010001111000000100101010" + "011101100000010110110001000100" + "101110111111001001111001110000" + "010101101100001010110111001100" + "101011011010100110010010100111" + }, + /* 12*/ { UNICODE_MODE, -1, 96 + 1, { 0, 0, "" }, { { TU("12345678"), -1, 3 }, { TU("91234567901"), -1, 4 }, { TU("12345678"), -1, 5 } }, "9999840012", 0, 33, 30, 1, "SCM prefix mode 2", + "110101110110111110111110001111" + "010101010111000011011001000000" + "110110110001001010100111111001" + "110010111100101111111111111110" + "111111000110010110101010000010" + "011011101000110011011000110100" + "110110100011111111111111110100" + "000011011000000010101010010010" + "111110111010011100100111001001" + "010101010011010000011101010110" + "000000000001100000000100000001" + "101010101110000001011010101000" + "010101100010000000000001010100" + "000000100000000000001000000000" + "101010110000000000001110101000" + "010101110000000000011101010110" + "000000101000000000001000000011" + "101010000000000000011010101010" + "010101011100000000000101010110" + "000000111000000000000100000010" + "101010100110000000001010101011" + "010101011000000001101101010100" + "000000001010000011010100000010" + "101010100110000001010110101000" + "010101010101010101010010100111" + "000000000000000000001111100100" + "101010101010101010100000011011" + "001001001110011001111101100010" + "110000110000100111010010101000" + "110001111010010001001101000010" + "100110000010010001101011000111" + "110011010111010010100011101000" + "111010011111011100110001010110" + }, + /* 13*/ { UNICODE_MODE, 3, 96 + 1, { 0, 0, "" }, { { TU("12345678"), -1, 3 }, { TU("91234567901"), -1, 4 }, { TU("12345678"), -1, 5 } }, "B999840012", 0, 33, 30, 1, "SCM prefix mode 3", + "110101110110111110111110001111" + "010101010111000011011001000000" + "110110110001001010100111111001" + "110010111100101111111111111110" + "111111000110010110101010000010" + "011011101000110011011000110100" + "110110100011111111111111110100" + "000011011000000010101010010010" + "111110111010011100100111001001" + "010101011011100000011101010110" + "000000000101010000001000000001" + "101010100100000011011010101000" + "010101000000000000110001010100" + "000000100000000000110000000000" + "101010000000000000000110101000" + "010101111000000000001101010110" + "000000101000000000001000000011" + "101010000000000000001010101010" + "010101100100000000010101010110" + "000000101000000000110100000010" + "101010110100000000001110101011" + "010101011110000000001001010100" + "000000000010000101110100000010" + "101010100111011001110010101000" + "010101010101010101010010100111" + "000000000000000000001111100100" + "101010101010101010100000011011" + "001001001110011001111101100010" + "110000110000100111010010101000" + "110001111010010001001101000010" + "100110000010010001101011000111" + "110011010111010010100011101000" + "111010011111011100110001010110" + }, }; const int data_size = ARRAY_SIZE(data); int i, j, seg_count, ret; @@ -1651,7 +1807,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { 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)); + ret = testUtilBwippSegs(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].segs, seg_count, data[i].primary, 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); @@ -1688,121 +1844,6 @@ static void test_encode_segs(const testCtx *const p_ctx) { testFinish(); } -static void test_best_supported_set(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - char *data; - int ret; - float w; - float h; - int ret_vector; - - int expected_rows; - int expected_width; - char *comment; - char *expected; - }; - static const struct item data[] = { - /* 0*/ { "am.//ab,\034TA# z\015!", 0, 100, 100, 0, 33, 30, "Different encodation than BWIPP, same number of codewords", - "111010000101111000111101010111" - "111110000000010100011000000000" - "110000101100110100111010101011" - "010101010101010101010101010100" - "000000000000000000000000000000" - "101010101010101010101010101010" - "010101010101010101010101010110" - "000000000000000000000000000010" - "101010101010101010101010101011" - "010101010111001100000101010110" - "000000001011000010000000000010" - "101010101100000000100110101010" - "010101001100000000101101010101" - "000000100000000000010000000010" - "101010110000000000010010101011" - "010101011000000000000101010110" - "000000001000000000001000000011" - "101010001000000000001010101000" - "010101010000000000001101010101" - "000000001100000000000000000010" - "101010110010000000010110101010" - "010101010100000001111001010110" - "000000001110110111111100000000" - "101010100110111101011010101000" - "010101010101010101010001100011" - "000000000000000000001110101000" - "101010101010101010100010100010" - "011000001001000010001111100000" - "110111111010111010011000001100" - "001011000101101010100000110110" - "110001100010100101010101001101" - "111000100110000011001110001100" - "011100101001111011111001111100" - }, - }; - const int data_size = ARRAY_SIZE(data); - int i, length, ret; - struct zint_symbol *symbol = NULL; - - 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 */ - - testStartSymbol("test_best_supported_set", &symbol); - - for (i = 0; i < data_size; i++) { - - if (testContinue(p_ctx, i)) continue; - - symbol = ZBarcode_Create(); - assert_nonnull(symbol, "Symbol not created\n"); - - length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, -1 /*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); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret); - - if (p_ctx->generate) { - printf(" /*%2d*/ { \"%s\", %d, %.0f, %.0f, %d, %d, %d, \"%s\",\n", - i, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), ret, - data[i].w, data[i].h, data[i].ret_vector, symbol->rows, symbol->width, data[i].comment); - testUtilModulesPrint(symbol, " ", "\n"); - printf(" },\n"); - } else { - 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); - - ret = ZBarcode_Buffer_Vector(symbol, 0); - assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d\n", i, ret, data[i].ret_vector); - - if (ret < ZINT_ERROR) { - if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { - 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); - } - - testFinish(); -} - /* #181 Nico Gunkel OSS-Fuzz */ static void test_fuzz(const testCtx *const p_ctx) { int debug = p_ctx->debug; @@ -1848,7 +1889,9 @@ static void test_fuzz(const testCtx *const p_ctx) { #include -#define TEST_PERF_ITERATIONS 1000 +#define TEST_PERF_ITER_MILLES 10 +#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000) +#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC) /* Not a real test, just performance indicator */ static void test_perf(const testCtx *const p_ctx) { @@ -1871,25 +1914,45 @@ static void test_perf(const testCtx *const p_ctx) { /* 0*/ { BARCODE_MAXICODE, UNICODE_MODE | ESCAPE_MODE, -1, -1, "1Z34567890\\GUPSN\\G102562\\G034\\G\\G1/1\\G\\GY\\G2201 Second St\\GFt Myers\\GFL\\R\\E", "339010000840001", 0, 33, 30, "Mode 2" }, + /* 1*/ { BARCODE_MAXICODE, UNICODE_MODE, 4, -1, "MaxiCode (19 chars)", "", 0, 33, 30, "Mode 4 small" }, + /* 2*/ { BARCODE_MAXICODE, DATA_MODE | ESCAPE_MODE, 4, -1, "ABCDabcdAabcABabcABCabcABCDaABCabABCabcABC\\d233a", "", 0, 33, 30, "Mode 4 medium" }, + /* 3*/ { BARCODE_MAXICODE, DATA_MODE | ESCAPE_MODE, 4, -1, + "ABabcdeAabcdABCabcdABabc\\d192\\d192 \\d192\\d224\\d224\\d028\\d224\\d001\\d001\\d001\\d029\\d00112345678a123456789aABCDa\\d192\\d224\\d001\\d192\\d001\\d224\\d030\\d004", + "", 0, 33, 30, "Mode 4 latches" }, + /* 4*/ { BARCODE_MAXICODE, UNICODE_MODE, 4, -1, + "THIS IS A 93 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, UNAPPENDED, MAXICODE SYMBOL...", "", 0, 33, 30, "Mode 4 txt max" }, + /* 5*/ { BARCODE_MAXICODE, UNICODE_MODE, 4, -1, + "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", + "", 0, 33, 30, "Mode 4 num max" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; + struct zint_symbol *symbol; - clock_t start, total_encode = 0, total_buffer = 0, diff_encode, diff_buffer; + clock_t start; + clock_t total_create = 0, total_encode = 0, total_buffer = 0; + clock_t diff_create, diff_encode, diff_buffer; + int comment_max = 0; if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ return; } + for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment); + + printf("Iterations %d\n", TEST_PERF_ITERATIONS); + for (i = 0; i < data_size; i++) { int j; if (testContinue(p_ctx, i)) continue; - diff_encode = diff_buffer = 0; + diff_create = diff_encode = diff_buffer = 0; for (j = 0; j < TEST_PERF_ITERATIONS; j++) { - struct zint_symbol *symbol = ZBarcode_Create(); + start = clock(); + symbol = ZBarcode_Create(); + diff_create += clock() - start; assert_nonnull(symbol, "Symbol not created\n"); length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug); @@ -1903,21 +1966,26 @@ static void test_perf(const testCtx *const p_ctx) { assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, 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); + #if 0 start = clock(); ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/); diff_buffer += clock() - start; assert_zero(ret, "i:%d ZBarcode_Buffer ret %d != 0 (%s)\n", i, ret, symbol->errtxt); + #endif ZBarcode_Delete(symbol); } - printf("%s: diff_encode %gms, diff_buffer %gms\n", data[i].comment, diff_encode * 1000.0 / CLOCKS_PER_SEC, diff_buffer * 1000.0 / CLOCKS_PER_SEC); + printf("%*s: encode % 8gms, buffer % 8gms, create % 8gms\n", comment_max, data[i].comment, + TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_create)); + total_create += diff_create; total_encode += diff_encode; total_buffer += diff_buffer; } - if (p_ctx->index != -1) { - printf("totals: encode %gms, buffer %gms\n", total_encode * 1000.0 / CLOCKS_PER_SEC, total_buffer * 1000.0 / CLOCKS_PER_SEC); + if (p_ctx->index == -1) { + printf("%*s: encode % 8gms, buffer % 8gms, create % 8gms\n", comment_max, "totals", + TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_create)); } } @@ -1928,7 +1996,6 @@ int main(int argc, char *argv[]) { { "test_input", test_input }, { "test_encode", test_encode }, { "test_encode_segs", test_encode_segs }, - { "test_best_supported_set", test_best_supported_set }, { "test_fuzz", test_fuzz }, { "test_perf", test_perf }, }; diff --git a/backend/tests/test_reedsol.c b/backend/tests/test_reedsol.c index 6c7b6511..ed7b1dc9 100644 --- a/backend/tests/test_reedsol.c +++ b/backend/tests/test_reedsol.c @@ -124,25 +124,25 @@ static void test_encoding(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { 0x43, 4, 1, 7, { 4, 20, 49, 37, 49, 38, 23 }, { 54, 17, 53, 58 } }, /* AUSPOST Australia Post Customer Barcoding Technical Specifications Diagram 10 */ - /* 1*/ { 0x43, 7, 1, 10, { 9, 50, 1, 41, 47, 2, 39, 37, 1, 27 }, { 38, 50, 8, 16, 10, 20, 40 } }, /* AZTEC ISO/IEC 24778:2008 Section G.4 */ - /* 2*/ { 0x13, 5, 1, 2, { 0, 9 }, { 12, 2, 3, 1, 9 } }, /* AZTEC ISO/IEC 24778:2008 Section G.4 Mode Message */ - /* 3*/ { 0x12d, 5, 1, 3, { 142, 164, 186 }, { 114, 25, 5, 88, 102 } }, /* DATAMATRIX ISO/IEC 16022:2006 Annex O */ - /* 4*/ { 0x89, 25, 1, 25, { 42, 13, 54, 39, 124, 91, 121, 65, 28, 40, 95, 48, 0, 126, 0, 126, 0, 126, 0, 126, 0, 126, 0, 126, 0 }, { 123, 47, 2, 20, 54, 112, 35, 23, 100, 89, 55, 17, 101, 4, 14, 33, 48, 62, 98, 52, 2, 79, 92, 70, 102 } }, /* GRIDMATRIX AIMD014 Section 6.8 */ - /* 5*/ { 0x163, 4, 1, 21, { 0x11, 0xED, 0xC8, 0xC5, 0x40, 0x0F, 0xF4 }, { 0xEB, 0xB4, 0x68, 0x1D } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.1 */ - /* 6*/ { 0x163, 24, 1, 27, { 0x11, 0xED, 0xC8, 0xC5, 0x40, 0x0F, 0xF4, 0x8A, 0x2C, 0xC3, 0x4E, 0x3D, 0x09, 0x25, 0x9A, 0x7A, 0x29, 0xAB, 0xEA, 0x3E, 0x46, 0x4C, 0x7E, 0x73, 0xE8, 0x6C, 0xC7 }, { 0x08, 0x57, 0x0C, 0xE0, 0x7A, 0xA5, 0xDD, 0xA2, 0x99, 0xCF, 0xA4, 0x82, 0xAD, 0x11, 0xB0, 0x84, 0x74, 0x5D, 0x9A, 0x99, 0x0B, 0xCD, 0x49, 0x77 } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.2 1st block */ - /* 7*/ { 0x163, 24, 1, 27, { 0xE7, 0x3E, 0x33, 0x29, 0xE8, 0xFC, }, { 0xA2, 0xA7, 0x68, 0x8A, 0x5F, 0xE6, 0xAA, 0x11, 0xA6, 0x69, 0x4A, 0xCF, 0xCF, 0x20, 0x5D, 0x00, 0x1B, 0x79, 0xA1, 0xFE, 0xB7, 0x94, 0x03, 0x9B } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.2 2nd block */ + /* 0*/ { 0x43, 4, 1, 7, { 4, 20, 49, 37, 49, 38, 23 }, { 58, 53, 17, 54 } }, /* AUSPOST Australia Post Customer Barcoding Technical Specifications Diagram 10 */ + /* 1*/ { 0x43, 7, 1, 10, { 9, 50, 1, 41, 47, 2, 39, 37, 1, 27 }, { 40, 20, 10, 16, 8, 50, 38 } }, /* AZTEC ISO/IEC 24778:2008 Section G.4 */ + /* 2*/ { 0x13, 5, 1, 2, { 0, 9 }, { 9, 1, 3, 2, 12 } }, /* AZTEC ISO/IEC 24778:2008 Section G.4 Mode Message */ + /* 3*/ { 0x12d, 5, 1, 3, { 142, 164, 186 }, { 102, 88, 5, 25, 114 } }, /* DATAMATRIX ISO/IEC 16022:2006 Annex O */ + /* 4*/ { 0x89, 25, 1, 25, { 42, 13, 54, 39, 124, 91, 121, 65, 28, 40, 95, 48, 0, 126, 0, 126, 0, 126, 0, 126, 0, 126, 0, 126, 0 }, { 102, 70, 92, 79, 2, 52, 98, 62, 48, 33, 14, 4, 101, 17, 55, 89, 100, 23, 35, 112, 54, 20, 2, 47, 123 } }, /* GRIDMATRIX AIMD014 Section 6.8 */ + /* 5*/ { 0x163, 4, 1, 21, { 0x11, 0xED, 0xC8, 0xC5, 0x40, 0x0F, 0xF4 }, { 0x1D, 0x68, 0xB4, 0xEB } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.1 */ + /* 6*/ { 0x163, 24, 1, 27, { 0x11, 0xED, 0xC8, 0xC5, 0x40, 0x0F, 0xF4, 0x8A, 0x2C, 0xC3, 0x4E, 0x3D, 0x09, 0x25, 0x9A, 0x7A, 0x29, 0xAB, 0xEA, 0x3E, 0x46, 0x4C, 0x7E, 0x73, 0xE8, 0x6C, 0xC7 }, { 0x77, 0x49, 0xCD, 0x0B, 0x99, 0x9A, 0x5D, 0x74, 0x84, 0xB0, 0x11, 0xAD, 0x82, 0xA4, 0xCF, 0x99, 0xA2, 0xDD, 0xA5, 0x7A, 0xE0, 0x0C, 0x57, 0x08 } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.2 1st block */ + /* 7*/ { 0x163, 24, 1, 27, { 0xE7, 0x3E, 0x33, 0x29, 0xE8, 0xFC, }, { 0x9B, 0x03, 0x94, 0xB7, 0xFE, 0xA1, 0x79, 0x1B, 0x00, 0x5D, 0x20, 0xCF, 0xCF, 0x4A, 0x69, 0xA6, 0x11, 0xAA, 0xE6, 0x5F, 0x8A, 0x68, 0xA7, 0xA2 } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.2 2nd block */ /* 8*/ { 0x163, 24, 1, 29, { 0x00 }, { 0x00 } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.2 3rd block */ - /* 9*/ { 0x25, 6, 1, 16, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 14, 7, 23, 3, 23, 15 } }, /* MAILMARK_4S Royal Mail Mailmark barcode C encoding and decoding Example 2.3.1 */ - /* 10*/ { 0x25, 6, 1, 16, { 15, 22, 3, 25, 23, 26, 7, 3, 20, 14, 1, 4, 16, 3, 9, 28 }, { 27, 22, 24, 16, 6, 24 } }, /* MAILMARK_4S Royal Mail Mailmark barcode C encoding and decoding Example 2.3.2 */ - /* 11*/ { 0x25, 7, 1, 19, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 20, 1, 20, 7, 14, 11, 18 } }, /* MAILMARK_4S Royal Mail Mailmark barcode L encoding and decoding Example 2.3.1 */ - /* 12*/ { 0x25, 7, 1, 19, { 0, 8, 21, 10, 29, 1, 29, 21, 2, 24, 15, 2, 19, 1, 4, 15, 11, 4, 16 }, { 19, 7, 9, 8, 6, 16, 16 } }, /* MAILMARK_4S Royal Mail Mailmark barcode L encoding and decoding Example 2.3.2 */ - /* 13*/ { 0x43, 10, 1, 10, { 4, 13, 63, 1, 24, 9, 59, 3, 15, 4 }, { 50, 2, 42, 51, 53, 34, 22, 20, 5, 16 } }, /* MAXICODE Annex H Primary */ - /* 14*/ { 0x43, 20, 1, 42, { 5, 57, 49, 47, 8, 18, 59, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 31, 2, 58, 6, 6, 39, 13, 63, 2, 30, 19, 19, 14, 19, 23, 17, 62, 8, 2, 23 } }, /* MAXICODE Annex H Secondary odd */ - /* 15*/ { 0x43, 20, 1, 42, { 47, 40, 57, 3, 1, 19, 41, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 1, 15, 22, 28, 39, 17, 60, 5, 35, 35, 4, 8, 0, 32, 51, 45, 63, 53, 61, 14 } }, /* MAXICODE Annex H Secondary even */ - /* 16*/ { 0x11d, 10, 0, 16, { 0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11 }, { 0xA5, 0x24, 0xD4, 0xC1, 0xED, 0x36, 0xC7, 0x87, 0x2C, 0x55 } }, /* QRCODE Annex I.2 */ - /* 17*/ { 0x11d, 5, 0, 5, { 0x40, 0x18, 0xAC, 0xC3, 0x00 }, { 0x86, 0x0D, 0x22, 0xAE, 0x30 } }, /* QRCODE Annex I.3 */ - /* 18*/ { 0x163, 256, 0, 1, { 0xFF }, { 255, 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, 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, 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, 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, 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, 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, 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, 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, 255, 255 } }, + /* 9*/ { 0x25, 6, 1, 16, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 15, 23, 3, 23, 7, 14 } }, /* MAILMARK_4S Royal Mail Mailmark barcode C encoding and decoding Example 2.3.1 */ + /* 10*/ { 0x25, 6, 1, 16, { 15, 22, 3, 25, 23, 26, 7, 3, 20, 14, 1, 4, 16, 3, 9, 28 }, { 24, 6, 16, 24, 22, 27 } }, /* MAILMARK_4S Royal Mail Mailmark barcode C encoding and decoding Example 2.3.2 */ + /* 11*/ { 0x25, 7, 1, 19, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 18, 11, 14, 7, 20, 1, 20 } }, /* MAILMARK_4S Royal Mail Mailmark barcode L encoding and decoding Example 2.3.1 */ + /* 12*/ { 0x25, 7, 1, 19, { 0, 8, 21, 10, 29, 1, 29, 21, 2, 24, 15, 2, 19, 1, 4, 15, 11, 4, 16 }, { 16, 16, 6, 8, 9, 7, 19 } }, /* MAILMARK_4S Royal Mail Mailmark barcode L encoding and decoding Example 2.3.2 */ + /* 13*/ { 0x43, 10, 1, 10, { 4, 13, 63, 1, 24, 9, 59, 3, 15, 4 }, { 16, 5, 20, 22, 34, 53, 51, 42, 2, 50 } }, /* MAXICODE Annex H Primary */ + /* 14*/ { 0x43, 20, 1, 42, { 5, 57, 49, 47, 8, 18, 59, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 23, 2, 8, 62, 17, 23, 19, 14, 19, 19, 30, 2, 63, 13, 39, 6, 6, 58, 2, 31 } }, /* MAXICODE Annex H Secondary odd */ + /* 15*/ { 0x43, 20, 1, 42, { 47, 40, 57, 3, 1, 19, 41, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 14, 61, 53, 63, 45, 51, 32, 0, 8, 4, 35, 35, 5, 60, 17, 39, 28, 22, 15, 1 } }, /* MAXICODE Annex H Secondary even */ + /* 16*/ { 0x11d, 10, 0, 16, { 0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11 }, { 0x55, 0x2C, 0x87, 0xC7, 0x36, 0xED, 0xC1, 0xD4, 0x24, 0xA5 } }, /* QRCODE Annex I.2 */ + /* 17*/ { 0x11d, 5, 0, 5, { 0x40, 0x18, 0xAC, 0xC3, 0x00 }, { 0x30, 0xAE, 0x22, 0x0D, 0x86 } }, /* QRCODE Annex I.3 */ + /* 18*/ { 0x163, 256, 0, 1, { 0xFF }, { 255, 255, 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, 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, 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, 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, 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, 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, 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, 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, 255 } }, }; int data_size = ARRAY_SIZE(data); int i; @@ -187,25 +187,25 @@ static void test_encoding_uint(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { 0x43, 4, 1, 7, { 4, 20, 49, 37, 49, 38, 23 }, { 54, 17, 53, 58 } }, /* AUSPOST Australia Post Customer Barcoding Technical Specifications Diagram 10 */ - /* 1*/ { 0x43, 7, 1, 10, { 9, 50, 1, 41, 47, 2, 39, 37, 1, 27 }, { 38, 50, 8, 16, 10, 20, 40 } }, /* AZTEC ISO/IEC 24778:2008 Section G.4 */ - /* 2*/ { 0x13, 5, 1, 2, { 0, 9 }, { 12, 2, 3, 1, 9 } }, /* AZTEC ISO/IEC 24778:2008 Section G.4 Mode Message */ - /* 3*/ { 0x12d, 5, 1, 3, { 142, 164, 186 }, { 114, 25, 5, 88, 102 } }, /* DATAMATRIX ISO/IEC 16022:2006 Annex O */ - /* 4*/ { 0x89, 25, 1, 25, { 42, 13, 54, 39, 124, 91, 121, 65, 28, 40, 95, 48, 0, 126, 0, 126, 0, 126, 0, 126, 0, 126, 0, 126, 0 }, { 123, 47, 2, 20, 54, 112, 35, 23, 100, 89, 55, 17, 101, 4, 14, 33, 48, 62, 98, 52, 2, 79, 92, 70, 102 } }, /* GRIDMATRIX AIMD014 Section 6.8 */ - /* 5*/ { 0x163, 4, 1, 21, { 0x11, 0xED, 0xC8, 0xC5, 0x40, 0x0F, 0xF4 }, { 0xEB, 0xB4, 0x68, 0x1D } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.1 */ - /* 6*/ { 0x163, 24, 1, 27, { 0x11, 0xED, 0xC8, 0xC5, 0x40, 0x0F, 0xF4, 0x8A, 0x2C, 0xC3, 0x4E, 0x3D, 0x09, 0x25, 0x9A, 0x7A, 0x29, 0xAB, 0xEA, 0x3E, 0x46, 0x4C, 0x7E, 0x73, 0xE8, 0x6C, 0xC7 }, { 0x08, 0x57, 0x0C, 0xE0, 0x7A, 0xA5, 0xDD, 0xA2, 0x99, 0xCF, 0xA4, 0x82, 0xAD, 0x11, 0xB0, 0x84, 0x74, 0x5D, 0x9A, 0x99, 0x0B, 0xCD, 0x49, 0x77 } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.2 1st block */ - /* 7*/ { 0x163, 24, 1, 27, { 0xE7, 0x3E, 0x33, 0x29, 0xE8, 0xFC, }, { 0xA2, 0xA7, 0x68, 0x8A, 0x5F, 0xE6, 0xAA, 0x11, 0xA6, 0x69, 0x4A, 0xCF, 0xCF, 0x20, 0x5D, 0x00, 0x1B, 0x79, 0xA1, 0xFE, 0xB7, 0x94, 0x03, 0x9B } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.2 2nd block */ + /* 0*/ { 0x43, 4, 1, 7, { 4, 20, 49, 37, 49, 38, 23 }, { 58, 53, 17, 54 } }, /* AUSPOST Australia Post Customer Barcoding Technical Specifications Diagram 10 */ + /* 1*/ { 0x43, 7, 1, 10, { 9, 50, 1, 41, 47, 2, 39, 37, 1, 27 }, { 40, 20, 10, 16, 8, 50, 38 } }, /* AZTEC ISO/IEC 24778:2008 Section G.4 */ + /* 2*/ { 0x13, 5, 1, 2, { 0, 9 }, { 9, 1, 3, 2, 12 } }, /* AZTEC ISO/IEC 24778:2008 Section G.4 Mode Message */ + /* 3*/ { 0x12d, 5, 1, 3, { 142, 164, 186 }, { 102, 88, 5, 25, 114 } }, /* DATAMATRIX ISO/IEC 16022:2006 Annex O */ + /* 4*/ { 0x89, 25, 1, 25, { 42, 13, 54, 39, 124, 91, 121, 65, 28, 40, 95, 48, 0, 126, 0, 126, 0, 126, 0, 126, 0, 126, 0, 126, 0 }, { 102, 70, 92, 79, 2, 52, 98, 62, 48, 33, 14, 4, 101, 17, 55, 89, 100, 23, 35, 112, 54, 20, 2, 47, 123 } }, /* GRIDMATRIX AIMD014 Section 6.8 */ + /* 5*/ { 0x163, 4, 1, 21, { 0x11, 0xED, 0xC8, 0xC5, 0x40, 0x0F, 0xF4 }, { 0x1D, 0x68, 0xB4, 0xEB } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.1 */ + /* 6*/ { 0x163, 24, 1, 27, { 0x11, 0xED, 0xC8, 0xC5, 0x40, 0x0F, 0xF4, 0x8A, 0x2C, 0xC3, 0x4E, 0x3D, 0x09, 0x25, 0x9A, 0x7A, 0x29, 0xAB, 0xEA, 0x3E, 0x46, 0x4C, 0x7E, 0x73, 0xE8, 0x6C, 0xC7 }, { 0x77, 0x49, 0xCD, 0x0B, 0x99, 0x9A, 0x5D, 0x74, 0x84, 0xB0, 0x11, 0xAD, 0x82, 0xA4, 0xCF, 0x99, 0xA2, 0xDD, 0xA5, 0x7A, 0xE0, 0x0C, 0x57, 0x08 } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.2 1st block */ + /* 7*/ { 0x163, 24, 1, 27, { 0xE7, 0x3E, 0x33, 0x29, 0xE8, 0xFC, }, { 0x9B, 0x03, 0x94, 0xB7, 0xFE, 0xA1, 0x79, 0x1B, 0x00, 0x5D, 0x20, 0xCF, 0xCF, 0x4A, 0x69, 0xA6, 0x11, 0xAA, 0xE6, 0x5F, 0x8A, 0x68, 0xA7, 0xA2 } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.2 2nd block */ /* 8*/ { 0x163, 24, 1, 29, { 0x00 }, { 0x00 } }, /* HANXIN ISO/IEC DIS 20830:2019 Annex K.2 3rd block */ - /* 9*/ { 0x25, 6, 1, 16, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 14, 7, 23, 3, 23, 15 } }, /* MAILMARK_4S Royal Mail Mailmark barcode C encoding and decoding Example 2.3.1 */ - /* 10*/ { 0x25, 6, 1, 16, { 15, 22, 3, 25, 23, 26, 7, 3, 20, 14, 1, 4, 16, 3, 9, 28 }, { 27, 22, 24, 16, 6, 24 } }, /* MAILMARK_4S Royal Mail Mailmark barcode C encoding and decoding Example 2.3.2 */ - /* 11*/ { 0x25, 7, 1, 19, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 20, 1, 20, 7, 14, 11, 18 } }, /* MAILMARK_4S Royal Mail Mailmark barcode L encoding and decoding Example 2.3.1 */ - /* 12*/ { 0x25, 7, 1, 19, { 0, 8, 21, 10, 29, 1, 29, 21, 2, 24, 15, 2, 19, 1, 4, 15, 11, 4, 16 }, { 19, 7, 9, 8, 6, 16, 16 } }, /* MAILMARK_4S Royal Mail Mailmark barcode L encoding and decoding Example 2.3.2 */ - /* 13*/ { 0x43, 10, 1, 10, { 4, 13, 63, 1, 24, 9, 59, 3, 15, 4 }, { 50, 2, 42, 51, 53, 34, 22, 20, 5, 16 } }, /* MAXICODE Annex H Primary */ - /* 14*/ { 0x43, 20, 1, 42, { 5, 57, 49, 47, 8, 18, 59, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 31, 2, 58, 6, 6, 39, 13, 63, 2, 30, 19, 19, 14, 19, 23, 17, 62, 8, 2, 23 } }, /* MAXICODE Annex H Secondary odd */ - /* 15*/ { 0x43, 20, 1, 42, { 47, 40, 57, 3, 1, 19, 41, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 1, 15, 22, 28, 39, 17, 60, 5, 35, 35, 4, 8, 0, 32, 51, 45, 63, 53, 61, 14 } }, /* MAXICODE Annex H Secondary even */ - /* 16*/ { 0x11d, 10, 0, 16, { 0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11 }, { 0xA5, 0x24, 0xD4, 0xC1, 0xED, 0x36, 0xC7, 0x87, 0x2C, 0x55 } }, /* QRCODE Annex I.2 */ - /* 17*/ { 0x11d, 5, 0, 5, { 0x40, 0x18, 0xAC, 0xC3, 0x00 }, { 0x86, 0x0D, 0x22, 0xAE, 0x30 } }, /* QRCODE Annex I.3 */ - /* 18*/ { 0x163, 256, 0, 1, { 0xFF }, { 255, 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, 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, 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, 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, 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, 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, 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, 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, 255, 255 } }, + /* 9*/ { 0x25, 6, 1, 16, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 15, 23, 3, 23, 7, 14 } }, /* MAILMARK_4S Royal Mail Mailmark barcode C encoding and decoding Example 2.3.1 */ + /* 10*/ { 0x25, 6, 1, 16, { 15, 22, 3, 25, 23, 26, 7, 3, 20, 14, 1, 4, 16, 3, 9, 28 }, { 24, 6, 16, 24, 22, 27 } }, /* MAILMARK_4S Royal Mail Mailmark barcode C encoding and decoding Example 2.3.2 */ + /* 11*/ { 0x25, 7, 1, 19, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 18, 11, 14, 7, 20, 1, 20 } }, /* MAILMARK_4S Royal Mail Mailmark barcode L encoding and decoding Example 2.3.1 */ + /* 12*/ { 0x25, 7, 1, 19, { 0, 8, 21, 10, 29, 1, 29, 21, 2, 24, 15, 2, 19, 1, 4, 15, 11, 4, 16 }, { 16, 16, 6, 8, 9, 7, 19 } }, /* MAILMARK_4S Royal Mail Mailmark barcode L encoding and decoding Example 2.3.2 */ + /* 13*/ { 0x43, 10, 1, 10, { 4, 13, 63, 1, 24, 9, 59, 3, 15, 4 }, { 16, 5, 20, 22, 34, 53, 51, 42, 2, 50 } }, /* MAXICODE Annex H Primary */ + /* 14*/ { 0x43, 20, 1, 42, { 5, 57, 49, 47, 8, 18, 59, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 23, 2, 8, 62, 17, 23, 19, 14, 19, 19, 30, 2, 63, 13, 39, 6, 6, 58, 2, 31 } }, /* MAXICODE Annex H Secondary odd */ + /* 15*/ { 0x43, 20, 1, 42, { 47, 40, 57, 3, 1, 19, 41, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 14, 61, 53, 63, 45, 51, 32, 0, 8, 4, 35, 35, 5, 60, 17, 39, 28, 22, 15, 1 } }, /* MAXICODE Annex H Secondary even */ + /* 16*/ { 0x11d, 10, 0, 16, { 0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11 }, { 0x55, 0x2C, 0x87, 0xC7, 0x36, 0xED, 0xC1, 0xD4, 0x24, 0xA5 } }, /* QRCODE Annex I.2 */ + /* 17*/ { 0x11d, 5, 0, 5, { 0x40, 0x18, 0xAC, 0xC3, 0x00 }, { 0x30, 0xAE, 0x22, 0x0D, 0x86 } }, /* QRCODE Annex I.3 */ + /* 18*/ { 0x163, 256, 0, 1, { 0xFF }, { 255, 255, 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, 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, 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, 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, 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, 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, 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, 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, 255 } }, }; int data_size = ARRAY_SIZE(data); int i; @@ -251,10 +251,10 @@ static void test_uint_encoding(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { 0x409, 1023, 4, 1, 7, { 0x3FF, 0x000, 0x100, 0x1FF, 0x3FF, 0x000, 0x123 }, { 229, 153, 993, 674 } }, - /* 1*/ { 0x1069, 4095, 4, 1, 7, { 0xFFF, 0x000, 0x700, 0x7FF, 0xFFF, 0x000, 0x123 }, { 3472, 2350, 3494, 575 } }, - /* 2*/ { 0x1000, 4095, 4, 0, 7, { 0xFFF, 0x000, 0x700, 0x7FF, 0xFFF, 0x000, 0x123 }, { 1, 65, 0, 64 } }, - /* 3*/ { 0x1000, 4095, 256, 0, 1, { 0xFFF }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 512, 0, 2048, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + /* 0*/ { 0x409, 1023, 4, 1, 7, { 0x3FF, 0x000, 0x100, 0x1FF, 0x3FF, 0x000, 0x123 }, { 674, 993, 153, 229 } }, + /* 1*/ { 0x1069, 4095, 4, 1, 7, { 0xFFF, 0x000, 0x700, 0x7FF, 0xFFF, 0x000, 0x123 }, { 575, 3494, 2350, 3472 } }, + /* 2*/ { 0x1000, 4095, 4, 0, 7, { 0xFFF, 0x000, 0x700, 0x7FF, 0xFFF, 0x000, 0x123 }, { 64, 0, 65, 1 } }, + /* 3*/ { 0x1000, 4095, 256, 0, 1, { 0xFFF }, { 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 512, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }, }; int data_size = ARRAY_SIZE(data); int i; diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index cc89bbfe..2e57f099 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -52,13 +52,17 @@ #include "../eci.h" #include "../output.h" -static int tests = 0; -static int failed = 0; -static int skipped = 0; -int assertionFailed = 0; -int assertionNum = 0; -struct zint_symbol **assertionPPSymbol = NULL; -const char *assertionFilename = ""; +static int testTests = 0; +static int testFailed = 0; +static int testSkipped = 0; +static int testDataset = 0; +static int testDatasetNum = 0; +static int testDatasetTot = 0; +int testAssertFailed = 0; +int testAssertNum = 0; +static int testAssertTot = 0; +struct zint_symbol **testAssertPPSymbol = NULL; +const char *testAssertFilename = ""; static const char *testName = NULL; static const char *testFunc = NULL; @@ -67,52 +71,52 @@ static const char *testFunc = NULL; #if (defined(_MSC_VER) && _MSC_VER <= 1200) || defined(ZINT_IS_C89) /* VC6 or C89 */ #include void assert_zero(int exp, const char *fmt, ...) { - assertionNum++; + testAssertNum++; if (exp != 0) { - va_list args; assertionFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); - if (assertionPPSymbol) { ZBarcode_Delete(*assertionPPSymbol); assertionPPSymbol = NULL; }; + va_list args; testAssertFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); + if (testAssertPPSymbol) { ZBarcode_Delete(*testAssertPPSymbol); testAssertPPSymbol = NULL; }; } } void assert_nonzero(int exp, const char *fmt, ...) { - assertionNum++; + testAssertNum++; if (exp == 0) { - va_list args; assertionFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); - if (assertionPPSymbol) { ZBarcode_Delete(*assertionPPSymbol); assertionPPSymbol = NULL; }; + va_list args; testAssertFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); + if (testAssertPPSymbol) { ZBarcode_Delete(*testAssertPPSymbol); testAssertPPSymbol = NULL; }; } } void assert_null(const void *exp, const char *fmt, ...) { - assertionNum++; + testAssertNum++; if (exp != NULL) { - va_list args; assertionFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); - if (assertionPPSymbol) { ZBarcode_Delete(*assertionPPSymbol); assertionPPSymbol = NULL; }; + va_list args; testAssertFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); + if (testAssertPPSymbol) { ZBarcode_Delete(*testAssertPPSymbol); testAssertPPSymbol = NULL; }; } } void assert_nonnull(const void *exp, const char *fmt, ...) { - assertionNum++; + testAssertNum++; if (exp == NULL) { - va_list args; assertionFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); - if (assertionPPSymbol) { ZBarcode_Delete(*assertionPPSymbol); assertionPPSymbol = NULL; }; + va_list args; testAssertFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); + if (testAssertPPSymbol) { ZBarcode_Delete(*testAssertPPSymbol); testAssertPPSymbol = NULL; }; } } void assert_equal(int e1, int e2, const char *fmt, ...) { - assertionNum++; + testAssertNum++; if (e1 != e2) { - va_list args; assertionFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); - if (assertionPPSymbol) { ZBarcode_Delete(*assertionPPSymbol); assertionPPSymbol = NULL; }; + va_list args; testAssertFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); + if (testAssertPPSymbol) { ZBarcode_Delete(*testAssertPPSymbol); testAssertPPSymbol = NULL; }; } } void assert_equalu64(uint64_t e1, uint64_t e2, const char *fmt, ...) { - assertionNum++; + testAssertNum++; if (e1 != e2) { - va_list args; assertionFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); - if (assertionPPSymbol) { ZBarcode_Delete(*assertionPPSymbol); assertionPPSymbol = NULL; }; + va_list args; testAssertFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); + if (testAssertPPSymbol) { ZBarcode_Delete(*testAssertPPSymbol); testAssertPPSymbol = NULL; }; } } void assert_notequal(int e1, int e2, const char *fmt, ...) { - assertionNum++; + testAssertNum++; if (e1 == e2) { - va_list args; assertionFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); - if (assertionPPSymbol) { ZBarcode_Delete(*assertionPPSymbol); assertionPPSymbol = NULL; }; + va_list args; testAssertFailed++; va_start(args, fmt); vprintf(fmt, args); va_end(args); testFinish(); + if (testAssertPPSymbol) { ZBarcode_Delete(*testAssertPPSymbol); testAssertPPSymbol = NULL; }; } } #endif @@ -129,66 +133,93 @@ void assert_notequal(int e1, int e2, const char *fmt, ...) { /* Begin individual test function */ void testStartReal(const char *func, const char *name, struct zint_symbol **pp_symbol) { - tests++; + testTests++; if (func && *func && name && *name && strcmp(func, name) == 0) { testName = ""; } else { testName = name; } testFunc = func ? func : ""; - assertionFailed = 0; - assertionNum = 0; - assertionPPSymbol = pp_symbol; - printf("_____%d: %s: %s...\n", tests, testFunc, testName ? testName : ""); + testDataset = 0; + testDatasetNum = 0; + testAssertFailed = 0; + testAssertNum = 0; + testAssertPPSymbol = pp_symbol; + printf("_____%d: %s: %s...\n", testTests, testFunc, testName ? testName : ""); } /* End individual test function */ void testFinish(void) { - fputs(assertionFailed ? "*****" : ".....", stdout); + testAssertTot += testAssertNum; + testDatasetTot += testDatasetNum; + fputs(testAssertFailed ? "*****" : ".....", stdout); if (testName && *testName) { - printf("%d: %s: %s ", tests, testFunc, testName); + printf("%d: %s: %s ", testTests, testFunc, testName); } else { - printf("%d: %s: ", tests, testFunc); + printf("%d: %s: ", testTests, testFunc); } - if (assertionFailed) { - printf("FAILED. (%d assertions failed.)\n", assertionFailed); - failed++; + if (testAssertFailed) { + printf("FAILED. (%d assertions failed)\n", testAssertFailed); + testFailed++; + } else if (testDataset) { + if (testAssertNum) { + printf("PASSED. (%d assertions, %d dataset items)\n", testAssertNum, testDatasetNum); + } else { + printf("EMPTY. (***No assertions executed***)\n"); + } } else { - printf("PASSED. (%d assertions passed.)\n", assertionNum); + if (testAssertNum) { + printf("PASSED. (%d assertions)\n", testAssertNum); + } else { + printf("EMPTY. (***No assertions executed***)\n"); + } } } /* Skip (and end) individual test function */ void testSkip(const char *msg) { - skipped++; - fputs(assertionFailed ? "*****" : ".....", stdout); + testSkipped++; + testAssertTot += testAssertNum; + testDatasetTot += testDatasetNum; + fputs(testAssertFailed ? "*****" : ".....", stdout); if (testName && *testName) { - printf("%d: %s: %s ", tests, testFunc, testName); + printf("%d: %s: %s ", testTests, testFunc, testName); } else { - printf("%d: %s: ", tests, testFunc); + printf("%d: %s: ", testTests, testFunc); } - if (assertionFailed) { - printf("FAILED. (%d assertions failed.)\n", assertionFailed); - failed++; + if (testAssertFailed) { + printf("FAILED. (%d assertions failed)\n", testAssertFailed); + testFailed++; + } else if (testDataset) { + printf("SKIPPED. %s. (%d assertions, %d dataset items)\n", msg, testAssertNum, testDatasetNum); } else { - printf("SKIPPED. %s. (%d assertions passed.)\n", msg, assertionNum); + printf("SKIPPED. %s. (%d assertions)\n", msg, testAssertNum); } } /* End test program */ void testReport(void) { - if (failed && skipped) { - printf("Total %d tests, %d skipped, %d **fails**.\n", tests, skipped, failed); + if (testFailed && testSkipped) { + printf("Total %d tests, %d skipped, %d **fails**.\n", testTests, testSkipped, testFailed); exit(-1); } - if (failed) { - printf("Total %d tests, %d **fails**.\n", tests, failed); + if (testFailed) { + printf("Total %d tests, %d **fails**.\n", testTests, testFailed); exit(-1); } - if (skipped) { - printf("Total %d tests, %d skipped.\n", tests, skipped); - } else if (tests) { - printf("Total %d tests, all passed.\n", tests); + if (testSkipped) { + printf("Total %d tests, %d skipped.\n", testTests, testSkipped); + } else if (testTests) { + if (testAssertTot) { + if (testDatasetTot) { + printf("Total %d tests (%d assertions, %d dataset items), all passed.\n", + testTests, testAssertTot, testDatasetTot); + } else { + printf("Total %d tests (%d assertions), all passed.\n", testTests, testAssertTot); + } + } else { + printf("***No assertions executed in %d tests.***\n", testTests); + } } else { fputs("***No tests run.***\n", stdout); } @@ -281,28 +312,28 @@ void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size) { filename = strrchr(argv[0], '/'); #endif if (filename) { - assertionFilename = filename + 1; + testAssertFilename = filename + 1; } else { - assertionFilename = argv[0]; + testAssertFilename = argv[0]; } } for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-d") == 0) { if (i + 1 == argc) { - fprintf(stderr, "testRun: -d debug value missing, ignoring\n"); + fprintf(stderr, "***testRun: -d debug value missing, ignoring***\n"); } else { int d; /* Allow multiple debug flags, OR-ing */ optarg = argv[++i]; if (!validate_int(optarg, &d)) { - fprintf(stderr, "testRun: -d debug value invalid, ignoring\n"); + fprintf(stderr, "***testRun: -d debug value invalid, ignoring***\n"); } else { ctx.debug |= d; } } } else if (strcmp(argv[i], "-f") == 0) { if (i + 1 == argc) { - fprintf(stderr, "testRun: -f func value missing, ignoring\n"); + fprintf(stderr, "***testRun: -f func value missing, ignoring***\n"); } else { optarg = argv[++i]; if (strlen(optarg) < 256) { @@ -314,13 +345,13 @@ void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size) { } func = func_buf; } else { - fprintf(stderr, "testRun: -f func value too long, ignoring\n"); + fprintf(stderr, "***testRun: -f func value too long, ignoring***\n"); func = NULL; } } } else if (strcmp(argv[i], "-n") == 0) { if (i + 1 == argc) { - fprintf(stderr, "testRun: -n func exclude value missing, ignoring\n"); + fprintf(stderr, "***testRun: -n func exclude value missing, ignoring***\n"); } else { optarg = argv[++i]; if (strlen(optarg) < 256) { @@ -332,13 +363,13 @@ void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size) { } func_not = func_not_buf; } else { - fprintf(stderr, "testRun: -p func exclude value too long, ignoring\n"); + fprintf(stderr, "***testRun: -p func exclude value too long, ignoring***\n"); func_not = NULL; } } } else if (strcmp(argv[i], "-m") == 0) { if (i + 1 == argc) { - fprintf(stderr, "testRun: -m func match value missing, ignoring\n"); + fprintf(stderr, "***testRun: -m func match value missing, ignoring***\n"); } else { func_match = argv[++i]; } @@ -346,30 +377,30 @@ void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size) { ctx.generate = 1; } else if (strcmp(argv[i], "-i") == 0) { if (i + 1 == argc) { - fprintf(stderr, "testRun: -i index value missing, ignoring\n"); + fprintf(stderr, "***testRun: -i index value missing, ignoring***\n"); } else { optarg = argv[++i]; if (!validate_int_range(optarg, &ctx.index, &ctx.index_end)) { - fprintf(stderr, "testRun: -i index value invalid, ignoring\n"); + fprintf(stderr, "***testRun: -i index value invalid, ignoring***\n"); ctx.index = ctx.index_end = -1; } } } else if (strcmp(argv[i], "-x") == 0) { if (i + 1 == argc) { - fprintf(stderr, "testRun: -x exclude value missing, ignoring\n"); + fprintf(stderr, "***testRun: -x exclude value missing, ignoring***\n"); } else { optarg = argv[++i]; if (exclude_idx + 1 == ZINT_TEST_CTX_EXC_MAX) { - fprintf(stderr, "testRun: too many -x exclude values, ignoring\n"); + fprintf(stderr, "***testRun: too many -x exclude values, ignoring***\n"); } else if (!validate_int_range(optarg, &ctx.exclude[exclude_idx], &ctx.exclude_end[exclude_idx])) { - fprintf(stderr, "testRun: -x exclude value invalid, ignoring\n"); + fprintf(stderr, "***testRun: -x exclude value invalid, ignoring***\n"); ctx.exclude[exclude_idx] = ctx.exclude_end[exclude_idx] = -1; } else { exclude_idx++; } } } else { - fprintf(stderr, "testRun: unknown arg '%s', ignoring\n", argv[i]); + fprintf(stderr, "***testRun: unknown arg '%s', ignoring***\n", argv[i]); } } @@ -389,16 +420,17 @@ void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size) { } if (func && !ran) { - fprintf(stderr, "testRun: unknown -f func arg '%s'\n", func); + fprintf(stderr, "***testRun: unknown -f func arg '%s'***\n", func); } if (func_match && !ran) { - fprintf(stderr, "testRun: no funcs matched -m arg '%s'\n", func_match); + fprintf(stderr, "***testRun: no funcs matched -m arg '%s'***\n", func_match); } } /* Call in a dataset loop to determine if a datum should be tested according to -i & -x args */ int testContinue(const testCtx *const p_ctx, const int i) { int j; + testDataset = 1; if (p_ctx->index != -1) { if (p_ctx->index_end != -1) { if (i < p_ctx->index || (p_ctx->index_end && i > p_ctx->index_end)) { @@ -421,6 +453,7 @@ int testContinue(const testCtx *const p_ctx, const int i) { printf("i:%d\n", i); fflush(stdout); /* For assertion failures */ } + testDatasetNum++; return 0; } @@ -3102,12 +3135,18 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int bwipp_opts = bwipp_opts_buf; } } else if (symbology == BARCODE_MAXICODE) { - int have_scm = memcmp(bwipp_data, "[)>^03001^02996", 15) == 0; + int have_eci = memcmp(bwipp_data, "^ECI", 4) == 0; + int have_scm = memcmp(bwipp_data + have_eci * 10, "[)>^03001^029", 13) == 0 + && z_isdigit(bwipp_data[13 + have_eci * 10]) + && z_isdigit(bwipp_data[14 + have_eci * 10]); int mode = option_1; + char prefix_buf[30]; + int prefix_len = 0; if (mode <= 0) { if (primary_len == 0) { mode = 4; } else { + mode = 2; for (i = 0; i < primary_len - 6; i++) { if (!z_isdigit(symbol->primary[i]) && (symbol->primary[i] != ' ')) { mode = 3; @@ -3121,9 +3160,21 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int strlen(bwipp_opts_buf) ? " " : "", mode); bwipp_opts = bwipp_opts_buf; } + if (option_2 > 0) { + char scm_vv_buf[40]; + sprintf(scm_vv_buf, "[)>^03001^029%02d", option_2 - 1); /* [)>\R01\Gvv */ + memmove(bwipp_data + 15, bwipp_data, strlen(bwipp_data) + 1); + memcpy(bwipp_data, scm_vv_buf, 15); + have_scm = 1; + have_eci = 0; + if (!parse) { + sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%sparse", + strlen(bwipp_opts_buf) ? " " : ""); + bwipp_opts = bwipp_opts_buf; + parse = 1; + } + } if (primary_len >= 6) { /* Keep gcc happy */ - char prefix_buf[30]; - int prefix_len; int postcode_len = primary_len - 6; char postcode[10]; if (postcode_len >= 10) postcode_len = 9; @@ -3144,31 +3195,27 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int sprintf(prefix_buf, "%s^029%.3s^029%.3s^029", postcode, primary + primary_len - 6, primary + primary_len - 3); prefix_len = (int) strlen(prefix_buf); - if (have_scm) { - memmove(bwipp_data + 15 + prefix_len, bwipp_data, strlen(bwipp_data) - 15 + 1); - memcpy(bwipp_data + 15, prefix_buf, prefix_len); - } else { - memmove(bwipp_data + prefix_len, bwipp_data, strlen(bwipp_data) + 1); - memcpy(bwipp_data, prefix_buf, prefix_len); + } + if (prefix_len || have_scm) { + char eci_buf[10]; + int offset = 15 * have_scm; + if (have_eci) { + memcpy(eci_buf, bwipp_data, 10); + memmove(bwipp_data, bwipp_data + 10, strlen(bwipp_data) - 10 + 1); } - if (!parse) { - sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%sparse", - strlen(bwipp_opts_buf) ? " " : ""); - bwipp_opts = bwipp_opts_buf; - parse = 1; + memmove(bwipp_data + offset + prefix_len, bwipp_data + offset, strlen(bwipp_data) - offset + 1); + memcpy(bwipp_data + offset, prefix_buf, prefix_len); + if (have_eci) { + memmove(bwipp_data + offset + prefix_len + 10, bwipp_data + offset + prefix_len, + strlen(bwipp_data) - (offset + prefix_len) + 1); + memcpy(bwipp_data + offset + prefix_len, eci_buf, 10); } } - if (option_2 > 0) { - char scm_vv_buf[40]; - sprintf(scm_vv_buf, "[^041>^03001^029%02d", option_2 - 1); /* [)>\R01\Gvv */ - memmove(bwipp_data + 18, bwipp_data, strlen(bwipp_data) + 1); - memcpy(bwipp_data, scm_vv_buf, 18); - if (!parse) { - sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%sparse", - strlen(bwipp_opts_buf) ? " " : ""); - bwipp_opts = bwipp_opts_buf; - parse = 1; - } + if (!parse) { + sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%sparse", + strlen(bwipp_opts_buf) ? " " : ""); + bwipp_opts = bwipp_opts_buf; + parse = 1; } if (symbol->structapp.count) { sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%ssam=%c%c", @@ -3759,7 +3806,7 @@ static const char *testUtilZXingCPPName(int index, const struct zint_symbol *sym { "", -1, 105, }, { "PDF417", BARCODE_HIBC_PDF, 106, }, { "", -1, 107, }, - { "", BARCODE_HIBC_MICPDF, 108, }, + { "MicroPDF417", BARCODE_HIBC_MICPDF, 108, }, { "", -1, 109, }, { "CodablockF", BARCODE_HIBC_BLOCKF, 110, }, { "", -1, 111, }, @@ -4110,6 +4157,7 @@ int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, in if (primary && primary[0]) { int primary_len = (int) strlen(primary); int maxi_len = 0; + int have_manual_scm = 0; if (symbol->option_2 >= 1 && symbol->option_2 <= 100) { /* Suppress gcc warning null destination pointer [-Wformat-overflow=] false-positive */ #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 7 @@ -4121,8 +4169,10 @@ int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, in #pragma GCC diagnostic pop #endif maxi_len = (int) strlen(maxi); + } else if (expected_len >= 9 && strncmp(expected, "[)>\03601\035", 7) == 0 + && z_isdigit(expected[7]) && z_isdigit(expected[8])) { + have_manual_scm = 1; } - #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); @@ -4135,14 +4185,17 @@ int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, in 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); - #endif maxi_len = (int) strlen(maxi); - memcpy(maxi + maxi_len, expected, expected_len); + if (have_manual_scm) { + memmove(maxi + 9, maxi, maxi_len); + memcpy(maxi, expected, 9); + memcpy(maxi + maxi_len + 9, expected + 9, expected_len - 9); + } else { + memcpy(maxi + maxi_len, expected, expected_len); + } expected = maxi; expected_len += maxi_len; + maxi[expected_len] = '\0'; } } else if (symbology == BARCODE_CODABAR) { /* Ignore start A/B/C/D and stop A/B/C/D chars to avoid upper/lowercase issues */ diff --git a/backend/tests/testcommon.h b/backend/tests/testcommon.h index 59d6d97c..83653f13 100644 --- a/backend/tests/testcommon.h +++ b/backend/tests/testcommon.h @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2019-2023 Robin Stuart + Copyright (C) 2019-2024 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -71,10 +71,10 @@ extern int pclose(FILE *stream); # pragma warning(disable: 4702) /* unreachable code */ #endif -extern int assertionFailed; -extern int assertionNum; -extern struct zint_symbol **assertionPPSymbol; -extern const char *assertionFilename; +extern int testAssertFailed; +extern int testAssertNum; +extern struct zint_symbol **testAssertPPSymbol; +extern const char *testAssertFilename; #if defined(_MSC_VER) && _MSC_VER < 1900 /* MSVC 2015 */ #define testStart(name) (testStartReal("", name, NULL)) @@ -114,9 +114,9 @@ void assert_equalu64(uint64_t e1, uint64_t e2, const char *fmt, ...); void assert_notequal(int e1, int e2, const char *fmt, ...); #else #define assert_exp(exp, ...) \ - { assertionNum++; if (!(exp)) { assertionFailed++; printf("%s:%d ", assertionFilename, __LINE__); \ + { testAssertNum++; if (!(exp)) { testAssertFailed++; printf("%s:%d ", testAssertFilename, __LINE__); \ printf(__VA_ARGS__); testFinish(); \ - if (assertionPPSymbol) { ZBarcode_Delete(*assertionPPSymbol); assertionPPSymbol = NULL; } return; } } + if (testAssertPPSymbol) { ZBarcode_Delete(*testAssertPPSymbol); testAssertPPSymbol = NULL; } return; } } #define assert_zero(exp, ...) assert_exp((exp) == 0, __VA_ARGS__) #define assert_nonzero(exp, ...) assert_exp((exp) != 0, __VA_ARGS__) diff --git a/backend/tests/tools/bwipp_dump.ps.tar.xz b/backend/tests/tools/bwipp_dump.ps.tar.xz index b6305941..efcff7d0 100644 Binary files a/backend/tests/tools/bwipp_dump.ps.tar.xz and b/backend/tests/tools/bwipp_dump.ps.tar.xz differ diff --git a/backend/tools/gen_gs1_lint.php b/backend/tools/gen_gs1_lint.php index 44690bfa..b0131aa5 100644 --- a/backend/tools/gen_gs1_lint.php +++ b/backend/tools/gen_gs1_lint.php @@ -452,9 +452,14 @@ foreach ($batches as $batch => $batch_specs) { $width += strlen($str); } $spec_func = $spec_funcs[$spec]; + $str = "$tab$tab{$tab}return $spec_func(data, data_len, p_err_no, p_err_posn, err_msg);"; + if (strlen($str) > 118) { + print ") {\n$tab$tab{$tab}return $spec_func(data,\n"; + print "$tab$tab$tab$tab$tab{$tab}data_len, p_err_no, p_err_posn, err_msg);\n"; + } else { + print ") {\n$str\n"; + } print <<