Dotcode: Add custom height setting and format code

This commit is contained in:
Robin Stuart 2016-08-07 20:11:51 +01:00
parent 0c5f9191e6
commit 674a491a56

View File

@ -52,21 +52,21 @@
/* DotCode symbol character dot patterns, from Annex C */ /* DotCode symbol character dot patterns, from Annex C */
static const int dot_patterns[113] = { static const int dot_patterns[113] = {
0x155,0x0ab,0x0ad,0x0b5,0x0d5,0x156,0x15a,0x16a,0x1aa,0x0ae, 0x155, 0x0ab, 0x0ad, 0x0b5, 0x0d5, 0x156, 0x15a, 0x16a, 0x1aa, 0x0ae,
0x0b6,0x0ba,0x0d6,0x0da,0x0ea,0x12b,0x12d,0x135,0x14b,0x14d, 0x0b6, 0x0ba, 0x0d6, 0x0da, 0x0ea, 0x12b, 0x12d, 0x135, 0x14b, 0x14d,
0x153,0x159,0x165,0x169,0x195,0x1a5,0x1a9,0x057,0x05b,0x05d, 0x153, 0x159, 0x165, 0x169, 0x195, 0x1a5, 0x1a9, 0x057, 0x05b, 0x05d,
0x06b,0x06d,0x075,0x097,0x09b,0x09d,0x0a7,0x0b3,0x0b9,0x0cb, 0x06b, 0x06d, 0x075, 0x097, 0x09b, 0x09d, 0x0a7, 0x0b3, 0x0b9, 0x0cb,
0x0cd,0x0d3,0x0d9,0x0e5,0x0e9,0x12e,0x136,0x13a,0x14e,0x15c, 0x0cd, 0x0d3, 0x0d9, 0x0e5, 0x0e9, 0x12e, 0x136, 0x13a, 0x14e, 0x15c,
0x166,0x16c,0x172,0x174,0x196,0x19a,0x1a6,0x1ac,0x1b2,0x1b4, 0x166, 0x16c, 0x172, 0x174, 0x196, 0x19a, 0x1a6, 0x1ac, 0x1b2, 0x1b4,
0x1ca,0x1d2,0x1d4,0x05e,0x06e,0x076,0x07a,0x09e,0x0bc,0x0ce, 0x1ca, 0x1d2, 0x1d4, 0x05e, 0x06e, 0x076, 0x07a, 0x09e, 0x0bc, 0x0ce,
0x0dc,0x0e6,0x0ec,0x0f2,0x0f4,0x117,0x11b,0x11d,0x127,0x133, 0x0dc, 0x0e6, 0x0ec, 0x0f2, 0x0f4, 0x117, 0x11b, 0x11d, 0x127, 0x133,
0x139,0x147,0x163,0x171,0x18b,0x18d,0x193,0x199,0x1a3,0x1b1, 0x139, 0x147, 0x163, 0x171, 0x18b, 0x18d, 0x193, 0x199, 0x1a3, 0x1b1,
0x1c5,0x1c9,0x1d1,0x02f,0x037,0x03b,0x03d,0x04f,0x067,0x073, 0x1c5, 0x1c9, 0x1d1, 0x02f, 0x037, 0x03b, 0x03d, 0x04f, 0x067, 0x073,
0x079,0x08f,0x0c7,0x0e3,0x0f1,0x11e,0x13c,0x178,0x18e,0x19c, 0x079, 0x08f, 0x0c7, 0x0e3, 0x0f1, 0x11e, 0x13c, 0x178, 0x18e, 0x19c,
0x1b8,0x1c6,0x1cc 0x1b8, 0x1c6, 0x1cc
}; };
int get_dot (char Dots[], int Hgt, int Wid, int x, int y) { int get_dot(char Dots[], int Hgt, int Wid, int x, int y) {
int retval = 0; int retval = 0;
if ((x >= 0) && (x < Wid) && (y >= 0) && (y < Hgt)) { if ((x >= 0) && (x < Wid) && (y >= 0) && (y < Hgt)) {
@ -79,7 +79,7 @@ int get_dot (char Dots[], int Hgt, int Wid, int x, int y) {
} }
/* Dot pattern scoring routine from Annex A */ /* Dot pattern scoring routine from Annex A */
int score_array (char Dots[], int Hgt, int Wid) { int score_array(char Dots[], int Hgt, int Wid) {
int x, y, worstedge, first, last, sum; int x, y, worstedge, first, last, sum;
sum = 0; sum = 0;
@ -87,14 +87,14 @@ int score_array (char Dots[], int Hgt, int Wid) {
// 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) for (x = 0; x < Wid; x += 2)
if (get_dot(Dots,Hgt,Wid,x,0)) { if (get_dot(Dots, Hgt, Wid, x, 0)) {
if (first < 0) { if (first < 0) {
first = x; first = x;
} }
last = x; last = x;
sum++; sum++;
} }
worstedge = sum + last-first; worstedge = sum + last - first;
worstedge *= Hgt; worstedge *= Hgt;
sum = 0; sum = 0;
@ -102,14 +102,14 @@ int score_array (char Dots[], int Hgt, int Wid) {
//across the bottom edge, ditto //across the bottom edge, ditto
for (x = Wid & 1; x < Wid; x += 2) for (x = Wid & 1; x < Wid; x += 2)
if (get_dot(Dots,Hgt,Wid,x,Hgt-1)) { if (get_dot(Dots, Hgt, Wid, x, Hgt - 1)) {
if (first < 0) { if (first < 0) {
first = x; first = x;
} }
last = x; last = x;
sum++; sum++;
} }
sum += last-first; sum += last - first;
sum *= Hgt; sum *= Hgt;
if (sum < worstedge) { if (sum < worstedge) {
worstedge = sum; worstedge = sum;
@ -120,14 +120,14 @@ int score_array (char Dots[], int Hgt, int Wid) {
//down the left edge, ditto //down the left edge, ditto
for (y = 0; y < Hgt; y += 2) for (y = 0; y < Hgt; y += 2)
if (get_dot(Dots,Hgt,Wid,0,y)) { if (get_dot(Dots, Hgt, Wid, 0, y)) {
if (first < 0) { if (first < 0) {
first = y; first = y;
} }
last = y; last = y;
sum++; sum++;
} }
sum += last-first; sum += last - first;
sum *= Wid; sum *= Wid;
if (sum < worstedge) { if (sum < worstedge) {
worstedge = sum; worstedge = sum;
@ -138,14 +138,14 @@ int score_array (char Dots[], int Hgt, int Wid) {
//down the right edge, ditto //down the right edge, ditto
for (y = Hgt & 1; y < Hgt; y += 2) for (y = Hgt & 1; y < Hgt; y += 2)
if (get_dot(Dots,Hgt,Wid,Wid-1,y)) { if (get_dot(Dots, Hgt, Wid, Wid - 1, y)) {
if (first < 0) { if (first < 0) {
first = y; first = y;
} }
last = y; last = y;
sum++; sum++;
} }
sum += last-first; sum += last - first;
sum *= Wid; sum *= Wid;
if (sum < worstedge) { if (sum < worstedge) {
worstedge = sum; worstedge = sum;
@ -156,15 +156,15 @@ int score_array (char Dots[], int Hgt, int Wid) {
sum = 0; sum = 0;
for (y = 0; y < Hgt; y++) { for (y = 0; y < Hgt; y++) {
for (x = y & 1; x < Wid; x += 2) { for (x = y & 1; x < Wid; x += 2) {
if ((!get_dot(Dots,Hgt,Wid,x-1,y-1)) if ((!get_dot(Dots, Hgt, Wid, x - 1, y - 1))
&& (!get_dot(Dots,Hgt,Wid,x+1,y-1)) && (!get_dot(Dots, Hgt, Wid, x + 1, y - 1))
&& (!get_dot(Dots,Hgt,Wid,x-1,y+1)) && (!get_dot(Dots, Hgt, Wid, x - 1, y + 1))
&&(!get_dot(Dots,Hgt,Wid,x+1,y+1)) &&(!get_dot(Dots, Hgt, Wid, x + 1, y + 1))
&& ((!get_dot(Dots,Hgt,Wid,x,y)) && ((!get_dot(Dots, Hgt, Wid, x, y))
|| ((!get_dot(Dots,Hgt,Wid,x-2,y)) || ((!get_dot(Dots, Hgt, Wid, x - 2, y))
&& (!get_dot(Dots,Hgt,Wid,x,y-2)) && (!get_dot(Dots, Hgt, Wid, x, y - 2))
&& (!get_dot(Dots,Hgt,Wid,x+2,y)) && (!get_dot(Dots, Hgt, Wid, x + 2, y))
&& (!get_dot(Dots,Hgt,Wid,x,y+2))))) { && (!get_dot(Dots, Hgt, Wid, x, y + 2))))) {
sum++; sum++;
} }
} }
@ -177,44 +177,47 @@ int score_array (char Dots[], int Hgt, int Wid) {
// "rsencode(nd,nc)" adds "nc" R-S check words to "nd" data words in wd[] // "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 // employing Galois Field GF, where GF is prime, with a prime modulus of PM
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
void rsencode (int nd, int nc, unsigned char *wd) {
void rsencode(int nd, int nc, unsigned char *wd) {
int i, j, k, nw, start, step, root[GF], c[GF]; int i, j, k, nw, start, step, root[GF], c[GF];
// Start by generating "nc" roots (antilogs): // Start by generating "nc" roots (antilogs):
root[0] = 1; root[0] = 1;
for (i=1; i<=nc; i++) for (i = 1; i <= nc; i++)
root[i] = (PM * root[i-1]) % GF; root[i] = (PM * root[i - 1]) % GF;
// Here we compute how many interleaved R-S blocks will be needed // Here we compute how many interleaved R-S blocks will be needed
nw = nd + nc; step = (nw + GF - 2)/(GF - 1); nw = nd + nc;
step = (nw + GF - 2) / (GF - 1);
// ...& then for each such block: // ...& then for each such block:
for (start=0; start<step; start++) { for (start = 0; start < step; start++) {
int ND = (nd-start+step-1)/step, NW = (nw-start+step-1)/step, NC = NW-ND; int ND = (nd - start + step - 1) / step, NW = (nw - start + step - 1) / step, NC = NW - ND;
// first compute the generator polynomial "c" of order "NC": // first compute the generator polynomial "c" of order "NC":
for (i=1; i<=NC; i++) for (i = 1; i <= NC; i++)
c[i] = 0; c[0] = 1; c[i] = 0;
c[0] = 1;
for (i=1; i<=NC; i++) { for (i = 1; i <= NC; i++) {
for (j=NC; j>=1; j--) { for (j = NC; j >= 1; j--) {
c[j] = (GF + c[j] - (root[i] * c[j-1]) % GF) % GF; c[j] = (GF + c[j] - (root[i] * c[j - 1]) % GF) % GF;
} }
} }
// & then compute the corresponding checkword values into wd[] // & then compute the corresponding checkword values into wd[]
// ... (a) starting at wd[start] & (b) stepping by step // ... (a) starting at wd[start] & (b) stepping by step
for (i=ND; i<NW; i++) for (i = ND; i < NW; i++)
wd[start+i*step] = 0; wd[start + i * step] = 0;
for (i=0; i<ND; i++) { for (i = 0; i < ND; i++) {
k = (wd[start+i*step] + wd[start+ND*step]) % GF; k = (wd[start + i * step] + wd[start + ND * step]) % GF;
for (j=0; j<NC-1; j++) { for (j = 0; j < NC - 1; j++) {
wd[start+(ND+j)*step] = (GF - ((c[j+1] * k) % GF) + wd[start+(ND+j+1)*step]) % GF; wd[start + (ND + j) * step] = (GF - ((c[j + 1] * k) % GF) + wd[start + (ND + j + 1) * step]) % GF;
} }
wd[start+(ND+NC-1)*step] = (GF - ((c[NC] * k) % GF)) % GF; wd[start + (ND + NC - 1) * step] = (GF - ((c[NC] * k) % GF)) % GF;
} }
for (i=ND; i<NW; i++) for (i = ND; i < NW; i++)
wd[start+i*step] = (GF - wd[start+i*step]) % GF; wd[start + i * step] = (GF - wd[start + i * step]) % GF;
} }
} }
@ -240,7 +243,7 @@ int datum_b(unsigned char source[], int position, int length) {
retval = 1; retval = 1;
} }
switch(source[position]) { switch (source[position]) {
case 9: // HT case 9: // HT
case 28: // FS case 28: // FS
case 29: // GS case 29: // GS
@ -275,7 +278,7 @@ int datum_c(unsigned char source[], int position, int length) {
int n_digits(unsigned char source[], int position, int length) { int n_digits(unsigned char source[], int position, int length) {
int i; int i;
for(i = position; ((source[i] >= '0') && (source[i] <= '9')) && (i < length); i++); for (i = position; ((source[i] >= '0') && (source[i] <= '9')) && (i < length); i++);
return i - position; return i - position;
} }
@ -284,8 +287,8 @@ int n_digits(unsigned char source[], int position, int length) {
int seventeen_ten(unsigned char source[], int position, int length) { int seventeen_ten(unsigned char source[], int position, int length) {
int found = 0; int found = 0;
if(n_digits(source, position, length) >= 10) { if (n_digits(source, position, length) >= 10) {
if(((source[position] == '1') && (source[position + 1] == '7')) if (((source[position] == '1') && (source[position + 1] == '7'))
&& ((source[position + 8] == '1') && (source[position + 9] == '0'))) { && ((source[position + 8] == '1') && (source[position + 9] == '0'))) {
found = 1; found = 1;
} }
@ -300,7 +303,7 @@ int seventeen_ten(unsigned char source[], int position, int length) {
int ahead_c(unsigned char source[], int position, int length) { int ahead_c(unsigned char source[], int position, int length) {
int count = 0; int count = 0;
for(int i = position; (i < length) && datum_c(source, i, length); i+= 2) { for (int i = position; (i < length) && datum_c(source, i, length); i += 2) {
count++; count++;
} }
@ -311,8 +314,8 @@ int ahead_c(unsigned char source[], int position, int length) {
int try_c(unsigned char source[], int position, int length) { int try_c(unsigned char source[], int position, int length) {
int retval = 0; int retval = 0;
if(n_digits(source, position, length) > 0) { if (n_digits(source, position, length) > 0) {
if(ahead_c(source, position, length) > ahead_c(source, position + 1, length)) { if (ahead_c(source, position, length) > ahead_c(source, position + 1, length)) {
retval = ahead_c(source, position, length); retval = ahead_c(source, position, length);
} }
} }
@ -324,7 +327,7 @@ int try_c(unsigned char source[], int position, int length) {
int ahead_a(unsigned char source[], int position, int length) { int ahead_a(unsigned char source[], int position, int length) {
int count = 0; int count = 0;
for(int i = position; ((i < length) && datum_a(source, i, length)) for (int i = position; ((i < length) && datum_a(source, i, length))
&& (try_c(source, i, length) < 2); i++) { && (try_c(source, i, length) < 2); i++) {
count++; count++;
} }
@ -336,7 +339,7 @@ int ahead_a(unsigned char source[], int position, int length) {
int ahead_b(unsigned char source[], int position, int length) { int ahead_b(unsigned char source[], int position, int length) {
int count = 0; int count = 0;
for(int i = position; ((i < length) && datum_b(source, i, length)) for (int i = position; ((i < length) && datum_b(source, i, length))
&& (try_c(source, i, length) < 2); i++) { && (try_c(source, i, length) < 2); i++) {
count++; count++;
} }
@ -348,7 +351,7 @@ int ahead_b(unsigned char source[], int position, int length) {
int binary(unsigned char source[], int position, int length) { int binary(unsigned char source[], int position, int length) {
int retval = 0; int retval = 0;
if(source[position] >= 128) { if (source[position] >= 128) {
retval = 1; retval = 1;
} }
@ -393,24 +396,28 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
// inside_macro only gets set to 97, 98 or 99 if the last two characters are RS/EOT // inside_macro only gets set to 97, 98 or 99 if the last two characters are RS/EOT
input_position += 2; input_position += 2;
done = 1; done = 1;
if (debug) { printf("A "); } if (debug) {
printf("A ");
}
} }
if ((input_position == length - 1) && (inside_macro == 100)) { if ((input_position == length - 1) && (inside_macro == 100)) {
// inside_macro only gets set to 100 if the last character is EOT // inside_macro only gets set to 100 if the last character is EOT
input_position++; input_position++;
done = 1; done = 1;
if (debug) { printf("A "); } if (debug) {
printf("A ");
}
} }
/* Step B1 */ /* Step B1 */
if ((!done) && (encoding_mode == 'C')) { if ((!done) && (encoding_mode == 'C')) {
if ((array_length == 0) && (length > 9)) { if ((array_length == 0) && (length > 9)) {
if((source[input_position] == '[') if ((source[input_position] == '[')
&& (source[input_position + 1] == ')') && (source[input_position + 1] == ')')
&& (source[input_position + 2] == '>') && (source[input_position + 2] == '>')
&& (source[input_position + 3] == 30) // RS && (source[input_position + 3] == 30) // RS
&& (source[length - 1] == 04)) { // EOT && (source[length - 1] == 04)) { // EOT
codeword_array[array_length] = 106; // Latch B codeword_array[array_length] = 106; // Latch B
array_length++; array_length++;
@ -423,7 +430,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
input_position += 7; input_position += 7;
inside_macro = 97; inside_macro = 97;
done = 1; done = 1;
if (debug) { printf("B1/1 "); } if (debug) {
printf("B1/1 ");
}
} }
if ((source[input_position + 4] == '0') && (source[input_position + 5] == '6')) { if ((source[input_position + 4] == '0') && (source[input_position + 5] == '6')) {
@ -432,7 +441,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
input_position += 7; input_position += 7;
inside_macro = 98; inside_macro = 98;
done = 1; done = 1;
if (debug) { printf("B1/2 "); } if (debug) {
printf("B1/2 ");
}
} }
if ((source[input_position + 4] == '1') && (source[input_position + 5] == '2')) { if ((source[input_position + 4] == '1') && (source[input_position + 5] == '2')) {
@ -441,7 +452,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
input_position += 7; input_position += 7;
inside_macro = 99; inside_macro = 99;
done = 1; done = 1;
if (debug) { printf("B1/3 "); } if (debug) {
printf("B1/3 ");
}
} }
} }
@ -451,7 +464,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
input_position += 4; input_position += 4;
inside_macro = 100; inside_macro = 100;
done = 1; done = 1;
if (debug) { printf("B1/4 "); } if (debug) {
printf("B1/4 ");
}
} }
} }
} }
@ -470,7 +485,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
array_length++; array_length++;
input_position += 10; input_position += 10;
done = 1; done = 1;
if (debug) { printf("B2/1 "); } if (debug) {
printf("B2/1 ");
}
} }
} }
@ -485,7 +502,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
} }
array_length++; array_length++;
done = 1; done = 1;
if (debug) { printf("B2/2 "); } if (debug) {
printf("B2/2 ");
}
} }
} }
@ -493,7 +512,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
if ((!done) && (encoding_mode == 'C')) { if ((!done) && (encoding_mode == 'C')) {
if (binary(source, input_position, length)) { if (binary(source, input_position, length)) {
if (n_digits(source, input_position + 1, length) > 0) { if (n_digits(source, input_position + 1, length) > 0) {
if ((source[input_position] - 128) < 32) { if ((source[input_position] - 128) < 32) {
codeword_array[array_length] = 110; // Bin Shift A codeword_array[array_length] = 110; // Bin Shift A
array_length++; array_length++;
codeword_array[array_length] = source[input_position] - 128 + 64; codeword_array[array_length] = source[input_position] - 128 + 64;
@ -511,7 +530,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
encoding_mode = 'X'; encoding_mode = 'X';
} }
done = 1; done = 1;
if (debug) { printf("B3 "); } if (debug) {
printf("B3 ");
}
} }
} }
@ -528,7 +549,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
codeword_array[array_length] = 101 + n; // nx Shift B codeword_array[array_length] = 101 + n; // nx Shift B
array_length++; array_length++;
for(i = 0; i < n; i++) { for (i = 0; i < n; i++) {
codeword_array[array_length] = source[input_position] - 32; codeword_array[array_length] = source[input_position] - 32;
array_length++; array_length++;
input_position++; input_position++;
@ -540,7 +561,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
} }
} }
done = 1; done = 1;
if (debug) { printf("B4 "); } if (debug) {
printf("B4 ");
}
} }
/* Step C1 */ /* Step C1 */
@ -551,7 +574,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
if (n <= 4) { if (n <= 4) {
codeword_array[array_length] = 103 + (n - 2); // nx Shift C codeword_array[array_length] = 103 + (n - 2); // nx Shift C
array_length++; array_length++;
for(i = 0; i < n; i++) { for (i = 0; i < n; i++) {
codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0'); codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
array_length++; array_length++;
input_position += 2; input_position += 2;
@ -562,7 +585,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
encoding_mode = 'C'; encoding_mode = 'C';
} }
done = 1; done = 1;
if (debug) { printf("C1 "); } if (debug) {
printf("C1 ");
}
} }
} }
@ -573,14 +598,18 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
array_length++; array_length++;
input_position++; input_position++;
done = 1; done = 1;
if (debug) { printf("C2/1 "); } if (debug) {
printf("C2/1 ");
}
} else { } else {
if (datum_b(source, input_position, length)) { if (datum_b(source, input_position, length)) {
codeword_array[array_length] = source[input_position] - 32; codeword_array[array_length] = source[input_position] - 32;
array_length++; array_length++;
input_position++; input_position++;
done = 1; done = 1;
if (debug) { printf("C2/2 "); } if (debug) {
printf("C2/2 ");
}
} }
} }
} }
@ -589,7 +618,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
if ((!done) && (encoding_mode == 'B')) { if ((!done) && (encoding_mode == 'B')) {
if (binary(source, input_position, length)) { if (binary(source, input_position, length)) {
if (datum_b(source, input_position + 1, length)) { if (datum_b(source, input_position + 1, length)) {
if ((source[input_position] - 128) < 32) { if ((source[input_position] - 128) < 32) {
codeword_array[array_length] = 110; // Bin Shift A codeword_array[array_length] = 110; // Bin Shift A
array_length++; array_length++;
codeword_array[array_length] = source[input_position] - 128 + 64; codeword_array[array_length] = source[input_position] - 128 + 64;
@ -607,7 +636,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
encoding_mode = 'X'; encoding_mode = 'X';
} }
done = 1; done = 1;
if (debug) { printf("C3 "); } if (debug) {
printf("C3 ");
}
} }
} }
@ -629,7 +660,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
encoding_mode = 'A'; encoding_mode = 'A';
} }
done = 1; done = 1;
if (debug) { printf("C4 "); } if (debug) {
printf("C4 ");
}
} }
/* Step D1 */ /* Step D1 */
@ -639,7 +672,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
if (n <= 4) { if (n <= 4) {
codeword_array[array_length] = 103 + (n - 2); // nx Shift C codeword_array[array_length] = 103 + (n - 2); // nx Shift C
array_length++; array_length++;
for(i = 0; i < n; i++) { for (i = 0; i < n; i++) {
codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0'); codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
array_length++; array_length++;
input_position += 2; input_position += 2;
@ -650,7 +683,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
encoding_mode = 'C'; encoding_mode = 'C';
} }
done = 1; done = 1;
if (debug) { printf("D1 "); } if (debug) {
printf("D1 ");
}
} }
} }
@ -661,18 +696,22 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
array_length++; array_length++;
input_position++; input_position++;
done = 1; done = 1;
if (debug) { printf("D2/1 "); } if (debug) {
printf("D2/1 ");
}
} else { } else {
if (datum_a(source, input_position, length)) { if (datum_a(source, input_position, length)) {
if (source[input_position] < 32) { if (source[input_position] < 32) {
codeword_array[array_length] = source[input_position] +64; codeword_array[array_length] = source[input_position] + 64;
} else { } else {
codeword_array[array_length] = source[input_position] - 32; codeword_array[array_length] = source[input_position] - 32;
} }
array_length++; array_length++;
input_position++; input_position++;
done = 1; done = 1;
if (debug) { printf("D2/2 "); } if (debug) {
printf("D2/2 ");
}
} }
} }
} }
@ -681,7 +720,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
if ((!done) && (encoding_mode == 'A')) { if ((!done) && (encoding_mode == 'A')) {
if (binary(source, input_position, length)) { if (binary(source, input_position, length)) {
if (datum_a(source, input_position + 1, length)) { if (datum_a(source, input_position + 1, length)) {
if ((source[input_position] - 128) < 32) { if ((source[input_position] - 128) < 32) {
codeword_array[array_length] = 110; // Bin Shift A codeword_array[array_length] = 110; // Bin Shift A
array_length++; array_length++;
codeword_array[array_length] = source[input_position] - 128 + 64; codeword_array[array_length] = source[input_position] - 128 + 64;
@ -699,7 +738,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
encoding_mode = 'X'; encoding_mode = 'X';
} }
done = 1; done = 1;
if (debug) { printf("D3 "); } if (debug) {
printf("D3 ");
}
} }
} }
@ -710,7 +751,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
if (n <= 6) { if (n <= 6) {
codeword_array[array_length] = 95 + n; // nx Shift B codeword_array[array_length] = 95 + n; // nx Shift B
array_length++; array_length++;
for(i = 0; i < n; i++) { for (i = 0; i < n; i++) {
codeword_array[array_length] = source[input_position] - 32; codeword_array[array_length] = source[input_position] - 32;
array_length++; array_length++;
input_position++; input_position++;
@ -721,7 +762,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
encoding_mode = 'B'; encoding_mode = 'B';
} }
done = 1; done = 1;
if (debug) { printf("D4 "); } if (debug) {
printf("D4 ");
}
} }
/* Step E1 */ /* Step E1 */
@ -730,12 +773,12 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
if (n >= 2) { if (n >= 2) {
/* Empty binary buffer */ /* Empty binary buffer */
for(i = 0; i < (binary_buffer_size + 1); i++) { for (i = 0; i < (binary_buffer_size + 1); i++) {
lawrencium[i] = binary_buffer % 103; lawrencium[i] = binary_buffer % 103;
binary_buffer /= 103; binary_buffer /= 103;
} }
for(i = 0; i < (binary_buffer_size + 1); i++) { for (i = 0; i < (binary_buffer_size + 1); i++) {
codeword_array[array_length] = lawrencium[binary_buffer_size - i]; codeword_array[array_length] = lawrencium[binary_buffer_size - i];
array_length++; array_length++;
} }
@ -745,7 +788,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
if (n <= 7) { if (n <= 7) {
codeword_array[array_length] = 101 + n; // Interrupt for nx Shift C codeword_array[array_length] = 101 + n; // Interrupt for nx Shift C
array_length++; array_length++;
for(i = 0; i < n; i++) { for (i = 0; i < n; i++) {
codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0'); codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
array_length++; array_length++;
input_position += 2; input_position += 2;
@ -756,7 +799,9 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
encoding_mode = 'C'; encoding_mode = 'C';
} }
done = 1; done = 1;
if (debug) { printf("E1 "); } if (debug) {
printf("E1 ");
}
} }
} }
@ -766,7 +811,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
* base 103 into five base 259 values..." * base 103 into five base 259 values..."
*/ */
if ((!done) && (encoding_mode == 'X')) { if ((!done) && (encoding_mode == 'X')) {
if(binary(source, input_position, length) if (binary(source, input_position, length)
|| binary(source, input_position + 1, length) || binary(source, input_position + 1, length)
|| binary(source, input_position + 2, length) || binary(source, input_position + 2, length)
|| binary(source, input_position + 3, length)) { || binary(source, input_position + 3, length)) {
@ -775,12 +820,12 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
binary_buffer_size++; binary_buffer_size++;
if (binary_buffer_size == 5) { if (binary_buffer_size == 5) {
for(i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
lawrencium[i] = binary_buffer % 103; lawrencium[i] = binary_buffer % 103;
binary_buffer /= 103; binary_buffer /= 103;
} }
for(i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
codeword_array[array_length] = lawrencium[5 - i]; codeword_array[array_length] = lawrencium[5 - i];
array_length++; array_length++;
} }
@ -789,19 +834,21 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
} }
input_position++; input_position++;
done = 1; done = 1;
if (debug) { printf("E2 "); } if (debug) {
printf("E2 ");
}
} }
} }
/* Step E3 */ /* Step E3 */
if ((!done) && (encoding_mode == 'X')) { if ((!done) && (encoding_mode == 'X')) {
/* Empty binary buffer */ /* Empty binary buffer */
for(i = 0; i < (binary_buffer_size + 1); i++) { for (i = 0; i < (binary_buffer_size + 1); i++) {
lawrencium[i] = binary_buffer % 103; lawrencium[i] = binary_buffer % 103;
binary_buffer /= 103; binary_buffer /= 103;
} }
for(i = 0; i < (binary_buffer_size + 1); i++) { for (i = 0; i < (binary_buffer_size + 1); i++) {
codeword_array[array_length] = lawrencium[binary_buffer_size - i]; codeword_array[array_length] = lawrencium[binary_buffer_size - i];
array_length++; array_length++;
} }
@ -817,11 +864,15 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
} }
array_length++; array_length++;
done = 1; done = 1;
if (debug) { printf("E3 "); } if (debug) {
printf("E3 ");
}
} }
} while (input_position < length); } while (input_position < length);
if (debug) { printf("\n\n"); } if (debug) {
printf("\n\n");
}
return array_length; return array_length;
} }
@ -834,7 +885,7 @@ int make_dotstream(unsigned char masked_array[], int array_length, char dot_stre
dot_stream[0] = '\0'; dot_stream[0] = '\0';
/* Mask value is encoded as two dots */ /* Mask value is encoded as two dots */
switch(masked_array[0]) { switch (masked_array[0]) {
case 0: case 0:
strcat(dot_stream, "00"); strcat(dot_stream, "00");
break; break;
@ -851,7 +902,7 @@ int make_dotstream(unsigned char masked_array[], int array_length, char dot_stre
/* The rest of the data uses 9-bit dot patterns from Annex C */ /* The rest of the data uses 9-bit dot patterns from Annex C */
for (i = 1; i < array_length; i++) { for (i = 1; i < array_length; i++) {
for(j = 0; j < 9; j++) { for (j = 0; j < 9; j++) {
if (dot_patterns[masked_array[i]] & (mask >> j)) { if (dot_patterns[masked_array[i]] & (mask >> j)) {
strcat(dot_stream, "1"); strcat(dot_stream, "1");
} else { } else {
@ -864,7 +915,8 @@ int make_dotstream(unsigned char masked_array[], int array_length, char dot_stre
} }
/* Determines if a given dot is a reserved corner dot /* 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
*/
int is_corner(int column, int row, int width, int height) { int is_corner(int column, int row, int width, int height) {
int corner = 0; int corner = 0;
@ -987,8 +1039,8 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
unsigned char codeword_array[length * 3]; unsigned char codeword_array[length * 3];
unsigned char masked_codeword_array[length * 3]; unsigned char masked_codeword_array[length * 3];
#else #else
unsigned char* codeword_array = (unsigned char *) _alloca(length * 3 * sizeof(unsigned char)); unsigned char* codeword_array = (unsigned char *) _alloca(length * 3 * sizeof (unsigned char));
unsigned char* masked_codeword_array = (unsigned char *) _alloca(length * 3 * sizeof(unsigned char)); unsigned char* masked_codeword_array = (unsigned char *) _alloca(length * 3 * sizeof (unsigned char));
#endif /* _MSC_VER */ #endif /* _MSC_VER */
data_length = dotcode_encode_message(symbol, source, length, codeword_array); data_length = dotcode_encode_message(symbol, source, length, codeword_array);
@ -1001,16 +1053,26 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
min_dots = 9 * (data_length + 3 + (data_length / 2)) + 2; min_dots = 9 * (data_length + 3 + (data_length / 2)) + 2;
//FIXME: Listen to user preferences here if (symbol->option_2 == 0) {
height = sqrt(2 * min_dots);
if ((height % 2) == 1) {
height++;
}
width = (2 * min_dots) / height; height = sqrt(2 * min_dots);
if (height % 2) {
height++;
}
if ((width % 2) != 1) { width = (2 * min_dots) / height;
width++; if (!(width % 2)) {
width++;
}
} else {
width = symbol->option_2;
height = min_dots / width;
if (!((width + height) % 2)) {
height++;
}
} }
n_dots = (height * width) / 2; n_dots = (height * width) / 2;
@ -1019,12 +1081,12 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
char dot_stream[n_dots + 3]; char dot_stream[n_dots + 3];
char dot_array[width * height]; char dot_array[width * height];
#else #else
char* dot_stream = (char *) _alloca((n_dots + 3) * sizeof(char)); char* dot_stream = (char *) _alloca((n_dots + 3) * sizeof (char));
char* dot_array = (char *) _alloca(width * height * sizeof(char)); char* dot_array = (char *) _alloca(width * height * sizeof (char));
#endif /* _MSC_VER */ #endif /* _MSC_VER */
/* Add pad characters */ /* Add pad characters */
for(pad_chars = 0; 9 * ((data_length + pad_chars + 3 + ((data_length + pad_chars) / 2)) + 2) < n_dots; pad_chars++); for (pad_chars = 0; 9 * ((data_length + pad_chars + 3 + ((data_length + pad_chars) / 2)) + 2) < n_dots; pad_chars++);
if (pad_chars > 0) { if (pad_chars > 0) {
codeword_array[data_length] = 109; // Latch to Code Set A codeword_array[data_length] = 109; // Latch to Code Set A
@ -1041,17 +1103,17 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
/* Evaluate data mask options */ /* Evaluate data mask options */
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
switch(i) { switch (i) {
case 0: case 0:
masked_codeword_array[0] = 0; masked_codeword_array[0] = 0;
for(j = 0; j < data_length; j++) { for (j = 0; j < data_length; j++) {
masked_codeword_array[j + 1] = codeword_array[j]; masked_codeword_array[j + 1] = codeword_array[j];
} }
break; break;
case 1: case 1:
weight = 0; weight = 0;
masked_codeword_array[0] = 1; masked_codeword_array[0] = 1;
for(j = 0; j < data_length; j++) { for (j = 0; j < data_length; j++) {
masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113; masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
weight += 3; weight += 3;
} }
@ -1059,7 +1121,7 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
case 2: case 2:
weight = 0; weight = 0;
masked_codeword_array[0] = 2; masked_codeword_array[0] = 2;
for(j = 0; j < data_length; j++) { for (j = 0; j < data_length; j++) {
masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113; masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
weight += 7; weight += 7;
} }
@ -1067,7 +1129,7 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
case 3: case 3:
weight = 0; weight = 0;
masked_codeword_array[0] = 3; masked_codeword_array[0] = 3;
for(j = 0; j < data_length; j++) { for (j = 0; j < data_length; j++) {
masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113; masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
weight += 17; weight += 17;
} }
@ -1079,7 +1141,7 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream); dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream);
/* Add pad bits */ /* Add pad bits */
for(j = dot_stream_length; j < n_dots; j++) { for (j = dot_stream_length; j < n_dots; j++) {
strcat(dot_stream, "1"); strcat(dot_stream, "1");
} }
@ -1095,7 +1157,7 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
high_score = mask_score[0]; high_score = mask_score[0];
best_mask = 0; best_mask = 0;
for(i = 1; i < 4; i++) { for (i = 1; i < 4; i++) {
if (mask_score[i] > high_score) { if (mask_score[i] > high_score) {
high_score = mask_score[i]; high_score = mask_score[i];
best_mask = i; best_mask = i;
@ -1104,17 +1166,17 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
if (best_mask != 3) { if (best_mask != 3) {
/* Reprocess to get symbol with best mask */ /* Reprocess to get symbol with best mask */
switch(best_mask) { switch (best_mask) {
case 0: case 0:
masked_codeword_array[0] = 0; masked_codeword_array[0] = 0;
for(j = 0; j < data_length; j++) { for (j = 0; j < data_length; j++) {
masked_codeword_array[j + 1] = codeword_array[j]; masked_codeword_array[j + 1] = codeword_array[j];
} }
break; break;
case 1: case 1:
weight = 0; weight = 0;
masked_codeword_array[0] = 1; masked_codeword_array[0] = 1;
for(j = 0; j < data_length; j++) { for (j = 0; j < data_length; j++) {
masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113; masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
weight += 3; weight += 3;
} }
@ -1122,7 +1184,7 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
case 2: case 2:
weight = 0; weight = 0;
masked_codeword_array[0] = 2; masked_codeword_array[0] = 2;
for(j = 0; j < data_length; j++) { for (j = 0; j < data_length; j++) {
masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113; masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
weight += 7; weight += 7;
} }
@ -1133,7 +1195,7 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream); dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream);
/* Add pad bits */ /* Add pad bits */
for(j = dot_stream_length; j < n_dots; j++) { for (j = dot_stream_length; j < n_dots; j++) {
strcat(dot_stream, "1"); strcat(dot_stream, "1");
} }
@ -1141,7 +1203,7 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
} /* else { the version with the best mask is already in memory } */ } /* else { the version with the best mask is already in memory } */
if (debug) { if (debug) {
for(k = 0; k < height; k++) { for (k = 0; k < height; k++) {
for (j = 0; j < width; j++) { for (j = 0; j < width; j++) {
printf("%c", dot_array[(k * width) + j]); printf("%c", dot_array[(k * width) + j]);
} }
@ -1162,5 +1224,7 @@ int dotcode(struct zint_symbol *symbol, unsigned char source[], int length) {
symbol->row_height[k] = 1; symbol->row_height[k] = 1;
} }
symbol->barcode_options += BARCODE_DOTTY_MODE;
return 0; return 0;
} }