diff --git a/backend/codablock.c b/backend/codablock.c index d45fe7e7..bc869ecc 100644 --- a/backend/codablock.c +++ b/backend/codablock.c @@ -40,7 +40,7 @@ #include #include "common.h" -INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], const size_t length); +INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], int length); #define uchar unsigned char @@ -627,7 +627,7 @@ static void SumASCII(uchar **ppOutPos, int Sum, int CharacterSet) /* Main function called by zint framework */ -INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[], const size_t length) { +INTERNAL int codablock(struct zint_symbol *symbol, unsigned char source[], int length) { int charCur, dataLength; int error_number; int rows, columns, useColumns; @@ -685,7 +685,7 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[], dataLength++; } /* Replace all Codes>127 with Code-128 */ - for (charCur = 0; charCur < (int) length; charCur++) { + for (charCur = 0; charCur < length; charCur++) { if (source[charCur]>127) { data[dataLength] = aFNC4; @@ -710,7 +710,7 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[], /* nor row nor column count given */ if (rows <= 0 && columns <= 0) { /* use 1/1 aspect/ratio Codablock */ - columns = floor(sqrt(dataLength)) + 5; + columns = (int) floor(sqrt(dataLength)) + 5; if (columns > 67) { columns = 67; } else if (columns < 9) { @@ -738,7 +738,7 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[], /* Data Check Characters K1 and K2, Annex F */ Sum1 = Sum2 = 0; - for (charCur = 0; charCur < (int) length; charCur++) { + for (charCur = 0; charCur < length; charCur++) { Sum1 = (Sum1 + (charCur + 1) * source[charCur]) % 86; /* Mod as we go along to avoid overflow */ Sum2 = (Sum2 + charCur * source[charCur]) % 86; } @@ -885,7 +885,8 @@ INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[], A2C128_C(&pOutPos,aFNC1,'\0'); else { - A2C128_C(&pOutPos, data[charCur], charCur + 1 < dataLength ? data[charCur + 1] : 0); + A2C128_C(&pOutPos, data[charCur], + (uchar) (charCur + 1 < dataLength ? data[charCur + 1] : 0)); ++charCur; /* We need this here to get the good index */ /* for the termination flags in Set. */ diff --git a/backend/code128.c b/backend/code128.c index 4854b8e7..33abbb5a 100644 --- a/backend/code128.c +++ b/backend/code128.c @@ -209,7 +209,7 @@ INTERNAL void dxsmooth(int list[2][C128_MAX], int *indexliste) { * Translate Code 128 Set A characters into barcodes. * This set handles all control characters NUL to US. */ -static void c128_set_a(unsigned char source, char dest[], int values[], int *bar_chars) { +static void c128_set_a(const unsigned char source, char dest[], int values[], int *bar_chars) { if (source > 127) { if (source < 160) { @@ -236,7 +236,7 @@ static void c128_set_a(unsigned char source, char dest[], int values[], int *bar * This set handles all characters which are not part of long numbers and not * control characters. */ -static void c128_set_b(unsigned char source, char dest[], int values[], int *bar_chars) { +static void c128_set_b(const unsigned char source, char dest[], int values[], int *bar_chars) { if (source > 127) { strcat(dest, C128Table[source - 32 - 128]); values[(*bar_chars)] = source - 32 - 128; @@ -250,7 +250,8 @@ static void c128_set_b(unsigned char source, char dest[], int values[], int *bar /* Translate Code 128 Set C characters into barcodes * This set handles numbers in a compressed form */ -static void c128_set_c(unsigned char source_a, unsigned char source_b, char dest[], int values[], int *bar_chars) { +static void c128_set_c(const unsigned char source_a, const unsigned char source_b, char dest[], int values[], + int *bar_chars) { int weight; weight = (10 * ctoi(source_a)) + ctoi(source_b); @@ -260,7 +261,8 @@ static void c128_set_c(unsigned char source_a, unsigned char source_b, char dest } /* Treats source as ISO 8859-1 and copies into symbol->text, converting to UTF-8. Returns length of symbol->text */ -STATIC_UNLESS_ZINT_TEST int hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char *source, int source_len) { +STATIC_UNLESS_ZINT_TEST int hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char *source, + const int source_len) { int i, j; for (i = 0, j = 0; i < source_len && j < (int) sizeof(symbol->text); i++) { @@ -293,7 +295,7 @@ STATIC_UNLESS_ZINT_TEST int hrt_cpy_iso8859_1(struct zint_symbol *symbol, const } /* Handle Code 128, 128B and HIBC 128 */ -INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], const size_t length) { +INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], int length) { int i, j, k, values[C128_MAX] = {0}, bar_characters, read, total_sum; int error_number, indexchaine, indexliste, f_state; int sourcelen; @@ -445,40 +447,40 @@ INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], /* Now we can calculate how long the barcode is going to be - and stop it from being too long */ last_set = set[0]; - glyph_count = 0.0; + glyph_count = 0.0f; for (i = 0; i < sourcelen; i++) { if ((set[i] == 'a') || (set[i] == 'b')) { - glyph_count = glyph_count + 1.0; + glyph_count = glyph_count + 1.0f; } if ((fset[i] == 'f') || (fset[i] == 'n')) { - glyph_count = glyph_count + 1.0; + glyph_count = glyph_count + 1.0f; } if (((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { if (set[i] != last_set) { last_set = set[i]; - glyph_count = glyph_count + 1.0; + glyph_count = glyph_count + 1.0f; } } if (i == 0) { if (fset[i] == 'F') { - glyph_count = glyph_count + 2.0; + glyph_count = glyph_count + 2.0f; } } else { if ((fset[i] == 'F') && (fset[i - 1] != 'F')) { - glyph_count = glyph_count + 2.0; + glyph_count = glyph_count + 2.0f; } if ((fset[i] != 'F') && (fset[i - 1] == 'F')) { - glyph_count = glyph_count + 2.0; + glyph_count = glyph_count + 2.0f; } } if (set[i] == 'C') { - glyph_count = glyph_count + 0.5; + glyph_count = glyph_count + 0.5f; } else { - glyph_count = glyph_count + 1.0; + glyph_count = glyph_count + 1.0f; } } - if (glyph_count > 60.0) { + if (glyph_count > 60.0f) { strcpy(symbol->errtxt, "341: Input too long"); return ZINT_ERROR_TOO_LONG; } @@ -696,7 +698,7 @@ INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], } /* Handle EAN-128 (Now known as GS1-128) */ -INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length) { +INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], int length) { int i, j, values[C128_MAX] = {0}, bar_characters, read, total_sum; int error_number, indexchaine, indexliste; int list[2][C128_MAX] = {{0}}; @@ -706,9 +708,9 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s int separator_row, linkage_flag, c_count; int reduced_length; #ifndef _MSC_VER - char reduced[length + 1]; + unsigned char reduced[length + 1]; #else - char* reduced = (char*) _alloca(length + 1); + unsigned char *reduced = (unsigned char *) _alloca(length + 1); #endif strcpy(dest, ""); @@ -735,7 +737,7 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s if (error_number != 0) { return error_number; } - reduced_length = strlen(reduced); + reduced_length = (int) ustrlen(reduced); /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ indexliste = 0; @@ -832,25 +834,25 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s /* Now we can calculate how long the barcode is going to be - and stop it from being too long */ last_set = set[0]; - glyph_count = 0.0; + glyph_count = 0.0f; for (i = 0; i < reduced_length; i++) { if ((set[i] == 'a') || (set[i] == 'b')) { - glyph_count = glyph_count + 1.0; + glyph_count = glyph_count + 1.0f; } if (((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { if (set[i] != last_set) { last_set = set[i]; - glyph_count = glyph_count + 1.0; + glyph_count = glyph_count + 1.0f; } } if ((set[i] == 'C') && (reduced[i] != '[')) { - glyph_count = glyph_count + 0.5; + glyph_count = glyph_count + 0.5f; } else { - glyph_count = glyph_count + 1.0; + glyph_count = glyph_count + 1.0f; } } - if (glyph_count > 60.0) { + if (glyph_count > 60.0f) { strcpy(symbol->errtxt, "344: Input too long"); return ZINT_ERROR_TOO_LONG; } @@ -1006,7 +1008,7 @@ INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const s } } - for (i = 0; i < (int) length; i++) { + for (i = 0; i < length; i++) { if ((source[i] != '[') && (source[i] != ']')) { symbol->text[i] = source[i]; } @@ -1059,7 +1061,7 @@ INTERNAL int nve_18(struct zint_symbol *symbol, unsigned char source[], int leng ean128_equiv[21] = itoc(nve_check); ean128_equiv[22] = '\0'; - error_number = ean_128(symbol, ean128_equiv, ustrlen(ean128_equiv)); + error_number = ean_128(symbol, ean128_equiv, (int) ustrlen(ean128_equiv)); return error_number; } @@ -1101,7 +1103,7 @@ INTERNAL int ean_14(struct zint_symbol *symbol, unsigned char source[], int leng ean128_equiv[17] = itoc(check_digit); ean128_equiv[18] = '\0'; - error_number = ean_128(symbol, ean128_equiv, ustrlen(ean128_equiv)); + error_number = ean_128(symbol, ean128_equiv, (int) ustrlen(ean128_equiv)); return error_number; } diff --git a/backend/common.c b/backend/common.c index d2befb5e..891b6379 100644 --- a/backend/common.c +++ b/backend/common.c @@ -30,7 +30,9 @@ SUCH DAMAGE. */ /* vim: set ts=4 sw=4 et : */ +#ifdef ZINT_TEST #include +#endif #ifdef _MSC_VER #include #endif diff --git a/backend/common.h b/backend/common.h index 68b244b7..a8ba5bb6 100644 --- a/backend/common.h +++ b/backend/common.h @@ -55,6 +55,7 @@ #define ustrlen(source) strlen((const char *) (source)) #define ustrcpy(target, source) strcpy((char *) (target), (const char *) (source)) #define ustrcat(target, source) strcat((char *) (target), (const char *) (source)) +#define ustrncat(target, source, count) strncat((char *) (target), (const char *) (source), (count)) #if defined(__GNUC__) && !defined(_WIN32) && !defined(ZINT_TEST) #define INTERNAL __attribute__ ((visibility ("hidden"))) diff --git a/backend/composite.c b/backend/composite.c index 30c7a7f0..6e7a03e2 100644 --- a/backend/composite.c +++ b/backend/composite.c @@ -64,13 +64,15 @@ #include "composite.h" INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int length); -INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); -INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[], int *p_with_addon); +INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); +INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, const unsigned char source[], + unsigned char local_source[], int *p_with_addon); INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); +INTERNAL int rss_date(const unsigned char source[], const int src_posn); -static int _min(int first, int second) { +static int _min(const int first, const int second) { if (first <= second) return first; @@ -79,12 +81,12 @@ static int _min(int first, int second) { } /* gets bit in bitString at bitPos */ -static int getBit(UINT *bitStr, int bitPos) { +static int getBit(const UINT *bitStr, const int bitPos) { return !!(bitStr[bitPos >> 4] & (0x8000 >> (bitPos & 15))); } /* converts bit string to base 928 values, codeWords[0] is highest order */ -static int encode928(UINT bitString[], UINT codeWords[], int bitLng) { +static int encode928(const UINT bitString[], UINT codeWords[], const int bitLng) { int i, j, b, cwNdx, cwLng; for (cwNdx = cwLng = b = 0; b < bitLng; b += 69, cwNdx += 7) { int bitCnt = _min(bitLng - b, 69); @@ -100,49 +102,37 @@ static int encode928(UINT bitString[], UINT codeWords[], int bitLng) { } for (i = cwCnt - 1; i > 0; i--) { /* add "carries" */ - codeWords[cwNdx + i - 1] += codeWords[cwNdx + i] / 928L; - codeWords[cwNdx + i] %= 928L; + codeWords[cwNdx + i - 1] += codeWords[cwNdx + i] / 928; + codeWords[cwNdx + i] %= 928; } } return (cwLng); } /* CC-A 2D component */ -static int cc_a(struct zint_symbol *symbol, char source[], int cc_width) { +static int cc_a(struct zint_symbol *symbol, const char source[], const int cc_width) { int i, segment, bitlen, cwCnt, variant, rows; - int k, offset, j, total, rsCodeWords[8]; + int k, offset, j, total, rsCodeWords[8] = {0}; int LeftRAPStart, RightRAPStart, CentreRAPStart, StartCluster; - int LeftRAP, RightRAP, CentreRAP, Cluster, dummy[5]; + int LeftRAP, RightRAP, CentreRAP, Cluster; int loop; - UINT codeWords[28]; - UINT bitStr[13]; + UINT codeWords[28] = {0}; + UINT bitStr[13] = {0}; char pattern[580]; - char local_source[210]; /* A copy of source but with padding zeroes to make 208 bits */ + int bp = 0; variant = 0; - for (i = 0; i < 13; i++) { - bitStr[i] = 0; - } - for (i = 0; i < 28; i++) { - codeWords[i] = 0; - } - bitlen = (int)strlen(source); - for (i = 0; i < 208; i++) { - local_source[i] = '0'; - } - for (i = 0; i < bitlen; i++) { - local_source[i] = source[i]; - } - local_source[208] = '\0'; - for (segment = 0; segment < 13; segment++) { int strpos = segment * 16; - for (i = 0; i < 16; i++) { - if (local_source[strpos + i] == '1') { - bitStr[segment] += (0x8000 >> i); + if (strpos >= bitlen) { + break; + } + for (i = 0; i < 16 && strpos + i < bitlen; i++) { + if (source[strpos + i] == '1') { + bitStr[segment] |= (0x8000 >> i); } } } @@ -205,9 +195,6 @@ static int cc_a(struct zint_symbol *symbol, char source[], int cc_width) { /* Reed-Solomon error correction */ - for (i = 0; i < 8; i++) { - rsCodeWords[i] = 0; - } for (i = 0; i < cwCnt; i++) { total = (codeWords[i] + rsCodeWords[k - 1]) % 929; for (j = k - 1; j >= 0; j--) { @@ -242,50 +229,44 @@ static int cc_a(struct zint_symbol *symbol, char source[], int cc_width) { Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ for (i = 0; i < rows; i++) { - strcpy(pattern, ""); + bp = 0; offset = 929 * Cluster; - for (j = 0; j < 5; j++) { - dummy[j] = 0; - } - for (j = 0; j < cc_width; j++) { - dummy[j + 1] = codeWords[i * cc_width + j]; - } + k = i * cc_width; /* Copy the data into codebarre */ if (cc_width != 3) { - bin_append(rap_side[LeftRAP - 1], 10, pattern); - } - bin_append(pdf_bitpattern[offset + dummy[1]], 16, pattern); - strcat(pattern, "0"); - if (cc_width == 3) { - bin_append(rap_centre[CentreRAP - 1], 10, pattern); + bp = bin_append_posn(rap_side[LeftRAP - 1], 10, pattern, bp); } + bp = bin_append_posn(pdf_bitpattern[offset + codeWords[k]], 16, pattern, bp); + pattern[bp++] = '0'; if (cc_width >= 2) { - bin_append(pdf_bitpattern[offset + dummy[2]], 16, pattern); - strcat(pattern, "0"); + if (cc_width == 3) { + bp = bin_append_posn(rap_centre[CentreRAP - 1], 10, pattern, bp); + } + bp = bin_append_posn(pdf_bitpattern[offset + codeWords[k + 1]], 16, pattern, bp); + pattern[bp++] = '0'; + if (cc_width >= 3) { + if (cc_width == 4) { + bp = bin_append_posn(rap_centre[CentreRAP - 1], 10, pattern, bp); + } + bp = bin_append_posn(pdf_bitpattern[offset + codeWords[k + 2]], 16, pattern, bp); + pattern[bp++] = '0'; + if (cc_width == 4) { + bp = bin_append_posn(pdf_bitpattern[offset + codeWords[k + 3]], 16, pattern, bp); + pattern[bp++] = '0'; + } + } } - if (cc_width == 4) { - bin_append(rap_centre[CentreRAP - 1], 10, pattern); - } - if (cc_width >= 3) { - bin_append(pdf_bitpattern[offset + dummy[3]], 16, pattern); - strcat(pattern, "0"); - } - if (cc_width == 4) { - bin_append(pdf_bitpattern[offset + dummy[4]], 16, pattern); - strcat(pattern, "0"); - } - bin_append(rap_side[RightRAP - 1], 10, pattern); - strcat(pattern, "1"); /* stop */ + bp = bin_append_posn(rap_side[RightRAP - 1], 10, pattern, bp); + pattern[bp++] = '1'; /* stop */ /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ - for (loop = 0; loop < (int) strlen(pattern); loop++) { + for (loop = 0; loop < bp; loop++) { if (pattern[loop] == '1') { set_module(symbol, i, loop); } } symbol->row_height[i] = 2; symbol->rows++; - symbol->width = strlen(pattern); /* Set up RAPs and Cluster for next row */ LeftRAP++; @@ -306,6 +287,7 @@ static int cc_a(struct zint_symbol *symbol, char source[], int cc_width) { Cluster = 0; } } + symbol->width = bp; if (symbol->debug & ZINT_DEBUG_PRINT) { printf("CC-A Columns: %d, Rows: %d\n", cc_width, symbol->rows); @@ -315,22 +297,22 @@ static int cc_a(struct zint_symbol *symbol, char source[], int cc_width) { } /* CC-B 2D component */ -static int cc_b(struct zint_symbol *symbol, char source[], int cc_width) { - int length, i; +static int cc_b(struct zint_symbol *symbol, const char source[], const int cc_width) { + int length = (int) strlen(source) / 8; + int i; #ifndef _MSC_VER - unsigned char data_string[(strlen(source) / 8) + 3]; + unsigned char data_string[length + 3]; #else - unsigned char *data_string = (unsigned char *) _alloca((strlen(source) / 8) + 3); + unsigned char *data_string = (unsigned char *) _alloca(length + 3); #endif int chainemc[180], mclength; - int k, j, p, longueur, mccorrection[50], offset; - int total, dummy[5]; + int k, j, p, longueur, mccorrection[50] = {0}, offset; + int total; char pattern[580]; int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster; int LeftRAP, CentreRAP, RightRAP, Cluster, loop; int columns; - - length = strlen(source) / 8; + int bp = 0; for (i = 0; i < length; i++) { int binloc = i * 8; @@ -338,12 +320,11 @@ static int cc_b(struct zint_symbol *symbol, char source[], int cc_width) { data_string[i] = 0; for (p = 0; p < 8; p++) { if (source[binloc + p] == '1') { - data_string[i] += (0x80 >> p); + data_string[i] |= (0x80 >> p); } } } - mclength = 0; /* "the CC-B component shall have codeword 920 in the first symbol character position" (section 9a) */ @@ -357,89 +338,66 @@ static int cc_b(struct zint_symbol *symbol, char source[], int cc_width) { variant = 0; if (cc_width == 2) { - variant = 13; - if (mclength <= 33) { - variant = 12; - } - if (mclength <= 29) { - variant = 11; - } - if (mclength <= 24) { - variant = 10; - } - if (mclength <= 19) { - variant = 9; - } - if (mclength <= 13) { - variant = 8; - } if (mclength <= 8) { variant = 7; + } else if (mclength <= 13) { + variant = 8; + } else if (mclength <= 19) { + variant = 9; + } else if (mclength <= 24) { + variant = 10; + } else if (mclength <= 29) { + variant = 11; + } else if (mclength <= 33) { + variant = 12; + } else { + variant = 13; } - } - - if (cc_width == 3) { - variant = 23; - if (mclength <= 70) { - variant = 22; - } - if (mclength <= 58) { - variant = 21; - } - if (mclength <= 46) { - variant = 20; - } - if (mclength <= 34) { - variant = 19; - } - if (mclength <= 24) { - variant = 18; - } - if (mclength <= 18) { - variant = 17; - } - if (mclength <= 14) { - variant = 16; - } - if (mclength <= 10) { - variant = 15; - } + } else if (cc_width == 3) { if (mclength <= 6) { variant = 14; + } else if (mclength <= 10) { + variant = 15; + } else if (mclength <= 14) { + variant = 16; + } else if (mclength <= 18) { + variant = 17; + } else if (mclength <= 24) { + variant = 18; + } else if (mclength <= 34) { + variant = 19; + } else if (mclength <= 46) { + variant = 20; + } else if (mclength <= 58) { + variant = 21; + } else if (mclength <= 70) { + variant = 22; + } else { + variant = 23; } - } - - if (cc_width == 4) { - variant = 34; - if (mclength <= 108) { - variant = 33; - } - if (mclength <= 90) { - variant = 32; - } - if (mclength <= 72) { - variant = 31; - } - if (mclength <= 54) { - variant = 30; - } - if (mclength <= 39) { - variant = 29; - } - if (mclength <= 30) { - variant = 28; - } - if (mclength <= 24) { - variant = 27; - } - if (mclength <= 18) { - variant = 26; - } - if (mclength <= 12) { - variant = 25; - } + } else if (cc_width == 4) { if (mclength <= 8) { variant = 24; + } else if (mclength <= 12) { + variant = 25; + } else if (mclength <= 18) { + variant = 26; + } else if (mclength <= 24) { + variant = 27; + } else if (mclength <= 30) { + variant = 28; + } else if (mclength <= 39) { + variant = 29; + } else if (mclength <= 54) { + variant = 30; + } else if (mclength <= 72) { + variant = 31; + } else if (mclength <= 90) { + variant = 32; + } else if (mclength <= 108) { + variant = 33; + } else { + variant = 34; } } @@ -462,9 +420,6 @@ static int cc_b(struct zint_symbol *symbol, char source[], int cc_width) { /* Reed-Solomon error correction */ longueur = mclength; - for (loop = 0; loop < 50; loop++) { - mccorrection[loop] = 0; - } for (i = 0; i < longueur; i++) { total = (chainemc[i] + mccorrection[k - 1]) % 929; for (j = k - 1; j >= 0; j--) { @@ -502,47 +457,41 @@ static int cc_b(struct zint_symbol *symbol, char source[], int cc_width) { /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ for (i = 0; i < symbol->rows; i++) { - strcpy(pattern, ""); + bp = 0; offset = 929 * Cluster; - for (j = 0; j < 5; j++) { - dummy[j] = 0; - } - for (j = 0; j < columns; j++) { - dummy[j + 1] = chainemc[i * columns + j]; - } + k = i * columns; /* Copy the data into codebarre */ - bin_append(rap_side[LeftRAP - 1], 10, pattern); - bin_append(pdf_bitpattern[offset + dummy[1]], 16, pattern); - strcat(pattern, "0"); - if (cc_width == 3) { - bin_append(rap_centre[CentreRAP - 1], 10, pattern); - } + bp = bin_append_posn(rap_side[LeftRAP - 1], 10, pattern, bp); + bp = bin_append_posn(pdf_bitpattern[offset + chainemc[k]], 16, pattern, bp); + pattern[bp++] = '0'; if (cc_width >= 2) { - bin_append(pdf_bitpattern[offset + dummy[2]], 16, pattern); - strcat(pattern, "0"); + if (cc_width == 3) { + bp = bin_append_posn(rap_centre[CentreRAP - 1], 10, pattern, bp); + } + bp = bin_append_posn(pdf_bitpattern[offset + chainemc[k + 1]], 16, pattern, bp); + pattern[bp++] = '0'; + if (cc_width >= 3) { + if (cc_width == 4) { + bp = bin_append_posn(rap_centre[CentreRAP - 1], 10, pattern, bp); + } + bp = bin_append_posn(pdf_bitpattern[offset + chainemc[k + 2]], 16, pattern, bp); + pattern[bp++] = '0'; + if (cc_width == 4) { + bp = bin_append_posn(pdf_bitpattern[offset + chainemc[k + 3]], 16, pattern, bp); + pattern[bp++] = '0'; + } + } } - if (cc_width == 4) { - bin_append(rap_centre[CentreRAP - 1], 10, pattern); - } - if (cc_width >= 3) { - bin_append(pdf_bitpattern[offset + dummy[3]], 16, pattern); - strcat(pattern, "0"); - } - if (cc_width == 4) { - bin_append(pdf_bitpattern[offset + dummy[4]], 16, pattern); - strcat(pattern, "0"); - } - bin_append(rap_side[RightRAP - 1], 10, pattern); - strcat(pattern, "1"); /* stop */ + bp = bin_append_posn(rap_side[RightRAP - 1], 10, pattern, bp); + pattern[bp++] = '1'; /* stop */ /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ - for (loop = 0; loop < (int) strlen(pattern); loop++) { + for (loop = 0; loop < bp; loop++) { if (pattern[loop] == '1') { set_module(symbol, i, loop); } } symbol->row_height[i] = 2; - symbol->width = strlen(pattern); /* Set up RAPs and Cluster for next row */ LeftRAP++; @@ -563,6 +512,7 @@ static int cc_b(struct zint_symbol *symbol, char source[], int cc_width) { Cluster = 0; } } + symbol->width = bp; if (symbol->debug & ZINT_DEBUG_PRINT) { printf("CC-B Columns: %d, Rows: %d\n", cc_width, symbol->rows); @@ -572,19 +522,19 @@ static int cc_b(struct zint_symbol *symbol, char source[], int cc_width) { } /* CC-C 2D component - byte compressed PDF417 */ -static int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc_level) { - int length, i, p; +static int cc_c(struct zint_symbol *symbol, const char source[], const int cc_width, const int ecc_level) { + int length = (int) strlen(source) / 8; + int i, p; #ifndef _MSC_VER - unsigned char data_string[(strlen(source) / 8) + 4]; + unsigned char data_string[length + 4]; #else - unsigned char *data_string = (unsigned char *) _alloca((strlen(source) / 8) + 4); + unsigned char *data_string = (unsigned char *) _alloca(length + 4); #endif int chainemc[1000], mclength, k; - int offset, longueur, loop, total, j, mccorrection[520]; + int offset, longueur, loop, total, j, mccorrection[520] = {0}; int c1, c2, c3, dummy[35]; char pattern[580]; - - length = strlen(source) / 8; + int bp = 0; for (i = 0; i < length; i++) { int binloc = i * 8; @@ -592,7 +542,7 @@ static int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc data_string[i] = 0; for (p = 0; p < 8; p++) { if (source[binloc + p] == '1') { - data_string[i] += (0x80 >> p); + data_string[i] |= (0x80 >> p); } } } @@ -636,9 +586,6 @@ static int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc } longueur = mclength; - for (loop = 0; loop < 520; loop++) { - mccorrection[loop] = 0; - } for (i = 0; i < longueur; i++) { total = (chainemc[i] + mccorrection[k - 1]) % 929; for (j = k - 1; j >= 0; j--) { @@ -662,12 +609,13 @@ static int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc } /* 818 - The CW string is finished */ - c1 = (mclength / cc_width - 1) / 3; - c2 = ecc_level * 3 + (mclength / cc_width - 1) % 3; + symbol->rows = mclength / cc_width; + c1 = (symbol->rows - 1) / 3; + c2 = ecc_level * 3 + (symbol->rows - 1) % 3; c3 = cc_width - 1; /* we now encode each row */ - for (i = 0; i <= (mclength / cc_width) - 1; i++) { + for (i = 0; i <= symbol->rows - 1; i++) { for (j = 0; j < cc_width; j++) { dummy[j + 1] = chainemc[i * cc_width + j]; } @@ -689,24 +637,23 @@ static int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc offset = 1858; /* cluster(6) */ break; } - strcpy(pattern, ""); - bin_append(0x1FEA8, 17, pattern); /* Row start */ + bp = 0; + bp = bin_append_posn(0x1FEA8, 17, pattern, bp); /* Row start */ for (j = 0; j <= cc_width + 1; j++) { - bin_append(pdf_bitpattern[offset + dummy[j]], 16, pattern); - strcat(pattern, "0"); + bp = bin_append_posn(pdf_bitpattern[offset + dummy[j]], 16, pattern, bp); + pattern[bp++] = '0'; } - bin_append(0x3FA29, 18, pattern); /* Row Stop */ + bp = bin_append_posn(0x3FA29, 18, pattern, bp); /* Row Stop */ - for (loop = 0; loop < (int) strlen(pattern); loop++) { + for (loop = 0; loop < bp; loop++) { if (pattern[loop] == '1') { set_module(symbol, i, loop); } } symbol->row_height[i] = 3; } - symbol->rows = (mclength / cc_width); - symbol->width = (int)strlen(pattern); + symbol->width = bp; if (symbol->debug & ZINT_DEBUG_PRINT) { printf("CC-C Columns: %d, Rows: %d\n", cc_width, symbol->rows); @@ -715,65 +662,51 @@ static int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc return 0; } -static int calc_padding_cca(int binary_length, int cc_width) { +static int calc_padding_cca(const int binary_length, const int cc_width) { int target_bitsize = 0; switch (cc_width) { case 2: - if (binary_length <= 167) { - target_bitsize = 167; - } - if (binary_length <= 138) { - target_bitsize = 138; - } - if (binary_length <= 118) { - target_bitsize = 118; - } - if (binary_length <= 108) { - target_bitsize = 108; - } - if (binary_length <= 88) { - target_bitsize = 88; - } - if (binary_length <= 78) { - target_bitsize = 78; - } if (binary_length <= 59) { target_bitsize = 59; + } else if (binary_length <= 78) { + target_bitsize = 78; + } else if (binary_length <= 88) { + target_bitsize = 88; + } else if (binary_length <= 108) { + target_bitsize = 108; + } else if (binary_length <= 118) { + target_bitsize = 118; + } else if (binary_length <= 138) { + target_bitsize = 138; + } else if (binary_length <= 167) { + target_bitsize = 167; } break; case 3: - if (binary_length <= 167) { - target_bitsize = 167; - } - if (binary_length <= 138) { - target_bitsize = 138; - } - if (binary_length <= 118) { - target_bitsize = 118; - } - if (binary_length <= 98) { - target_bitsize = 98; - } if (binary_length <= 78) { target_bitsize = 78; + } else if (binary_length <= 98) { + target_bitsize = 98; + } else if (binary_length <= 118) { + target_bitsize = 118; + } else if (binary_length <= 138) { + target_bitsize = 138; + } else if (binary_length <= 167) { + target_bitsize = 167; } break; case 4: - if (binary_length <= 197) { - target_bitsize = 197; - } - if (binary_length <= 167) { - target_bitsize = 167; - } - if (binary_length <= 138) { - target_bitsize = 138; - } - if (binary_length <= 108) { - target_bitsize = 108; - } if (binary_length <= 78) { target_bitsize = 78; + } else if (binary_length <= 108) { + target_bitsize = 108; + } else if (binary_length <= 138) { + target_bitsize = 138; + } else if (binary_length <= 167) { + target_bitsize = 167; + } else if (binary_length <= 197) { + target_bitsize = 197; } break; } @@ -781,98 +714,73 @@ static int calc_padding_cca(int binary_length, int cc_width) { return target_bitsize; } -static int calc_padding_ccb(int binary_length, int cc_width) { +static int calc_padding_ccb(const int binary_length, const int cc_width) { int target_bitsize = 0; switch (cc_width) { case 2: - if (binary_length <= 336) { - target_bitsize = 336; - } - if (binary_length <= 296) { - target_bitsize = 296; - } - if (binary_length <= 256) { - target_bitsize = 256; - } - if (binary_length <= 208) { - target_bitsize = 208; - } - if (binary_length <= 160) { - target_bitsize = 160; - } - if (binary_length <= 104) { - target_bitsize = 104; - } if (binary_length <= 56) { target_bitsize = 56; + } else if (binary_length <= 104) { + target_bitsize = 104; + } else if (binary_length <= 160) { + target_bitsize = 160; + } else if (binary_length <= 208) { + target_bitsize = 208; + } else if (binary_length <= 256) { + target_bitsize = 256; + } else if (binary_length <= 296) { + target_bitsize = 296; + } else if (binary_length <= 336) { + target_bitsize = 336; } break; case 3: - if (binary_length <= 768) { - target_bitsize = 768; - } - if (binary_length <= 648) { - target_bitsize = 648; - } - if (binary_length <= 536) { - target_bitsize = 536; - } - if (binary_length <= 416) { - target_bitsize = 416; - } - if (binary_length <= 304) { - target_bitsize = 304; - } - if (binary_length <= 208) { - target_bitsize = 208; - } - if (binary_length <= 152) { - target_bitsize = 152; - } - if (binary_length <= 112) { - target_bitsize = 112; - } - if (binary_length <= 72) { - target_bitsize = 72; - } if (binary_length <= 32) { target_bitsize = 32; + } else if (binary_length <= 72) { + target_bitsize = 72; + } else if (binary_length <= 112) { + target_bitsize = 112; + } else if (binary_length <= 152) { + target_bitsize = 152; + } else if (binary_length <= 208) { + target_bitsize = 208; + } else if (binary_length <= 304) { + target_bitsize = 304; + } else if (binary_length <= 416) { + target_bitsize = 416; + } else if (binary_length <= 536) { + target_bitsize = 536; + } else if (binary_length <= 648) { + target_bitsize = 648; + } else if (binary_length <= 768) { + target_bitsize = 768; } break; case 4: - if (binary_length <= 1184) { - target_bitsize = 1184; - } - if (binary_length <= 1016) { - target_bitsize = 1016; - } - if (binary_length <= 840) { - target_bitsize = 840; - } - if (binary_length <= 672) { - target_bitsize = 672; - } - if (binary_length <= 496) { - target_bitsize = 496; - } - if (binary_length <= 352) { - target_bitsize = 352; - } - if (binary_length <= 264) { - target_bitsize = 264; - } - if (binary_length <= 208) { - target_bitsize = 208; - } - if (binary_length <= 152) { - target_bitsize = 152; - } - if (binary_length <= 96) { - target_bitsize = 96; - } if (binary_length <= 56) { target_bitsize = 56; + } else if (binary_length <= 96) { + target_bitsize = 96; + } else if (binary_length <= 152) { + target_bitsize = 152; + } else if (binary_length <= 208) { + target_bitsize = 208; + } else if (binary_length <= 264) { + target_bitsize = 264; + } else if (binary_length <= 352) { + target_bitsize = 352; + } else if (binary_length <= 496) { + target_bitsize = 496; + } else if (binary_length <= 672) { + target_bitsize = 672; + } else if (binary_length <= 840) { + target_bitsize = 840; + } else if (binary_length <= 1016) { + target_bitsize = 1016; + } else if (binary_length <= 1184) { + target_bitsize = 1184; } break; } @@ -880,7 +788,7 @@ static int calc_padding_ccb(int binary_length, int cc_width) { return target_bitsize; } -static int calc_padding_ccc(int binary_length, int *cc_width, int lin_width, int *ecc) { +static int calc_padding_ccc(const int binary_length, int *cc_width, const int lin_width, int *ecc) { int target_bitsize = 0; int byte_length, codewords_used, ecc_level, ecc_codewords, rows; int codewords_total, target_codewords, target_bytesize; @@ -918,11 +826,11 @@ static int calc_padding_ccc(int binary_length, int *cc_width, int lin_width, int if (*(cc_width) > 30) { *(cc_width) = 30; } - rows = ceil((double) codewords_used / *(cc_width)); + rows = (int) ceil((double) codewords_used / *(cc_width)); /* stop the symbol from becoming too high */ while (rows > 30 && *(cc_width) < 30) { *(cc_width) = *(cc_width) + 1; - rows = ceil((double) codewords_used / *(cc_width)); + rows = (int) ceil((double) codewords_used / *(cc_width)); } if (rows > 30) { @@ -946,18 +854,20 @@ static int calc_padding_ccc(int binary_length, int *cc_width, int lin_width, int } /* Handles all data encodation from section 5 of ISO/IEC 24723 */ -static int cc_binary_string(struct zint_symbol *symbol, const char source[], char binary_string[], int cc_mode, int *cc_width, int *ecc, int lin_width) { +static int cc_binary_string(struct zint_symbol *symbol, const unsigned char source[], const int source_len, + char binary_string[], const int cc_mode, int *cc_width, int *ecc, const int lin_width) { int encoding_method, read_posn, alpha_pad; int i, j, ai_crop, ai_crop_posn, fnc1_latch; - int ai90_mode, last_digit, remainder, binary_length; + int ai90_mode, remainder; + char last_digit = '\0'; int mode; - int source_len = strlen(source); #ifndef _MSC_VER char general_field[source_len + 1]; #else char *general_field = (char *) _alloca(source_len + 1); #endif int target_bitsize; + int bp = 0; int debug = symbol->debug & ZINT_DEBUG_PRINT; encoding_method = 1; @@ -972,53 +882,38 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha if ((source[0] == '1') && ((source[1] == '0') || (source[1] == '1') || (source[1] == '7'))) { /* Source starts (10), (11) or (17) */ - encoding_method = 2; - } - - if ((source[0] == '9') && (source[1] == '0')) { + if (source[1] == '0' || rss_date(source, 2) >= 0) { /* Check date valid if (11) or (17) */ + encoding_method = 2; + } + } else if ((source[0] == '9') && (source[1] == '0')) { /* Source starts (90) */ encoding_method = 3; } if (encoding_method == 1) { - strcat(binary_string, "0"); + binary_string[bp++] = '0'; if (debug) printf("CC-%c Encodation Method: 0\n", 'A' + (cc_mode - 1)); - } - if (encoding_method == 2) { + } else if (encoding_method == 2) { /* Encoding Method field "10" - date and lot number */ - strcat(binary_string, "10"); + bp = bin_append_posn(2, 2, binary_string, bp); /* "10" */ if (source[1] == '0') { /* No date data */ - strcat(binary_string, "11"); + bp = bin_append_posn(3, 2, binary_string, bp); /* "11" */ read_posn = 2; } else { - long int group_val; /* Production Date (11) or Expiration Date (17) */ - char date_str[4]; - date_str[0] = source[2]; - date_str[1] = source[3]; - date_str[2] = '\0'; - group_val = atoi(date_str) * 384; - date_str[0] = source[4]; - date_str[1] = source[5]; - group_val += (atoi(date_str) - 1) * 32; - - date_str[0] = source[6]; - date_str[1] = source[7]; - group_val += atoi(date_str); - - bin_append(group_val, 16, binary_string); + bp = bin_append_posn(rss_date(source, 2), 16, binary_string, bp); if (source[1] == '1') { /* Production Date AI 11 */ - strcat(binary_string, "0"); + binary_string[bp++] = '0'; } else { /* Expiration Date AI 17 */ - strcat(binary_string, "1"); + binary_string[bp++] = '1'; } read_posn = 8; @@ -1026,21 +921,24 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha /* Followed by AI 10 - strip this from general field */ read_posn += 2; } else if (source[read_posn]) { - /* ISO/IEC 24723:2010 5.3.1 "If a lot number does not directly follow the date element string, a FNC1 is encoded following the date element string ..." */ + /* ISO/IEC 24723:2010 5.3.1 "If a lot number does not directly follow the date element string, + a FNC1 is encoded following the date element string ..." */ fnc1_latch = 1; } else { /* "... even if no more data follows the date element string" */ - /* So still need FNC1 character but can't do single FNC1 in numeric mode, so insert alphanumeric latch "0000" and alphanumeric FNC1 "01111" - (this implementation detail taken from BWIPP https://github.com/bwipp/postscriptbarcode Copyright (c) 2004-2019 Terry Burton) */ - strcat(binary_string, "000001111"); + /* So still need FNC1 character but can't do single FNC1 in numeric mode, so insert alphanumeric latch + "0000" and alphanumeric FNC1 "01111" (this implementation detail taken from BWIPP + https://github.com/bwipp/postscriptbarcode Copyright (c) 2004-2019 Terry Burton) */ + bp = bin_append_posn(15, 9, binary_string, bp); /* "000001111" */ /* Note an alphanumeric FNC1 is also a numeric latch, so now in numeric mode */ } } - if (debug) printf("CC-%c Encodation Method: 10, Compaction Field: %.*s\n", 'A' + (cc_mode - 1), read_posn, source); - } + if (debug) { + printf("CC-%c Encodation Method: 10, Compaction Field: %.*s\n", 'A' + (cc_mode - 1), read_posn, source); + } - if (encoding_method == 3) { + } else if (encoding_method == 3) { /* Encodation Method field of "11" - AI 90 */ #ifndef _MSC_VER char ninety[source_len + 1]; @@ -1061,7 +959,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha i++; } while ((source_len > i + 2) && ('[' != source[i + 2])); ninety[i] = '\0'; - ninety_len = strlen(ninety); + ninety_len = i; /* Find out if the AI 90 data is alphabetic or numeric or both */ @@ -1109,7 +1007,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha int numeric_value; int table3_letter; /* Encodation method "11" can be used */ - strcat(binary_string, "11"); + bp = bin_append_posn(3, 2, binary_string, bp); /* "11" */ numeric -= test1; alpha--; @@ -1119,15 +1017,17 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha if (alphanum == 0 && alpha > numeric) { /* Alpha mode */ - strcat(binary_string, "11"); + bp = bin_append_posn(3, 2, binary_string, bp); /* "11" */ ai90_mode = 2; } else if (alphanum == 0 && alpha == 0) { /* Numeric mode */ - strcat(binary_string, "10"); + bp = bin_append_posn(2, 2, binary_string, bp); /* "10" */ ai90_mode = 3; - } else { /* Note if first 4 are digits then it would be shorter to go into NUMERIC mode first; not implemented */ + } else { + /* Note if first 4 are digits then it would be shorter to go into NUMERIC mode first; not + implemented */ /* Alphanumeric mode */ - strcat(binary_string, "0"); + binary_string[bp++] = '0'; ai90_mode = 1; mode = ALPHANUMERIC; } @@ -1136,7 +1036,8 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha if (next_ai_posn < source_len && source[next_ai_posn] == '[') { /* There are more AIs afterwards */ - if (next_ai_posn + 2 < source_len && (source[next_ai_posn + 1] == '2') && (source[next_ai_posn + 2] == '1')) { + if (next_ai_posn + 2 < source_len + && (source[next_ai_posn + 1] == '2') && (source[next_ai_posn + 2] == '1')) { /* AI 21 follows */ ai_crop = 1; } else if (next_ai_posn + 4 < source_len @@ -1148,12 +1049,12 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha } switch (ai_crop) { - case 0: strcat(binary_string, "0"); + case 0: binary_string[bp++] = '0'; break; - case 1: strcat(binary_string, "10"); + case 1: bp = bin_append_posn(2, 2, binary_string, bp); /* "10" */ ai_crop_posn = next_ai_posn + 1; break; - case 3: strcat(binary_string, "11"); + case 3: bp = bin_append_posn(3, 2, binary_string, bp); /* "11" */ ai_crop_posn = next_ai_posn + 1; break; } @@ -1177,18 +1078,18 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha if (table3_letter != -1) { /* Encoding can be done according to 5.3.2 c) 2) */ /* five bit binary string representing value before letter */ - bin_append(numeric_value, 5, binary_string); + bp = bin_append_posn(numeric_value, 5, binary_string, bp); /* followed by four bit representation of letter from Table 3 */ - bin_append(table3_letter, 4, binary_string); + bp = bin_append_posn(table3_letter, 4, binary_string, bp); } else { /* Encoding is done according to 5.3.2 c) 3) */ - bin_append(31, 5, binary_string); + bp = bin_append_posn(31, 5, binary_string, bp); /* ten bit representation of number */ - bin_append(numeric_value, 10, binary_string); + bp = bin_append_posn(numeric_value, 10, binary_string, bp); /* five bit representation of ASCII character */ - bin_append(ninety[test1] - 65, 5, binary_string); + bp = bin_append_posn(ninety[test1] - 65, 5, binary_string, bp); } read_posn = test1 + 3; @@ -1198,13 +1099,13 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha /* Alpha encodation (section 5.3.3) */ do { if ((source[read_posn] >= 'A') && (source[read_posn] <= 'Z')) { - bin_append(source[read_posn] - 65, 5, binary_string); + bp = bin_append_posn(source[read_posn] - 65, 5, binary_string, bp); } else if ((source[read_posn] >= '0') && (source[read_posn] <= '9')) { - bin_append(source[read_posn] + 4, 6, binary_string); + bp = bin_append_posn(source[read_posn] + 4, 6, binary_string, bp); } else if (source[read_posn] == '[') { - bin_append(31, 5, binary_string); + bp = bin_append_posn(31, 5, binary_string, bp); } read_posn++; @@ -1213,12 +1114,12 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha } if (debug) { - printf("CC-%c Encodation Method: 11, Compaction Field: %.*s, Binary: %s (%d)\n", - 'A' + (cc_mode - 1), read_posn, source, binary_string, (int) strlen(binary_string)); + printf("CC-%c Encodation Method: 11, Compaction Field: %.*s, Binary: %.*s (%d)\n", + 'A' + (cc_mode - 1), read_posn, source, bp, binary_string, bp); } } else { /* Use general field encodation instead */ - strcat(binary_string, "0"); + binary_string[bp++] = '0'; read_posn = 0; if (debug) printf("CC-%c Encodation Method: 0\n", 'A' + (cc_mode - 1)); } @@ -1249,29 +1150,28 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha if (debug) { printf("Mode %s, General Field: %.40s%s\n", mode == NUMERIC ? "NUMERIC" : mode == ALPHANUMERIC ? "ALPHANUMERIC" : "ISO646", - general_field, strlen(general_field) > 40 ? "..." : ""); + general_field, j > 40 ? "..." : ""); } - if (strlen(general_field) != 0) { + if (j != 0) { /* If general field not empty */ alpha_pad = 0; + + if (!general_field_encode(general_field, j, &mode, &last_digit, binary_string, &bp)) { + /* Invalid characters in input data */ + strcpy(symbol->errtxt, "441: Invalid characters in input data"); + return ZINT_ERROR_INVALID_DATA; + } } - if (!general_field_encode(general_field, &mode, &last_digit, binary_string)) { - /* Invalid characters in input data */ - strcpy(symbol->errtxt, "441: Invalid characters in input data"); - return ZINT_ERROR_INVALID_DATA; - } - - binary_length = (int)strlen(binary_string); switch (cc_mode) { case 1: - target_bitsize = calc_padding_cca(binary_length, *(cc_width)); + target_bitsize = calc_padding_cca(bp, *(cc_width)); break; case 2: - target_bitsize = calc_padding_ccb(binary_length, *(cc_width)); + target_bitsize = calc_padding_ccb(bp, *(cc_width)); break; case 3: - target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc); + target_bitsize = calc_padding_ccc(bp, cc_width, lin_width, ecc); break; } @@ -1280,39 +1180,40 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha return ZINT_ERROR_TOO_LONG; } - remainder = target_bitsize - binary_length; + remainder = target_bitsize - bp; if (last_digit) { /* There is still one more numeric digit to encode */ if ((remainder >= 4) && (remainder <= 6)) { - /* ISO/IEC 24723:2010 5.4.1 c) 2) "If four to six bits remain, add 1 to the digit value and encode the result in the next four bits. ..." */ - bin_append(ctoi(last_digit) + 1, 4, binary_string); + /* ISO/IEC 24723:2010 5.4.1 c) 2) "If four to six bits remain, add 1 to the digit value and encode the + result in the next four bits. ..." */ + bp = bin_append_posn(ctoi(last_digit) + 1, 4, binary_string, bp); if (remainder > 4) { - /* "... The fifth and sixth bits, if present, shall be “0”s." (Covered by adding truncated alphanumeric latch below but do explicitly anyway) */ - bin_append(0, remainder - 4, binary_string); + /* "... The fifth and sixth bits, if present, shall be “0”s." (Covered by adding truncated + alphanumeric latch below but do explicitly anyway) */ + bp = bin_append_posn(0, remainder - 4, binary_string, bp); } } else { - bin_append((11 * ctoi(last_digit)) + 18, 7, binary_string); + bp = bin_append_posn((11 * ctoi(last_digit)) + 18, 7, binary_string, bp); /* This may push the symbol up to the next size */ } } - if (strlen(binary_string) > 11805) { /* (2361 * 5) */ + if (bp > 11805) { /* (2361 * 5) */ strcpy(symbol->errtxt, "443: Input too long"); return ZINT_ERROR_TOO_LONG; } - binary_length = (int)strlen(binary_string); switch (cc_mode) { case 1: - target_bitsize = calc_padding_cca(binary_length, *(cc_width)); + target_bitsize = calc_padding_cca(bp, *(cc_width)); break; case 2: - target_bitsize = calc_padding_ccb(binary_length, *(cc_width)); + target_bitsize = calc_padding_ccb(bp, *(cc_width)); break; case 3: - target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc); + target_bitsize = calc_padding_ccc(bp, cc_width, lin_width, ecc); break; } @@ -1321,35 +1222,32 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha return ZINT_ERROR_TOO_LONG; } - if (binary_length < target_bitsize) { + if (bp < target_bitsize) { /* Now add padding to binary string */ if (alpha_pad == 1) { - strcat(binary_string, "11111"); + bp = bin_append_posn(31, 5, binary_string, bp); /* "11111" */ /* Extra FNC1 character required after Alpha encodation (section 5.3.3) */ } if (mode == NUMERIC) { - strcat(binary_string, "0000"); + bp = bin_append_posn(0, 4, binary_string, bp); /* "0000" */ } - while (strlen(binary_string) < (unsigned int) target_bitsize) { - strcat(binary_string, "00100"); - } - - if (strlen(binary_string) > (unsigned int) target_bitsize) { - binary_string[target_bitsize] = '\0'; + while (bp < target_bitsize) { + bp = bin_append_posn(4, 5, binary_string, bp); /* "00100" */ } } + binary_string[target_bitsize] = '\0'; if (debug) { printf("ECC: %d, CC width %d\n", *ecc, *cc_width); - printf("Binary: %s (%d)\n", binary_string, (int) strlen(binary_string)); + printf("Binary: %s (%d)\n", binary_string, target_bitsize); } return 0; } -static int linear_dummy_run(unsigned char *source, int length, char *errtxt) { +static int linear_dummy_run(unsigned char *source, const int length, char *errtxt) { struct zint_symbol *dummy; int error_number; int linear_width; @@ -1372,7 +1270,7 @@ static int linear_dummy_run(unsigned char *source, int length, char *errtxt) { } INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int length) { - int error_number, cc_mode, cc_width, ecc_level; + int error_number, cc_mode, cc_width = 0, ecc_level = 0; int j, i, k; unsigned int bs = 13 * length + 500 + 1; /* Allow for 8 bits + 5-bit latch per char + 500 bits overhead/padding */ #ifndef _MSC_VER @@ -1420,14 +1318,13 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l switch (symbol->symbology) { /* Determine width of 2D component according to ISO/IEC 24723 Table 1 */ case BARCODE_EANX_CC: - cc_width = 0; if (pri_len < 20) { int padded_pri_len; int with_addon; - char padded_pri[21]; + unsigned char padded_pri[21]; padded_pri[0] = '\0'; - ean_leading_zeroes(symbol, (unsigned char *) symbol->primary, (unsigned char *) padded_pri, &with_addon); - padded_pri_len = strlen(padded_pri); + ean_leading_zeroes(symbol, (unsigned char *) symbol->primary, padded_pri, &with_addon); + padded_pri_len = (int) ustrlen(padded_pri); if (padded_pri_len <= 7) { /* EAN-8 */ cc_width = 3; } else { @@ -1473,17 +1370,14 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l break; } - memset(binary_string, 0, bs); - if (cc_mode < 1 || cc_mode > 3) { cc_mode = 1; } if (cc_mode == 1) { - i = cc_binary_string(symbol, (char *) source, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); + i = cc_binary_string(symbol, source, length, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); if (i == ZINT_ERROR_TOO_LONG) { cc_mode = 2; - memset(binary_string, 0, bs); } else if (i != 0) { return i; } @@ -1491,13 +1385,12 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l if (cc_mode == 2) { /* If the data didn't fit into CC-A it is recalculated for CC-B */ - i = cc_binary_string(symbol, (char *) source, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); + i = cc_binary_string(symbol, source, length, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); if (i == ZINT_ERROR_TOO_LONG) { if (symbol->symbology != BARCODE_GS1_128_CC) { return ZINT_ERROR_TOO_LONG; } cc_mode = 3; - memset(binary_string, 0, bs); } else if (i != 0) { return i; } @@ -1505,7 +1398,7 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l if (cc_mode == 3) { /* If the data didn't fit in CC-B (and linear part is GS1-128) it is recalculated for CC-C */ - i = cc_binary_string(symbol, (char *) source, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); + i = cc_binary_string(symbol, source, length, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); if (i != 0) { return i; } @@ -1598,14 +1491,16 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l case BARCODE_GS1_128_CC: if (cc_mode == 3) { bottom_shift = 7; } else { - /* ISO/IEC 24723:2010 12.3 g) "GS1-128 components linked to the right quiet zone of the CC-A or CC-B: the CC-A or CC-B component is - aligned with the last space module of one of the rightmost symbol characters of the linear component. To - calculate the target Code 128 symbol character position for alignment, number the positions from right to - left (0 is the Stop character, 1 is the Check character, etc.), and then Position = (total number of Code 128 symbol characters – 9) div 2" + /* ISO/IEC 24723:2010 12.3 g) "GS1-128 components linked to the right quiet zone of the CC-A or CC-B: + the CC-A or CC-B component is aligned with the last space module of one of the rightmost symbol + characters of the linear component. To calculate the target Code 128 symbol character position for + alignment, number the positions from right to left (0 is the Stop character, 1 is the Check + character, etc.), and then Position = (total number of Code 128 symbol characters – 9) div 2" */ int num_symbols = (linear_width - 2) / 11; int position = (num_symbols - 9) / 2; - int calc_shift = linear->width - position * 11 - 1 - symbol->width; /* Less 1 to align with last space module */ + /* Less 1 to align with last space module */ + int calc_shift = linear->width - position * 11 - 1 - symbol->width; if (position) { calc_shift -= 2; /* Less additional stop modules */ } diff --git a/backend/general_field.c b/backend/general_field.c index b82522e4..89451fd7 100644 --- a/backend/general_field.c +++ b/backend/general_field.c @@ -38,7 +38,7 @@ static char alphanum_puncs[] = "*,-./"; static char isoiec_puncs[] = "!\"%&'()*+,-./:;<=>?_ "; /* Returns type of char at `i`. FNC1 counted as NUMERIC. Returns 0 if invalid char */ -static int general_field_type(char *general_field, int i) { +static int general_field_type(const char *general_field, const int i) { if (general_field[i] == '[' || (general_field[i] >= '0' && general_field[i] <= '9')) { return NUMERIC; } @@ -52,7 +52,8 @@ static int general_field_type(char *general_field, int i) { } /* Returns true if next (including `i`) `num` chars of type `type`, or if given (non-zero), `type2` */ -static int general_field_next(char *general_field, int i, int general_field_len, int num, int type, int type2) { +static int general_field_next(const char *general_field, int i, const int general_field_len, int num, const int type, + const int type2) { if (i + num > general_field_len) { return 0; } @@ -66,7 +67,8 @@ static int general_field_next(char *general_field, int i, int general_field_len, } /* Returns true if next (including `i`) `num` up to `max_num` chars of type `type` and occur at end */ -static int general_field_next_terminate(char *general_field, int i, int general_field_len, int num, int max_num, int type) { +static int general_field_next_terminate(const char *general_field, int i, const int general_field_len, int num, + const int max_num, const int type) { if (i + max_num < general_field_len) { return 0; } @@ -79,7 +81,8 @@ static int general_field_next_terminate(char *general_field, int i, int general_ } /* Returns true if none of the next (including `i`) `num` chars (or end occurs) of type `type` */ -static int general_field_next_none(char *general_field, int i, int general_field_len, int num, int type) { +static int general_field_next_none(const char *general_field, int i, const int general_field_len, int num, + const int type) { for (; i < general_field_len && num; i++, num--) { if (general_field_type(general_field, i) == type) { return 0; @@ -90,11 +93,12 @@ static int general_field_next_none(char *general_field, int i, int general_field /* Attempts to apply encoding rules from sections 7.2.5.5.1 to 7.2.5.5.3 * of ISO/IEC 24724:2011 (same as sections 5.4.1 to 5.4.3 of ISO/IEC 24723:2010) */ -INTERNAL int general_field_encode(char *general_field, int *p_mode, int *p_last_digit, char binary_string[]) { +INTERNAL int general_field_encode(const char *general_field, const int general_field_len, int *p_mode, + char *p_last_digit, char binary_string[], int *p_bp) { int i, d1, d2; int mode = *p_mode; - int last_digit = 0; /* Set to odd remaining digit at end if any */ - int general_field_len = strlen(general_field); + char last_digit = '\0'; /* Set to odd remaining digit at end if any */ + int bp = *p_bp; for (i = 0; i < general_field_len; ) { int type = general_field_type(general_field, i); @@ -104,75 +108,89 @@ INTERNAL int general_field_encode(char *general_field, int *p_mode, int *p_last_ switch (mode) { case NUMERIC: if (i < general_field_len - 1) { /* If at least 2 characters remain */ - if (type != NUMERIC || general_field_type(general_field, i + 1) != NUMERIC) { /* 7.2.5.5.1/5.4.1 a) */ - strcat(binary_string, "0000"); /* Alphanumeric latch */ + if (type != NUMERIC || general_field_type(general_field, i + 1) != NUMERIC) { + /* 7.2.5.5.1/5.4.1 a) */ + bp = bin_append_posn(0, 4, binary_string, bp); /* Alphanumeric latch "0000" */ mode = ALPHANUMERIC; } else { d1 = general_field[i] == '[' ? 10 : ctoi(general_field[i]); d2 = general_field[i + 1] == '[' ? 10 : ctoi(general_field[i + 1]); - bin_append((11 * d1) + d2 + 8, 7, binary_string); + bp = bin_append_posn((11 * d1) + d2 + 8, 7, binary_string, bp); i += 2; } } else { /* If 1 character remains */ - if (type != NUMERIC) { /* 7.2.5.5.1/5.4.1 b) */ - strcat(binary_string, "0000"); /* Alphanumeric latch */ + if (type != NUMERIC) { + /* 7.2.5.5.1/5.4.1 b) */ + bp = bin_append_posn(0, 4, binary_string, bp); /* Alphanumeric latch "0000" */ mode = ALPHANUMERIC; } else { - last_digit = general_field[i]; /* Ending with single digit. 7.2.5.5.1 c) and 5.4.1 c) dealt with separately outside this procedure */ + /* Ending with single digit. + * 7.2.5.5.1 c) and 5.4.1 c) dealt with separately outside this procedure */ + last_digit = general_field[i]; i++; } } break; case ALPHANUMERIC: - if (general_field[i] == '[') { /* 7.2.5.5.2/5.4.2 a) */ - strcat(binary_string, "01111"); + if (general_field[i] == '[') { + /* 7.2.5.5.2/5.4.2 a) */ + bp = bin_append_posn(15, 5, binary_string, bp); /* "01111" */ mode = NUMERIC; i++; - } else if (type == ISOIEC) { /* 7.2.5.5.2/5.4.2 b) */ - strcat(binary_string, "00100"); /* ISO/IEC 646 latch */ + } else if (type == ISOIEC) { + /* 7.2.5.5.2/5.4.2 b) */ + bp = bin_append_posn(4, 5, binary_string, bp); /* ISO/IEC 646 latch "00100" */ mode = ISOIEC; - } else if (general_field_next(general_field, i, general_field_len, 6, NUMERIC, 0)) { /* 7.2.5.5.2/5.4.2 c) */ - strcat(binary_string, "000"); /* Numeric latch */ + } else if (general_field_next(general_field, i, general_field_len, 6, NUMERIC, 0)) { + /* 7.2.5.5.2/5.4.2 c) */ + bp = bin_append_posn(0, 3, binary_string, bp); /* Numeric latch "000" */ mode = NUMERIC; - } else if (general_field_next_terminate(general_field, i, general_field_len, 4, 5 /*Can limit to 5 max due to above*/, NUMERIC)) { /* 7.2.5.5.2/5.4.2 d) */ - strcat(binary_string, "000"); /* Numeric latch */ + } else if (general_field_next_terminate(general_field, i, general_field_len, 4, + 5 /*Can limit to 5 max due to above*/, NUMERIC)) { + /* 7.2.5.5.2/5.4.2 d) */ + bp = bin_append_posn(0, 3, binary_string, bp); /* Numeric latch "000" */ mode = NUMERIC; } else if ((general_field[i] >= '0') && (general_field[i] <= '9')) { - bin_append(general_field[i] - 43, 5, binary_string); + bp = bin_append_posn(general_field[i] - 43, 5, binary_string, bp); i++; } else if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { - bin_append(general_field[i] - 33, 6, binary_string); + bp = bin_append_posn(general_field[i] - 33, 6, binary_string, bp); i++; } else { - bin_append(posn(alphanum_puncs, general_field[i]) + 58, 6, binary_string); + bp = bin_append_posn(posn(alphanum_puncs, general_field[i]) + 58, 6, binary_string, bp); i++; } break; case ISOIEC: - if (general_field[i] == '[') { /* 7.2.5.5.3/5.4.3 a) */ - strcat(binary_string, "01111"); + if (general_field[i] == '[') { + /* 7.2.5.5.3/5.4.3 a) */ + bp = bin_append_posn(15, 5, binary_string, bp); /* "01111" */ mode = NUMERIC; i++; } else { int next_10_not_isoiec = general_field_next_none(general_field, i, general_field_len, 10, ISOIEC); - if (next_10_not_isoiec && general_field_next(general_field, i, general_field_len, 4, NUMERIC, 0)) { /* 7.2.5.5.3/5.4.3 b) */ - strcat(binary_string, "000"); /* Numeric latch */ + if (next_10_not_isoiec && general_field_next(general_field, i, general_field_len, 4, + NUMERIC, 0)) { + /* 7.2.5.5.3/5.4.3 b) */ + bp = bin_append_posn(0, 3, binary_string, bp); /* Numeric latch "000" */ mode = NUMERIC; - } else if (next_10_not_isoiec && general_field_next(general_field, i, general_field_len, 5, ALPHANUMERIC, NUMERIC)) { /* 7.2.5.5.3/5.4.3 c) */ + } else if (next_10_not_isoiec && general_field_next(general_field, i, general_field_len, 5, + ALPHANUMERIC, NUMERIC)) { + /* 7.2.5.5.3/5.4.3 c) */ /* Note this rule can produce longer bitstreams if most of the alphanumerics are numeric */ - strcat(binary_string, "00100"); /* Alphanumeric latch */ + bp = bin_append_posn(4, 5, binary_string, bp); /* Alphanumeric latch "00100" */ mode = ALPHANUMERIC; } else if ((general_field[i] >= '0') && (general_field[i] <= '9')) { - bin_append(general_field[i] - 43, 5, binary_string); + bp = bin_append_posn(general_field[i] - 43, 5, binary_string, bp); i++; } else if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { - bin_append(general_field[i] - 1, 7, binary_string); + bp = bin_append_posn(general_field[i] - 1, 7, binary_string, bp); i++; } else if ((general_field[i] >= 'a') && (general_field[i] <= 'z')) { - bin_append(general_field[i] - 7, 7, binary_string); + bp = bin_append_posn(general_field[i] - 7, 7, binary_string, bp); i++; } else { - bin_append(posn(isoiec_puncs, general_field[i]) + 232, 8, binary_string); + bp = bin_append_posn(posn(isoiec_puncs, general_field[i]) + 232, 8, binary_string, bp); i++; } } @@ -182,5 +200,7 @@ INTERNAL int general_field_encode(char *general_field, int *p_mode, int *p_last_ *p_mode = mode; *p_last_digit = last_digit; + *p_bp = bp; + return 1; } diff --git a/backend/general_field.h b/backend/general_field.h index 184eb291..5ab8847c 100644 --- a/backend/general_field.h +++ b/backend/general_field.h @@ -39,7 +39,10 @@ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - INTERNAL int general_field_encode(char *general_field, int *p_mode, int *p_last_digit, char binary_string[]); + +INTERNAL int general_field_encode(const char *general_field, const int general_field_len, int *p_mode, + char *p_last_digit, char binary_string[], int *p_bp); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/backend/gs1.c b/backend/gs1.c index 99ff3c32..255f9e5b 100644 --- a/backend/gs1.c +++ b/backend/gs1.c @@ -69,9 +69,9 @@ static void itostr(char ai_string[], int ai_value) { } /* Returns the number of times a character occurs in a string */ -static int ustrchr_cnt(const unsigned char string[], const size_t length, const unsigned char c) { +static int ustrchr_cnt(const unsigned char string[], const int length, const unsigned char c) { int count = 0; - unsigned int i; + int i; for (i = 0; i < length; i++) { if (string[i] == c) { count++; @@ -80,13 +80,14 @@ static int ustrchr_cnt(const unsigned char string[], const size_t length, const return count; } -INTERNAL int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const size_t src_len, char reduced[]) { +INTERNAL int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const int src_len, + unsigned char reduced[]) { int i, j, last_ai, ai_latch; char ai_string[7]; /* 6 char max "(NNNN)" */ int bracket_level, max_bracket_level, ai_length, max_ai_length, min_ai_length; int ai_count; int error_latch; - int error_value; + int error_value = 0; #ifdef _MSC_VER int *ai_value; int *ai_location; @@ -104,7 +105,7 @@ INTERNAL int gs1_verify(struct zint_symbol *symbol, const unsigned char source[] #endif /* Detect extended ASCII characters */ - for (i = 0; i < (int) src_len; i++) { + for (i = 0; i < src_len; i++) { if (source[i] >= 128) { strcpy(symbol->errtxt, "250: Extended ASCII characters are not supported by GS1"); return ZINT_ERROR_INVALID_DATA; @@ -140,8 +141,7 @@ INTERNAL int gs1_verify(struct zint_symbol *symbol, const unsigned char source[] min_ai_length = 5; j = 0; ai_latch = 0; - error_value = 0; - for (i = 0; i < (int) src_len; i++) { + for (i = 0; i < src_len; i++) { ai_length += j; if (((j == 1) && (source[i] != ']')) && ((source[i] < '0') || (source[i] > '9'))) { ai_latch = 1; @@ -198,7 +198,7 @@ INTERNAL int gs1_verify(struct zint_symbol *symbol, const unsigned char source[] } ai_count = 0; - for (i = 1; i < (int) src_len; i++) { + for (i = 1; i < src_len; i++) { if (source[i - 1] == '[') { ai_location[ai_count] = i; j = 0; @@ -223,7 +223,8 @@ INTERNAL int gs1_verify(struct zint_symbol *symbol, const unsigned char source[] data_length[i] = 0; do { data_length[i]++; - } while ((source[data_location[i] + data_length[i] - 1] != '[') && (data_location[i] + data_length[i] <= (int) src_len)); + } while ((source[data_location[i] + data_length[i] - 1] != '[') + && (data_location[i] + data_length[i] <= src_len)); data_length[i]--; } @@ -689,7 +690,7 @@ INTERNAL int gs1_verify(struct zint_symbol *symbol, const unsigned char source[] /* Resolve AI data - put resulting string in 'reduced' */ j = 0; ai_latch = 1; - for (i = 0; i < (int) src_len; i++) { + for (i = 0; i < src_len; i++) { if ((source[i] != '[') && (source[i] != ']')) { reduced[j++] = source[i]; } diff --git a/backend/gs1.h b/backend/gs1.h index 228af50d..db96f722 100644 --- a/backend/gs1.h +++ b/backend/gs1.h @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2009-2017 Robin Stuart + Copyright (C) 2009 - 2020 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,7 +37,8 @@ extern "C" { #endif /* __cplusplus */ - extern int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const size_t src_len, char reduced[]); +INTERNAL int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const int src_len, + unsigned char reduced[]); #ifdef __cplusplus } diff --git a/backend/library.c b/backend/library.c index 884aad2d..236eb231 100644 --- a/backend/library.c +++ b/backend/library.c @@ -41,6 +41,10 @@ #define TECHNETIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" +/* It's assumed that int is at least 32 bits, the following will compile-time fail if not + * https://stackoverflow.com/a/1980056/664741 */ +typedef int static_assert_int_at_least_32bits[CHAR_BIT != 8 || sizeof(int) < 4 ? -1 : 1]; + struct zint_symbol *ZBarcode_Create() { struct zint_symbol *symbol; @@ -54,7 +58,11 @@ struct zint_symbol *ZBarcode_Create() { symbol->fgcolor = &symbol->fgcolour[0]; strcpy(symbol->bgcolour, "ffffff"); symbol->bgcolor = &symbol->bgcolour[0]; +#ifdef NO_PNG + strcpy(symbol->outfile, "out.gif"); +#else strcpy(symbol->outfile, "out.png"); +#endif symbol->scale = 1.0f; symbol->option_1 = -1; symbol->show_hrt = 1; // Show human readable text @@ -132,8 +140,8 @@ INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int lengt INTERNAL int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */ INTERNAL int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */ INTERNAL int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */ -INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], const size_t length); /* Code 128 and NVE-18 */ -INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* EAN-128 (GS1-128) */ +INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 128 and NVE-18 */ +INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-128 (GS1-128) */ INTERNAL int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */ INTERNAL int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */ INTERNAL int telepen(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Telepen ASCII */ @@ -172,7 +180,7 @@ INTERNAL int code_one(struct zint_symbol *symbol, unsigned char source[], int le INTERNAL int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Grid Matrix */ INTERNAL int han_xin(struct zint_symbol * symbol, unsigned char source[], int length); /* Han Xin */ INTERNAL int dotcode(struct zint_symbol * symbol, const unsigned char source[], int length); /* DotCode */ -INTERNAL int codablock(struct zint_symbol * symbol, const unsigned char source[], const size_t length); /* Codablock */ +INTERNAL int codablock(struct zint_symbol *symbol, unsigned char source[], int length); /* Codablock */ INTERNAL int upnqr(struct zint_symbol *symbol, unsigned char source[], int length); /* UPNQR */ INTERNAL int qr_code(struct zint_symbol *symbol, unsigned char source[], int length); /* QR Code */ INTERNAL int dmatrix(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length); /* Data Matrix (IEC16022) */ @@ -749,7 +757,8 @@ static int reduced_charset(struct zint_symbol *symbol, unsigned char *source, in if ((symbol->input_mode & 0x07) == UNICODE_MODE) { /* Prior check ensures ECI only set for those that support it */ preprocessed = preprocessed_buf; - error_number = utf_to_eci(symbol->eci && symbol->eci <= 899 ? symbol->eci : 3, source, preprocessed, &in_length); + error_number = utf_to_eci(symbol->eci && symbol->eci <= 899 ? symbol->eci : 3, source, preprocessed, + &in_length); if (error_number != 0) { strcpy(symbol->errtxt, "204: Invalid characters in input data"); return error_number; @@ -1077,6 +1086,15 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int if (!symbol) return ZINT_ERROR_INVALID_DATA; + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("ZBarcode_Encode: symbology: %d, input_mode: 0x%X, ECI: %d, option_1: %d, option_2: %d," + " option_3: %d, scale: %g\n output_options: 0x%X, in_length: %d," + " First 10 source: \"%.10s\", First 10 primary: \"%.10s\"\n", + symbol->symbology, symbol->input_mode, symbol->eci, symbol->option_1, symbol->option_2, + symbol->option_3, symbol->scale, symbol->output_options, in_length, + source, symbol->primary); + } + error_number = 0; if (source == NULL) { @@ -1092,8 +1110,13 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); return ZINT_ERROR_INVALID_DATA; } + if (in_length > ZINT_MAX_DATA_LEN) { + strcpy(symbol->errtxt, "243: Input data too long"); + error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); + return ZINT_ERROR_TOO_LONG; + } - if (strcmp(symbol->outfile, "") == 0) { + if (*symbol->outfile == '\0') { #ifdef NO_PNG strcpy(symbol->outfile, "out.gif"); #else @@ -1280,9 +1303,9 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int // Reduce input for composite and non-forced symbologies, others (EAN128 and RSS_EXP based) will handle it themselves if (is_composite(symbol->symbology) || !check_force_gs1(symbol->symbology)) { #ifndef _MSC_VER - char reduced[in_length + 1]; + unsigned char reduced[in_length + 1]; #else - char* reduced = (char*) _alloca(in_length + 1); + unsigned char *reduced = (unsigned char *) _alloca(in_length + 1); #endif error_number = gs1_verify(symbol, local_source, in_length, reduced); if (error_number != 0) { @@ -1553,7 +1576,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { if (!strcmp(filename, "-")) { file = stdin; - fileLen = ZINT_MAX_FILE_LEN; + fileLen = ZINT_MAX_DATA_LEN; } else { file = fopen(filename, "rb"); if (!file) { @@ -1574,7 +1597,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { fclose(file); return ZINT_ERROR_INVALID_DATA; } - if (fileLen > ZINT_MAX_FILE_LEN) { + if (fileLen > ZINT_MAX_DATA_LEN) { strcpy(symbol->errtxt, "230: Input file too long"); error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); fclose(file); @@ -1673,7 +1696,8 @@ int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol, char *fil int ZBarcode_Version() { if (ZINT_VERSION_BUILD) { - return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE * 10 + ZINT_VERSION_BUILD; + return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE * 10 + + ZINT_VERSION_BUILD; } return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE; } diff --git a/backend/rss.c b/backend/rss.c index 481c9195..3635cd84 100644 --- a/backend/rss.c +++ b/backend/rss.c @@ -77,7 +77,7 @@ * combins(n,r): returns the number of Combinations of r selected from n: * Combinations = n! / ((n - r)! * r!) **********************************************************************/ -static int combins(int n, int r) { +static int combins(const int n, const int r) { int i, j; int maxDenom, minDenom; int val; @@ -117,7 +117,7 @@ static int combins(int n, int r) { * noNarrow = 0 will skip patterns without a one module wide element * **********************************************************************/ -static void getRSSwidths(int widths[], int val, int n, int elements, int maxWidth, int noNarrow) { +static void getRSSwidths(int widths[], int val, int n, const int elements, const int maxWidth, const int noNarrow) { int bar; int elmWidth; int mxwElement; @@ -158,7 +158,7 @@ static void getRSSwidths(int widths[], int val, int n, int elements, int maxWidt } /* Calculate check digit from Annex A */ -static int calc_check_digit(unsigned char *src) { +static int calc_check_digit(const unsigned char *src) { int i, check_digit; int count = 0; @@ -174,7 +174,7 @@ static int calc_check_digit(unsigned char *src) { } /* Set GTIN-14 human readable text */ -static void set_gtin14_hrt(struct zint_symbol *symbol, unsigned char *source, int src_len) { +static void set_gtin14_hrt(struct zint_symbol *symbol, const unsigned char *source, const int src_len) { int i; unsigned char hrt[15]; @@ -193,53 +193,52 @@ static void set_gtin14_hrt(struct zint_symbol *symbol, unsigned char *source, in } /* Expand from a width pattern to a bit pattern */ -static int rss_expand(struct zint_symbol *symbol, int writer, char *p_latch, int width) { +static int rss_expand(struct zint_symbol *symbol, int writer, int *p_latch, const int width) { int j; int latch = *p_latch; for (j = 0; j < width; j++) { - if (latch == '1') { + if (latch) { set_module(symbol, symbol->rows, writer); } else { unset_module(symbol, symbol->rows, writer); } writer++; } - if (latch == '1') { - *p_latch = '0'; - } else { - *p_latch = '1'; - } + + *p_latch = !latch; return writer; } /* Adjust top/bottom separator for finder patterns */ -static void rss14_finder_adjust(struct zint_symbol *symbol, int separator_row, int above_below, int finder_start) { +static void rss14_finder_adjust(struct zint_symbol *symbol, const int separator_row, const int above_below, + const int finder_start) { int i, finder_end; int module_row = separator_row + above_below; int latch; /* Alternation is always left-to-right for Omnidirectional separators (unlike for Expanded) */ - latch = '1'; + latch = 1; for (i = finder_start, finder_end = finder_start + 13; i < finder_end; i++) { if (!module_is_set(symbol, module_row, i)) { - if (latch == '1') { + if (latch) { set_module(symbol, separator_row, i); - latch = '0'; + latch = 0; } else { unset_module(symbol, separator_row, i); - latch = '1'; + latch = 1; } } else { unset_module(symbol, separator_row, i); - latch = '1'; + latch = 1; } } } /* Top/bottom separator for DataBar */ -static void rss14_separator(struct zint_symbol *symbol, int width, int separator_row, int above_below, int finder_start, int finder2_start, int bottom_finder_value_3) { +static void rss14_separator(struct zint_symbol *symbol, int width, const int separator_row, const int above_below, + const int finder_start, const int finder2_start, const int bottom_finder_value_3) { int i, finder_end, finder_value_3_set; int module_row = separator_row + above_below; @@ -276,7 +275,7 @@ INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_l uint64_t left_pair, right_pair; int data_character[4] = {0}, data_group[4] = {0}, v_odd[4], v_even[4]; int data_widths[8][4], checksum, c_left, c_right, total_widths[46], writer; - char latch; + int latch; int separator_row; int widths[4]; @@ -325,69 +324,55 @@ INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_l /* Calculate four data characters */ - data_character[0] = left_pair / 1597; - data_character[1] = left_pair % 1597; + data_character[0] = (int) (left_pair / 1597); + data_character[1] = (int) (left_pair % 1597); - data_character[2] = right_pair / 1597; - data_character[3] = right_pair % 1597; + data_character[2] = (int) (right_pair / 1597); + data_character[3] = (int) (right_pair % 1597); /* Calculate odd and even subset values */ - if ((data_character[0] >= 0) && (data_character[0] <= 160)) { + if (data_character[0] <= 160) { data_group[0] = 0; - } - if ((data_character[0] >= 161) && (data_character[0] <= 960)) { + } else if (data_character[0] <= 960) { data_group[0] = 1; - } - if ((data_character[0] >= 961) && (data_character[0] <= 2014)) { + } else if (data_character[0] <= 2014) { data_group[0] = 2; - } - if ((data_character[0] >= 2015) && (data_character[0] <= 2714)) { + } else if (data_character[0] <= 2714) { data_group[0] = 3; - } - if ((data_character[0] >= 2715) && (data_character[0] <= 2840)) { + } else { data_group[0] = 4; } - if ((data_character[1] >= 0) && (data_character[1] <= 335)) { + if (data_character[1] <= 335) { data_group[1] = 5; - } - if ((data_character[1] >= 336) && (data_character[1] <= 1035)) { + } else if (data_character[1] <= 1035) { data_group[1] = 6; - } - if ((data_character[1] >= 1036) && (data_character[1] <= 1515)) { + } else if (data_character[1] <= 1515) { data_group[1] = 7; - } - if ((data_character[1] >= 1516) && (data_character[1] <= 1596)) { + } else { data_group[1] = 8; } - if ((data_character[3] >= 0) && (data_character[3] <= 335)) { + if (data_character[3] <= 335) { data_group[3] = 5; - } - if ((data_character[3] >= 336) && (data_character[3] <= 1035)) { + } else if (data_character[3] <= 1035) { data_group[3] = 6; - } - if ((data_character[3] >= 1036) && (data_character[3] <= 1515)) { + } else if (data_character[3] <= 1515) { data_group[3] = 7; - } - if ((data_character[3] >= 1516) && (data_character[3] <= 1596)) { + } else { data_group[3] = 8; } - if ((data_character[2] >= 0) && (data_character[2] <= 160)) { + if (data_character[2] <= 160) { data_group[2] = 0; - } - if ((data_character[2] >= 161) && (data_character[2] <= 960)) { + } else if (data_character[2] <= 960) { data_group[2] = 1; - } - if ((data_character[2] >= 961) && (data_character[2] <= 2014)) { + } else if (data_character[2] <= 2014) { data_group[2] = 2; - } - if ((data_character[2] >= 2015) && (data_character[2] <= 2714)) { + } else if (data_character[2] <= 2714) { data_group[2] = 3; - } - if ((data_character[2] >= 2715) && (data_character[2] <= 2840)) { + } else { data_group[2] = 4; } @@ -472,7 +457,7 @@ INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_l /* Put this data into the symbol */ if ((symbol->symbology == BARCODE_DBAR_OMN) || (symbol->symbology == BARCODE_DBAR_OMN_CC)) { writer = 0; - latch = '0'; + latch = 0; for (i = 0; i < 46; i++) { writer = rss_expand(symbol, writer, &latch, total_widths[i]); } @@ -494,7 +479,7 @@ INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_l if ((symbol->symbology == BARCODE_DBAR_STK) || (symbol->symbology == BARCODE_DBAR_STK_CC)) { /* top row */ writer = 0; - latch = '0'; + latch = 0; for (i = 0; i < 23; i++) { writer = rss_expand(symbol, writer, &latch, total_widths[i]); } @@ -507,7 +492,7 @@ INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_l set_module(symbol, symbol->rows, 0); unset_module(symbol, symbol->rows, 1); writer = 2; - latch = '1'; + latch = 1; for (i = 23; i < 46; i++) { writer = rss_expand(symbol, writer, &latch, total_widths[i]); } @@ -544,7 +529,7 @@ INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_l if ((symbol->symbology == BARCODE_DBAR_OMNSTK) || (symbol->symbology == BARCODE_DBAR_OMNSTK_CC)) { /* top row */ writer = 0; - latch = '0'; + latch = 0; for (i = 0; i < 23; i++) { writer = rss_expand(symbol, writer, &latch, total_widths[i]); } @@ -556,7 +541,7 @@ INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_l set_module(symbol, symbol->rows, 0); unset_module(symbol, symbol->rows, 1); writer = 2; - latch = '1'; + latch = 1; for (i = 23; i < 46; i++) { writer = rss_expand(symbol, writer, &latch, total_widths[i]); } @@ -599,7 +584,7 @@ INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int int left_group, right_group, left_odd, left_even, right_odd, right_even; int left_widths[14], right_widths[14]; int checksum, check_elements[14], total_widths[47], writer; - char latch; + int latch; int separator_row; int widths[7]; @@ -693,10 +678,10 @@ INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int right_group = 0; } - left_odd = left_character / t_even_ltd[left_group]; - left_even = left_character % t_even_ltd[left_group]; - right_odd = right_character / t_even_ltd[right_group]; - right_even = right_character % t_even_ltd[right_group]; + left_odd = (int) (left_character / t_even_ltd[left_group]); + left_even = (int) (left_character % t_even_ltd[left_group]); + right_odd = (int) (right_character / t_even_ltd[right_group]); + right_even = (int) (right_character % t_even_ltd[right_group]); getRSSwidths(widths, left_odd, modules_odd_ltd[left_group], 7, widest_odd_ltd[left_group], 1); for (i = 0; i <= 6; i++) { @@ -739,7 +724,7 @@ INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int } writer = 0; - latch = '0'; + latch = 0; for (i = 0; i < 47; i++) { writer = rss_expand(symbol, writer, &latch, total_widths[i]); } @@ -765,22 +750,40 @@ INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int return error_number; } +/* Check and convert date to RSS date value */ +INTERNAL int rss_date(const unsigned char source[], const int src_posn) { + int yy = to_int(source + src_posn, 2); + int mm = to_int(source + src_posn + 2, 2); + int dd = to_int(source + src_posn + 4, 2); + + /* Month can't be zero but day can (means last day of month, + * GS1 General Specifications Sections 3.4.2 to 3.4.7) */ + if (yy < 0 || mm <= 0 || mm > 12 || dd < 0 || dd > 31) { + return -1; + } + return yy * 384 + (mm - 1) * 32 + dd; +} + /* Handles all data encodation from section 7.2.5 of ISO/IEC 24724 */ -static int rss_binary_string(struct zint_symbol *symbol, char source[], char binary_string[]) { - int encoding_method, i, j, read_posn, last_digit, debug = (symbol->debug & ZINT_DEBUG_PRINT), mode = NUMERIC; +static int rss_binary_string(struct zint_symbol *symbol, const unsigned char source[], char binary_string[], + int *p_bp) { + int encoding_method, i, j, read_posn, debug = (symbol->debug & ZINT_DEBUG_PRINT), mode = NUMERIC; + char last_digit = '\0'; int symbol_characters, characters_per_row; + int length = (int) ustrlen(source); #ifndef _MSC_VER - char general_field[strlen(source) + 1]; + char general_field[length + 1]; #else - char* general_field = (char*) _alloca(strlen(source) + 1); + char *general_field = (char *) _alloca(length + 1); #endif + int bp = *p_bp; int remainder, d1, d2; - char padstring[40]; + int cdf_bp_start; /* Compressed data field start - debug only */ /* Decide whether a compressed data field is required and if so what method to use - method 2 = no compressed data field */ - if ((strlen(source) >= 16) && ((source[0] == '0') && (source[1] == '1'))) { + if ((length >= 16) && ((source[0] == '0') && (source[1] == '1'))) { /* (01) and other AIs */ encoding_method = 1; if (debug) printf("Choosing Method 1\n"); @@ -790,157 +793,110 @@ static int rss_binary_string(struct zint_symbol *symbol, char source[], char bin if (debug) printf("Choosing Method 2\n"); } - if (((strlen(source) >= 20) && (encoding_method == 1)) && ((source[2] == '9') && (source[16] == '3'))) { + if (((length >= 20) && (encoding_method == 1)) && ((source[2] == '9') && (source[16] == '3'))) { /* Possibly encoding method > 2 */ + if (debug) printf("Checking for other methods\n"); - if ((strlen(source) >= 26) && (source[17] == '1')) { + if ((length >= 26) && (source[17] == '1') && (source[18] == '0')) { /* Methods 3, 7, 9, 11 and 13 */ - if (source[18] == '0') { - /* (01) and (310x) */ - char weight_str[7]; + /* (01) and (310x) */ + int weight = to_int(source + 20, 6); - for (i = 0; i < 6; i++) { - weight_str[i] = source[20 + i]; - } - weight_str[6] = '\0'; + /* Maximum weight = 99999 for 7 to 14 (ISO/IEC 24724:2011 7.2.5.4.4) */ + if (weight >= 0 && weight <= 99999) { - if (weight_str[0] == '0') { /* Maximum weight = 99999 */ - - if ((source[19] == '3') && (strlen(source) == 26)) { + if (length == 26) { + if ((source[19] == '3') && weight <= 32767) { /* In grams, max 32.767 kilos */ /* (01) and (3103) */ - float weight; /* In kilos */ - weight = atof(weight_str) / 1000.0; - - if (weight <= 32.767) { - encoding_method = 3; - } + encoding_method = 3; + } else { + /* (01), (310x) - use method 7 with dummy date 38400 */ + encoding_method = 7; } - if (strlen(source) == 34) { - if ((source[26] == '1') && (source[27] == '1')) { - /* (01), (310x) and (11) - metric weight and production date */ - encoding_method = 7; - } + } else if ((length == 34) && (source[26] == '1') && + (source[27] == '1' || source[27] == '3' || source[27] == '5' || source[27] == '7') && + rss_date(source, 28) >= 0) { - if ((source[26] == '1') && (source[27] == '3')) { - /* (01), (310x) and (13) - metric weight and packaging date */ - encoding_method = 9; - } - - if ((source[26] == '1') && (source[27] == '5')) { - /* (01), (310x) and (15) - metric weight and "best before" date */ - encoding_method = 11; - } - - if ((source[26] == '1') && (source[27] == '7')) { - /* (01), (310x) and (17) - metric weight and expiration date */ - encoding_method = 13; - } - } + /* (01), (310x) and (11) - metric weight and production date */ + /* (01), (310x) and (13) - metric weight and packaging date */ + /* (01), (310x) and (15) - metric weight and "best before" date */ + /* (01), (310x) and (17) - metric weight and expiration date */ + encoding_method = 6 + (source[27] - '0'); } } - if (debug) printf("Now using method %d\n", encoding_method); - } - if ((strlen(source) >= 26) && (source[17] == '2')) { + } else if ((length >= 26) && (source[17] == '2') && (source[18] == '0')) { /* Methods 4, 8, 10, 12 and 14 */ - if (source[18] == '0') { - /* (01) and (320x) */ - char weight_str[7]; + /* (01) and (320x) */ + int weight = to_int(source + 20, 6); - for (i = 0; i < 6; i++) { - weight_str[i] = source[20 + i]; - } - weight_str[6] = '\0'; + /* Maximum weight = 99999 for 7 to 14 (ISO/IEC 24724:2011 7.2.5.4.4) */ + if (weight >= 0 && weight <= 99999) { - if (weight_str[0] == '0') { /* Maximum weight = 99999 */ - - if (((source[19] == '2') || (source[19] == '3')) && (strlen(source) == 26)) { + /* (3202) in 0.01 pounds, max 99.99 pounds; (3203) in 0.001 pounds, max 22.767 pounds */ + if (length == 26) { + if ((source[19] == '2' && weight <= 9999) || (source[19] == '3' && weight <= 22767)) { /* (01) and (3202)/(3203) */ - float weight; /* In pounds */ - - if (source[19] == '3') { - weight = (float) (atof(weight_str) / 1000.0F); - if (weight <= 22.767) { - encoding_method = 4; - } - } else { - weight = (float) (atof(weight_str) / 100.0F); - if (weight <= 99.99) { - encoding_method = 4; - } - } - + encoding_method = 4; + } else { + /* (01), (320x) - use method 8 with dummy date 38400 */ + encoding_method = 8; } - if (strlen(source) == 34) { - if ((source[26] == '1') && (source[27] == '1')) { - /* (01), (320x) and (11) - English weight and production date */ - encoding_method = 8; - } + } else if ((length == 34) && (source[26] == '1') && + (source[27] == '1' || source[27] == '3' || source[27] == '5' || source[27] == '7') && + rss_date(source, 28) >= 0) { - if ((source[26] == '1') && (source[27] == '3')) { - /* (01), (320x) and (13) - English weight and packaging date */ - encoding_method = 10; - } - - if ((source[26] == '1') && (source[27] == '5')) { - /* (01), (320x) and (15) - English weight and "best before" date */ - encoding_method = 12; - } - - if ((source[26] == '1') && (source[27] == '7')) { - /* (01), (320x) and (17) - English weight and expiration date */ - encoding_method = 14; - } - } + /* (01), (320x) and (11) - English weight and production date */ + /* (01), (320x) and (13) - English weight and packaging date */ + /* (01), (320x) and (15) - English weight and "best before" date */ + /* (01), (320x) and (17) - English weight and expiration date */ + encoding_method = 7 + (source[27] - '0'); } } - if (debug) printf("Now using method %d\n", encoding_method); - } - - if (source[17] == '9') { + } else if ((source[17] == '9') && ((source[19] >= '0') && (source[19] <= '3'))) { /* Methods 5 and 6 */ - if ((source[18] == '2') && ((source[19] >= '0') && (source[19] <= '3'))) { + if (source[18] == '2') { /* (01) and (392x) */ encoding_method = 5; - } - if ((source[18] == '3') && ((source[19] >= '0') && (source[19] <= '3'))) { + } else if (source[18] == '3' && to_int(source + 20, 3) >= 0) { /* Check 3-digit currency string */ /* (01) and (393x) */ encoding_method = 6; } - if (debug) printf("Now using method %d\n", encoding_method); } + + if (debug && encoding_method != 1) printf("Now using method %d\n", encoding_method); } switch (encoding_method) { /* Encoding method - Table 10 */ - case 1: strcat(binary_string, "1XX"); + case 1: bp = bin_append_posn(4, 3, binary_string, bp); /* "1XX" */ read_posn = 16; break; - case 2: strcat(binary_string, "00XX"); + case 2: bp = bin_append_posn(0, 4, binary_string, bp); /* "00XX" */ read_posn = 0; break; case 3: // 0100 case 4: // 0101 - bin_append(4 + (encoding_method - 3), 4, binary_string); - read_posn = strlen(source); + bp = bin_append_posn(4 + (encoding_method - 3), 4, binary_string, bp); + read_posn = 26; break; - case 5: strcat(binary_string, "01100XX"); + case 5: bp = bin_append_posn(0x30, 7, binary_string, bp); /* "01100XX" */ read_posn = 20; break; - case 6: strcat(binary_string, "01101XX"); + case 6: bp = bin_append_posn(0x34, 7, binary_string, bp); /* "01101XX" */ read_posn = 23; break; default: /* modes 7 to 14 */ - bin_append(56 + (encoding_method - 7), 7, binary_string); - read_posn = strlen(source); + bp = bin_append_posn(56 + (encoding_method - 7), 7, binary_string, bp); + read_posn = length; /* 34 or 26 */ break; } - if (debug) printf("Setting binary = %s\n", binary_string); + if (debug) printf("Setting binary = %.*s\n", bp, binary_string); /* Variable length symbol bit field is just given a place holder (XX) for the time being */ @@ -949,7 +905,7 @@ static int rss_binary_string(struct zint_symbol *symbol, char source[], char bin numeric data before carrying out compression */ for (i = 0; i < read_posn; i++) { if ((source[i] < '0') || (source[i] > '9')) { - if ((source[i] != '[') && (source[i] != ']')) { + if (source[i] != '[') { /* Something is wrong */ strcpy(symbol->errtxt, "385: Invalid characters in input data"); return ZINT_ERROR_INVALID_DATA; @@ -960,155 +916,110 @@ static int rss_binary_string(struct zint_symbol *symbol, char source[], char bin /* Now encode the compressed data field */ if (debug) printf("Proceeding to encode data\n"); + cdf_bp_start = bp; /* Debug use only */ + if (encoding_method == 1) { /* Encoding method field "1" - general item identification data */ - char group[4]; - group[0] = source[2]; - group[1] = '\0'; + bp = bin_append_posn(ctoi(source[2]), 4, binary_string, bp); /* Leading digit after stripped "01" */ - bin_append(atoi(group), 4, binary_string); - - for (i = 1; i < 5; i++) { - group[0] = source[(i * 3)]; - group[1] = source[(i * 3) + 1]; - group[2] = source[(i * 3) + 2]; - group[3] = '\0'; - - bin_append(atoi(group), 10, binary_string); + for (i = 3; i < 15; i += 3) { /* Next 12 digits, excluding final check digit */ + bp = bin_append_posn(to_int(source + i, 3), 10, binary_string, bp); } - } - if ((encoding_method == 3) || (encoding_method == 4)) { + } else if ((encoding_method == 3) || (encoding_method == 4)) { /* Encoding method field "0100" - variable weight item (0,001 kilogram icrements) */ /* Encoding method field "0101" - variable weight item (0,01 or 0,001 pound increment) */ - char group[4]; - char weight_str[7]; - for (i = 1; i < 5; i++) { - group[0] = source[(i * 3)]; - group[1] = source[(i * 3) + 1]; - group[2] = source[(i * 3) + 2]; - group[3] = '\0'; - - bin_append(atoi(group), 10, binary_string); + for (i = 3; i < 15; i += 3) { /* Leading "019" stripped, and final check digit excluded */ + bp = bin_append_posn(to_int(source + i, 3), 10, binary_string, bp); } - for (i = 0; i < 6; i++) { - weight_str[i] = source[20 + i]; - } - weight_str[6] = '\0'; - if ((encoding_method == 4) && (source[19] == '3')) { - bin_append(atoi(weight_str) + 10000, 15, binary_string); + bp = bin_append_posn(to_int(source + 20, 6) + 10000, 15, binary_string, bp); } else { - bin_append(atoi(weight_str), 15, binary_string); + bp = bin_append_posn(to_int(source + 20, 6), 15, binary_string, bp); } - } - if ((encoding_method == 5) || (encoding_method == 6)) { + } else if ((encoding_method == 5) || (encoding_method == 6)) { /* Encoding method "01100" - variable measure item and price */ /* Encoding method "01101" - variable measure item and price with ISO 4217 Currency Code */ - char group[4]; - - for (i = 1; i < 5; i++) { - group[0] = source[(i * 3)]; - group[1] = source[(i * 3) + 1]; - group[2] = source[(i * 3) + 2]; - group[3] = '\0'; - - bin_append(atoi(group), 10, binary_string); + for (i = 3; i < 15; i += 3) { /* Leading "019" stripped, and final check digit excluded */ + bp = bin_append_posn(to_int(source + i, 3), 10, binary_string, bp); } - bin_append(source[19] - '0', 2, binary_string); + bp = bin_append_posn(source[19] - '0', 2, binary_string, bp); /* 0-3 x of 392x/393x */ if (encoding_method == 6) { - char currency_str[5]; - - for (i = 0; i < 3; i++) { - currency_str[i] = source[20 + i]; - } - currency_str[3] = '\0'; - - bin_append(atoi(currency_str), 10, binary_string); + bp = bin_append_posn(to_int(source + 20, 3), 10, binary_string, bp); /* 3-digit currency */ } - } - if ((encoding_method >= 7) && (encoding_method <= 14)) { + } else if ((encoding_method >= 7) && (encoding_method <= 14)) { /* Encoding method fields "0111000" through "0111111" - variable weight item plus date */ - char group[4]; int group_val; char weight_str[8]; - for (i = 1; i < 5; i++) { - group[0] = source[(i * 3)]; - group[1] = source[(i * 3) + 1]; - group[2] = source[(i * 3) + 2]; - group[3] = '\0'; - - bin_append(atoi(group), 10, binary_string); + for (i = 3; i < 15; i += 3) { /* Leading "019" stripped, and final check digit excluded */ + bp = bin_append_posn(to_int(source + i, 3), 10, binary_string, bp); } - weight_str[0] = source[19]; + weight_str[0] = source[19]; /* 0-9 x of 310x/320x */ - for (i = 0; i < 5; i++) { - weight_str[i + 1] = source[21 + i]; + for (i = 1; i < 6; i++) { /* Leading "0" of weight excluded */ + weight_str[i] = source[20 + i]; } weight_str[6] = '\0'; - bin_append(atoi(weight_str), 20, binary_string); + bp = bin_append_posn(atoi(weight_str), 20, binary_string, bp); - if (strlen(source) == 34) { + if (length == 34) { /* Date information is included */ - char date_str[4]; - date_str[0] = source[28]; - date_str[1] = source[29]; - date_str[2] = '\0'; - group_val = atoi(date_str) * 384; - - date_str[0] = source[30]; - date_str[1] = source[31]; - group_val += (atoi(date_str) - 1) * 32; - - date_str[0] = source[32]; - date_str[1] = source[33]; - group_val += atoi(date_str); + group_val = rss_date(source, 28); } else { group_val = 38400; } - bin_append(group_val, 16, binary_string); + bp = bin_append_posn((int) group_val, 16, binary_string, bp); + } + + if (debug && bp > cdf_bp_start) { + printf("Compressed data field (%d) = %.*s\n", bp - cdf_bp_start, bp - cdf_bp_start, + binary_string + cdf_bp_start); } /* The compressed data field has been processed if appropriate - the rest of the data (if any) goes into a general-purpose data compaction field */ j = 0; - for (i = read_posn; i < (int) strlen(source); i++) { + for (i = read_posn; i < length; i++) { general_field[j] = source[i]; j++; } general_field[j] = '\0'; + if (debug) printf("General field data = %s\n", general_field); - if (!general_field_encode(general_field, &mode, &last_digit, binary_string)) { - /* Invalid characters in input data */ - strcpy(symbol->errtxt, "386: Invalid characters in input data"); - return ZINT_ERROR_INVALID_DATA; - } - if (debug) printf("Resultant binary = %s\n", binary_string); - if (debug) printf("\tLength: %d\n", (int) strlen(binary_string)); + if (j != 0) { /* If general field not empty */ - remainder = 12 - (strlen(binary_string) % 12); + if (!general_field_encode(general_field, j, &mode, &last_digit, binary_string, &bp)) { + /* Invalid characters in input data */ + strcpy(symbol->errtxt, "386: Invalid characters in input data"); + return ZINT_ERROR_INVALID_DATA; + } + } + + if (debug) printf("Resultant binary = %.*s\n\tLength: %d\n", bp, binary_string, bp); + + remainder = 12 - (bp % 12); if (remainder == 12) { remainder = 0; } - symbol_characters = ((strlen(binary_string) + remainder) / 12) + 1; + symbol_characters = ((bp + remainder) / 12) + 1; if ((symbol->symbology == BARCODE_DBAR_EXPSTK) || (symbol->symbology == BARCODE_DBAR_EXPSTK_CC)) { characters_per_row = symbol->option_2 * 2; @@ -1126,26 +1037,26 @@ static int rss_binary_string(struct zint_symbol *symbol, char source[], char bin symbol_characters = 4; } - remainder = (12 * (symbol_characters - 1)) - strlen(binary_string); + remainder = (12 * (symbol_characters - 1)) - bp; if (last_digit) { /* There is still one more numeric digit to encode */ if (debug) printf("Adding extra (odd) numeric digit\n"); if ((remainder >= 4) && (remainder <= 6)) { - bin_append(ctoi(last_digit) + 1, 4, binary_string); + bp = bin_append_posn(ctoi(last_digit) + 1, 4, binary_string, bp); } else { d1 = ctoi(last_digit); d2 = 10; - bin_append((11 * d1) + d2 + 8, 7, binary_string); + bp = bin_append_posn((11 * d1) + d2 + 8, 7, binary_string, bp); } - remainder = 12 - (strlen(binary_string) % 12); + remainder = 12 - (bp % 12); if (remainder == 12) { remainder = 0; } - symbol_characters = ((strlen(binary_string) + remainder) / 12) + 1; + symbol_characters = ((bp + remainder) / 12) + 1; if ((symbol->symbology == BARCODE_DBAR_EXPSTK) || (symbol->symbology == BARCODE_DBAR_EXPSTK_CC)) { characters_per_row = symbol->option_2 * 2; @@ -1163,13 +1074,12 @@ static int rss_binary_string(struct zint_symbol *symbol, char source[], char bin symbol_characters = 4; } - remainder = (12 * (symbol_characters - 1)) - strlen(binary_string); + remainder = (12 * (symbol_characters - 1)) - bp; - if (debug) printf("Resultant binary = %s\n", binary_string); - if (debug) printf("\tLength: %d\n", (int) strlen(binary_string)); + if (debug) printf("Resultant binary = %.*s\n\tLength: %d\n", bp, binary_string, bp); } - if (strlen(binary_string) > 252) { /* 252 = (21 * 12) */ + if (bp > 252) { /* 252 = (21 * 12) */ strcpy(symbol->errtxt, "387: Input too long"); return ZINT_ERROR_TOO_LONG; } @@ -1177,18 +1087,13 @@ static int rss_binary_string(struct zint_symbol *symbol, char source[], char bin /* Now add padding to binary string (7.2.5.5.4) */ i = remainder; if (mode == NUMERIC) { - strcpy(padstring, "0000"); + bp = bin_append_posn(0, 4, binary_string, bp); /* "0000" */ i -= 4; - } else { - strcpy(padstring, ""); } for (; i > 0; i -= 5) { - strcat(padstring, "00100"); + bp = bin_append_posn(4, 5, binary_string, bp); /* "00100" */ } - padstring[remainder] = '\0'; - strcat(binary_string, padstring); - /* Patch variable length symbol bit field */ d1 = symbol_characters & 1; @@ -1201,21 +1106,26 @@ static int rss_binary_string(struct zint_symbol *symbol, char source[], char bin if (encoding_method == 1) { binary_string[2] = d1 ? '1' : '0'; binary_string[3] = d2 ? '1' : '0'; - } - if (encoding_method == 2) { + } else if (encoding_method == 2) { binary_string[3] = d1 ? '1' : '0'; binary_string[4] = d2 ? '1' : '0'; - } - if ((encoding_method == 5) || (encoding_method == 6)) { + } else if ((encoding_method == 5) || (encoding_method == 6)) { binary_string[6] = d1 ? '1' : '0'; binary_string[7] = d2 ? '1' : '0'; } - if (debug) printf("Resultant binary = %s\n", binary_string); - if (debug) printf("\tLength: %d\n", (int) strlen(binary_string)); + if (debug) { + printf("Resultant binary = %.*s\n\tLength: %d, Symbol chars: %d\n", bp, binary_string, bp, symbol_characters); + } + + *p_bp = bp; + return 0; } -static void rssexp_separator(struct zint_symbol *symbol, int width, int cols, int separator_row, int above_below, int special_case_row, int left_to_right, int odd_last_row, int *p_v2_latch) { +/* Separator for DataBar Expanded Stacked and DataBar Expanded Composite */ +static void rssexp_separator(struct zint_symbol *symbol, int width, const int cols, const int separator_row, + const int above_below, const int special_case_row, const int left_to_right, const int odd_last_row, + int *p_v2_latch) { int i, i_start, i_end, j, k; int module_row = separator_row + above_below; int v2_latch = p_v2_latch ? *p_v2_latch : 0; @@ -1231,9 +1141,11 @@ static void rssexp_separator(struct zint_symbol *symbol, int width, int cols, in /* finder adjustment */ for (j = 0; j < cols; j++) { - k = (49 * j) + 19 + special_case_row; /* 49 == data (17) + finder (15) + data(17) triplet, 19 == 2 (guard) + 17 (initial check/data character) */ + /* 49 == data (17) + finder (15) + data(17) triplet, 19 == 2 (guard) + 17 (initial check/data character) */ + k = (49 * j) + 19 + special_case_row; if (left_to_right) { - i_start = v2_latch ? 2 : 0; /* Last 13 modules of version 2 finder and first 13 modules of version 1 finder */ + /* Last 13 modules of version 2 finder and first 13 modules of version 1 finder */ + i_start = v2_latch ? 2 : 0; i_end = v2_latch ? 15 : 13; for (i = i_start; i < i_end; i++) { if (module_is_set(symbol, module_row, i + k)) { @@ -1252,7 +1164,8 @@ static void rssexp_separator(struct zint_symbol *symbol, int width, int cols, in if (odd_last_row) { k -= 17; /* No data char at beginning of row, i.e. ends with finder */ } - i_start = v2_latch ? 14 : 12; /* First 13 modules of version 1 finder and last 13 modules of version 2 finder */ + /* First 13 modules of version 1 finder and last 13 modules of version 2 finder */ + i_start = v2_latch ? 14 : 12; i_end = v2_latch ? 2 : 0; for (i = i_start; i >= i_end; i--) { if (module_is_set(symbol, module_row, i + k)) { @@ -1278,18 +1191,21 @@ static void rssexp_separator(struct zint_symbol *symbol, int width, int cols, in /* GS1 DataBar Expanded */ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int src_len) { - int i, j, k, p, data_chars, vs[21], group[21], v_odd[21], v_even[21]; - char substring[21][14], latch; + int i, j, k, p, codeblocks, data_chars, vs, group, v_odd, v_even; + int latch; int char_widths[21][8], checksum, check_widths[8], c_group; int check_char, c_odd, c_even, elements[235], pattern_width, reader, writer; int separator_row; - unsigned int bin_len = 13 * src_len + 200 + 1; /* Allow for 8 bits + 5-bit latch per char + 200 bits overhead/padding */ + /* Allow for 8 bits + 5-bit latch per char + 200 bits overhead/padding */ + unsigned int bin_len = 13 * src_len + 200 + 1; int widths[4]; + int bp = 0; #ifndef _MSC_VER - char reduced[src_len + 1], binary_string[bin_len]; + unsigned char reduced[src_len + 1]; + char binary_string[bin_len]; #else - char* reduced = (char*) _alloca(src_len + 1); - char* binary_string = (char*) _alloca(bin_len); + unsigned char *reduced = (unsigned char *) _alloca(src_len + 1); + char *binary_string = (char *) _alloca(bin_len); #endif separator_row = 0; @@ -1299,6 +1215,10 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int return i; } + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("Reduced (%d): %s\n", (int) ustrlen(reduced), reduced); + } + if ((symbol->symbology == BARCODE_DBAR_EXP_CC) || (symbol->symbology == BARCODE_DBAR_EXPSTK_CC)) { /* make space for a composite separator pattern */ separator_row = symbol->rows; @@ -1306,62 +1226,48 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int symbol->rows += 1; } - strcpy(binary_string, ""); - if (symbol->option_1 == 2) { /* The "component linkage" flag */ - strcat(binary_string, "1"); + binary_string[bp++] = '1'; } else { - strcat(binary_string, "0"); + binary_string[bp++] = '0'; } - i = rss_binary_string(symbol, reduced, binary_string); + i = rss_binary_string(symbol, reduced, binary_string, &bp); if (i != 0) { return i; } - data_chars = strlen(binary_string) / 12; + data_chars = bp / 12; for (i = 0; i < data_chars; i++) { + k = i * 12; + vs = 0; for (j = 0; j < 12; j++) { - substring[i][j] = binary_string[(i * 12) + j]; - } - substring[i][12] = '\0'; - } - - for (i = 0; i < data_chars; i++) { - vs[i] = 0; - for (p = 0; p < 12; p++) { - if (substring[i][p] == '1') { - vs[i] += (0x800 >> p); + if (binary_string[k + j] == '1') { + vs |= (0x800 >> j); } } - } - for (i = 0; i < data_chars; i++) { - if (vs[i] <= 347) { - group[i] = 1; + if (vs <= 347) { + group = 1; + } else if (vs <= 1387) { + group = 2; + } else if (vs <= 2947) { + group = 3; + } else if (vs <= 3987) { + group = 4; + } else { + group = 5; } - if ((vs[i] >= 348) && (vs[i] <= 1387)) { - group[i] = 2; - } - if ((vs[i] >= 1388) && (vs[i] <= 2947)) { - group[i] = 3; - } - if ((vs[i] >= 2948) && (vs[i] <= 3987)) { - group[i] = 4; - } - if (vs[i] >= 3988) { - group[i] = 5; - } - v_odd[i] = (vs[i] - g_sum_exp[group[i] - 1]) / t_even_exp[group[i] - 1]; - v_even[i] = (vs[i] - g_sum_exp[group[i] - 1]) % t_even_exp[group[i] - 1]; + v_odd = (vs - g_sum_exp[group - 1]) / t_even_exp[group - 1]; + v_even = (vs - g_sum_exp[group - 1]) % t_even_exp[group - 1]; - getRSSwidths(widths, v_odd[i], modules_odd_exp[group[i] - 1], 4, widest_odd_exp[group[i] - 1], 0); + getRSSwidths(widths, v_odd, modules_odd_exp[group - 1], 4, widest_odd_exp[group - 1], 0); char_widths[i][0] = widths[0]; char_widths[i][2] = widths[1]; char_widths[i][4] = widths[2]; char_widths[i][6] = widths[3]; - getRSSwidths(widths, v_even[i], modules_even_exp[group[i] - 1], 4, widest_even_exp[group[i] - 1], 1); + getRSSwidths(widths, v_even, modules_even_exp[group - 1], 4, widest_even_exp[group - 1], 1); char_widths[i][1] = widths[0]; char_widths[i][3] = widths[1]; char_widths[i][5] = widths[2]; @@ -1388,17 +1294,13 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int if (check_char <= 347) { c_group = 1; - } - if ((check_char >= 348) && (check_char <= 1387)) { + } else if (check_char <= 1387) { c_group = 2; - } - if ((check_char >= 1388) && (check_char <= 2947)) { + } else if (check_char <= 2947) { c_group = 3; - } - if ((check_char >= 2948) && (check_char <= 3987)) { + } else if (check_char <= 3987) { c_group = 4; - } - if (check_char >= 3988) { + } else { c_group = 5; } @@ -1417,14 +1319,14 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int check_widths[7] = widths[3]; /* Initialise element array */ - pattern_width = ((((data_chars + 1) / 2) + ((data_chars + 1) & 1)) * 5) + ((data_chars + 1) * 8) + 4; - for (i = 0; i < pattern_width; i++) { - elements[i] = 0; - } + codeblocks = (data_chars + 1) / 2 + ((data_chars + 1) & 1); + pattern_width = (codeblocks * 5) + ((data_chars + 1) * 8) + 4; + memset(elements, 0, sizeof(int) * pattern_width); /* Put finder patterns in element array */ - for (i = 0; i < (((data_chars + 1) / 2) + ((data_chars + 1) & 1)); i++) { - k = ((((((data_chars + 1) - 2) / 2) + ((data_chars + 1) & 1)) - 1) * 11) + i; + p = (((((data_chars + 1) - 2) / 2) + ((data_chars + 1) & 1)) - 1) * 11; + for (i = 0; i < codeblocks; i++) { + k = p + i; for (j = 0; j < 5; j++) { elements[(21 * i) + j + 10] = finder_pattern_exp[((finder_sequence[k] - 1) * 5) + j]; } @@ -1437,15 +1339,17 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int /* Put forward reading data characters in element array */ for (i = 1; i < data_chars; i += 2) { + k = (((i - 1) / 2) * 21) + 23; for (j = 0; j < 8; j++) { - elements[(((i - 1) / 2) * 21) + 23 + j] = char_widths[i][j]; + elements[k + j] = char_widths[i][j]; } } /* Put reversed data characters in element array */ for (i = 0; i < data_chars; i += 2) { + k = ((i / 2) * 21) + 15; for (j = 0; j < 8; j++) { - elements[((i / 2) * 21) + 15 + j] = char_widths[i][7 - j]; + elements[k + j] = char_widths[i][7 - j]; } } @@ -1459,7 +1363,7 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int elements[pattern_width - 1] = 1; writer = 0; - latch = '0'; + latch = 0; for (i = 0; i < pattern_width; i++) { writer = rss_expand(symbol, writer, &latch, elements[i]); } @@ -1492,7 +1396,6 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int * [01]90614141999996[10]1234222222222221 * Patch by Daniel Frede */ - int codeblocks = (data_chars + 1) / 2 + ((data_chars + 1) % 2); if ((symbol->option_2 < 1) || (symbol->option_2 > 11)) { symbol->option_2 = 2; @@ -1528,15 +1431,17 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int sub_elements[1] = 1; elements_in_sub = 2; - /* If last row and is partial and even-numbered, and have even columns (segment pairs), and odd number of finders */ + /* If last row and is partial and even-numbered, and have even columns (segment pairs), + * and odd number of finders (== odd number of columns) */ if ((current_row == stack_rows) && (num_columns != symbol->option_2) && - !(current_row & 1) && !(symbol->option_2 & 1) && (num_columns & 1)) { /* Odd number of finders == odd number of columns */ + !(current_row & 1) && !(symbol->option_2 & 1) && (num_columns & 1)) { /* Special case bottom row */ special_case_row = 1; sub_elements[0] = 2; /* Extra space (latch set below) */ } - /* If odd number of columns or current row odd-numbered or special case last row then left-to-right, else right-to-left */ + /* If odd number of columns or current row odd-numbered or special case last row then left-to-right, + * else right-to-left */ if ((symbol->option_2 & 1) || (current_row & 1) || special_case_row) { left_to_right = 1; } else { @@ -1545,7 +1450,8 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int if (symbol->debug & ZINT_DEBUG_PRINT) { if (current_row == stack_rows) { - printf("Last row: number of columns: %d / %d, left to right: %d, special case: %d\n", num_columns, symbol->option_2, left_to_right, special_case_row); + printf("Last row: number of columns: %d / %d, left to right: %d, special case: %d\n", + num_columns, symbol->option_2, left_to_right, special_case_row); } } @@ -1572,7 +1478,7 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int sub_elements[elements_in_sub + 1] = 1; elements_in_sub += 2; - latch = (current_row & 1) || special_case_row ? '0' : '1'; + latch = (current_row & 1) || special_case_row ? 0 : 1; writer = 0; for (i = 0; i < elements_in_sub; i++) { @@ -1592,13 +1498,15 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int symbol->row_height[symbol->rows - 2] = 1; /* bottom separator pattern (above current row) */ - rssexp_separator(symbol, writer, reader, symbol->rows - 1, 1 /*above*/, special_case_row, left_to_right, odd_last_row, &v2_latch); + rssexp_separator(symbol, writer, reader, symbol->rows - 1, 1 /*above*/, special_case_row, + left_to_right, odd_last_row, &v2_latch); symbol->row_height[symbol->rows - 1] = 1; } if (current_row != stack_rows) { /* top separator pattern (below current row) */ - rssexp_separator(symbol, writer, reader, symbol->rows + 1, -1 /*below*/, 0 /*special_case_row*/, left_to_right, 0 /*odd_last_row*/, &v2_latch); + rssexp_separator(symbol, writer, reader, symbol->rows + 1, -1 /*below*/, 0 /*special_case_row*/, + left_to_right, 0 /*odd_last_row*/, &v2_latch); symbol->row_height[symbol->rows + 1] = 1; } @@ -1609,7 +1517,8 @@ INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int if (symbol->symbology == BARCODE_DBAR_EXP_CC || symbol->symbology == BARCODE_DBAR_EXPSTK_CC) { /* Composite separator */ - rssexp_separator(symbol, symbol->width, 4, separator_row, 1 /*above*/, 0 /*special_case_row*/, 1 /*left_to_right*/, 0 /*odd_last_row*/, NULL); + rssexp_separator(symbol, symbol->width, 4, separator_row, 1 /*above*/, 0 /*special_case_row*/, + 1 /*left_to_right*/, 0 /*odd_last_row*/, NULL); } for (i = 0; i < symbol->rows; i++) { diff --git a/backend/tests/test_composite.c b/backend/tests/test_composite.c index 0a715364..f718e888 100644 --- a/backend/tests/test_composite.c +++ b/backend/tests/test_composite.c @@ -2852,6 +2852,94 @@ static void test_fuzz(int index, int debug) { testFinish(); } +#include + +#define TEST_PERF_ITERATIONS 1000 + +// Not a real test, just performance indicator +static void test_perf(int index, int debug) { + + if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */ + return; + } + + int ret; + struct item { + int symbology; + int option_1; + char *data; + char *composite; + int ret; + + int expected_rows; + int expected_width; + char *comment; + }; + struct item data[] = { + /* 0*/ { BARCODE_EANX_CC, 1, "123456789012", + "[91]123456789012345678901234567890123456789012345678901234", + 0, 11, 99, "58 chars CC-A" }, + /* 1*/ { BARCODE_UPCA_CC, 2, "12345678901", + "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[94]12345678901234567890123456789012345678901234567890", + 0, 48, 99, "336 chars CC-B" }, + /* 2*/ { BARCODE_GS1_128_CC, 3, "[01]12345678901231", + "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[94]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[95]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "[96]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", + 0, 32, 205, "564 chars CC-C" }, + }; + int data_size = ARRAY_SIZE(data); + + clock_t start, total_encode = 0, total_buffer = 0, diff_encode, diff_buffer; + + for (int i = 0; i < data_size; i++) { + + if (index != -1 && i != index) continue; + + diff_encode = diff_buffer = 0; + + for (int j = 0; j < TEST_PERF_ITERATIONS; j++) { + struct zint_symbol *symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + int length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + assert_zero(length >= 128, "i:%d length %d >= 128\n", i, length); + strcpy(symbol->primary, data[i].data); + + int composite_length = strlen(data[i].composite); + + start = clock(); + ret = ZBarcode_Encode(symbol, (const unsigned char *) data[i].composite, composite_length); + diff_encode += clock() - start; + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + + assert_equal(symbol->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); + + 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); + + 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); + + total_encode += diff_encode; + total_buffer += diff_buffer; + } + if (index != -1) { + printf("totals: encode %gms, buffer %gms\n", total_encode * 1000.0 / CLOCKS_PER_SEC, total_buffer * 1000.0 / CLOCKS_PER_SEC); + } +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ @@ -2865,6 +2953,7 @@ int main(int argc, char *argv[]) { { "test_encodation_11", test_encodation_11, 1, 1, 1 }, { "test_addongap", test_addongap, 1, 1, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 }, + { "test_perf", test_perf, 1, 0, 1 }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_gs1.c b/backend/tests/test_gs1.c index d9ff1824..66b4ca0c 100644 --- a/backend/tests/test_gs1.c +++ b/backend/tests/test_gs1.c @@ -286,7 +286,7 @@ static void test_hrt(int index, int debug) { testFinish(); } -extern int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const size_t src_len, char reduced[]); +#include "../gs1.h" static void test_gs1_verify(int index) { @@ -801,7 +801,7 @@ static void test_gs1_verify(int index) { int length = strlen(data[i].data); - ret = gs1_verify(symbol, (unsigned char *) data[i].data, length, reduced); + ret = gs1_verify(symbol, (unsigned char *) data[i].data, length, (unsigned char *) reduced); assert_equal(ret, data[i].ret, "i:%d ret %d != %d (length %d \"%s\") %s\n", i, ret, data[i].ret, length, data[i].data, symbol->errtxt); if (ret == 0) { diff --git a/backend/tests/test_library.c b/backend/tests/test_library.c index 0ab54f92..9607b42b 100644 --- a/backend/tests/test_library.c +++ b/backend/tests/test_library.c @@ -390,6 +390,11 @@ static void test_bad_args(void) { assert_equal(ZBarcode_Encode_File_and_Buffer(symbol, empty, 0), ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File_and_Buffer(symbol, empty, 0) != ZINT_ERROR_INVALID_DATA\n"); assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode_File_and_Buffer(symbol, empty, 0) no errtxt\n"); + // Data too big + symbol->errtxt[0] = '\0'; + assert_equal(ZBarcode_Encode(symbol, (unsigned char *) empty, 17401), ZINT_ERROR_TOO_LONG, "ZBarcode_Encode(symbol, empty, 17401) != ZINT_ERROR_TOO_LONG\n"); + assert_nonzero(strlen(symbol->errtxt), "ZBarcode_Encode(symbol, empty, 17401) no errtxt\n"); + ZBarcode_Delete(symbol); testFinish(); diff --git a/backend/tests/test_rss.c b/backend/tests/test_rss.c index 08f91903..bb392409 100644 --- a/backend/tests/test_rss.c +++ b/backend/tests/test_rss.c @@ -195,114 +195,115 @@ static void test_examples(int index, int generate, int debug) { int expected_rows; int expected_width; + int bwipp_cmp; char *comment; char *expected; }; // Verified manually against GS1 General Specifications 20.0 (GGS) and ISO/IEC 24724:2011, and verified via bwipp_dump.ps against BWIPP struct item data[] = { - /* 0*/ { BARCODE_DBAR_OMN, -1, "0950110153001", 1, 96, "GGS Figure 5.5.2.1.1-1. GS1 DataBar Omnidirectional", + /* 0*/ { BARCODE_DBAR_OMN, -1, "0950110153001", 1, 96, 1, "GGS Figure 5.5.2.1.1-1. GS1 DataBar Omnidirectional", "010000010100000101000111110000010111101101011100100011011101000101100000000111001110110111001101" }, - /* 1*/ { BARCODE_DBAR_EXP, -1, "[01]90614141000015[3202]000150", 1, 151, "GGS Figure 5.5.2.3.1-1. GS1 DataBar Expanded", + /* 1*/ { BARCODE_DBAR_EXP, -1, "[01]90614141000015[3202]000150", 1, 151, 1, "GGS Figure 5.5.2.3.1-1. GS1 DataBar Expanded", "0101100011001100001011111111000010100100010000111101110011100010100010111100000011100111010111111011010100000100000110001111110000101000000100011010010" }, - /* 2*/ { BARCODE_DBAR_EXPSTK, -1, "[01]90614141000015[3202]000150", 5, 102, "GGS Figure 5.5.2.3.2-1. GS1 DataBar Expanded Stacked, same (tec-it separator differs)", + /* 2*/ { BARCODE_DBAR_EXPSTK, -1, "[01]90614141000015[3202]000150", 5, 102, 1, "GGS Figure 5.5.2.3.2-1. GS1 DataBar Expanded Stacked, same (tec-it separator differs)", "010110001100110000101111111100001010010001000011110111001110001010001011110000001110011101011111101101" "000001110011001111010000000010100101101110111100001000110001110101110100001010100001100010100000010000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" "000001011111011111001010000001010010111111011100100000000000000000000000000000000000000000000000000000" "001010100000100000110001111110000101000000100011010010000000000000000000000000000000000000000000000000" }, - /* 3*/ { BARCODE_DBAR_OMN, -1, "2001234567890", 1, 96, "24724:2011 Figure 1 — GS1 DataBar Omnidirectional", + /* 3*/ { BARCODE_DBAR_OMN, -1, "2001234567890", 1, 96, 1, "24724:2011 Figure 1 — GS1 DataBar Omnidirectional", "010100011101000001001111111000010100110110111110110000010010100101100000000111000110110110001101" }, - /* 4*/ { BARCODE_DBAR_OMN, -1, "0441234567890", 1, 96, "24724:2011 Figure 2 — GS1 DataBar Omnidirectional", + /* 4*/ { BARCODE_DBAR_OMN, -1, "0441234567890", 1, 96, 1, "24724:2011 Figure 2 — GS1 DataBar Omnidirectional", "010010001000010001000111000000010101000001100110101100100100000101111110000011000010100011100101" }, - /* 5*/ { BARCODE_DBAR_OMN, -1, "0001234567890", 1, 96, "24724:2011 Figure 4 — GS1 DataBar Truncated", + /* 5*/ { BARCODE_DBAR_OMN, -1, "0001234567890", 1, 96, 1, "24724:2011 Figure 4 — GS1 DataBar Truncated", "010101001000000001001111111000010111001011011110111001010110000101111111000111001100111101110101" }, - /* 6*/ { BARCODE_DBAR_STK, -1, "0001234567890", 3, 50, "24724:2011 Figure 5 — GS1 DataBar Stacked NOTE: Figure 5 separator differs from GGS Figure 5.5.2.1.3-1. which has ends set", + /* 6*/ { BARCODE_DBAR_STK, -1, "0001234567890", 3, 50, 1, "24724:2011 Figure 5 — GS1 DataBar Stacked NOTE: Figure 5 separator differs from GGS Figure 5.5.2.1.3-1. which has ends set", "01010100100000000100111111100001011100101101111010" "00001010101011111010000000111010100011010010000000" "10111001010110000101111111000111001100111101110101" }, - /* 7*/ { BARCODE_DBAR_OMNSTK, -1, "0003456789012", 5, 50, "24724:2011 Figure 6 — GS1 DataBar Stacked Omnidirectional", + /* 7*/ { BARCODE_DBAR_OMNSTK, -1, "0003456789012", 5, 50, 1, "24724:2011 Figure 6 — GS1 DataBar Stacked Omnidirectional", "01010100100000000100111110000001010011100110011010" "00001011011111111010000001010100101100011001100000" "00000101010101010101010101010101010101010101010000" "00001000100010111010010101010000111101001101110000" "10110111011101000101100000000111000010110010001101" }, - /* 8*/ { BARCODE_DBAR_LTD, -1, "1501234567890", 1, 79, "24724:2011 Figure 7 — GS1 DataBar Limited", + /* 8*/ { BARCODE_DBAR_LTD, -1, "1501234567890", 1, 79, 1, "24724:2011 Figure 7 — GS1 DataBar Limited", "0100011001100011011010100111010010101101001101001001011000110111001100110100000" }, - /* 9*/ { BARCODE_DBAR_LTD, -1, "0031234567890", 1, 79, "24724:2011 Figure 8 — (a) GS1 DataBar Limited", + /* 9*/ { BARCODE_DBAR_LTD, -1, "0031234567890", 1, 79, 1, "24724:2011 Figure 8 — (a) GS1 DataBar Limited", "0101010000010010001000010111001010110110100101011000001010010010110000010100000" }, - /* 10*/ { BARCODE_DBAR_EXP, -1, "[01]98898765432106[3202]012345[15]991231", 1, 200, "24724:2011 Figure 10 — GS1 DataBar Expanded", + /* 10*/ { BARCODE_DBAR_EXP, -1, "[01]98898765432106[3202]012345[15]991231", 1, 200, 1, "24724:2011 Figure 10 — GS1 DataBar Expanded", "01001000011000110110111111110000101110000110010100011010000001100010101111110000111010011100000010010100111110111001100011111100001011101100000100100100011110010110001011111111001110001101111010000101" }, - /* 11*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3103]001750", 1, 151, "24724:2011 Figure 11 — GS1 DataBar Expanded", + /* 11*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3103]001750", 1, 151, 1, "24724:2011 Figure 11 — GS1 DataBar Expanded", "0101110010000010011011111111000010111000010011000101011110111001100010111100000011100101110001110111011110101111000110001111110000101011000010011111010" }, - /* 12*/ { BARCODE_DBAR_EXPSTK, -1, "[01]98898765432106[3202]012345[15]991231", 5, 102, "24724:2011 Figure 12 — GS1 DataBar Expanded Stacked symbol", + /* 12*/ { BARCODE_DBAR_EXPSTK, -1, "[01]98898765432106[3202]012345[15]991231", 5, 102, 1, "24724:2011 Figure 12 — GS1 DataBar Expanded Stacked symbol", "010010000110001101101111111100001011100001100101000110100000011000101011111100001110100111000000100101" "000001111001110010010000000010100100011110011010111001011111100111010100000010100001011000111111010000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" "000011101000010011100001000000001011100101100001110110110111110010001001010000001010011000100000110000" "101000010111101100011100111111110100011010011110001001001000001101110100001111110001100111011111001010" }, - /* 13*/ { BARCODE_DBAR_EXPSTK, -1, "[01]95012345678903[3103]000123", 5, 102, "24724:2011 Figure 13 — GS1 DataBar Expanded Stacked", + /* 13*/ { BARCODE_DBAR_EXPSTK, -1, "[01]95012345678903[3103]000123", 5, 102, 1, "24724:2011 Figure 13 — GS1 DataBar Expanded Stacked", "010100010001111000101111111100001010111000001100010111000110001001101011110000001110010111000111011101" "000011101110000111010000000010100101000111110011101000111001110110010100001010100001101000111000100000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" "000000001010000111001010000001010010111011011111100000000000000000000000000000000000000000000000000000" "001011110101111000110001111110000101000100100000011010000000000000000000000000000000000000000000000000" }, - /* 14*/ { BARCODE_DBAR_LTD, -1, "0009876543210", 1, 79, "24724:2011 Figure F.2 — GS1 DataBar Limited", + /* 14*/ { BARCODE_DBAR_LTD, -1, "0009876543210", 1, 79, 1, "24724:2011 Figure F.2 — GS1 DataBar Limited", "0101010010010011000011000001010110100101100101000100010100010000010010010100000" }, - /* 15*/ { BARCODE_DBAR_EXP, -1, "[10]12A", 1, 102, "24724:2011 Figure F.3 — GS1 DataBar Expanded", + /* 15*/ { BARCODE_DBAR_EXP, -1, "[10]12A", 1, 102, 1, "24724:2011 Figure F.3 — GS1 DataBar Expanded", "010100000110100000101111111100001010001000000010110101111100100111001011110000000010011101111111010101" }, - /* 16*/ { BARCODE_DBAR_STK, -1, "0000000000000", 3, 50, "#183 GS1 DataBar Stacked separator alternation; verified manually against tec-it.com", + /* 16*/ { BARCODE_DBAR_STK, -1, "0000000000000", 3, 50, 1, "#183 GS1 DataBar Stacked separator alternation; verified manually against tec-it.com", "01010100100000000100011111111001011111110010101010" "00000101011111111010100000001010100000001101010000" "10101010110000000101111111110111011111111011010101" }, - /* 17*/ { BARCODE_DBAR_EXP, -1, "[255]95011015340010123456789", 1, 232, "GGS 2.6.2.1 Example 1", + /* 17*/ { BARCODE_DBAR_EXP, -1, "[255]95011015340010123456789", 1, 232, 1, "GGS 2.6.2.1 Example 1", "0100011000110001011011111111000010100000010101100001100001100111001010111110000001100100001110100001001000011011111010001111110000101001011111100111011001000111100100101111111100111011111001100100110010011100010111100011110000001010" }, - /* 18*/ { BARCODE_DBAR_EXP, -1, "[255]95011015340010123456789[3900]000", 1, 298, "GGS 2.6.2.1 Example 2", + /* 18*/ { BARCODE_DBAR_EXP, -1, "[255]95011015340010123456789[3900]000", 1, 298, 1, "GGS 2.6.2.1 Example 2", "0101100011111010001011111111000010100001000001001101100001100111001010111110000001100100001110100001001000011011111010001111110000101001011111100111011001000111100100101111111100111011111001100100110010011100010111100011000000001010111111011101000100001000110001101011111111100110011110010010001101" }, - /* 19*/ { BARCODE_DBAR_EXP, -1, "[255]9501101534001[17]160531[3902]050", 1, 281, "GGS 2.6.2.1 Example 3", + /* 19*/ { BARCODE_DBAR_EXP, -1, "[255]9501101534001[17]160531[3902]050", 1, 281, 1, "GGS 2.6.2.1 Example 3", "01011001000110011110111111110000101000000101011000011000011001110010101111100000011001000011101000010010000110111110100011111100001010010111111001110111000010010100001011111111001110000100001100110100010000001101001000110000000010111010011110011101110010110001100010111111111001101" }, - /* 20*/ { BARCODE_DBAR_EXPSTK, 3, "[255]9501101534001012345[8111]0500", 5, 151, "GGS 2.6.2.1 Example 4, same (tec-it separator differs)", + /* 20*/ { BARCODE_DBAR_EXPSTK, 3, "[255]9501101534001012345[8111]0500", 5, 151, 1, "GGS 2.6.2.1 Example 4, same (tec-it separator differs)", "0101100111100011001011111111000010100000010101100001100001100111001010111110000001100100001110100001001000011011111010001111110000101001011111100111010" "0000011000011100110100000000101001011111101010011110011110011000110101000001010100011011110001011110110111100100000101010000001010010110100000011000000" "0000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000" "0000110111000011011010000000010000100000100111011001100001100100010010100101010100101110110001111001011101100011101110100000000010000000000000000000000" "1011001000111100100101111111100111011111011000100110011110011011101100011000000001010001001110000110100010011100010001011111111100110100000000000000000" }, - /* 21*/ { BARCODE_DBAR_EXPSTK, 3, "[255]9501101534001[3941]0035", 5, 151, "GGS 2.6.2.1 Example 5, same (tec-it separator differs)", + /* 21*/ { BARCODE_DBAR_EXPSTK, 3, "[255]9501101534001[3941]0035", 5, 151, 1, "GGS 2.6.2.1 Example 5, same (tec-it separator differs)", "0100001101011000011011111111000010100000010101100001100001100111001010111110000001100100001110100001001000011011111010001111110000101001011111100111010" "0000110010100111100100000000101001011111101010011110011110011000110101000001010100011011110001011110110111100100000101010000001010010110100000011000000" "0000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000" "0000011011111011111010000000010000111100101011111001000100011100111010100001010100000000000000000000000000000000000000000000000000000000000000000000000" "1010100100000100000101111111100111000011010100000110111011100011000100011110000001010000000000000000000000000000000000000000000000000000000000000000000" }, - /* 22*/ { BARCODE_DBAR_OMN, -1, "0950110153000", 1, 96, "https://www.gs1.org/standards/barcodes/databar, same, verified manually against tec-it", + /* 22*/ { BARCODE_DBAR_OMN, -1, "0950110153000", 1, 96, 1, "https://www.gs1.org/standards/barcodes/databar, same, verified manually against tec-it", "010000010100000101000111111110010111101101011100100011011011000101111110000011001110110111001101" }, - /* 23*/ { BARCODE_DBAR_STK, -1, "0950110153000", 3, 50, "https://www.gs1.org/standards/barcodes/databar, same, verified manually against tec-it", + /* 23*/ { BARCODE_DBAR_STK, -1, "0950110153000", 3, 50, 1, "https://www.gs1.org/standards/barcodes/databar, same, verified manually against tec-it", "01000001010000010100011111111001011110110101110010" "00001100101101101010100001010100100001001010100000" "10100011011011000101111110000011001110110111001101" }, - /* 24*/ { BARCODE_DBAR_EXPSTK, -1, "[01]09501101530003[17]140704[10]AB-123", 9, 102, "https://www.gs1.org/standards/barcodes/databar, same (tec-it separator differs)", + /* 24*/ { BARCODE_DBAR_EXPSTK, -1, "[01]09501101530003[17]140704[10]AB-123", 9, 102, 1, "https://www.gs1.org/standards/barcodes/databar, same (tec-it separator differs)", "010101111100001001101111111100001011100001110110010100000011011010001011111000000110011010000001001101" "000010000011110110010000000010100100011110001001101011111100100101110100000101010001100101111110110000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" @@ -313,64 +314,64 @@ static void test_examples(int index, int generate, int debug) { "000010111101011110010100101010100100111100110010111001001100011111010100000000010000000000000000000000" "010001000010100001100011000000001011000011001101000110110011100000101011111111100110100000000000000000" }, - /* 25*/ { BARCODE_DBAR_EXP, -1, "[01]09501101530003[17]140704[10]AB-123", 1, 281, "https://www.gs1.org/standards/barcodes/databar, same, verified manually against tec-it", + /* 25*/ { BARCODE_DBAR_EXP, -1, "[01]09501101530003[17]140704[10]AB-123", 1, 281, 1, "https://www.gs1.org/standards/barcodes/databar, same, verified manually against tec-it", "01010111110000100110111111110000101110000111011001010000001101101000101111100000011001101000000100110001110100010001100011111100001010100000111100100100100111000001001011111111001110000011011001000100010000101000011000110000000010110000110011010001101100111000001010111111111001101" }, - /* 26*/ { BARCODE_DBAR_STK, -1, "07010001234567", 3, 50, "https://www.gs1.no/support/standardbibliotek/datafangst/gs1-databar, same, verified manually against tec-it", + /* 26*/ { BARCODE_DBAR_STK, -1, "07010001234567", 3, 50, 1, "https://www.gs1.no/support/standardbibliotek/datafangst/gs1-databar, same, verified manually against tec-it", "01000100001010000100011100000001011000100110001010" "00000011010101011010101011111010100111010101010000" "10111100101110100101100000000111011000001000110101" }, - /* 27*/ { BARCODE_DBAR_OMNSTK, -1, "12380000000008", 5, 50, "Example with finder values 3 & 3; for bottom row see 5.3.2.2, same as BWIPP (tec-it and IDAutomation differ (ie no shift))", + /* 27*/ { BARCODE_DBAR_OMNSTK, -1, "12380000000008", 5, 50, 1, "Example with finder values 3 & 3; for bottom row see 5.3.2.2, same as BWIPP (tec-it and IDAutomation differ (ie no shift))", "01011101001000000100010000000001010000001101011010" "00000010110111111010101010101010101111110010100000" "00000101010101010101010101010101010101010101010000" "00001101100011001010000000000100101100111011110000" "10100010011100110101111111110111010011000100001101" }, - /* 28*/ { BARCODE_DBAR_OMNSTK, -1, "99991234912372", 5, 50, "Example with finder values 8 & 6, same as BWIPP, verified manually against tec-it and IDAutomation", + /* 28*/ { BARCODE_DBAR_OMNSTK, -1, "99991234912372", 5, 50, 1, "Example with finder values 8 & 6, same as BWIPP, verified manually against tec-it and IDAutomation", "01001011101110000101110000000001011111011100101010" "00000100010001111010001010101010100000100011010000" "00000101010101010101010101010101010101010101010000" "00001000100011001010000000010100100001000100100000" "10100111011100110101111111100011011110111011011101" }, - /* 29*/ { BARCODE_DBAR_OMNSTK, -1, "32219876543217", 5, 50, "Example with finder values 6 & 1, same as BWIPP, verified manually against tec-it and IDAutomation", + /* 29*/ { BARCODE_DBAR_OMNSTK, -1, "32219876543217", 5, 50, 1, "Example with finder values 6 & 1, same as BWIPP, verified manually against tec-it and IDAutomation", "01001011000010001100111000000001011100010101000010" "00000100111101110010000101010100100011101010110000" "00000101010101010101010101010101010101010101010000" "00001110011100101010000010101000110100001000010000" "10110001100011010101111100000111001011110111100101" }, - /* 30*/ { BARCODE_DBAR_OMNSTK, -1, "32219876543255", 5, 50, "Example with finder values 7 & 7, same as BWIPP, verified manually against tec-it and IDAutomation", + /* 30*/ { BARCODE_DBAR_OMNSTK, -1, "32219876543255", 5, 50, 1, "Example with finder values 7 & 7, same as BWIPP, verified manually against tec-it and IDAutomation", "01001011000010001101111100000001011100010101000010" "00000100111101110010000010101010100011101010110000" "00000101010101010101010101010101010101010101010000" "00000111001110101010000000101010110100001000010000" "10111000110001010101111111000001001011110111100101" }, - /* 31*/ { BARCODE_DBAR_OMNSTK, -1, "04072912296211", 5, 50, "Example with finder values 7 & 8, same as BWIPP, verified manually against tec-it and IDAutomation", + /* 31*/ { BARCODE_DBAR_OMNSTK, -1, "04072912296211", 5, 50, 1, "Example with finder values 7 & 8, same as BWIPP, verified manually against tec-it and IDAutomation", "01001001000000010101111100000001011111000100101010" "00000110111111101010000010101010100000111011010000" "00000101010101010101010101010101010101010101010000" "00001110100010111010000000001010111010000111010000" "10110001011101000101111111110001000101111000101101" }, - /* 32*/ { BARCODE_DBAR_OMNSTK, -1, "06666666666666", 5, 50, "Example with finder values 6 & 4, same as BWIPP, verified manually against tec-it and IDAutomation", + /* 32*/ { BARCODE_DBAR_OMNSTK, -1, "06666666666666", 5, 50, 1, "Example with finder values 6 & 4, same as BWIPP, verified manually against tec-it and IDAutomation", "01000100010010000100111000000001011110111100101010" "00001011101101111010000101010100100001000011010000" "00000101010101010101010101010101010101010101010000" "00000100011111001010000101010100101001100001110000" "10101011100000110101111000000011010110011110000101" }, - /* 33*/ { BARCODE_DBAR_EXPSTK, -1, "[90]12345678901234567", 5, 102, "Example with 7 chars, 1 full row, bottom 3 chars", + /* 33*/ { BARCODE_DBAR_EXPSTK, -1, "[90]12345678901234567", 5, 102, 1, "Example with 7 chars, 1 full row, bottom 3 chars", "010010100001111000101111111100001010000010001110110100111110001011101011111100001110001111010011000101" "000001011110000111010000000010100101111101110001001011000001110100010100000010100001110000101100110000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" "000000100000000101111110110001101011110001110011010100101000000101000010010111000000000000000000000000" "101110011111111010000001001110010100001110001100101010000111111000111101101000111101000000000000000000" }, - /* 34*/ { BARCODE_DBAR_EXPSTK, -1, "[90]123456789012345678901234567", 9, 102, "Example with 10 chars, 2 full rows, bottom 2 chars", + /* 34*/ { BARCODE_DBAR_EXPSTK, -1, "[90]123456789012345678901234567", 9, 102, 1, "Example with 10 chars, 2 full rows, bottom 2 chars", "010000111100100010101111111100001010001000100000110100111110001011101011111000000110001111010011000101" "000011000011011101010000000010100101110111011111001011000001110100010100000101010001110000101100110000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" @@ -381,7 +382,7 @@ static void test_examples(int index, int generate, int debug) { "000010000110110001010100001010100100000111010011000000000000000000000000000000000000000000000000000000" "010001111001001110100011110000001011111000101100100100000000000000000000000000000000000000000000000000" }, - /* 35*/ { BARCODE_DBAR_EXPSTK, -1, "[90]123456789012345678901234567890", 9, 102, "Example with 11 chars, 2 full rows, bottom 3 chars", + /* 35*/ { BARCODE_DBAR_EXPSTK, -1, "[90]123456789012345678901234567890", 9, 102, 1, "Example with 11 chars, 2 full rows, bottom 3 chars", "010111011100010001101111111100001010000010001110110100111110001011101011111000000110001111010011000101" "000000100011101110010000000010100101111101110001001011000001110100010100000101010001110000101100110000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" @@ -392,7 +393,7 @@ static void test_examples(int index, int generate, int debug) { "000010000110110001010100101010100100111000100011011011000110001101110100000000010000000000000000000000" "010001111001001110100011000000001011000111011100100100111001110010001011111111100110100000000000000000" }, - /* 36*/ { BARCODE_DBAR_EXPSTK, -1, "[91]1234567890123456789012345678901234", 9, 102, "Example with 12 chars, 3 full rows", + /* 36*/ { BARCODE_DBAR_EXPSTK, -1, "[91]1234567890123456789012345678901234", 9, 102, 1, "Example with 12 chars, 3 full rows", "010100010011111001101111111100001011001000010000010100111110001011101011111000000110001111010011000101" "000011101100000110010000000010100100110111101111101011000001110100010100000101010001110000101100110000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" @@ -403,7 +404,7 @@ static void test_examples(int index, int generate, int debug) { "000010000110110001010100101010100100111000100011011011000110001110110100000000010001101110100001000000" "010001111001001110100011000000001011000111011100100100111001110001001011111111100110010001011110111101" }, - /* 37*/ { BARCODE_DBAR_EXPSTK, -1, "[91]123456789012345678901234567890123456789012", 13, 102, "Example with 15 chars, 3 full rows, bottom 7 chars", + /* 37*/ { BARCODE_DBAR_EXPSTK, -1, "[91]123456789012345678901234567890123456789012", 13, 102, 1, "Example with 15 chars, 3 full rows, bottom 7 chars", "010010000111101011101111111100001011100000101100010100111110001011101011110000000010001111010011000101" "000001111000010100010000000010100100011111010011101011000001110100010100001010101001110000101100110000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" @@ -418,7 +419,7 @@ static void test_examples(int index, int generate, int debug) { "000000100000000101001001111101100011000010000110010100101010100101011111011100100000000000000000000000" "101110011111111010110110000010011100111101111001101010000000011000100000100011011101000000000000000000" }, - /* 38*/ { BARCODE_DBAR_EXPSTK, 3, "[91]123456789012345678901234567890123456789012", 9, 151, "Example with 15 chars, 2 full rows, bottom 3 chars", + /* 38*/ { BARCODE_DBAR_EXPSTK, 3, "[91]123456789012345678901234567890123456789012", 9, 151, 1, "Example with 15 chars, 2 full rows, bottom 3 chars", "0100100001111010111011111111000010111000001011000101001111100010111010111100000000100011110100110001011110001011011110001111110000101010011000111000010" "0000011110000101000100000000101001000111110100111010110000011101000101000010101010011100001011001110100001110100100001010000001010010101100111000110000" "0000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000" @@ -429,7 +430,7 @@ static void test_examples(int index, int generate, int debug) { "0000001001110111110101001010101001010011000010000110001101111100100101000000001000000000000000000000000000000000000000000000000000000000000000000000000" "0101110110001000001000110000000010101100111101111001110010000011011010111111110011101000000000000000000000000000000000000000000000000000000000000000000" }, - /* 39*/ { BARCODE_DBAR_EXPSTK, -1, "[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFG", 17, 102, "Example with 19 chars, 4 full rows, bottom 3 chars", + /* 39*/ { BARCODE_DBAR_EXPSTK, -1, "[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFG", 17, 102, 1, "Example with 19 chars, 4 full rows, bottom 3 chars", "010101111100011101101111111100001011100000101100010101111110011110101011110000000010111000111110010101" "000010000011100010010000000010100100011111010011101010000001100001010100001010101001000111000001100000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" @@ -448,7 +449,7 @@ static void test_examples(int index, int generate, int debug) { "000010011111000111010001010101010101000111001111011011110100110000110100000000010000000000000000000000" "010101100000111000100110000000001010111000110000100100001011001111001011111111100110100000000000000000" }, - /* 40*/ { BARCODE_DBAR_EXPSTK, -1, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 21, 102, "Example with 22 chars, 5 full rows, bottom 2 chars", + /* 40*/ { BARCODE_DBAR_EXPSTK, -1, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 21, 102, 1, "Example with 22 chars, 5 full rows, bottom 2 chars", "010101011110111111101111111100001011001000000101000100111110001011101011110000000010001111010011000101" "000010100001000000010000000010100100110111111010111011000001110100010100001010101001110000101100110000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" @@ -471,7 +472,7 @@ static void test_examples(int index, int generate, int debug) { "000001000111010000101000101010101010100001011000110000000000000000000000000000000000000000000000000000" "001000111000101111010011000000000101011110100111000010000000000000000000000000000000000000000000000000" }, - /* 41*/ { BARCODE_DBAR_EXPSTK, 3, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 13, 151, "Example with 22 chars, 3 full rows, bottom 4 chars", + /* 41*/ { BARCODE_DBAR_EXPSTK, 3, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 13, 151, 1, "Example with 22 chars, 3 full rows, bottom 4 chars", "0101010111101111111011111111000010110010000001010001001111100010111010111100000000100011110100110001011110001011011110001111110000101010011000111000010" "0000101000010000000100000000101001001101111110101110110000011101000101000010101010011100001011001110100001110100100001010000001010010101100111000110000" "0000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000" @@ -486,7 +487,7 @@ static void test_examples(int index, int generate, int debug) { "0000101110001000111010000000001000101111101000110001110001110100001010001010101010101000010110001100000000000000000000000000000000000000000000000000000" "1010010001110111000101111111110011010000010111001110001110001011110100110000000001010111101001110000100000000000000000000000000000000000000000000000000" }, - /* 42*/ { BARCODE_DBAR_EXPSTK, 4, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 9, 200, "Example with 22 chars, 2 full rows, bottom 6 chars", + /* 42*/ { BARCODE_DBAR_EXPSTK, 4, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 9, 200, 1, "Example with 22 chars, 2 full rows, bottom 6 chars", "01010101111011111110111111110000101100100000010100010011111000101110101111000000001000111101001100010111100010110111100011111100001010100110001110000101001110000010001011110000001110001110001000100101" "00001010000100000001000000001010010011011111101011101100000111010001010000101010100111000010110011101000011101001000010100000010100101011001110001111010110001111101110100001010100001110001110111010000" "00000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" @@ -497,7 +498,7 @@ static void test_examples(int index, int generate, int debug) { "00000011000110001001000000010101010000011110011010101101110001000111010000000001000101111101000110001110001110100001010001010101010101000010110001100000000000000000000000000000000000000000000000000000" "01011100111001110110011111100000101111100001100101010010001110111000101111111110011010000010111001110001110001011110100110000000001010111101001110000100000000000000000000000000000000000000000000000000" }, - /* 43*/ { BARCODE_DBAR_EXPSTK, 5, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 9, 249, "Example with 22 chars, 2 full rows, bottom 2 chars", + /* 43*/ { BARCODE_DBAR_EXPSTK, 5, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 9, 249, 1, "Example with 22 chars, 2 full rows, bottom 2 chars", "010101011110111111101111111100001011001000000101000100111110001011101011110000000010001111010011000101111000101101111000111111000010101001100011100001010011100000100010111100000011100011100010001001000111100100111010001111000000101100011101110010010" "000010100001000000010000000010100100110111111010111011000001110100010100001010101001110000101100111010000111010010000101000000101001010110011100011110101100011111011101000010101000011100011101110110111000011011000101010000101010010011100010001100000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000" @@ -508,45 +509,45 @@ static void test_examples(int index, int generate, int debug) { "000010001110100001010001010101010101000010110001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "010001110001011110100110000000001010111101001110000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, - /* 44*/ { BARCODE_DBAR_EXPSTK, 6, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 5, 298, "Example with 22 chars, 1 full row, bottom 10 chars", + /* 44*/ { BARCODE_DBAR_EXPSTK, 6, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 5, 298, 1, "Example with 22 chars, 1 full row, bottom 10 chars", "0101010111101111111011111111000010110010000001010001001111100010111010111100000000100011110100110001011110001011011110001111110000101010011000111000010100111000001000101111000000111000111000100010010001111001001110100011110000001011000111011100100100111001110001001011111111001110100001011110111101" "0000101000010000000100000000101001001101111110101110110000011101000101000010101010011100001011001110100001110100100001010000001010010101100111000111101011000111110111010000101010000111000111011101101110000110110001010100001010100100111000100011011011000110001110110100000000100001011110100001000000" "0000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" "0000000100111011111010100101010100101001100001000011000100010111101110100000101010001100000110011010010001100011000100100000001010101000001111001101010110111000100011101000000000100010111110100011000111000111010000101000101010101010100001011000110000000000000000000000000000000000000000000000000000" "0010111011000100000100011000000001010110011110111100111011101000010001011111000000110011111001100101101110011100111011001111110000010111110000110010101001000111011100010111111111001101000001011100111000111000101111010011000000000101011110100111000010000000000000000000000000000000000000000000000000" }, - /* 45*/ { BARCODE_DBAR_EXPSTK, 7, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 5, 347, "Example with 22 chars, 1 full row, bottom 8 chars", + /* 45*/ { BARCODE_DBAR_EXPSTK, 7, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 5, 347, 1, "Example with 22 chars, 1 full row, bottom 8 chars", "01010101111011111110111111110000101100100000010100010011111000101110101111000000001000111101001100010111100010110111100011111100001010100110001110000101001110000010001011110000001110001110001000100100011110010011101000111100000010110001110111001001001110011100010010111111110011101000010111101111011101100010000010001100000000101011001111011110010" "00001010000100000001000000001010010011011111101011101100000111010001010000101010100111000010110011101000011101001000010100000010100101011001110001111010110001111101110100001010100001110001110111011011100001101100010101000010101001001110001000110110110001100011101101000000001000010111101000010000100010011101111101010010101010010100110000100000000" "00000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000" "00000100010111101110100000101010001100000110011010010001100011000100100000001010101000001111001101010110111000100011101000000000100010111110100011000111000111010000101000101010101010100001011000110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "10111011101000010001011111000000110011111001100101101110011100111011001111110000010111110000110010101001000111011100010111111111001101000001011100111000111000101111010011000000000101011110100111000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, - /* 46*/ { BARCODE_DBAR_EXPSTK, 8, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 5, 396, "Example with 22 chars, 1 full row, bottom 6 chars", + /* 46*/ { BARCODE_DBAR_EXPSTK, 8, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 5, 396, 1, "Example with 22 chars, 1 full row, bottom 6 chars", "010101011110111111101111111100001011001000000101000100111110001011101011110000000010001111010011000101111000101101111000111111000010101001100011100001010011100000100010111100000011100011100010001001000111100100111010001111000000101100011101110010010011100111000100101111111100111010000101111011110111011000100000100011000000001010110011110111100111011101000010001011111000000110011111001100101101" "000010100001000000010000000010100100110111111010111011000001110100010100001010101001110000101100111010000111010010000101000000101001010110011100011110101100011111011101000010101000011100011101110110111000011011000101010000101010010011100010001101101100011000111011010000000010000101111010000100001000100111011111010100101010100101001100001000011000100010111101110100000101010001100000110011010000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" "000000011000110001001000000010101010000011110011010101101110001000111010000000001000101111101000110001110001110100001010001010101010101000010110001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "001011100111001110110011111100000101111100001100101010010001110111000101111111110011010000010111001110001110001011110100110000000001010111101001110000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, - /* 47*/ { BARCODE_DBAR_EXPSTK, 9, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 5, 445, "Example with 22 chars, 1 full row, bottom 4 chars", + /* 47*/ { BARCODE_DBAR_EXPSTK, 9, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 5, 445, 1, "Example with 22 chars, 1 full row, bottom 4 chars", "0101010111101111111011111111000010110010000001010001001111100010111010111100000000100011110100110001011110001011011110001111110000101010011000111000010100111000001000101111000000111000111000100010010001111001001110100011110000001011000111011100100100111001110001001011111111001110100001011110111101110110001000001000110000000010101100111101111001110111010000100010111110000001100111110011001011011100111001110110011111100000101111100001100101010" "0000101000010000000100000000101001001101111110101110110000011101000101000010101010011100001011001110100001110100100001010000001010010101100111000111101011000111110111010000101010000111000111011101101110000110110001010100001010100100111000100011011011000110001110110100000000100001011110100001000010001001110111110101001010101001010011000010000110001000101111011101000001010100011000001100110100100011000110001001000000010101010000011110011010000" "0000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000" "0000101110001000111010000000001000101111101000110001110001110100001010001010101010101000010110001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "1010010001110111000101111111110011010000010111001110001110001011110100110000000001010111101001110000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, - /* 48*/ { BARCODE_DBAR_EXPSTK, 10, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 5, 494, "Example with 22 chars, 1 full row, bottom 2 chars", + /* 48*/ { BARCODE_DBAR_EXPSTK, 10, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 5, 494, 1, "Example with 22 chars, 1 full row, bottom 2 chars", "01010101111011111110111111110000101100100000010100010011111000101110101111000000001000111101001100010111100010110111100011111100001010100110001110000101001110000010001011110000001110001110001000100100011110010011101000111100000010110001110111001001001110011100010010111111110011101000010111101111011101100010000010001100000000101011001111011110011101110100001000101111100000011001111100110010110111001110011101100111111000001011111000011001010100100011101110001011111111100110100000101110011101" "00001010000100000001000000001010010011011111101011101100000111010001010000101010100111000010110011101000011101001000010100000010100101011001110001111010110001111101110100001010100001110001110111011011100001101100010101000010101001001110001000110110110001100011101101000000001000010111101000010000100010011101111101010010101010010100110000100001100010001011110111010000010101000110000011001101001000110001100010010000000101010100000111100110101011011100010001110100000000010001011111010001100000" "00000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" "00000100011101000010100010101010101010000101100011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "00100011100010111101001100000000010101111010011100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, - /* 49*/ { BARCODE_DBAR_EXPSTK, 11, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 1, 543, "Example with 22 chars, 1 row", + /* 49*/ { BARCODE_DBAR_EXPSTK, 11, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 1, 543, 1, "Example with 22 chars, 1 row", "010101011110111111101111111100001011001000000101000100111110001011101011110000000010001111010011000101111000101101111000111111000010101001100011100001010011100000100010111100000011100011100010001001000111100100111010001111000000101100011101110010010011100111000100101111111100111010000101111011110111011000100000100011000000001010110011110111100111011101000010001011111000000110011111001100101101110011100111011001111110000010111110000110010101001000111011100010111111111001101000001011100111000111000101111010011000000000101011110100111000010" }, - /* 50*/ { BARCODE_DBAR_EXPSTK, 1, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 41, 53, "Example with 22 chars, 11 rows", + /* 50*/ { BARCODE_DBAR_EXPSTK, 1, "[91]12345678901234567890123456789012345678901234567890123456789012345678", 41, 53, 1, "Example with 22 chars, 11 rows", "01010101111011111110111111110000101100100000010100010" "00001010000100000001000000001010010011011111101010000" "00000101010101010101010101010101010101010101010100000" @@ -589,14 +590,14 @@ static void test_examples(int index, int generate, int debug) { "00001000111010000101000101010101010100001011000110000" "01000111000101111010011000000000101011110100111000010" }, - /* 51*/ { BARCODE_DBAR_EXPSTK, 6, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 5, 298, "#200 Daniel Gredler mostly empty last row, 16 chars, 2 rows, bottom row 4 chars", + /* 51*/ { BARCODE_DBAR_EXPSTK, 6, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 5, 298, 1, "#200 Daniel Gredler mostly empty last row, 16 chars, 2 rows, bottom row 4 chars", "0100011101110001011011111111000010110000100101111101101000000110001010111100000000101001110000001001010011111011100110001111110000101110101000011000011010011100011000101111000000111001111000111101010111110010110000100011110000001010110010000010000111011111000100101011111100001110011110011000100101" "0000100010001110100100000000101001001111011010000010010111111001110101000010101010010110001111110110101100000100011001010000001010010001010111100111100101100011100111010000101010000110000111000010101000001101001111010100001010100101001101111101111000100000111011010100000010100001100001100111010000" "0000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" "0000110000010010011000010000000010111110011010001001111010011011100010010101010010101110100011111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "1010001111101101100111001111111101000001100101110110000101100100011101000000001100010001011100000110100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, - /* 52*/ { BARCODE_DBAR_EXPSTK, 3, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 9, 151, "#200 16 chars, 3 rows, bottom row 4 chars", + /* 52*/ { BARCODE_DBAR_EXPSTK, 3, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 9, 151, 1, "#200 16 chars, 3 rows, bottom row 4 chars", "0100011101110001011011111111000010110000100101111101101000000110001010111100000000101001110000001001010011111011100110001111110000101110101000011000010" "0000100010001110100100000000101001001111011010000010010111111001110101000010101010010110001111110110101100000100011001010000001010010001010111100110000" "0000010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000" @@ -607,30 +608,114 @@ static void test_examples(int index, int generate, int debug) { "0000011111000101110101001010101001000111011001011110010001011001111101000000001000011001001000001100000000000000000000000000000000000000000000000000000" "0101100000111010001000110000000010111000100110100001101110100110000010111111110011100110110111110001010000000000000000000000000000000000000000000000000" }, - /* 53*/ { BARCODE_DBAR_EXPSTK, 4, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 5, 200, "#200 16 chars, 2 full rows", + /* 53*/ { BARCODE_DBAR_EXPSTK, 4, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 5, 200, 1, "#200 16 chars, 2 full rows", "01000111011100010110111111110000101100001001011111011010000001100010101111000000001010011100000010010100111110111001100011111100001011101010000110000110100111000110001011110000001110011110001111010101" "00001000100011101001000000001010010011110110100000100101111110011101010000101010100101100011111101101011000001000110010100000010100100010101111001111001011000111001110100001010100001100001110000100000" "00000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000" "00001100000100100110000100000000101111100110100010011110100110111000100101010100101011101000111110010110111001100001100001010000001010110111000001000111101111101100101001010100001010111100101100000000" "10100011111011011001110011111111010000011001011101100001011001000111010000000011000100010111000001101001000110011110011100001111110101001000111110111000010000010011010100000011110001000011010011111010" }, - /* 54*/ { BARCODE_DBAR_EXPSTK, 5, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 5, 249, "#200 16 chars, 2 rows, bottom row 6 chars", + /* 54*/ { BARCODE_DBAR_EXPSTK, 5, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 5, 249, 1, "#200 16 chars, 2 rows, bottom row 6 chars", "010001110111000101101111111100001011000010010111110110100000011000101011110000000010100111000000100101001111101110011000111111000010111010100001100001101001110001100010111100000011100111100011110101011111001011000010001111000000101011001000001000010" "000010001000111010010000000010100100111101101000001001011111100111010100001010101001011000111111011010110000010001100101000000101001000101011110011110010110001110011101000010101000011000011100001010100000110100111101010000101010010100110111110110000" "000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000" "000001000001110110101000000101000011000011001110110100111110001011101010010101010010001110110010111100100010110011111010000000010000110010010000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "101110111110001001010111111000011100111100110001001011000001110100010001100000000101110001001101000011011101001100000101111111100111001101101111100010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, - /* 55*/ { BARCODE_DBAR_EXPSTK, 7, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 5, 347, "#200 16 chars, 2 rows, bottom row 2 chars", + /* 55*/ { BARCODE_DBAR_EXPSTK, 7, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 5, 347, 1, "#200 16 chars, 2 rows, bottom row 2 chars", "01000111011100010110111111110000101100001001011111011010000001100010101111000000001010011100000010010100111110111001100011111100001011101010000110000110100111000110001011110000001110011110001111010101111100101100001000111100000010101100100000100001110111110001001010111111000011100111100110001001011000001110100010001100000000101110001001101000010" "00001000100011101001000000001010010011110110100000100101111110011101010000101010100101100011111101101011000001000110010100000010100100010101111001111001011000111001110100001010100001100001110000101010000011010011110101000010101001010011011111011110001000001110110101000000101000011000011001110110100111110001011101010010101010010001110110010110000" "00000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000" "00001000101100111110100000000100001100100100000110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "10110111010011000001011111111001110011011011111000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, - /* 56*/ { BARCODE_DBAR_EXPSTK, 8, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 1, 396, "#200 16 chars, 1 row", + /* 56*/ { BARCODE_DBAR_EXPSTK, 8, "[01]98898765432106[3202]012345[15]991231[3203]001234[17]010203", 1, 396, 1, "#200 16 chars, 1 row", "010001110111000101101111111100001011000010010111110110100000011000101011110000000010100111000000100101001111101110011000111111000010111010100001100001101001110001100010111100000011100111100011110101011111001011000010001111000000101011001000001000011101111100010010101111110000111001111001100010010110000011101000100011000000001011100010011010000110111010011000001011111111001110011011011111000101" }, + /* 57*/ { BARCODE_DBAR_EXP, -1, "[01]00012345678905[10]ABC123", 1, 232, 1, "24724:2011 7.2.5.4.1, encoding method 1 '1'", + "0100011000001011011011111111000010110011000010111101011110011011111010111110000001100010110000110111000111101101011110001111110000101110001100100001010011101111110110101111111100111001011011111101110011011100101111100011110000001010" + }, + /* 58*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3103]001750", 1, 151, 1, "24724:2011 7.2.5.4.2, encoding method 3 '0100'", + "0101110010000010011011111111000010111000010011000101011110111001100010111100000011100101110001110111011110101111000110001111110000101011000010011111010" + }, + /* 59*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3103]032767", 1, 151, 1, "Encoding method 3 '0100' with weight = 32767", + "0101001000111000011011111111000010111000010011000101011110111001100010111100000011100101110001110111011110111011000110001111110000101101111101110111010" + }, + /* 60*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3103]032768", 1, 200, 1, "Possible encoding method 3 '0100' but weight > 32767 so encoding method 7 '0111000' with dummy date", + "01001100000101001110111111110000101000110111000010010111100110111110101111110000111000101100001101110001111011010111100011111100001011000110100110000110100000100110001011111111001110011001111010000101" + }, + /* 61*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3202]000156", 1, 151, 1, "24724:2011 7.2.5.4.3, encoding method 4 '0101'", + "0101001000111100001011111111000010100111000100001101011110111001100010111100000011100101110001110111011110101111000110001111110000101100001000001010010" + }, + /* 62*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3202]009999", 1, 151, 1, "Encoding method 4 '0101' with weight = 9999", + "0101110001000100011011111111000010100111000100001101011110111001100010111100000011100101110001110111011110110100011110001111110000101100111110010001010" + }, + /* 63*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3202]010000", 1, 200, 1, "Possible encoding method 4 '0101' but weight > 9999 so encoding method 8 with dummy date", + "01001000101110000110111111110000101110100011000010010111100110111110101111110000111000101100001101110001111011010111100011111100001010000011101001100111101101001110001011111111001110011001111010000101" + }, + /* 64*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3203]022767", 1, 151, 1, "Encoding method 4 '0101' with weight = 22767", + "0101110010011000001011111111000010100111000100001101011110111001100010111100000011100101110001110111011110111011000110001111110000101101111101110111010" + }, + /* 65*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3203]022768", 1, 200, 1, "Possible encoding method 4 '0101' but weight > 22767 so encoding method 8 with dummy date", + "01000110111000100010111111110000101110100011000010010111100110111110101111110000111000101100001101110001111011010111100011111100001010011100010110000100001101000001101011111111001110011001111010000101" + }, + /* 66*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3922]795", 1, 183, 1, "24724:2011 7.2.5.4.5, encoding method 5 '01100XX', no following AIs", + "010110000010001011101111111100001010011100000101100101111001101111101011111100001110001011000011011100011110110101111000111111000010100111101110100001100011011100100010111111110011101" + }, + /* 67*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3922]795[20]01", 1, 200, 1, "Encoding method 5 '01100XX' with following AI", + "01000110110000110010111111110000101111000100001010010111100110111110101111110000111000101100001101110001111011010111100011111100001010011110111010000110001110001011001011111111001110100111110001110101" + }, + /* 68*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3932]0401234", 1, 200, 1, "24724:2011 7.2.5.4.6, encoding method 6 '01101XX', no following AIs", + "01000111101010000010111111110000101110100000110010010111100110111110101111110000111000101100001101110001111011010111100011111100001011100011001101100100111110001011101011111111001110001101111001011101" + }, + /* 69*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3932]0401234[20]01", 1, 232, 1, "Encoding method 6 '01101XX' with following AI", + "0100010001000110111011111111000010110000101000111001011110011011111010111110000001100010110000110111000111101101011110001111110000101110001100110110010011111000101110101111111100111000100110011110010011101111001000100011110000001010" + }, + /* 70*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3932]A401234", 1, 232, 0, "Possible encoding method 6 '01101XX' but invalid currency code so encoding method 1; BWIPP no check", + "0100011000010011011011111111000010100100011111001101011110011011111010111110000001100010110000110111000111101101011110001111110000101100011001111001010001011011000000101111111100111001101011111110110001111001001110100011110000001010" + }, + /* 71*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3102]099999[11]201209", 1, 200, 1, "Encoding method 7 '0111000' with weight <= 99999 and valid date", + "01000101111001000010111111110000101000110111000010010111100110111110101111110000111000101100001101110001111011010111100011111100001010111100100001000100000011100101001011111111001110010000100100011101" + }, + /* 72*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3102]099999", 1, 200, 1, "Encoding method 7 '0111000' with weight <= 99999 but no date", + "01000111011000010010111111110000101000110111000010010111100110111110101111110000111000101100001101110001111011010111100011111100001010111100100001000110100100011000001011111111001110011001111010000101" + }, + /* 73*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3102]100000[11]201209", 1, 281, 1, "Possible encoding method 7 '0111000' but weight > 99999 so encoding method 1", + "01010011110001110010111111110000101001000111110011010111100110111110101111100000011000101100001101110001111011010111100011111100001010010110001110000110010000011110101011111111001110000011100110101100001001110100011000110000000010100101100000100001011100011001111010111111111001101" + }, + /* 74*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3102]099999[11]200000", 1, 281, 1, "Possible encoding method 7 '0111000' with weight <= 99999 but date invalid so encoding method 1", + "01011001110001001110111111110000101001000111110011010111100110111110101111100000011000101100001101110001111011010111100011111100001010010110001110000110010011110100001011111111001110110011100010111100001001110100011000110000000010101100001000000101010111101111110010111111111001101" + }, + /* 75*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3201]099999[11]201209", 1, 200, 1, "Encoding method 8 '0111001' with weight <= 99999 and valid date", + "01001000001101001110111111110000101110100011000010010111100110111110101111110000111000101100001101110001111011010111100011111100001011000100001101100111010111001110001011111111001110010000100100011101" + }, + /* 76*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3201]099999", 1, 200, 1, "Encoding method 8 '0111001' with weight <= 99999 but no date", + "01000101110010000110111111110000101110100011000010010111100110111110101111110000111000101100001101110001111011010111100011111100001011000100001101100111010000111011101011111111001110011001111010000101" + }, + /* 77*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3201]100000[11]201209", 1, 281, 1, "Possible encoding method 8 '0111001' but weight > 99999 so encoding method 1", + "01011101100011000110111111110000101001000111110011010111100110111110101111100000011000101100001101110001111011010111100011111100001011101010000110000111011110001100101011111111001110000011100110101100001001110100011000110000000010100101100000100001011100011001111010111111111001101" + }, + /* 78*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3201]099999[11]000000", 1, 281, 1, "Possible encoding method 8 '0111001' but date invalid so encoding method 1", + "01011110100001001110111111110000101001000111110011010111100110111110101111100000011000101100001101110001111011010111100011111100001011101010000110000111000011110101101011111111001110110011100010111100001110100001011000110000000010101100001000000101010111101111110010111111111001101" + }, + /* 79*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3100]099999[13]201209", 1, 200, 1, "Encoding method 9 '0111010' with weight <= 99999 and valid date", + "01001000001101001110111111110000101111001010000010010111100110111110101111110000111000101100001101110001111011010111100011111100001011000111000001010111010000110110001011111111001110010000100100011101" + }, + /* 80*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3204]099999[13]201209", 1, 200, 1, "Encoding method 10 '0111011' with weight <= 99999 and valid date", + "01001000111000010110111111110000101100101000001110010111100110111110101111110000111000101100001101110001111011010111100011111100001010011101000011110101110000101111101011111111001110010000100100011101" + }, + /* 81*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3103]012233[15]991231", 1, 200, 1, "24724:2011 7.2.5.4.4, encoding method 11 '0111100' with weight <= 99999 and valid date", + "01001100000100111010111111110000101011100100000110010111100110111110101111110000111000101100001101110001111011010111100011111100001011000011010110000111001100110001001011111111001110001101111010000101" + }, + /* 82*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3205]099999[15]201209", 1, 200, 1, "Encoding method 12 '0111101' with weight <= 99999 and valid date", + "01001110000010011010111111110000101000001101110100010111100110111110101111110000111000101100001101110001111011010111100011111100001011110011010001100101001100011000001011111111001110010000100100011101" + }, + /* 83*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3109]099999[17]201209", 1, 200, 1, "Encoding method 13 '0111110' with weight <= 99999 and valid date", + "01001110000010100110111111110000101110000100110100010111100110111110101111110000111000101100001101110001111011010111100011111100001011011101111101000111010111001110001011111111001110010000100100011101" + }, + /* 84*/ { BARCODE_DBAR_EXP, -1, "[01]90012345678908[3200]099999[17]201209", 1, 200, 1, "Encoding method 14 '0111111' with weight <= 99999 and valid date", + "01001110000010100110111111110000101111000100010100010111100110111110101111110000111000101100001101110001111011010111100011111100001011000111000001010111010000110110001011111111001110010000100100011101" + }, }; int data_size = sizeof(data) / sizeof(struct item); @@ -651,8 +736,8 @@ static void test_examples(int index, int generate, int debug) { assert_zero(ret, "i:%d ZBarcode_Encode ret %d != 0 (%s)\n", i, ret, symbol->errtxt); if (generate) { - printf(" /*%3d*/ { %s, %d, \"%s\", %d, %d, \"%s\",\n", - i, testUtilBarcodeName(symbol->symbology), data[i].option_2, data[i].data, symbol->rows, symbol->width, data[i].comment); + printf(" /*%3d*/ { %s, %d, \"%s\", %d, %d, %d, \"%s\",\n", + i, testUtilBarcodeName(symbol->symbology), data[i].option_2, data[i].data, symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment); testUtilModulesDump(symbol, " ", "\n"); printf(" },\n"); } else { @@ -664,12 +749,16 @@ static void test_examples(int index, int generate, int debug) { assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { - ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + 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 = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); - ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); - assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected); + ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); + assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", + i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected); + } } } diff --git a/backend/tests/test_upcean.c b/backend/tests/test_upcean.c index 89ca2d0b..ca13a29f 100644 --- a/backend/tests/test_upcean.c +++ b/backend/tests/test_upcean.c @@ -405,52 +405,65 @@ static void test_isbn_input(int index, int debug) { /* 0*/ { "0", 0, 0 }, // Left zero-padded if < 10 chars /* 1*/ { "12345678", ZINT_ERROR_INVALID_CHECK, -1 }, /* 2*/ { "12345679", 0, 0 }, // 9 is correct check digit - /* 3*/ { "123456789", 0, 0 }, - /* 4*/ { "0123456789", 0, 0 }, - /* 5*/ { "1234567890", ZINT_ERROR_INVALID_CHECK, -1 }, - /* 6*/ { "123456789X", 0, 0 }, // X is correct check digit - /* 7*/ { "123456789x", 0, 0 }, // x is correct check digit - /* 8*/ { "8175257660", 0, 0 }, // 0 is correct check digit - /* 9*/ { "0590764845", 0, 0 }, // 5 is correct check digit - /* 10*/ { "0906495741", 0, 0 }, // 1 is correct check digit - /* 11*/ { "0140430016", 0, 0 }, // 6 is correct check digit - /* 12*/ { "0571086187", 0, 0 }, // 7 is correct check digit - /* 13*/ { "0486600882", 0, 0 }, // 2 is correct check digit - /* 14*/ { "12345678901", ZINT_ERROR_TOO_LONG, -1 }, - /* 15*/ { "123456789012", ZINT_ERROR_TOO_LONG, -1 }, - /* 16*/ { "1234567890123", ZINT_ERROR_INVALID_DATA, -1 }, - /* 17*/ { "9784567890120", 0, 0 }, // 0 is correct check digit - /* 18*/ { "9783161484100", 0, 0 }, // 0 is correct check digit - /* 19*/ { "9781846688225", 0, 0 }, // 5 is correct check digit - /* 20*/ { "9781847657954", 0, 0 }, // 4 is correct check digit - /* 21*/ { "9781846688188", 0, 0 }, // 8 is correct check digit - /* 22*/ { "9781847659293", 0, 0 }, // 3 is correct check digit - /* 23*/ { "97845678901201", ZINT_ERROR_TOO_LONG, -1 }, - /* 24*/ { "3954994+12", 0, 0 }, - /* 25*/ { "3954994+12345", 0, 0 }, - /* 26*/ { "3954994+123456", ZINT_ERROR_TOO_LONG, -1 }, - /* 27*/ { "3954994+", 0, 0 }, - /* 28*/ { "61954993+1", 0, 0 }, - /* 29*/ { "61954993+123", 0, 0 }, - /* 30*/ { "361954999+12", 0, 0 }, - /* 31*/ { "361954999+1234", 0, 0 }, - /* 32*/ { "361954999+12", 0, 0 }, - /* 33*/ { "199900003X+12", 0, 0 }, - /* 34*/ { "199900003x+12", 0, 0 }, - /* 35*/ { "199900003X+12345", 0, 0 }, - /* 36*/ { "199900003x+12345", 0, 0 }, - /* 37*/ { "9791234567896+12", 0, 0 }, - /* 38*/ { "9791234567896+12345", 0, 0 }, - /* 39*/ { "9791234567896+", 0, 0 }, - /* 40*/ { "97912345678961+", ZINT_ERROR_TOO_LONG, -1 }, - /* 41*/ { "97912345678961+12345", ZINT_ERROR_TOO_LONG, -1 }, - /* 42*/ { "9791234567896+123456", ZINT_ERROR_TOO_LONG, -1 }, + /* 3*/ { "98765434", 0, 0 }, // 4 is correct check digit + /* 4*/ { "123456789", 0, 0 }, + /* 5*/ { "340013817", ZINT_ERROR_INVALID_CHECK, -1 }, + /* 6*/ { "340013818", 0, 0 }, // 8 is correct check digit + /* 7*/ { "902888455", 0, 0 }, // 5 is correct check digit + /* 8*/ { "0123456789", 0, 0 }, + /* 9*/ { "1234567890", ZINT_ERROR_INVALID_CHECK, -1 }, + /* 10*/ { "123456789X", 0, 0 }, // X is correct check digit + /* 11*/ { "123456789x", 0, 0 }, // x is correct check digit + /* 12*/ { "8175257660", 0, 0 }, // 0 is correct check digit + /* 13*/ { "0590764845", 0, 0 }, // 5 is correct check digit + /* 14*/ { "0906495741", 0, 0 }, // 1 is correct check digit + /* 15*/ { "0140430016", 0, 0 }, // 6 is correct check digit + /* 16*/ { "0571086187", 0, 0 }, // 7 is correct check digit + /* 17*/ { "0486600882", 0, 0 }, // 2 is correct check digit + /* 18*/ { "12345678901", ZINT_ERROR_TOO_LONG, -1 }, + /* 19*/ { "123456789012", ZINT_ERROR_TOO_LONG, -1 }, + /* 20*/ { "1234567890123", ZINT_ERROR_INVALID_DATA, -1 }, + /* 21*/ { "9784567890123", ZINT_ERROR_INVALID_CHECK, -1 }, + /* 22*/ { "9784567890120", 0, 0 }, // 0 is correct check digit + /* 23*/ { "9783161484100", 0, 0 }, // 0 is correct check digit + /* 24*/ { "9781846688225", 0, 0 }, // 5 is correct check digit + /* 25*/ { "9781847657954", 0, 0 }, // 4 is correct check digit + /* 26*/ { "9781846688188", 0, 0 }, // 8 is correct check digit + /* 27*/ { "9781847659293", 0, 0 }, // 3 is correct check digit + /* 28*/ { "97845678901201", ZINT_ERROR_TOO_LONG, -1 }, + /* 29*/ { "3954994+12", 0, 0 }, + /* 30*/ { "3954994+12345", 0, 0 }, + /* 31*/ { "3954994+123456", ZINT_ERROR_TOO_LONG, -1 }, + /* 32*/ { "3954994+", 0, 0 }, + /* 33*/ { "61954993+1", 0, 0 }, + /* 34*/ { "61954992+123", ZINT_ERROR_INVALID_CHECK, -1 }, + /* 35*/ { "61954993+123", 0, 0 }, + /* 36*/ { "361954990+12", ZINT_ERROR_INVALID_CHECK, -1 }, + /* 37*/ { "361954999+12", 0, 0 }, + /* 38*/ { "361954999+1234", 0, 0 }, + /* 39*/ { "361954999+12", 0, 0 }, + /* 40*/ { "1999000030+12", ZINT_ERROR_INVALID_CHECK, -1 }, + /* 41*/ { "199900003X+12", 0, 0 }, + /* 42*/ { "199900003x+12", 0, 0 }, + /* 43*/ { "1999000031+12345", ZINT_ERROR_INVALID_CHECK, -1 }, + /* 44*/ { "199900003X+12345", 0, 0 }, + /* 45*/ { "199900003x+12345", 0, 0 }, + /* 46*/ { "9791234567895+12", ZINT_ERROR_INVALID_CHECK, -1 }, + /* 47*/ { "9791234567896+12", 0, 0 }, + /* 48*/ { "9791234567897+12345", ZINT_ERROR_INVALID_CHECK, -1 }, + /* 49*/ { "9791234567896+12345", 0, 0 }, + /* 50*/ { "9791234567892+", ZINT_ERROR_INVALID_CHECK, -1 }, + /* 51*/ { "9791234567896+", 0, 0 }, + /* 52*/ { "97912345678961+", ZINT_ERROR_TOO_LONG, -1 }, + /* 53*/ { "97912345678961+12345", ZINT_ERROR_TOO_LONG, -1 }, + /* 54*/ { "9791234567896+123456", ZINT_ERROR_TOO_LONG, -1 }, }; int data_size = sizeof(data) / sizeof(struct item); for (int i = 0; i < data_size; i++) { if (index != -1 && i != index) continue; + if ((debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) printf("i:%d\n", i); struct zint_symbol *symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index 5325e56e..c8d5a722 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -42,11 +42,6 @@ #include #include -#ifndef COMMON_INLINE -extern int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord); -extern int module_colour_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord); -#endif - static int tests = 0; static int failed = 0; static int skipped = 0; @@ -1737,7 +1732,7 @@ static const char *testUtilBwippName(int index, const struct zint_symbol *symbol { "", -1, 44, 0, 0, 0, 0, 0, }, { "", -1, 45, 0, 0, 0, 0, 0, }, { "", -1, 46, 0, 0, 0, 0, 0, }, - { "msi", BARCODE_MSI_PLESSEY, 47, 0, 0, 0, 0, 0, }, + { "msi", BARCODE_MSI_PLESSEY, 47, 0, 1, 0, 0, 0, }, { "", -1, 48, 0, 0, 0, 0, 0, }, { "symbol", BARCODE_FIM, 49, 0, 0, 0, 0, 0, }, { "code39", BARCODE_LOGMARS, 50, 0, 1, 0, 0, 0, }, @@ -2177,6 +2172,26 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int } bwipp_opts = bwipp_opts_buf; /* Set always as option_2 == 2 is bwipp default */ } + } else if (symbology == BARCODE_PLESSEY) { + sprintf(bwipp_opts_buf + (int) strlen(bwipp_opts_buf), "%sincludecheck", strlen(bwipp_opts_buf) ? " " : ""); + bwipp_opts = bwipp_opts_buf; + } else if (symbology == BARCODE_MSI_PLESSEY) { + if (option_2 > 0) { + sprintf(bwipp_opts_buf + (int) strlen(bwipp_opts_buf), "%sincludecheck", strlen(bwipp_opts_buf) ? " " : ""); + + const char *checktype = NULL; + if (option_2 == 2) { + checktype = "mod1010"; + } else if (option_2 == 3) { + checktype = "mod11 badmod11"; + } else if (option_2 == 4) { + checktype = "mod1110 badmod11"; + } + if (checktype) { + sprintf(bwipp_opts_buf + (int) strlen(bwipp_opts_buf), "%schecktype=%s", strlen(bwipp_opts_buf) ? " " : "", checktype); + } + bwipp_opts = bwipp_opts_buf; + } } else if (symbology == BARCODE_PDF417 || symbology == BARCODE_PDF417COMP || symbology == BARCODE_HIBC_PDF || symbology == BARCODE_MICROPDF417 || symbology == BARCODE_HIBC_MICPDF) { for (r = 0; r < symbol->rows; r++) bwipp_row_height[r] = 1; /* Change from 3 */ @@ -2265,8 +2280,16 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int } } else if (symbology == BARCODE_CODEONE) { if (option_2 >= 1 && option_2 <= 10) { - static char codeone_versions[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'S', 'T' }; - sprintf(bwipp_opts_buf + (int) strlen(bwipp_opts_buf), "%sversion=%c", strlen(bwipp_opts_buf) ? " " : "", codeone_versions[option_2 - 1]); + static const char *codeone_versions[] = { "A", "B", "C", "D", "E", "F", "G", "H" }; + const char *codeone_version; + if (option_2 == 9) { + codeone_version = length <= 6 ? "S-10" : length <= 12 ? "S-20" : "S-30"; + } else if (option_2 == 10) { + codeone_version = "T-16"; // TODO: Allow for different T sizes + } else { + codeone_version = codeone_versions[option_2 - 1]; + } + sprintf(bwipp_opts_buf + (int) strlen(bwipp_opts_buf), "%sversion=%s", strlen(bwipp_opts_buf) ? " " : "", codeone_version); bwipp_opts = bwipp_opts_buf; } } @@ -2337,6 +2360,12 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int memmove(cmd + GS_INITIAL_LEN + sizeof(adj), cmd + GS_INITIAL_LEN, strlen(cmd) + 1 - GS_INITIAL_LEN); memcpy(cmd + GS_INITIAL_LEN, adj, sizeof(adj)); } + if (symbology == BARCODE_PLESSEY) { + /* Ceiling ratio 3/4/5 width bar/space -> 2 width then round ratio 2 width bar/space -> 3 width */ + char adj[16] = " -sc=0.4 -sr=1.3"; + memmove(cmd + GS_INITIAL_LEN + sizeof(adj), cmd + GS_INITIAL_LEN, strlen(cmd) + 1 - GS_INITIAL_LEN); + memcpy(cmd + GS_INITIAL_LEN, adj, sizeof(adj)); + } if (symbology == BARCODE_CODE11 || symbology == BARCODE_CODE39 || symbology == BARCODE_EXCODE39 || symbology == BARCODE_HIBC_39 || symbology == BARCODE_LOGMARS || symbology == BARCODE_PHARMA || symbology == BARCODE_PZN || symbology == BARCODE_CODE32 || symbology == BARCODE_VIN || symbology == BARCODE_C25INTER || symbology == BARCODE_DPLEIT || symbology == BARCODE_DPIDENT || symbology == BARCODE_ITF14 diff --git a/backend/tests/testcommon.h b/backend/tests/testcommon.h index 381f922f..e59cbf69 100644 --- a/backend/tests/testcommon.h +++ b/backend/tests/testcommon.h @@ -39,6 +39,10 @@ #include #include "../common.h" +#ifdef __cplusplus +extern "C" { +#endif + #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif @@ -75,7 +79,7 @@ void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size); #define ZINT_DEBUG_TEST_BWIPP 128 #define ZINT_DEBUG_TEST_PERFORMANCE 256 -extern void vector_free(struct zint_symbol *symbol); /* Free vector structures */ +INTERNAL void vector_free(struct zint_symbol *symbol); /* Free vector structures */ int testUtilSetSymbol(struct zint_symbol *symbol, int symbology, int input_mode, int eci, int option_1, int option_2, int option_3, int output_options, char *data, int length, int debug); const char *testUtilBarcodeName(int symbology); @@ -119,4 +123,8 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int int testUtilBwippCmp(const struct zint_symbol *symbol, char *msg, const char *bwipp_buf, const char *expected); int testUtilBwippCmpRow(const struct zint_symbol *symbol, int row, char *msg, const char *bwipp_buf, const char *expected); +#ifdef __cplusplus +} +#endif + #endif /* TESTCOMMON_H */ diff --git a/backend/tests/tools/bwipp_dump-barcode.ps.diff b/backend/tests/tools/bwipp_dump-barcode.ps.diff index 89b3bdfc..0a4941b3 100644 --- a/backend/tests/tools/bwipp_dump-barcode.ps.diff +++ b/backend/tests/tools/bwipp_dump-barcode.ps.diff @@ -1,5 +1,5 @@ ---- ../../../../postscriptbarcode/build/monolithic/barcode.ps 2020-10-26 01:13:25.080992540 +0000 -+++ ../tools/bwipp_dump.ps 2020-10-26 11:19:21.268222231 +0000 +--- ../../../../postscriptbarcode/build/monolithic/barcode.ps 2020-12-19 06:21:55.358036729 +0000 ++++ ../tools/bwipp_dump.ps 2020-12-21 14:41:10.265502623 +0000 @@ -29,6 +29,8 @@ % CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS % IN THE SOFTWARE. @@ -9,7 +9,7 @@ % --BEGIN TEMPLATE-- % --BEGIN RESOURCE preamble-- -@@ -24466,34 +24468,80 @@ +@@ -24471,34 +24473,80 @@ pop } ifelse @@ -109,7 +109,7 @@ end -@@ -24552,7 +24600,7 @@ +@@ -24557,7 +24605,7 @@ pop } ifelse @@ -118,7 +118,7 @@ % Get the result of encoding with ean8 and gs1-cc options (lintype) (ean8) put -@@ -24560,29 +24608,75 @@ +@@ -24565,29 +24613,75 @@ options (dontdraw) true put % Plot the linear part @@ -214,7 +214,7 @@ end -@@ -24641,34 +24735,80 @@ +@@ -24646,34 +24740,80 @@ pop } ifelse @@ -314,7 +314,7 @@ end -@@ -24742,34 +24882,80 @@ +@@ -24747,34 +24887,80 @@ /opt options >> def @@ -414,7 +414,7 @@ end -@@ -24828,7 +25014,7 @@ +@@ -24833,7 +25019,7 @@ pop } ifelse @@ -423,7 +423,7 @@ options (lintype) (databaromni) put options (linkage) true put -@@ -24839,7 +25025,7 @@ +@@ -24844,7 +25030,7 @@ linear options //databaromni exec dup (sbs) get /linsbs exch def dup (bhs) get 0 get 72 mul /linheight exch def @@ -432,7 +432,7 @@ % Plot the separator /sepfinder { -@@ -24870,20 +25056,66 @@ +@@ -24875,20 +25061,66 @@ sep 0 [0 0 0] putinterval sep sep length 4 sub [0 0 0 0] putinterval 18 sepfinder 64 sepfinder @@ -511,7 +511,7 @@ end -@@ -24941,7 +25173,7 @@ +@@ -24946,7 +25178,7 @@ pop } ifelse @@ -520,7 +520,7 @@ options (lintype) (databarstacked) put options (linkage) true put -@@ -24952,7 +25184,7 @@ +@@ -24957,7 +25189,7 @@ linear options //databarstacked exec dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def dup (pixy) get /linheight exch def @@ -529,7 +529,7 @@ % Plot the separator /sepfinder { -@@ -24980,20 +25212,52 @@ +@@ -24985,20 +25217,52 @@ sep 0 [ 0 0 0 0 ] putinterval sep sep length 4 sub [ 0 0 0 0 ] putinterval 18 sepfinder @@ -594,7 +594,7 @@ end -@@ -25051,7 +25315,7 @@ +@@ -25056,7 +25320,7 @@ pop } ifelse @@ -603,7 +603,7 @@ options (lintype) (databarstackedomni) put options (linkage) true put -@@ -25062,7 +25326,7 @@ +@@ -25067,7 +25331,7 @@ linear options //databarstackedomni exec dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def dup (pixy) get /linheight exch def @@ -612,7 +612,7 @@ % Plot the separator /sepfinder { -@@ -25090,20 +25354,52 @@ +@@ -25095,20 +25359,52 @@ sep 0 [ 0 0 0 0 ] putinterval sep sep length 4 sub [ 0 0 0 0 ] putinterval 18 sepfinder @@ -677,7 +677,7 @@ end -@@ -25276,7 +25572,7 @@ +@@ -25281,7 +25577,7 @@ pop } ifelse @@ -686,7 +686,7 @@ options (lintype) (databarlimited) put options (linkage) true put -@@ -25287,7 +25583,7 @@ +@@ -25292,7 +25588,7 @@ linear options //databarlimited exec dup (sbs) get /linsbs exch def dup (bhs) get 0 get 72 mul /linheight exch def @@ -695,7 +695,7 @@ % Plot the separator mark -@@ -25295,22 +25591,68 @@ +@@ -25300,22 +25596,68 @@ counttomark 1 sub array astore /sep exch def pop pop sep 0 [0 0 0] putinterval sep sep length 9 sub [0 0 0 0 0 0 0 0 0] putinterval % 4 + 5 right guard spaces @@ -778,7 +778,7 @@ end -@@ -25369,7 +25711,7 @@ +@@ -25374,7 +25716,7 @@ pop } ifelse @@ -787,7 +787,7 @@ options (lintype) (databarexpanded) put options (linkage) true put -@@ -25380,7 +25722,7 @@ +@@ -25385,7 +25727,7 @@ linear options //databarexpanded exec dup (sbs) get /linsbs exch def dup (bhs) get 0 get 72 mul /linheight exch def @@ -796,7 +796,7 @@ % Plot the separator /sepfinder { -@@ -25409,20 +25751,60 @@ +@@ -25414,20 +25756,60 @@ 18 98 bot length 13 sub {} for 69 98 bot length 13 sub {} for ] {sepfinder} forall @@ -869,7 +869,7 @@ end -@@ -25480,7 +25862,7 @@ +@@ -25485,7 +25867,7 @@ pop } ifelse @@ -878,7 +878,7 @@ options (lintype) (databarexpandedstacked) put options (linkage) true put -@@ -25491,7 +25873,7 @@ +@@ -25496,7 +25878,7 @@ linear options //databarexpandedstacked exec dup (pixs) get 0 2 index (pixx) get getinterval /bot exch def dup (pixy) get /linheight exch def @@ -887,7 +887,7 @@ % Plot the separator /sepfinder { -@@ -25517,21 +25899,49 @@ +@@ -25522,21 +25904,49 @@ 19 98 bot length 13 sub {} for 70 98 bot length 13 sub {} for ] {sepfinder} forall @@ -950,7 +950,7 @@ end -@@ -25590,7 +26000,7 @@ +@@ -25595,7 +26005,7 @@ pop } ifelse @@ -959,7 +959,7 @@ options (inkspread) (0) put options (dontdraw) true put -@@ -25617,35 +26027,87 @@ +@@ -25622,35 +26032,87 @@ linear << options {} forall >> //gs1-128 exec dup (sbs) get /linsbs exch def dup (bhs) get 0 get 72 mul /linheight exch def @@ -1061,7 +1061,7 @@ end -@@ -26919,3 +27381,176 @@ +@@ -26924,3 +27386,181 @@ % --END ENCODER hibcazteccode-- % --END TEMPLATE-- @@ -1076,7 +1076,7 @@ +% `-sb=` is the bwipp barcode routine name +% `-sd=` is the data (`sd2=` is also available for overspill data > 2K to get around Ghostscript arg_str_max) +% `-so=` are options (as space separated key=val pairs (or just key if boolean true)) -+ ++ +% Command line "-s" options put into system dictionary as strings +/n systemdict /n known def + @@ -1153,7 +1153,12 @@ + % Check if given ratio arg to adjust width of bars/spaces (e.g. "0.6" reduces 3 -> 2, "1.3" increases 2 -> 3) + systemdict /r known { + /r systemdict /r get cvr def -+ /f { r mul round cvi } def ++ systemdict /c known { % Apply ceiling ratio beforehand ++ /c systemdict /c get cvr def ++ /f { c mul ceiling cvi r mul round cvi } def ++ } { ++ /f { r mul round cvi } def ++ } ifelse + } { + /f {} def + } ifelse @@ -1231,7 +1236,7 @@ + } if +} ifelse + -+% If have renderer ++% If have renderer +ret /ren known { + % Scale + /s systemdict /s known { systemdict /s get cvi } { 2 } ifelse def diff --git a/backend/tests/tools/bwipp_dump.ps.tar.xz b/backend/tests/tools/bwipp_dump.ps.tar.xz index 02dbc179..9ebe33c0 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/upcean.c b/backend/upcean.c index 54478134..1692bc57 100644 --- a/backend/upcean.c +++ b/backend/upcean.c @@ -79,17 +79,13 @@ static const char *EANsetB[10] = { }; /* Calculate the correct check digit for a UPC barcode */ -static char upc_check(char source[]) { - unsigned int i, count, check_digit; +static char upc_check(const char source[], const int length) { + int i, count, check_digit; count = 0; - for (i = 0; i < strlen(source); i++) { - count += ctoi(source[i]); - - if (!(i & 1)) { - count += 2 * (ctoi(source[i])); - } + for (i = 0; i < length; i++) { + count += (i & 1) ? ctoi(source[i]) : 3 * ctoi(source[i]); } check_digit = 10 - (count % 10); @@ -100,115 +96,88 @@ static char upc_check(char source[]) { } /* UPC A is usually used for 12 digit numbers, but this function takes a source of any length */ -static void upca_draw(char source[], char dest[]) { - unsigned int i, half_way, length = strlen(source); +static void upca_draw(const char source[], const int length, unsigned char dest[]) { + int i, half_way; half_way = length / 2; /* start character */ - strcat(dest, "111"); + ustrcat(dest, "111"); for (i = 0; i < length; i++) { if (i == half_way) { /* middle character - separates manufacturer no. from product no. */ /* also inverts right hand characters */ - strcat(dest, "11111"); + ustrcat(dest, "11111"); } - lookup(NEON, EANsetA, source[i], dest); + lookup(NEON, EANsetA, source[i], (char *) dest); } /* stop character */ - strcat(dest, "111"); + ustrcat(dest, "111"); } /* Make a UPC A barcode when we haven't been given the check digit */ -static int upca(struct zint_symbol *symbol, unsigned char source[], char dest[]) { - int length; +static int upca(struct zint_symbol *symbol, const unsigned char source[], int length, unsigned char dest[]) { char gtin[15]; int error_number = 0; - strcpy(gtin, (char*) source); - length = strlen(gtin); + ustrcpy(gtin, source); if (length == 11) { - gtin[length] = upc_check(gtin); - gtin[length + 1] = '\0'; + gtin[length++] = upc_check(gtin, 11); + gtin[length] = '\0'; } else { - gtin[length - 1] = '\0'; - if (source[length - 1] != upc_check(gtin)) { + if (source[length - 1] != upc_check(gtin, 11)) { if (symbol->debug & ZINT_DEBUG_PRINT) { - printf("UPC-A: Invalid check digit %s, gtin: %s, Check digit: %c\n", source, gtin, upc_check(gtin)); + printf("UPC-A: Invalid check digit %s, gtin: %s, Check digit: %c\n", source, gtin, + upc_check(gtin, 11)); } strcpy(symbol->errtxt, "270: Invalid check digit"); return ZINT_ERROR_INVALID_CHECK; } - gtin[length - 1] = upc_check(gtin); } if (symbol->debug & ZINT_DEBUG_PRINT) { - printf("UPC-A: %s, gtin: %s, Check digit: %c\n", source, gtin, length == 11 ? gtin[length] : gtin[length - 1]); + printf("UPC-A: %s, gtin: %s, Check digit: %c\n", source, gtin, + length == 11 ? gtin[length] : gtin[length - 1]); } - upca_draw(gtin, dest); + upca_draw(gtin, length, dest); ustrcpy(symbol->text, gtin); return error_number; } /* UPC E is a zero-compressed version of UPC A */ -static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) { - unsigned int i, num_system, length; - char emode, equivalent[12], check_digit, parity[8], temp[9]; +static int upce(struct zint_symbol *symbol, unsigned char source[], int length, unsigned char dest[]) { + int i, num_system; + char emode, equivalent[12], check_digit, parity[8]; char hrt[9]; int error_number = 0; /* Two number systems can be used - system 0 and system 1 */ - if (symbol->symbology != BARCODE_UPCE_CHK) { - /* No check digit in input data */ - if (ustrlen(source) == 7) { - switch (source[0]) { - case '0': num_system = 0; - break; - case '1': num_system = 1; - break; - default: num_system = 0; - /* First source char ignored */ - break; - } - strcpy(temp, (char*) source); - strcpy(hrt, (char*) source); - for (i = 1; i <= 7; i++) { - source[i - 1] = temp[i]; - } - } else { - num_system = 0; - hrt[0] = '0'; - hrt[1] = '\0'; - strcat(hrt, (char*) source); + if ((symbol->symbology != BARCODE_UPCE_CHK && length == 7) || length == 8) { + switch (source[0]) { + case '0': num_system = 0; + break; + case '1': num_system = 1; + break; + default: num_system = 0; + /* First source char ignored */ + break; } + ustrcpy(hrt, source); + for (i = 1; i <= length; i++) { + source[i - 1] = hrt[i]; + } + length--; } else { - /* Check digit is included in input data */ - if (ustrlen(source) == 8) { - switch (source[0]) { - case '0': num_system = 0; - break; - case '1': num_system = 1; - break; - default: num_system = 0; - /* First source char ignored */ - break; - } - strcpy(temp, (char*) source); - strcpy(hrt, (char*) source); - for (i = 1; i <= 8; i++) { - source[i - 1] = temp[i]; - } - } else { - num_system = 0; - hrt[0] = '0'; - hrt[1] = '\0'; - strcat(hrt, (char*) source); - } + /* Length 6 with no check digit, or length 7 with check digit, system 0, insert leading zero */ + num_system = 0; + hrt[0] = '0'; + hrt[1] = '\0'; + ustrncat(hrt, source, length); } /* Expand the zero-compressed UPCE code to make a UPCA equivalent (EN Table 5) */ @@ -217,7 +186,7 @@ static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) equivalent[i] = '0'; } if (num_system == 1) { - equivalent[0] = temp[0]; + equivalent[0] = hrt[0]; } equivalent[1] = source[0]; equivalent[2] = source[1]; @@ -271,7 +240,7 @@ static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) /* Get the check digit from the expanded UPCA code */ - check_digit = upc_check(equivalent); + check_digit = upc_check(equivalent, 11); /* Use the number system and check digit information to choose a parity scheme */ if (num_system == 1) { @@ -283,20 +252,19 @@ static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) /* Take all this information and make the barcode pattern */ /* start character */ - strcat(dest, "111"); + ustrcat(dest, "111"); - length = ustrlen(source); for (i = 0; i < length; i++) { switch (parity[i]) { - case 'A': lookup(NEON, EANsetA, source[i], dest); + case 'A': lookup(NEON, EANsetA, source[i], (char *) dest); break; - case 'B': lookup(NEON, EANsetB, source[i], dest); + case 'B': lookup(NEON, EANsetB, source[i], (char *) dest); break; } } /* stop character */ - strcat(dest, "111111"); + ustrcat(dest, "111111"); if (symbol->symbology != BARCODE_UPCE_CHK) { hrt[7] = check_digit; @@ -304,7 +272,8 @@ static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) } else { if (hrt[7] != check_digit) { if (symbol->debug & ZINT_DEBUG_PRINT) { - printf("UPC-E: Invalid check digit %s, equivalent: %s, hrt: %s, Check digit: %c\n", source, equivalent, hrt, check_digit); + printf("UPC-E: Invalid check digit %s, equivalent: %s, hrt: %s, Check digit: %c\n", source, + equivalent, hrt, check_digit); } strcpy(symbol->errtxt, "274: Invalid check digit"); return ZINT_ERROR_INVALID_CHECK; @@ -320,22 +289,22 @@ static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) } /* EAN-2 and EAN-5 add-on codes */ -static void add_on(unsigned char source[], char dest[], int addon_gap) { +static void add_on(const unsigned char source[], const int length, unsigned char dest[], const int addon_gap) { char parity[6]; - unsigned int i, code_type, length; + int i, code_type; /* If an add-on then append with space */ if (addon_gap != 0) { - i = strlen(dest); + i = (int) ustrlen(dest); dest[i] = itoc(addon_gap); dest[i + 1] = '\0'; } /* Start character */ - strcat(dest, "112"); + ustrcat(dest, "112"); /* Determine EAN2 or EAN5 add-on */ - if (ustrlen(source) == 2) { + if (length == 2) { code_type = EAN2; } else { code_type = EAN5; @@ -364,38 +333,32 @@ static void add_on(unsigned char source[], char dest[], int addon_gap) { strcpy(parity, EAN5Parity[parity_bit]); } - length = ustrlen(source); for (i = 0; i < length; i++) { switch (parity[i]) { - case 'A': lookup(NEON, EANsetA, source[i], dest); + case 'A': lookup(NEON, EANsetA, source[i], (char *) dest); break; - case 'B': lookup(NEON, EANsetB, source[i], dest); + case 'B': lookup(NEON, EANsetB, source[i], (char *) dest); break; } /* Glyph separator */ - if (i != (ustrlen(source) - 1)) { - strcat(dest, "11"); + if (i != (length - 1)) { + ustrcat(dest, "11"); } } } /* ************************ EAN-13 ****************** */ -/* Calculate the correct check digit for a EAN-13 barcode */ -static char ean_check(char source[]) { +/* Calculate the correct check digit for a EAN-13 barcode (including ISBN(13)) */ +static char ean_check(const char source[], const int length) { int i; - unsigned int h, count, check_digit; + int count, check_digit; count = 0; - h = strlen(source); - for (i = h - 1; i >= 0; i--) { - count += ctoi(source[i]); - - if (i & 1) { - count += 2 * ctoi(source[i]); - } + for (i = 0; i < length; i++) { + count += (i & 1) ? 3 * ctoi(source[i]) : ctoi(source[i]); } check_digit = 10 - (count % 10); if (check_digit == 10) { @@ -404,34 +367,32 @@ static char ean_check(char source[]) { return itoc(check_digit); } -static int ean13(struct zint_symbol *symbol, unsigned char source[], char dest[]) { - unsigned int length, i, half_way; +static int ean13(struct zint_symbol *symbol, const unsigned char source[], int length, unsigned char dest[]) { + int i, half_way; char parity[6]; char gtin[15]; int error_number = 0; - strcpy(parity, ""); - strcpy(gtin, (char*) source); + parity[0] = '\0'; + ustrcpy(gtin, source); /* Add the appropriate check digit */ - length = strlen(gtin); if (length == 12) { - gtin[length] = ean_check(gtin); - gtin[length + 1] = '\0'; + gtin[length++] = ean_check(gtin, 12); + gtin[length] = '\0'; } else { - gtin[length - 1] = '\0'; - if (source[length - 1] != ean_check(gtin)) { + if (source[length - 1] != ean_check(gtin, 12)) { if (symbol->debug & ZINT_DEBUG_PRINT) { - printf("EAN-13 Invalid check digit: %s, gtin: %s, Check digit: %c\n", source, gtin, ean_check(gtin)); + printf("EAN-13 Invalid check digit: %s, gtin: %s, Check digit: %c\n", source, gtin, + ean_check(gtin, 12)); } strcpy(symbol->errtxt, "275: Invalid check digit"); return ZINT_ERROR_INVALID_CHECK; } - gtin[length - 1] = ean_check(gtin); } if (symbol->debug & ZINT_DEBUG_PRINT) { - printf("EAN-13: %s, gtin: %s, Check digit: %c\n", source, gtin, length == 12 ? gtin[length] : gtin[length - 1]); + printf("EAN-13: %s, gtin: %s, Check digit: %c\n", source, gtin, gtin[length - 1]); } /* Get parity for first half of the symbol */ @@ -441,93 +402,69 @@ static int ean13(struct zint_symbol *symbol, unsigned char source[], char dest[] half_way = 7; /* start character */ - strcat(dest, "111"); - length = strlen(gtin); + ustrcat(dest, "111"); for (i = 1; i < length; i++) { if (i == half_way) { /* middle character - separates manufacturer no. from product no. */ /* also inverses right hand characters */ - strcat(dest, "11111"); + ustrcat(dest, "11111"); } if (((i > 1) && (i < 7)) && (parity[i - 2] == 'B')) { - lookup(NEON, EANsetB, gtin[i], dest); + lookup(NEON, EANsetB, gtin[i], (char *) dest); } else { - lookup(NEON, EANsetA, gtin[i], dest); + lookup(NEON, EANsetA, gtin[i], (char *) dest); } } /* stop character */ - strcat(dest, "111"); + ustrcat(dest, "111"); ustrcpy(symbol->text, gtin); return error_number; } /* Make an EAN-8 barcode when we haven't been given the check digit */ -static int ean8(struct zint_symbol *symbol, unsigned char source[], char dest[]) { +static int ean8(struct zint_symbol *symbol, const unsigned char source[], int length, unsigned char dest[]) { /* EAN-8 is basically the same as UPC-A but with fewer digits */ - int length; char gtin[10]; int error_number = 0; - strcpy(gtin, (char*) source); - length = strlen(gtin); + ustrcpy(gtin, source); if (length == 7) { - gtin[length] = upc_check(gtin); - gtin[length + 1] = '\0'; + gtin[length++] = upc_check(gtin, 7); + gtin[length] = '\0'; } else { - gtin[length - 1] = '\0'; - if (source[length - 1] != upc_check(gtin)) { + if (source[length - 1] != upc_check(gtin, 7)) { if (symbol->debug & ZINT_DEBUG_PRINT) { - printf("EAN-8: Invalid check digit %s, gtin: %s, Check digit: %c\n", source, gtin, upc_check(gtin)); + printf("EAN-8: Invalid check digit %s, gtin: %s, Check digit: %c\n", source, gtin, + upc_check(gtin, 7)); } strcpy(symbol->errtxt, "276: Invalid check digit"); return ZINT_ERROR_INVALID_CHECK; } - gtin[length - 1] = upc_check(gtin); } if (symbol->debug & ZINT_DEBUG_PRINT) { - printf("EAN-8: %s, gtin: %s, Check digit: %c\n", source, gtin, length == 7 ? gtin[length] : gtin[length - 1]); + printf("EAN-8: %s, gtin: %s, Check digit: %c\n", source, gtin, + length == 7 ? gtin[length] : gtin[length - 1]); } - upca_draw(gtin, dest); + upca_draw(gtin, length, dest); ustrcpy(symbol->text, gtin); return error_number; } -/* For ISBN(13) only */ -static char isbn13_check(unsigned char source[]) { - unsigned int i, weight, sum, check, h; - - sum = 0; - weight = 1; - h = ustrlen(source) - 1; - - for (i = 0; i < h; i++) { - sum += ctoi(source[i]) * weight; - if (weight == 1) weight = 3; - else weight = 1; - } - - check = sum % 10; - check = 10 - check; - if (check == 10) check = 0; - return itoc(check); -} - /* For ISBN(10) and SBN only */ -static char isbn_check(unsigned char source[]) { - unsigned int i, weight, sum, check, h; +static char isbn_check(const unsigned char source[], const int length) { + int i, weight, sum, check; char check_char; sum = 0; weight = 1; - h = ustrlen(source) - 1; - for (i = 0; i < h; i++) { + for (i = 0; i < length; i++) { /* Length will always be 9 */ sum += ctoi(source[i]) * weight; weight++; } @@ -541,7 +478,7 @@ static char isbn_check(unsigned char source[]) { } /* Make an EAN-13 barcode from an SBN or ISBN */ -static int isbn(struct zint_symbol *symbol, unsigned char source[], const size_t src_len, char dest[]) { +static int isbn(struct zint_symbol *symbol, unsigned char source[], const int src_len, unsigned char dest[]) { int i, error_number; char check_digit; @@ -565,8 +502,11 @@ static int isbn(struct zint_symbol *symbol, unsigned char source[], const size_t return ZINT_ERROR_INVALID_DATA; } - check_digit = isbn13_check(source); + check_digit = ean_check((const char *) source, 12); if (source[src_len - 1] != check_digit) { + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("ISBN: Invalid check digit %s, Check digit: %c\n", source, check_digit); + } strcpy(symbol->errtxt, "280: Incorrect ISBN check"); return ZINT_ERROR_INVALID_CHECK; } @@ -582,8 +522,11 @@ static int isbn(struct zint_symbol *symbol, unsigned char source[], const size_t } if (src_len == 9 || src_len == 10) /* Using 10 digit ISBN or 9 digit SBN padded with leading zero */ { - check_digit = isbn_check(source); - if (check_digit != source[ustrlen(source) - 1]) { + check_digit = isbn_check(source, 9); + if (check_digit != source[9]) { + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("ISBN(10)/SBN: Invalid check digit %s, Check digit: %c\n", source, check_digit); + } strcpy(symbol->errtxt, src_len == 9 ? "281: Incorrect SBN check" : "281: Incorrect ISBN check"); return ZINT_ERROR_INVALID_CHECK; } @@ -596,16 +539,17 @@ static int isbn(struct zint_symbol *symbol, unsigned char source[], const size_t source[12] = '\0'; } - return ean13(symbol, source, dest); + return ean13(symbol, source, 12, dest); } /* Add leading zeroes to EAN and UPC strings */ -INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[], int *p_with_addon) { +INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, const unsigned char source[], + unsigned char local_source[], int *p_with_addon) { unsigned char first_part[20], second_part[7], zfirst_part[20], zsecond_part[7]; int with_addon = 0; int first_len = 0, second_len = 0, zfirst_len = 0, zsecond_len = 0, i, h; - h = ustrlen(source); + h = (int) ustrlen(source); for (i = 0; i < h; i++) { if (source[i] == '+') { with_addon = 1; @@ -633,46 +577,52 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char sourc second_part[second_len] = '\0'; /* Calculate target lengths */ - if (second_len <= 5) { - zsecond_len = 5; - } - if (second_len <= 2) { - zsecond_len = 2; - } if (second_len == 0) { zsecond_len = 0; + } else { + if (second_len <= 5) { + if (second_len <= 2) { + zsecond_len = 2; + } else { + zsecond_len = 5; + } + } } switch (symbol->symbology) { case BARCODE_EANX: case BARCODE_EANX_CC: if (first_len <= 12) { - zfirst_len = 12; - } - if (first_len <= 7) { - zfirst_len = 7; + if (first_len <= 7) { + zfirst_len = 7; + } else { + zfirst_len = 12; + } } if (second_len == 0 && symbol->symbology == BARCODE_EANX) { /* No composite EAN-2/5 */ if (first_len <= 5) { - zfirst_len = 5; - } - if (first_len <= 2) { - zfirst_len = 2; + if (first_len <= 2) { + zfirst_len = 2; + } else { + zfirst_len = 5; + } } } break; case BARCODE_EANX_CHK: if (first_len <= 13) { - zfirst_len = 13; - } - if (first_len <= 8) { - zfirst_len = 8; + if (first_len <= 8) { + zfirst_len = 8; + } else { + zfirst_len = 13; + } } if (second_len == 0) { if (first_len <= 5) { - zfirst_len = 5; - } - if (first_len <= 2) { - zfirst_len = 2; + if (first_len <= 2) { + zfirst_len = 2; + } else { + zfirst_len = 5; + } } } break; @@ -687,16 +637,14 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char sourc case BARCODE_UPCE_CC: if (first_len == 7) { zfirst_len = 7; - } - if (first_len <= 6) { + } else if (first_len <= 6) { zfirst_len = 6; } break; case BARCODE_UPCE_CHK: if (first_len == 8) { zfirst_len = 8; - } - if (first_len <= 7) { + } else if (first_len <= 7) { zfirst_len = 7; } break; @@ -711,21 +659,21 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char sourc /* Add leading zeroes */ zfirst_part[0] = '\0'; for (i = 0; i < (zfirst_len - first_len); i++) { - strcat((char*) zfirst_part, "0"); + ustrcat(zfirst_part, "0"); } - strcat((char*) zfirst_part, (char*) first_part); + ustrcat(zfirst_part, first_part); zsecond_part[0] = '\0'; for (i = 0; i < (zsecond_len - second_len); i++) { - strcat((char*) zsecond_part, "0"); + ustrcat(zsecond_part, "0"); } - strcat((char*) zsecond_part, (char*) second_part); + ustrcat(zsecond_part, second_part); /* Copy adjusted data back to local_source */ - strcat((char*) local_source, (char*) zfirst_part); - if (ustrlen(zsecond_part)) { - strcat((char*) local_source, "+"); - strcat((char*) local_source, (char*) zsecond_part); + ustrcat(local_source, zfirst_part); + if (*zsecond_part) { + ustrcat(local_source, "+"); + ustrcat(local_source, zsecond_part); } if (p_with_addon) { @@ -737,10 +685,11 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char sourc INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_len) { unsigned char first_part[20] = {0}, second_part[7] = {0}, dest[1000] = {0}; unsigned char local_source[21] = {0}; /* Allow 13 + "+" + 6 (too long add-on) + 1 */ - unsigned int latch, reader, writer; + int latch, reader, writer; int with_addon; int error_number, i, plus_count; int addon_gap = 0; + int first_part_len, second_part_len; latch = FALSE; writer = 0; @@ -781,6 +730,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le reader = 0; if (with_addon) { + int local_length = (int) ustrlen(local_source); do { if (local_source[reader] == '+') { first_part[writer] = '\0'; @@ -798,39 +748,42 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le reader++; writer++; } - } while (reader <= ustrlen(local_source)); + } while (reader <= local_length); - if (symbol->symbology == BARCODE_UPCA || symbol->symbology == BARCODE_UPCA_CHK || symbol->symbology == BARCODE_UPCA_CC) { + if (symbol->symbology == BARCODE_UPCA || symbol->symbology == BARCODE_UPCA_CHK + || symbol->symbology == BARCODE_UPCA_CC) { addon_gap = symbol->option_2 >= 9 && symbol->option_2 <= 12 ? symbol->option_2 : 9; } else { addon_gap = symbol->option_2 >= 7 && symbol->option_2 <= 12 ? symbol->option_2 : 7; } } else { - strcpy((char*) first_part, (char*) local_source); + ustrcpy(first_part, local_source); } + first_part_len = (int) ustrlen(first_part); + switch (symbol->symbology) { case BARCODE_EANX: case BARCODE_EANX_CHK: - switch (ustrlen(first_part)) { - case 2: add_on(first_part, (char*) dest, 0); + switch (first_part_len) { + case 2: add_on(first_part, first_part_len, dest, 0); ustrcpy(symbol->text, first_part); break; - case 5: add_on(first_part, (char*) dest, 0); + case 5: add_on(first_part, first_part_len, dest, 0); ustrcpy(symbol->text, first_part); break; case 7: - case 8: error_number = ean8(symbol, first_part, (char*) dest); + case 8: error_number = ean8(symbol, first_part, first_part_len, dest); break; case 12: - case 13: error_number = ean13(symbol, first_part, (char*) dest); + case 13: error_number = ean13(symbol, first_part, first_part_len, dest); break; default: strcpy(symbol->errtxt, "286: Input wrong length"); return ZINT_ERROR_TOO_LONG; } break; case BARCODE_EANX_CC: - switch (ustrlen(first_part)) { /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */ + switch (first_part_len) { /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */ case 7: set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 67); set_module(symbol, symbol->rows + 1, 0); @@ -841,7 +794,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; - error_number = ean8(symbol, first_part, (char*) dest); + error_number = ean8(symbol, first_part, first_part_len, dest); break; case 12: case 13:set_module(symbol, symbol->rows, 1); @@ -854,7 +807,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; - error_number = ean13(symbol, first_part, (char*) dest); + error_number = ean13(symbol, first_part, first_part_len, dest); break; default: strcpy(symbol->errtxt, "287: Input wrong length"); return ZINT_ERROR_TOO_LONG; @@ -862,15 +815,15 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le break; case BARCODE_UPCA: case BARCODE_UPCA_CHK: - if ((ustrlen(first_part) == 11) || (ustrlen(first_part) == 12)) { - error_number = upca(symbol, first_part, (char*) dest); + if ((first_part_len == 11) || (first_part_len == 12)) { + error_number = upca(symbol, first_part, first_part_len, dest); } else { strcpy(symbol->errtxt, "288: Input wrong length"); return ZINT_ERROR_TOO_LONG; } break; case BARCODE_UPCA_CC: - if (ustrlen(first_part) == 11 || ustrlen(first_part) == 12) { + if (first_part_len == 11 || first_part_len == 12) { set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 95); set_module(symbol, symbol->rows + 1, 0); @@ -881,7 +834,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; - error_number = upca(symbol, first_part, (char*) dest); + error_number = upca(symbol, first_part, first_part_len, dest); } else { strcpy(symbol->errtxt, "289: Input wrong length"); return ZINT_ERROR_TOO_LONG; @@ -889,15 +842,15 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le break; case BARCODE_UPCE: case BARCODE_UPCE_CHK: - if ((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= (symbol->symbology == BARCODE_UPCE ? 7 : 8))) { - error_number = upce(symbol, first_part, (char*) dest); + if ((first_part_len >= 6) && (first_part_len <= (symbol->symbology == BARCODE_UPCE ? 7 : 8))) { + error_number = upce(symbol, first_part, first_part_len, dest); } else { strcpy(symbol->errtxt, "290: Input wrong length"); return ZINT_ERROR_TOO_LONG; } break; case BARCODE_UPCE_CC: - if ((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) { + if ((first_part_len >= 6) && (first_part_len <= 7)) { set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 51); set_module(symbol, symbol->rows + 1, 0); @@ -908,14 +861,14 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; - error_number = upce(symbol, first_part, (char*) dest); + error_number = upce(symbol, first_part, first_part_len, dest); } else { strcpy(symbol->errtxt, "291: Input wrong length"); return ZINT_ERROR_TOO_LONG; } break; case BARCODE_ISBNX: - error_number = isbn(symbol, first_part, ustrlen(first_part), (char*) dest); + error_number = isbn(symbol, first_part, first_part_len, dest); break; } @@ -923,24 +876,26 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le return error_number; } - switch (ustrlen(second_part)) { + second_part_len = (int) ustrlen(second_part); + + switch (second_part_len) { case 0: break; case 2: - add_on(second_part, (char*) dest, addon_gap); - strcat((char*) symbol->text, "+"); - strcat((char*) symbol->text, (char*) second_part); + add_on(second_part, second_part_len, dest, addon_gap); + ustrcat(symbol->text, "+"); + ustrcat(symbol->text, second_part); break; case 5: - add_on(second_part, (char*) dest, addon_gap); - strcat((char*) symbol->text, "+"); - strcat((char*) symbol->text, (char*) second_part); + add_on(second_part, second_part_len, dest, addon_gap); + ustrcat(symbol->text, "+"); + ustrcat(symbol->text, second_part); break; default: strcpy(symbol->errtxt, "292: Add-on input wrong length"); return ZINT_ERROR_TOO_LONG; } - expand(symbol, (char*) dest); + expand(symbol, (const char *) dest); switch (symbol->symbology) { case BARCODE_EANX_CC: diff --git a/backend/zint.h b/backend/zint.h index 7f2483fa..90d58b8c 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -307,7 +307,7 @@ extern "C" { #define ZINT_CAP_MASK 0x0800 // The largest amount of data that can be encoded is 4350 4-byte UTF-8 chars in Han Xin Code -#define ZINT_MAX_FILE_LEN 17400 +#define ZINT_MAX_DATA_LEN 17400 // Debug flags #define ZINT_DEBUG_PRINT 1 diff --git a/frontend/main.c b/frontend/main.c index c7f1f552..7dc418af 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -297,7 +297,7 @@ static int is_raster(char *filetype) { static int batch_process(struct zint_symbol *symbol, char *filename, int mirror_mode, char *filetype, int rotate_angle) { FILE *file; - unsigned char buffer[ZINT_MAX_FILE_LEN] = {0}; // Maximum HanXin input + unsigned char buffer[ZINT_MAX_DATA_LEN] = {0}; // Maximum HanXin input unsigned char character = 0; int posn = 0, error_number = 0, line_count = 1; char output_file[256]; diff --git a/frontend/tests/test_args.c b/frontend/tests/test_args.c index e4d29fc2..f11549aa 100644 --- a/frontend/tests/test_args.c +++ b/frontend/tests/test_args.c @@ -389,7 +389,7 @@ static void test_stdin_input(int index, int debug) { assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i), "i:%d exec(%s) NULL\n", i, cmd); assert_nonzero(testUtilExists(data[i].outfile), "i:%d testUtilExists(%s) != 1\n", i, data[i].outfile); - //assert_zero(remove(data[i].outfile), "i:%d remove(%s) != 0 (%d)\n", i, data[i].outfile, errno); + assert_zero(remove(data[i].outfile), "i:%d remove(%s) != 0 (%d)\n", i, data[i].outfile, errno); } testFinish();