mirror of
https://git.code.sf.net/p/zint/code
synced 2025-12-19 19:07:09 +00:00
general: prefix all INTERNAL funcs/tables with zint_, except
those in "backend/common.h", which are prefixed by `z_` - makes symbol clashes more unlikely when zint is statically linked (ticket #337, props Ulrich Becker) DOTCODE: fix padding allowance (10 -> 52 - probable max 35) to cover cases with large no. of columns requested and little data, to prevent `codeword_array` buffer overflow AZTEC/CODEONE: some code fiddling general_field: prefix defines with `GF_`, shorten static funcs prefix `general_field_` -> `gf_`
This commit is contained in:
@@ -42,9 +42,8 @@
|
||||
#include "common.h"
|
||||
#include "gs1.h"
|
||||
|
||||
#define GF 113
|
||||
#define PM 3
|
||||
#define SCORE_UNLIT_EDGE -99999
|
||||
#define DC_GF 113
|
||||
#define DC_SCORE_UNLIT_EDGE -99999
|
||||
|
||||
/* DotCode symbol character dot patterns, from Annex C */
|
||||
static const unsigned short dc_dot_patterns[113] = {
|
||||
@@ -62,20 +61,15 @@ static const unsigned short dc_dot_patterns[113] = {
|
||||
0x1b8, 0x1c6, 0x1cc
|
||||
};
|
||||
|
||||
/* Printed() routine from Annex A adapted to char array of ASCII 1's and 0's */
|
||||
/* `Printed()` routine from Annex A adapted to char array of ASCII 1's and 0's - is dot set? */
|
||||
static int dc_get_dot(const char Dots[], const int Hgt, const int Wid, const int x, const int y) {
|
||||
|
||||
if ((x >= 0) && (x < Wid) && (y >= 0) && (y < Hgt)) {
|
||||
if (Dots[(y * Wid) + x] == '1') {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return x >= 0 && x < Wid && y >= 0 && y < Hgt && Dots[(y * Wid) + x] == '1';
|
||||
}
|
||||
|
||||
/* `ClrCol()` routine from Annex A - is column empty? */
|
||||
static int dc_clr_col(const char *Dots, const int Hgt, const int Wid, const int x) {
|
||||
int y;
|
||||
|
||||
for (y = x & 1; y < Hgt; y += 2) {
|
||||
if (dc_get_dot(Dots, Hgt, Wid, x, y)) {
|
||||
return 0;
|
||||
@@ -85,8 +79,10 @@ static int dc_clr_col(const char *Dots, const int Hgt, const int Wid, const int
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* `ClrRow()` routine from Annex A - is row empty? */
|
||||
static int dc_clr_row(const char *Dots, const int Hgt, const int Wid, const int y) {
|
||||
int x;
|
||||
|
||||
for (x = y & 1; x < Wid; x += 2) {
|
||||
if (dc_get_dot(Dots, Hgt, Wid, x, y)) {
|
||||
return 0;
|
||||
@@ -96,7 +92,7 @@ static int dc_clr_row(const char *Dots, const int Hgt, const int Wid, const int
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* calc penalty for empty interior columns */
|
||||
/* `ColPenalty()` routine from Annex A - calc penalty for empty interior columns */
|
||||
static int dc_col_penalty(const char *Dots, const int Hgt, const int Wid) {
|
||||
int x, penalty = 0, penalty_local = 0;
|
||||
|
||||
@@ -118,7 +114,7 @@ static int dc_col_penalty(const char *Dots, const int Hgt, const int Wid) {
|
||||
return penalty + penalty_local;
|
||||
}
|
||||
|
||||
/* calc penalty for empty interior rows */
|
||||
/* `RowPenalty()` routine from Annex A - calc penalty for empty interior rows */
|
||||
static int dc_row_penalty(const char *Dots, const int Hgt, const int Wid) {
|
||||
int y, penalty = 0, penalty_local = 0;
|
||||
|
||||
@@ -140,12 +136,12 @@ static int dc_row_penalty(const char *Dots, const int Hgt, const int Wid) {
|
||||
return penalty + penalty_local;
|
||||
}
|
||||
|
||||
/* Dot pattern scoring routine from Annex A */
|
||||
/* `ScoreArray()` routine from Annex A - dot pattern scoring */
|
||||
static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
int x, y, worstedge, first, last, sum;
|
||||
int penalty = 0;
|
||||
int penalty;
|
||||
|
||||
/* first, guard against "pathelogical" gaps in the array
|
||||
/* First, guard against "pathelogical" gaps in the array
|
||||
subtract a penalty score for empty rows/columns from total code score for each mask,
|
||||
where the penalty is Sum(N ^ n), where N is the number of positions in a column/row,
|
||||
and n is the number of consecutive empty rows/columns */
|
||||
@@ -155,7 +151,7 @@ static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
first = -1;
|
||||
last = -1;
|
||||
|
||||
/* across the top edge, count printed dots and measure their extent */
|
||||
/* Across the top edge, count printed dots and measure their extent */
|
||||
for (x = 0; x < Wid; x += 2) {
|
||||
if (dc_get_dot(Dots, Hgt, Wid, x, 0)) {
|
||||
if (first < 0) {
|
||||
@@ -166,7 +162,7 @@ static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
}
|
||||
}
|
||||
if (sum == 0) {
|
||||
return SCORE_UNLIT_EDGE; /* guard against empty top edge */
|
||||
return DC_SCORE_UNLIT_EDGE; /* Guard against empty top edge */
|
||||
}
|
||||
|
||||
worstedge = sum + last - first;
|
||||
@@ -176,7 +172,7 @@ static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
first = -1;
|
||||
last = -1;
|
||||
|
||||
/* across the bottom edge, ditto */
|
||||
/* Across the bottom edge, ditto */
|
||||
for (x = Wid & 1; x < Wid; x += 2) {
|
||||
if (dc_get_dot(Dots, Hgt, Wid, x, Hgt - 1)) {
|
||||
if (first < 0) {
|
||||
@@ -187,7 +183,7 @@ static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
}
|
||||
}
|
||||
if (sum == 0) {
|
||||
return SCORE_UNLIT_EDGE; /* guard against empty bottom edge */
|
||||
return DC_SCORE_UNLIT_EDGE; /* Guard against empty bottom edge */
|
||||
}
|
||||
|
||||
sum += last - first;
|
||||
@@ -200,7 +196,7 @@ static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
first = -1;
|
||||
last = -1;
|
||||
|
||||
/* down the left edge, ditto */
|
||||
/* Down the left edge, ditto */
|
||||
for (y = 0; y < Hgt; y += 2) {
|
||||
if (dc_get_dot(Dots, Hgt, Wid, 0, y)) {
|
||||
if (first < 0) {
|
||||
@@ -211,7 +207,7 @@ static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
}
|
||||
}
|
||||
if (sum == 0) {
|
||||
return SCORE_UNLIT_EDGE; /* guard against empty left edge */
|
||||
return DC_SCORE_UNLIT_EDGE; /* Guard against empty left edge */
|
||||
}
|
||||
|
||||
sum += last - first;
|
||||
@@ -224,7 +220,7 @@ static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
first = -1;
|
||||
last = -1;
|
||||
|
||||
/* down the right edge, ditto */
|
||||
/* Down the right edge, ditto */
|
||||
for (y = Hgt & 1; y < Hgt; y += 2) {
|
||||
if (dc_get_dot(Dots, Hgt, Wid, Wid - 1, y)) {
|
||||
if (first < 0) {
|
||||
@@ -235,7 +231,7 @@ static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
}
|
||||
}
|
||||
if (sum == 0) {
|
||||
return SCORE_UNLIT_EDGE; /* guard against empty right edge */
|
||||
return DC_SCORE_UNLIT_EDGE; /* Guard against empty right edge */
|
||||
}
|
||||
|
||||
sum += last - first;
|
||||
@@ -244,7 +240,7 @@ static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
worstedge = sum;
|
||||
}
|
||||
|
||||
/* throughout the array, count the # of unprinted 5-somes (cross patterns)
|
||||
/* Throughout the array, count the # of unprinted 5-somes (cross patterns)
|
||||
plus the # of printed dots surrounded by 8 unprinted neighbors */
|
||||
sum = 0;
|
||||
for (y = 0; y < Hgt; y++) {
|
||||
@@ -262,11 +258,9 @@ static int dc_score_array(const char Dots[], const int Hgt, const int Wid) {
|
||||
return (worstedge - sum * sum - penalty);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
// "rsencode(nd,nc)" adds "nc" R-S check words to "nd" data words in wd[]
|
||||
// employing Galois Field GF, where GF is prime, with a prime modulus of PM
|
||||
//-------------------------------------------------------------------------*/
|
||||
|
||||
/* `dc_rsencode(nd, nc, wd)` adds `nc` R-S check words to `nd` data words in `wd[]`
|
||||
employing Galois Field `DC_GF`, where `DC_GF` is prime, with a prime modulus of 3
|
||||
- adapted from `rsencode()` routine from Annex B */
|
||||
static void dc_rsencode(const int nd, const int nc, unsigned char *wd) {
|
||||
/* Pre-calculated coefficients for GF(113) of generator polys of degree 3 to 39. To generate run
|
||||
"backend/tests/test_dotcode -f generate -g" and place result below */
|
||||
@@ -336,7 +330,7 @@ static void dc_rsencode(const int nd, const int nc, unsigned char *wd) {
|
||||
|
||||
/* Here we compute how many interleaved R-S blocks will be needed */
|
||||
nw = nd + nc;
|
||||
step = (nw + GF - 2) / (GF - 1);
|
||||
step = (nw + DC_GF - 2) / (DC_GF - 1);
|
||||
|
||||
/* ...& then for each such block: */
|
||||
for (start = 0; start < step; start++) {
|
||||
@@ -345,24 +339,24 @@ static void dc_rsencode(const int nd, const int nc, unsigned char *wd) {
|
||||
const int NC = NW - ND;
|
||||
unsigned char *const e = wd + start + ND * step;
|
||||
|
||||
/* first set the generator polynomial "c" of order "NC": */
|
||||
/* First set the generator polynomial `c` of order `NC`: */
|
||||
c = coefs + cinds[NC - 3];
|
||||
|
||||
/* & then compute the corresponding checkword values into wd[]
|
||||
... (a) starting at wd[start] & (b) stepping by step */
|
||||
/* & then compute the corresponding checkword values into `wd[]`
|
||||
... (a) starting at `wd[start]` & (b) stepping by step */
|
||||
for (i = 0; i < NC; i++) {
|
||||
e[i * step] = 0;
|
||||
}
|
||||
for (i = 0; i < ND; i++) {
|
||||
k = (wd[start + i * step] + e[0]) % GF;
|
||||
k = (wd[start + i * step] + e[0]) % DC_GF;
|
||||
for (j = 0; j < NC - 1; j++) {
|
||||
e[j * step] = (GF - ((c[j + 1] * k) % GF) + e[(j + 1) * step]) % GF;
|
||||
e[j * step] = (DC_GF - ((c[j + 1] * k) % DC_GF) + e[(j + 1) * step]) % DC_GF;
|
||||
}
|
||||
e[(NC - 1) * step] = (GF - ((c[NC] * k) % GF)) % GF;
|
||||
e[(NC - 1) * step] = (DC_GF - ((c[NC] * k) % DC_GF)) % DC_GF;
|
||||
}
|
||||
for (i = 0; i < NC; i++) {
|
||||
if (e[i * step]) {
|
||||
e[i * step] = GF - e[i * step];
|
||||
e[i * step] = DC_GF - e[i * step];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -370,20 +364,15 @@ static void dc_rsencode(const int nd, const int nc, unsigned char *wd) {
|
||||
|
||||
/* Check if the next character is directly encodable in code set A (Annex F.II.D) */
|
||||
static int dc_datum_a(const unsigned char source[], const int length, const int position) {
|
||||
|
||||
if (position < length && source[position] <= 95) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return position < length && source[position] <= 95;
|
||||
}
|
||||
|
||||
/* Check if the next character is directly encodable in code set B (Annex F.II.D).
|
||||
* Note changed to return 2 if CR/LF */
|
||||
Note changed to return 2 if CR/LF */
|
||||
static int dc_datum_b(const unsigned char source[], const int length, const int position) {
|
||||
|
||||
if (position < length) {
|
||||
if ((source[position] >= 32) && (source[position] <= 127)) {
|
||||
if (source[position] >= 32 && source[position] <= 127) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -396,7 +385,7 @@ static int dc_datum_b(const unsigned char source[], const int length, const int
|
||||
break;
|
||||
}
|
||||
|
||||
if ((position + 1 < length) && (source[position] == 13) && (source[position + 1] == 10)) { /* CRLF */
|
||||
if (position + 1 < length && source[position] == 13 && source[position + 1] == 10) { /* CRLF */
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@@ -406,7 +395,7 @@ static int dc_datum_b(const unsigned char source[], const int length, const int
|
||||
|
||||
/* Check if the next characters are directly encodable in code set C (Annex F.II.D) */
|
||||
static int dc_datum_c(const unsigned char source[], const int length, const int position) {
|
||||
return is_twodigits(source, length, position);
|
||||
return z_is_twodigits(source, length, position);
|
||||
}
|
||||
|
||||
/* Checks ahead for 10 or more digits starting "17xxxxxx10..." (Annex F.II.B) */
|
||||
@@ -414,16 +403,15 @@ static int dc_seventeen_ten(const unsigned char source[], const int length, cons
|
||||
|
||||
if (position + 9 < length && source[position] == '1' && source[position + 1] == '7'
|
||||
&& source[position + 8] == '1' && source[position + 9] == '0'
|
||||
&& cnt_digits(source, length, position + 2, 6) >= 6) {
|
||||
&& z_cnt_digits(source, length, position + 2, 6) >= 6) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Checks how many characters ahead can be reached while dc_datum_c is true,
|
||||
* returning the resulting number of codewords (Annex F.II.E)
|
||||
*/
|
||||
/* Checks how many characters ahead can be reached while dc_datum_c is true,
|
||||
returning the resulting number of codewords (Annex F.II.E) */
|
||||
static int dc_ahead_c(const unsigned char source[], const int length, const int position) {
|
||||
int count = 0;
|
||||
int i;
|
||||
@@ -438,7 +426,7 @@ static int dc_ahead_c(const unsigned char source[], const int length, const int
|
||||
/* Annex F.II.F */
|
||||
static int dc_try_c(const unsigned char source[], const int length, const int position) {
|
||||
|
||||
if (position < length && z_isdigit(source[position])) { /* cnt_digits(position) > 0 */
|
||||
if (position < length && z_isdigit(source[position])) { /* z_cnt_digits(position) > 0 */
|
||||
const int ahead_c_position = dc_ahead_c(source, length, position);
|
||||
if (ahead_c_position > dc_ahead_c(source, length, position + 1)) {
|
||||
return ahead_c_position;
|
||||
@@ -479,12 +467,7 @@ static int dc_ahead_b(const unsigned char source[], const int length, const int
|
||||
|
||||
/* Checks if the next character is in the range 128 to 255 (Annex F.II.I) */
|
||||
static int dc_binary(const unsigned char source[], const int length, const int position) {
|
||||
|
||||
if (position < length && source[position] >= 128) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return position < length && source[position] >= 128;
|
||||
}
|
||||
|
||||
/* Empty binary buffer */
|
||||
@@ -549,10 +532,10 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
if (symbol->output_options & READER_INIT) {
|
||||
codeword_array[ap++] = 109; /* FNC3 */
|
||||
|
||||
} else if (!gs1 && eci == 0 && length > 2 && is_twodigits(source, length, 0)) {
|
||||
} else if (!gs1 && eci == 0 && length > 2 && z_is_twodigits(source, length, 0)) {
|
||||
codeword_array[ap++] = 107; /* FNC1 */
|
||||
|
||||
} else if (posn(lead_specials, source[0]) != -1) {
|
||||
} else if (z_posn(lead_specials, source[0]) != -1) {
|
||||
/* Prevent encodation as a macro if a special character is in first position */
|
||||
codeword_array[ap++] = 101; /* Latch A */
|
||||
codeword_array[ap++] = source[0] + 64;
|
||||
@@ -573,7 +556,7 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
} else {
|
||||
inside_macro = 99;
|
||||
}
|
||||
} else if (!format_050612 && is_twodigits(source, length, 4) ) {
|
||||
} else if (!format_050612 && z_is_twodigits(source, length, 4) ) {
|
||||
inside_macro = 100; /* Note no longer using for malformed 05/06/12 */
|
||||
}
|
||||
if (inside_macro) {
|
||||
@@ -581,8 +564,8 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
encoding_mode = 'B';
|
||||
codeword_array[ap++] = inside_macro; /* Macro */
|
||||
if (inside_macro == 100) {
|
||||
codeword_array[ap++] = ctoi(source[4]) + 16;
|
||||
codeword_array[ap++] = ctoi(source[5]) + 16;
|
||||
codeword_array[ap++] = z_ctoi(source[4]) + 16;
|
||||
codeword_array[ap++] = z_ctoi(source[5]) + 16;
|
||||
position += 6;
|
||||
} else {
|
||||
position += 7;
|
||||
@@ -614,7 +597,7 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
if (eci <= 39) {
|
||||
codeword_array[ap++] = eci;
|
||||
} else {
|
||||
/* the next three codewords valued A, B & C encode the ECI value of
|
||||
/* The next three codewords valued A, B & C encode the ECI value of
|
||||
(A - 40) * 12769 + B * 113 + C + 40 (Section 5.2.1) */
|
||||
int a, b, c;
|
||||
a = (eci - 40) / 12769;
|
||||
@@ -650,9 +633,9 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
/* Step C2 */
|
||||
if (dc_seventeen_ten(source, length, position)) {
|
||||
codeword_array[ap++] = 100; /* (17)...(10) */
|
||||
codeword_array[ap++] = to_int(source + position + 2, 2);
|
||||
codeword_array[ap++] = to_int(source + position + 4, 2);
|
||||
codeword_array[ap++] = to_int(source + position + 6, 2);
|
||||
codeword_array[ap++] = z_to_int(source + position + 2, 2);
|
||||
codeword_array[ap++] = z_to_int(source + position + 4, 2);
|
||||
codeword_array[ap++] = z_to_int(source + position + 6, 2);
|
||||
position += 10;
|
||||
if (debug_print) fputs("C2/1 ", stdout);
|
||||
continue;
|
||||
@@ -663,7 +646,7 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
codeword_array[ap++] = 107; /* FNC1 */
|
||||
position++;
|
||||
} else {
|
||||
codeword_array[ap++] = to_int(source + position, 2);
|
||||
codeword_array[ap++] = z_to_int(source + position, 2);
|
||||
position += 2;
|
||||
}
|
||||
if (debug_print) fputs("C2/2 ", stdout);
|
||||
@@ -672,7 +655,7 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
|
||||
/* Step C3 */
|
||||
if (dc_binary(source, length, position)) {
|
||||
/* cnt_digits(position + 1) > 0 */
|
||||
/* z_cnt_digits(position + 1) > 0 */
|
||||
if (position + 1 < length && z_isdigit(source[position + 1])) {
|
||||
if ((source[position] - 128) < 32) {
|
||||
codeword_array[ap++] = 110; /* Upper Shift A */
|
||||
@@ -735,7 +718,7 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
if (n <= 4) {
|
||||
codeword_array[ap++] = 103 + (n - 2); /* nx Shift C */
|
||||
for (i = 0; i < n; i++) {
|
||||
codeword_array[ap++] = to_int(source + position, 2);
|
||||
codeword_array[ap++] = z_to_int(source + position, 2);
|
||||
position += 2;
|
||||
}
|
||||
} else {
|
||||
@@ -829,7 +812,7 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
if (n <= 4) {
|
||||
codeword_array[ap++] = 103 + (n - 2); /* nx Shift C */
|
||||
for (i = 0; i < n; i++) {
|
||||
codeword_array[ap++] = to_int(source + position, 2);
|
||||
codeword_array[ap++] = z_to_int(source + position, 2);
|
||||
position += 2;
|
||||
}
|
||||
} else {
|
||||
@@ -917,7 +900,7 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
if (n <= 7) {
|
||||
codeword_array[ap++] = 101 + n; /* Interrupt for nx Shift C */
|
||||
for (i = 0; i < n; i++) {
|
||||
codeword_array[ap++] = to_int(source + position, 2);
|
||||
codeword_array[ap++] = z_to_int(source + position, 2);
|
||||
position += 2;
|
||||
}
|
||||
} else {
|
||||
@@ -1021,16 +1004,16 @@ static int dc_encode_message_segs(struct zint_symbol *symbol, const struct zint_
|
||||
last_RSEOT = last_seg->source[last_seg->length - 2] == 30; /* RS */
|
||||
}
|
||||
|
||||
if (raw_text && rt_init_segs(symbol, seg_count)) {
|
||||
return ZINT_ERROR_MEMORY; /* `rt_init_segs()` only fails with OOM */
|
||||
if (raw_text && z_rt_init_segs(symbol, seg_count)) {
|
||||
return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */
|
||||
}
|
||||
|
||||
for (i = 0; i < seg_count; i++) {
|
||||
ap = dc_encode_message(symbol, segs[i].source, segs[i].length, segs[i].eci, i == seg_count - 1 /*last_seg*/,
|
||||
last_EOT, last_RSEOT, ap, codeword_array, &encoding_mode, &inside_macro, &bin_buf, &bin_buf_size,
|
||||
structapp_array, p_structapp_size);
|
||||
if (raw_text && rt_cpy_seg(symbol, i, &segs[i])) { /* Note including macro header and RS + EOT */
|
||||
return ZINT_ERROR_MEMORY; /* `rt_cpy_seg()` only fails with OOM */
|
||||
if (raw_text && z_rt_cpy_seg(symbol, i, &segs[i])) { /* Note including macro header and RS + EOT */
|
||||
return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg()` only fails with OOM */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,19 +1029,18 @@ static int dc_make_dotstream(const unsigned char masked_array[], const int array
|
||||
int bp = 0;
|
||||
|
||||
/* Mask value is encoded as two dots */
|
||||
bp = bin_append_posn(masked_array[0], 2, dot_stream, bp);
|
||||
bp = z_bin_append_posn(masked_array[0], 2, dot_stream, bp);
|
||||
|
||||
/* The rest of the data uses 9-bit dot patterns from Annex C */
|
||||
for (i = 1; i < array_length; i++) {
|
||||
bp = bin_append_posn(dc_dot_patterns[masked_array[i]], 9, dot_stream, bp);
|
||||
bp = z_bin_append_posn(dc_dot_patterns[masked_array[i]], 9, dot_stream, bp);
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
/* Determines if a given dot is a reserved corner dot
|
||||
* to be used by one of the last six bits
|
||||
*/
|
||||
to be used by one of the last six bits */
|
||||
static int dc_is_corner(const int column, const int row, const int width, const int height) {
|
||||
|
||||
/* Top Left */
|
||||
@@ -1193,6 +1175,7 @@ static void dc_apply_mask(const int mask, const int data_length, unsigned char *
|
||||
dc_rsencode(data_length + 1, ecc_length, masked_codeword_array);
|
||||
}
|
||||
|
||||
/* Ensure corners are "lit" */
|
||||
static void dc_force_corners(const int width, const int height, char *dot_array) {
|
||||
if (width & 1) {
|
||||
/* "Vertical" symbol */
|
||||
@@ -1213,7 +1196,7 @@ static void dc_force_corners(const int width, const int height, char *dot_array)
|
||||
}
|
||||
}
|
||||
|
||||
INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
|
||||
INTERNAL int zint_dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
|
||||
int warn_number = 0;
|
||||
int i, j, k;
|
||||
int jc, n_dots;
|
||||
@@ -1231,22 +1214,22 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
const int gs1 = (symbol->input_mode & 0x07) == GS1_MODE;
|
||||
const int debug_print = (symbol->debug & ZINT_DEBUG_PRINT);
|
||||
/* Allow 4 codewords per input + 2 (FNC) + seg_count * 4 (ECI) + 2 (special char 1st position)
|
||||
+ 5 (Structured Append) + 10 (PAD) */
|
||||
const int codeword_array_len = segs_length(segs, seg_count) * 4 + 2 + seg_count * 4 + 2 + 5 + 10;
|
||||
+ 5 (Structured Append) + 52 (PAD - maximum probably 35, allowing for 468 dots / 9 == 52) */
|
||||
const int codeword_array_len = z_segs_length(segs, seg_count) * 4 + 2 + seg_count * 4 + 2 + 5 + 52;
|
||||
unsigned char *codeword_array = (unsigned char *) z_alloca(codeword_array_len);
|
||||
char *dot_stream;
|
||||
char *dot_array;
|
||||
unsigned char *masked_codeword_array;
|
||||
|
||||
if (symbol->eci > 811799) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 525, "ECI code '%d' out of range (0 to 811799)",
|
||||
return z_errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 525, "ECI code '%d' out of range (0 to 811799)",
|
||||
symbol->eci);
|
||||
}
|
||||
|
||||
if (symbol->option_2 > 0) {
|
||||
if (symbol->option_2 < 5 || symbol->option_2 > 200) {
|
||||
return ZEXT errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 527,
|
||||
"Number of columns '%d' is out of range (5 to 200)", symbol->option_2);
|
||||
return ZEXT z_errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 527,
|
||||
"Number of columns '%d' is out of range (5 to 200)", symbol->option_2);
|
||||
}
|
||||
width = symbol->option_2;
|
||||
}
|
||||
@@ -1258,38 +1241,38 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
|
||||
if (symbol->structapp.count) {
|
||||
if (symbol->structapp.count < 2 || symbol->structapp.count > 35) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 730,
|
||||
return z_errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 730,
|
||||
"Structured Append count '%d' out of range (2 to 35)", symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
|
||||
return ZEXT errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 731,
|
||||
"Structured Append index '%1$d' out of range (1 to count %2$d)",
|
||||
symbol->structapp.index, symbol->structapp.count);
|
||||
return ZEXT z_errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 731,
|
||||
"Structured Append index '%1$d' out of range (1 to count %2$d)",
|
||||
symbol->structapp.index, symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.id[0]) {
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 732, "Structured Append ID not available for DotCode");
|
||||
return z_errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 732, "Structured Append ID not available for DotCode");
|
||||
}
|
||||
}
|
||||
|
||||
/* GS1 General Specifications 22.0 section 5.8.2 says Structured Append and ECIs not supported
|
||||
for GS1 DotCode so check and return ZINT_WARN_NONCOMPLIANT if either true */
|
||||
if (gs1 && warn_number == 0) {
|
||||
if (gs1) {
|
||||
for (i = 0; i < seg_count; i++) {
|
||||
if (segs[i].eci) {
|
||||
warn_number = errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 733,
|
||||
warn_number = z_errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 733,
|
||||
"Using ECI in GS1 mode not supported by GS1 standards");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (warn_number == 0 && symbol->structapp.count) {
|
||||
warn_number = errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 734,
|
||||
warn_number = z_errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 734,
|
||||
"Using Structured Append in GS1 mode not supported by GS1 standards");
|
||||
}
|
||||
}
|
||||
|
||||
if (dc_encode_message_segs(symbol, segs, seg_count, codeword_array, &binary_finish, &data_length,
|
||||
structapp_array, &structapp_size)) {
|
||||
return ZINT_ERROR_MEMORY; /* `rt_cpy_seg()` etc. only fail with OOM */
|
||||
return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg()` etc. only fail with OOM */
|
||||
}
|
||||
|
||||
/* Suppresses clang-tidy clang-analyzer-core.UndefinedBinaryOperatorResult/uninitialized.ArraySubscript
|
||||
@@ -1355,22 +1338,27 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
printf("Width %d, Height %d\n", width, height);
|
||||
}
|
||||
|
||||
if ((height > 200) || (width > 200)) {
|
||||
if (height > 200 || width > 200) {
|
||||
if (height > 200 && width > 200) {
|
||||
ZEXT errtxtf(0, symbol, 526, "Resulting symbol size '%1$dx%2$d' (HxW) is too large (maximum 200x200)",
|
||||
height, width);
|
||||
ZEXT z_errtxtf(0, symbol, 526, "Resulting symbol size '%1$dx%2$d' (HxW) is too large (maximum 200x200)",
|
||||
height, width);
|
||||
} else if (width > 200) {
|
||||
z_errtxtf(0, symbol, 528, "Resulting symbol width '%d' is too large (maximum 200)", width);
|
||||
} else {
|
||||
ZEXT errtxtf(0, symbol, 528, "Resulting symbol %1$s '%2$d' is too large (maximum 200)",
|
||||
width > 200 ? "width" : "height", width > 200 ? width : height);
|
||||
z_errtxtf(0, symbol, 735, "Resulting symbol height '%d' is too large (maximum 200)", height);
|
||||
}
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
}
|
||||
|
||||
if ((height < 5) || (width < 5)) {
|
||||
if (height < 5 || width < 5) {
|
||||
/* Note: this branch probably no longer reached */
|
||||
assert(height >= 5 || width >= 5); /* If width < 5, min height is 19 */
|
||||
return ZEXT errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 529,
|
||||
"Resulting symbol %1$s '%2$d' is too small (minimum 5)",
|
||||
width < 5 ? "width" : "height", width < 5 ? width : height);
|
||||
if (width < 5) {
|
||||
z_errtxtf(0, symbol, 529, "Resulting symbol width '%d' is too small (minimum 5)", width);
|
||||
} else {
|
||||
z_errtxtf(0, symbol, 736, "Resulting symbol height '%d' is too small (minimum 5)", height);
|
||||
}
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
}
|
||||
|
||||
n_dots = (height * width) / 2;
|
||||
@@ -1379,10 +1367,12 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
dot_array = (char *) z_alloca(width * height);
|
||||
|
||||
/* Add pad characters */
|
||||
padding_dots = n_dots - min_dots; /* get the number of free dots available for padding */
|
||||
padding_dots = n_dots - min_dots; /* Get the number of free dots available for padding */
|
||||
|
||||
if (debug_print) printf("Padding dots: %d\n", padding_dots);
|
||||
|
||||
if (padding_dots >= 9) {
|
||||
int is_first = 1; /* first padding character flag */
|
||||
int is_first = 1; /* First padding character flag */
|
||||
int padp = data_length - structapp_size;
|
||||
while (padding_dots >= 9) {
|
||||
if (padding_dots < 18 && (data_length & 1) == 0) {
|
||||
@@ -1394,7 +1384,7 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
padding_dots -= 18;
|
||||
}
|
||||
} else {
|
||||
break; /* not enough padding dots left for padding */
|
||||
break; /* Not enough padding dots left for padding */
|
||||
}
|
||||
if (is_first && binary_finish) {
|
||||
codeword_array[padp++] = 109;
|
||||
@@ -1430,7 +1420,7 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
}
|
||||
#ifdef ZINT_TEST
|
||||
if (symbol->debug & ZINT_DEBUG_TEST) {
|
||||
debug_test_codeword_dump(symbol, codeword_array, data_length);
|
||||
z_debug_test_codeword_dump(symbol, codeword_array, data_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1558,7 +1548,7 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
for (k = 0; k < height; k++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
if (dot_array[(k * width) + j] == '1') {
|
||||
set_module(symbol, k, j);
|
||||
z_set_module(symbol, k, j);
|
||||
}
|
||||
}
|
||||
symbol->row_height[k] = 1;
|
||||
|
||||
Reference in New Issue
Block a user