mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Update DotCode to latest draft (April 24, 2017)
This commit is contained in:
parent
fd8a4f4d35
commit
847fa6f332
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
libzint - the open source barcode library
|
libzint - the open source barcode library
|
||||||
Copyright (C) 2016 Robin Stuart <rstuart114@gmail.com>
|
Copyright (C) 2017 Robin Stuart <rstuart114@gmail.com>
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
@ -78,9 +78,76 @@ int get_dot(char Dots[], int Hgt, int Wid, int x, int y) {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int clr_col(char *Dots, int Hgt, int Wid, int x) {
|
||||||
|
int y;
|
||||||
|
for (y = x & 1; y < Hgt; y += 2) {
|
||||||
|
if (get_dot(Dots, Hgt, Wid, x, y)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clr_row(char *Dots, int Hgt, int Wid, int y) {
|
||||||
|
int x;
|
||||||
|
for (x = y & 1; x < Wid; x += 2) {
|
||||||
|
if (get_dot(Dots, Hgt, Wid, x, y)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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;
|
||||||
|
int penalty_local = 0;
|
||||||
|
int penalty = 0;
|
||||||
|
|
||||||
|
// first, guard against "pathelogical" gaps in the array
|
||||||
|
if (Hgt & 1) {
|
||||||
|
if (Hgt < 12) {
|
||||||
|
sum = 0;
|
||||||
|
for (x = 1; x < Wid - 1; x++) {
|
||||||
|
if (!(clr_col(Dots, Hgt, Wid, x))) {
|
||||||
|
sum = 0;
|
||||||
|
if (penalty_local) {
|
||||||
|
penalty += penalty_local;
|
||||||
|
penalty_local = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sum++;
|
||||||
|
if (sum == 1) {
|
||||||
|
penalty_local = Hgt;
|
||||||
|
} else {
|
||||||
|
penalty_local *= Hgt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Wid < 12) {
|
||||||
|
sum = 0;
|
||||||
|
for (y = 1; y < Hgt - 1; y++) {
|
||||||
|
if (!(clr_row(Dots, Hgt, Wid, y))) {
|
||||||
|
sum = 0;
|
||||||
|
if (penalty_local) {
|
||||||
|
penalty += penalty_local;
|
||||||
|
penalty_local = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sum++;
|
||||||
|
if (sum == 1) {
|
||||||
|
penalty_local = Wid;
|
||||||
|
} else {
|
||||||
|
penalty_local *= Wid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
first = -1;
|
first = -1;
|
||||||
@ -100,6 +167,7 @@ int score_array(char Dots[], int Hgt, int Wid) {
|
|||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
first = -1;
|
first = -1;
|
||||||
|
last = -1;
|
||||||
|
|
||||||
//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)
|
||||||
@ -118,6 +186,7 @@ int score_array(char Dots[], int Hgt, int Wid) {
|
|||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
first = -1;
|
first = -1;
|
||||||
|
last = -1;
|
||||||
|
|
||||||
//down the left edge, ditto
|
//down the left edge, ditto
|
||||||
for (y = 0; y < Hgt; y += 2)
|
for (y = 0; y < Hgt; y += 2)
|
||||||
@ -136,6 +205,7 @@ int score_array(char Dots[], int Hgt, int Wid) {
|
|||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
first = -1;
|
first = -1;
|
||||||
|
last = -1;
|
||||||
|
|
||||||
//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)
|
||||||
@ -171,7 +241,7 @@ int score_array(char Dots[], int Hgt, int Wid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (worstedge - sum * sum);
|
return (worstedge - sum * sum - penalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@ -240,7 +310,7 @@ int datum_b(const unsigned char source[], int position, int length) {
|
|||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
if (position < length) {
|
if (position < length) {
|
||||||
if (source[position] >= 32) {
|
if ((source[position] >= 32) && (source[position] <= 127)) {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,20 +458,73 @@ int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char sourc
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (symbol->input_mode != GS1_MODE) {
|
if (symbol->input_mode != GS1_MODE) {
|
||||||
|
if (length > 2) {
|
||||||
|
if (((source[input_position] >= '0') && (source[input_position] <= '9')) &&
|
||||||
|
((source[input_position + 1] >= '0') && (source[input_position + 1] <= '9'))) {
|
||||||
codeword_array[array_length] = 107; // FNC1
|
codeword_array[array_length] = 107; // FNC1
|
||||||
array_length++;
|
array_length++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (symbol->eci > 3) {
|
if (symbol->eci > 3) {
|
||||||
codeword_array[array_length] = 108; // FNC2
|
codeword_array[array_length] = 108; // FNC2
|
||||||
array_length++;
|
array_length++;
|
||||||
|
if (symbol->eci <= 39) {
|
||||||
codeword_array[array_length] = symbol->eci;
|
codeword_array[array_length] = symbol->eci;
|
||||||
array_length++;
|
array_length++;
|
||||||
|
} else {
|
||||||
|
// 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 = (symbol->eci - 40) % 12769;
|
||||||
|
b = ((symbol->eci - 40) - (12769 * a)) % 113;
|
||||||
|
c = (symbol->eci - 40) - (12769 * a) - (113 * b);
|
||||||
|
|
||||||
|
codeword_array[array_length] = a + 40;
|
||||||
|
array_length++;
|
||||||
|
codeword_array[array_length] = b;
|
||||||
|
array_length++;
|
||||||
|
codeword_array[array_length] = c;
|
||||||
|
array_length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent encodation as a macro if a special character is in first position
|
||||||
|
if (source[input_position] == 9) {
|
||||||
|
codeword_array[array_length] = 101; // Latch A
|
||||||
|
array_length++;
|
||||||
|
codeword_array[array_length] = 73; // HT
|
||||||
|
array_length++;
|
||||||
|
encoding_mode = 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source[input_position] == 28) {
|
||||||
|
codeword_array[array_length] = 101; // Latch A
|
||||||
|
array_length++;
|
||||||
|
codeword_array[array_length] = 92; // FS
|
||||||
|
array_length++;
|
||||||
|
encoding_mode = 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source[input_position] == 29) {
|
||||||
|
codeword_array[array_length] = 101; // Latch A
|
||||||
|
array_length++;
|
||||||
|
codeword_array[array_length] = 93; // GS
|
||||||
|
array_length++;
|
||||||
|
encoding_mode = 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source[input_position] == 30) {
|
||||||
|
codeword_array[array_length] = 101; // Latch A
|
||||||
|
array_length++;
|
||||||
|
codeword_array[array_length] = 94; // RS
|
||||||
|
array_length++;
|
||||||
|
encoding_mode = 'A';
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
done = 0;
|
done = 0;
|
||||||
|
|
||||||
/* Step A */
|
/* Step A */
|
||||||
if ((input_position == length - 2) && (inside_macro != 0) && (inside_macro != 100)) {
|
if ((input_position == length - 2) && (inside_macro != 0) && (inside_macro != 100)) {
|
||||||
// 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
|
||||||
@ -430,12 +553,11 @@ int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char sourc
|
|||||||
&& (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
|
|
||||||
array_length++;
|
|
||||||
encoding_mode = 'B';
|
|
||||||
|
|
||||||
if ((source[input_position + 6] == 29) && (source[length - 2] == 30)) { // GS/RS
|
if ((source[input_position + 6] == 29) && (source[length - 2] == 30)) { // GS/RS
|
||||||
if ((source[input_position + 4] == '0') && (source[input_position + 5] == '5')) {
|
if ((source[input_position + 4] == '0') && (source[input_position + 5] == '5')) {
|
||||||
|
codeword_array[array_length] = 102; // Shift B
|
||||||
|
array_length++;
|
||||||
codeword_array[array_length] = 97; // Macro
|
codeword_array[array_length] = 97; // Macro
|
||||||
array_length++;
|
array_length++;
|
||||||
input_position += 7;
|
input_position += 7;
|
||||||
@ -447,6 +569,8 @@ int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char sourc
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((source[input_position + 4] == '0') && (source[input_position + 5] == '6')) {
|
if ((source[input_position + 4] == '0') && (source[input_position + 5] == '6')) {
|
||||||
|
codeword_array[array_length] = 102; // Shift B
|
||||||
|
array_length++;
|
||||||
codeword_array[array_length] = 98; // Macro
|
codeword_array[array_length] = 98; // Macro
|
||||||
array_length++;
|
array_length++;
|
||||||
input_position += 7;
|
input_position += 7;
|
||||||
@ -458,6 +582,8 @@ int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char sourc
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((source[input_position + 4] == '1') && (source[input_position + 5] == '2')) {
|
if ((source[input_position + 4] == '1') && (source[input_position + 5] == '2')) {
|
||||||
|
codeword_array[array_length] = 102; // Shift B
|
||||||
|
array_length++;
|
||||||
codeword_array[array_length] = 99; // Macro
|
codeword_array[array_length] = 99; // Macro
|
||||||
array_length++;
|
array_length++;
|
||||||
input_position += 7;
|
input_position += 7;
|
||||||
@ -469,7 +595,10 @@ int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char sourc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!done) {
|
if ((!done) && (source[input_position] >= '0') && (source[input_position] <= '9') &&
|
||||||
|
(source[input_position + 1] >= '0') && (source[input_position + 1] <= '9')) {
|
||||||
|
codeword_array[array_length] = 102; // Shift B
|
||||||
|
array_length++;
|
||||||
codeword_array[array_length] = 100; // Macro
|
codeword_array[array_length] = 100; // Macro
|
||||||
array_length++;
|
array_length++;
|
||||||
input_position += 4;
|
input_position += 4;
|
||||||
@ -912,6 +1041,18 @@ int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char sourc
|
|||||||
} while (input_position < length);
|
} while (input_position < length);
|
||||||
|
|
||||||
if (encoding_mode == 'X') {
|
if (encoding_mode == 'X') {
|
||||||
|
if (binary_buffer_size != 0) {
|
||||||
|
/* Empty binary buffer */
|
||||||
|
for (i = 0; i < (binary_buffer_size + 1); i++) {
|
||||||
|
lawrencium[i] = binary_buffer % 103;
|
||||||
|
binary_buffer /= 103;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < (binary_buffer_size + 1); i++) {
|
||||||
|
codeword_array[array_length] = lawrencium[binary_buffer_size - i];
|
||||||
|
array_length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
*(binary_finish) = 1;
|
*(binary_finish) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user