mirror of
https://git.code.sf.net/p/zint/code
synced 2026-05-14 18:13:53 +00:00
AUSPOST: support Null FCC (DPID all zeroes); TODO: BWIPP support
CODE128: properly fix not switching before FNC1 in 2nd position after alpha (commit [7b0767]) PLANET/KIX: adapt POSTNET to cater for both general: use static strings to save a few bytes (start/stop in particular); various other code fiddles postal: move tables into funcs
This commit is contained in:
420
backend/postal.c
420
backend/postal.c
@@ -40,54 +40,6 @@ static const char KASUTSET[] = "1234567890-abcdefgh";
|
||||
static const char CHKASUTSET[] = "0123456789-abcdefgh";
|
||||
#define SHKASUTSET_F (IS_NUM_F | IS_MNS_F | IS_UPR_F) /* SHKASUTSET "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ" */
|
||||
|
||||
/* PostNet number encoding table - In this table L is long as S is short */
|
||||
static const char PNTable[10][5] = {
|
||||
{'L','L','S','S','S'}, {'S','S','S','L','L'}, {'S','S','L','S','L'}, {'S','S','L','L','S'}, {'S','L','S','S','L'},
|
||||
{'S','L','S','L','S'}, {'S','L','L','S','S'}, {'L','S','S','S','L'}, {'L','S','S','L','S'}, {'L','S','L','S','S'}
|
||||
};
|
||||
|
||||
static const char PLTable[10][5] = {
|
||||
{'S','S','L','L','L'}, {'L','L','L','S','S'}, {'L','L','S','L','S'}, {'L','L','S','S','L'}, {'L','S','L','L','S'},
|
||||
{'L','S','L','S','L'}, {'L','S','S','L','L'}, {'S','L','L','L','S'}, {'S','L','L','S','L'}, {'S','L','S','L','L'}
|
||||
};
|
||||
|
||||
static const char RoyalValues[36][2] = {
|
||||
{ 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 },
|
||||
{ 2, 5 }, { 2, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 0 }, { 4, 1 }, { 4, 2 },
|
||||
{ 4, 3 }, { 4, 4 }, { 4, 5 }, { 4, 0 }, { 5, 1 }, { 5, 2 }, { 5, 3 }, { 5, 4 }, { 5, 5 }, { 5, 0 },
|
||||
{ 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 0 }
|
||||
};
|
||||
|
||||
/* 0 = Full, 1 = Ascender, 2 = Descender, 3 = Tracker */
|
||||
static const char RoyalTable[36][4] = {
|
||||
{'3','3','0','0'}, {'3','2','1','0'}, {'3','2','0','1'}, {'2','3','1','0'}, {'2','3','0','1'}, {'2','2','1','1'},
|
||||
{'3','1','2','0'}, {'3','0','3','0'}, {'3','0','2','1'}, {'2','1','3','0'}, {'2','1','2','1'}, {'2','0','3','1'},
|
||||
{'3','1','0','2'}, {'3','0','1','2'}, {'3','0','0','3'}, {'2','1','1','2'}, {'2','1','0','3'}, {'2','0','1','3'},
|
||||
{'1','3','2','0'}, {'1','2','3','0'}, {'1','2','2','1'}, {'0','3','3','0'}, {'0','3','2','1'}, {'0','2','3','1'},
|
||||
{'1','3','0','2'}, {'1','2','1','2'}, {'1','2','0','3'}, {'0','3','1','2'}, {'0','3','0','3'}, {'0','2','1','3'},
|
||||
{'1','1','2','2'}, {'1','0','3','2'}, {'1','0','2','3'}, {'0','1','3','2'}, {'0','1','2','3'}, {'0','0','3','3'}
|
||||
};
|
||||
|
||||
static const char FlatTable[10][4] = {
|
||||
{'0','5','0','4'}, { "18" }, {'0','1','1','7'}, {'0','2','1','6'}, {'0','3','1','5'},
|
||||
{'0','4','1','4'}, {'0','5','1','3'}, {'0','6','1','2'}, {'0','7','1','1'}, {'0','8','1','0'}
|
||||
};
|
||||
|
||||
static const char KoreaTable[10][10] = {
|
||||
{'1','3','1','3','1','5','0','6','1','3'}, {'0','7','1','3','1','3','1','3','1','3'},
|
||||
{'0','4','1','7','1','3','1','3','1','3'}, {'1','5','0','6','1','3','1','3','1','3'},
|
||||
{'0','4','1','3','1','7','1','3','1','3'}, { "17171313" },
|
||||
{'1','3','1','5','0','6','1','3','1','3'}, {'0','4','1','3','1','3','1','7','1','3'},
|
||||
{ "17131713" }, { "13171713" }
|
||||
};
|
||||
|
||||
static const char JapanTable[19][3] = {
|
||||
{'1','1','4'}, {'1','3','2'}, {'3','1','2'}, {'1','2','3'}, {'1','4','1'},
|
||||
{'3','2','1'}, {'2','1','3'}, {'2','3','1'}, {'4','1','1'}, {'1','4','4'},
|
||||
{'4','1','4'}, {'3','2','4'}, {'3','4','2'}, {'2','3','4'}, {'4','3','2'},
|
||||
{'2','4','3'}, {'4','2','3'}, {'4','4','1'}, {'1','1','1'}
|
||||
};
|
||||
|
||||
/* Set height for POSTNET/PLANET/CEPNet codes, maintaining ratio */
|
||||
static int usps_set_height(struct zint_symbol *symbol, const int no_errtxt) {
|
||||
/* USPS Domestic Mail Manual (USPS DMM 300) Jan 8, 2006 (updated 2011) 708.4.2.5 POSTNET Barcode Dimensions and
|
||||
@@ -133,14 +85,26 @@ static int usps_set_height(struct zint_symbol *symbol, const int no_errtxt) {
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Handles the POSTNET system used for Zip codes in the US */
|
||||
/* Also handles Brazilian CEPNet - more information CEPNet e Código Bidimensional Datamatrix 2D (26/05/2021) at
|
||||
/* Handles the POSTNET system for delivering mail by ZIP codes in the US */
|
||||
/* Also handles PLANET, used to tag outgoing/return mail & identify sender */
|
||||
/* Also handles Brazilian CEPNet (ZIP-like) - more info CEPNet e Código Bidimensional Datamatrix 2D (26/05/2021) at
|
||||
https://www.correios.com.br/enviar/correspondencia/arquivos/nacional/
|
||||
guia-tecnico-cepnet-e-2d-triagem-enderecamento-27-04-2021.pdf/view
|
||||
*/
|
||||
static int postnet_enc(struct zint_symbol *symbol, const unsigned char source[], char *d, const int length) {
|
||||
INTERNAL int zint_postnet(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
/* For POSTNET/CEPNet 1 is ascender and 0 is tracker, vice versa for PLANET */
|
||||
static const char POSTNET_PLANET[10][5] = {
|
||||
{ 1,1,0,0,0 }, { 0,0,0,1,1 }, { 0,0,1,0,1 }, { 0,0,1,1,0 }, { 0,1,0,0,1 },
|
||||
{ 0,1,0,1,0 }, { 0,1,1,0,0 }, { 1,0,0,0,1 }, { 1,0,0,1,0 }, { 1,0,1,0,0 }
|
||||
};
|
||||
/* Suppress clang-tidy-20 garbage value false positive by initializing (see "vector.c" `vection_add_rect()`) */
|
||||
char dest[256] = {0}; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
|
||||
char *d = dest;
|
||||
unsigned int loopey, h;
|
||||
int writer;
|
||||
int error_number = 0, warn_number;
|
||||
int i, sum, check_digit;
|
||||
int error_number = 0;
|
||||
const int ascender = symbol->symbology != BARCODE_PLANET; /* PLANET uses 0 for ascender, 1 for tracker */
|
||||
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
|
||||
|
||||
if (length > 38) {
|
||||
@@ -148,11 +112,19 @@ static int postnet_enc(struct zint_symbol *symbol, const unsigned char source[],
|
||||
}
|
||||
|
||||
if (symbol->symbology == BARCODE_CEPNET) {
|
||||
/* 5 (area) + 3 (+location within area) */
|
||||
if (length != 8) {
|
||||
error_number = z_errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 780,
|
||||
"Input length %d wrong (should be 8 digits)", length);
|
||||
}
|
||||
} else if (symbol->symbology == BARCODE_PLANET) {
|
||||
/* 2 (delivery/return) + 9 or 11 (identification) */
|
||||
if (length != 11 && length != 13) {
|
||||
error_number = z_errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 478,
|
||||
"Input length %d is not standard (should be 11 or 13 digits)", length);
|
||||
}
|
||||
} else {
|
||||
/* 5 ZIP (area), 9 ZIP+4 (+location within area), 11 ZIP+6 (+delivery point barcode) */
|
||||
if (length != 5 && length != 9 && length != 11) {
|
||||
error_number = z_errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 479,
|
||||
"Input length %d is not standard (should be 5, 9 or 11 digits)", length);
|
||||
@@ -162,137 +134,53 @@ static int postnet_enc(struct zint_symbol *symbol, const unsigned char source[],
|
||||
return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 481,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
sum = 0;
|
||||
|
||||
/* Start character */
|
||||
*d++ = 'L';
|
||||
*d++ = ascender;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < length; i++, d += 5) {
|
||||
const int val = source[i] - '0';
|
||||
memcpy(d, PNTable[val], 5);
|
||||
memcpy(d, POSTNET_PLANET[val], 5);
|
||||
sum += val;
|
||||
}
|
||||
|
||||
check_digit = (10 - (sum % 10)) % 10;
|
||||
memcpy(d, PNTable[check_digit], 5);
|
||||
memcpy(d, POSTNET_PLANET[check_digit], 5);
|
||||
d += 5;
|
||||
|
||||
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check digit: %d\n", check_digit);
|
||||
|
||||
/* Stop character */
|
||||
memcpy(d, "L", 2); /* Include terminating NUL */
|
||||
*d++ = ascender;
|
||||
|
||||
if (content_segs && z_ct_cpy_cat(symbol, source, length, (char) z_itoc(check_digit), NULL /*cat*/, 0)) {
|
||||
return ZINT_ERROR_MEMORY; /* `z_ct_cpy_cat()` only fails with OOM */
|
||||
}
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Puts POSTNET barcodes into the pattern matrix */
|
||||
INTERNAL int zint_postnet(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
/* Suppress clang-tidy-20 garbage value false positive by initializing (see "vector.c" `vection_add_rect()`) */
|
||||
char height_pattern[256] = {0}; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
|
||||
unsigned int loopey, h;
|
||||
int writer;
|
||||
int error_number, warn_number;
|
||||
|
||||
error_number = postnet_enc(symbol, source, height_pattern, length);
|
||||
if (error_number >= ZINT_ERROR) {
|
||||
return error_number;
|
||||
}
|
||||
|
||||
writer = 0;
|
||||
h = (int) strlen(height_pattern);
|
||||
for (loopey = 0; loopey < h; loopey++) {
|
||||
if (height_pattern[loopey] == 'L') {
|
||||
h = d - dest;
|
||||
for (loopey = 0, writer = 0; loopey < h; loopey++, writer += 2) {
|
||||
if (dest[loopey] == ascender) {
|
||||
z_set_module(symbol, 0, writer);
|
||||
}
|
||||
z_set_module(symbol, 1, writer);
|
||||
writer += 2;
|
||||
z_set_module(symbol, 1, writer); /* Tracker */
|
||||
}
|
||||
warn_number = usps_set_height(symbol, error_number /*no_errtxt*/);
|
||||
symbol->rows = 2;
|
||||
symbol->width = writer - 1;
|
||||
|
||||
return error_number ? error_number : warn_number;
|
||||
}
|
||||
|
||||
/* Handles the PLANET system used for item tracking in the US */
|
||||
static int planet_enc(struct zint_symbol *symbol, const unsigned char source[], char *d, const int length) {
|
||||
int i, sum, check_digit;
|
||||
int error_number = 0;
|
||||
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
|
||||
|
||||
if (length > 38) {
|
||||
return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 482, "Input length %d too long (maximum 38)", length);
|
||||
}
|
||||
if (length != 11 && length != 13) {
|
||||
error_number = z_errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 478,
|
||||
"Input length %d is not standard (should be 11 or 13 digits)", length);
|
||||
}
|
||||
if ((i = z_not_sane(NEON_F, source, length))) {
|
||||
return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 483,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
sum = 0;
|
||||
|
||||
/* Start character */
|
||||
*d++ = 'L';
|
||||
|
||||
for (i = 0; i < length; i++, d += 5) {
|
||||
const int val = source[i] - '0';
|
||||
memcpy(d, PLTable[val], 5);
|
||||
sum += val;
|
||||
}
|
||||
|
||||
check_digit = (10 - (sum % 10)) % 10;
|
||||
memcpy(d, PLTable[check_digit], 5);
|
||||
d += 5;
|
||||
|
||||
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check digit: %d\n", check_digit);
|
||||
|
||||
/* Stop character */
|
||||
memcpy(d, "L", 2); /* Include terminating NUL */
|
||||
|
||||
if (content_segs && z_ct_cpy_cat(symbol, source, length, (char) z_itoc(check_digit), NULL /*cat*/, 0)) {
|
||||
return ZINT_ERROR_MEMORY; /* `z_ct_cpy_cat()` only fails with OOM */
|
||||
}
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Puts PLANET barcodes into the pattern matrix */
|
||||
INTERNAL int zint_planet(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
/* Suppress clang-tidy-20 garbage value false positive by initializing (see "vector.c" `vection_add_rect()`) */
|
||||
char height_pattern[256] = {0}; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
|
||||
unsigned int loopey, h;
|
||||
int writer;
|
||||
int error_number, warn_number;
|
||||
|
||||
error_number = planet_enc(symbol, source, height_pattern, length);
|
||||
if (error_number >= ZINT_ERROR) {
|
||||
return error_number;
|
||||
}
|
||||
|
||||
writer = 0;
|
||||
h = (int) strlen(height_pattern);
|
||||
for (loopey = 0; loopey < h; loopey++) {
|
||||
if (height_pattern[loopey] == 'L') {
|
||||
z_set_module(symbol, 0, writer);
|
||||
}
|
||||
z_set_module(symbol, 1, writer);
|
||||
writer += 2;
|
||||
}
|
||||
warn_number = usps_set_height(symbol, error_number /*no_errtxt*/);
|
||||
symbol->rows = 2;
|
||||
symbol->width = writer - 1;
|
||||
|
||||
return error_number ? error_number : warn_number;
|
||||
}
|
||||
|
||||
/* Korean Postal Authority */
|
||||
INTERNAL int zint_koreapost(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
static const char KoreaTable[10][10] = {
|
||||
{'1','3','1','3','1','5','0','6','1','3'}, {'0','7','1','3','1','3','1','3','1','3'},
|
||||
{'0','4','1','7','1','3','1','3','1','3'}, {'1','5','0','6','1','3','1','3','1','3'},
|
||||
{'0','4','1','3','1','7','1','3','1','3'}, { "17171313" },
|
||||
{'1','3','1','5','0','6','1','3','1','3'}, {'0','4','1','3','1','3','1','7','1','3'},
|
||||
{ "17131713" }, { "13171713" }
|
||||
};
|
||||
int total, i, check, zeroes, error_number = 0;
|
||||
unsigned char local_source[8];
|
||||
char dest[80];
|
||||
@@ -346,6 +234,11 @@ INTERNAL int zint_koreapost(struct zint_symbol *symbol, unsigned char source[],
|
||||
/* The simplest barcode symbology ever! Supported by MS Word, so here it is!
|
||||
glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */
|
||||
INTERNAL int zint_fim(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
static const char a[9] = { '1','1','1','5','1','5','1','1','1' };
|
||||
static const char b[11] = { '1','3','1','1','1','3','1','1','1','3','1' };
|
||||
static const char c[11] = { '1','1','1','3','1','3','1','3','1','1','1' };
|
||||
static const char d[13] = { '1','1','1','1','1','3','1','3','1','1','1','1','1' };
|
||||
static const char e[7] = { '1','3','1','7','1','3','1' };
|
||||
int error_number = 0;
|
||||
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
|
||||
|
||||
@@ -357,19 +250,19 @@ INTERNAL int zint_fim(struct zint_symbol *symbol, unsigned char source[], int le
|
||||
|
||||
switch ((char) source[0]) {
|
||||
case 'A':
|
||||
z_expand(symbol, "111515111", 9);
|
||||
z_expand(symbol, a, 9);
|
||||
break;
|
||||
case 'B':
|
||||
z_expand(symbol, "13111311131", 11);
|
||||
z_expand(symbol, b, 11);
|
||||
break;
|
||||
case 'C':
|
||||
z_expand(symbol, "11131313111", 11);
|
||||
z_expand(symbol, c, 11);
|
||||
break;
|
||||
case 'D':
|
||||
z_expand(symbol, "1111131311111", 13);
|
||||
z_expand(symbol, d, 13);
|
||||
break;
|
||||
case 'E':
|
||||
z_expand(symbol, "1317131", 7);
|
||||
z_expand(symbol, e, 7);
|
||||
break;
|
||||
default:
|
||||
return z_errtxt(ZINT_ERROR_INVALID_DATA, symbol, 487,
|
||||
@@ -428,22 +321,57 @@ INTERNAL int zint_daft_set_height(struct zint_symbol *symbol, const float min_he
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Handles the 4 State barcodes used in the UK by Royal Mail. Returns check_character */
|
||||
static int rm4scc_enc(struct zint_symbol *symbol, const int *posns, char *d, const int length) {
|
||||
/* Helper to expand 4-states into 3 rows, where 0 = Full, 1 = Ascender, 2 = Descender, 3 Tracker (always) */
|
||||
static void post_4state(struct zint_symbol *symbol, char *dest, const int length) {
|
||||
int loopey, writer;
|
||||
|
||||
for (loopey = 0, writer = 0; loopey < length; loopey++, writer += 2) {
|
||||
if (dest[loopey] == 1 || dest[loopey] == 0) { /* Ascender/full */
|
||||
z_set_module(symbol, 0, writer);
|
||||
}
|
||||
z_set_module(symbol, 1, writer); /* Tracker */
|
||||
if (dest[loopey] == 2 || dest[loopey] == 0) { /* Descender/full */
|
||||
z_set_module(symbol, 2, writer);
|
||||
}
|
||||
}
|
||||
symbol->rows = 3;
|
||||
symbol->width = writer - 1;
|
||||
}
|
||||
|
||||
/* Used by Royal Mail 4-state (& KIX) - 0 = Full, 1 = Ascender, 2 = Descender, 3 = Tracker */
|
||||
static const char RM4KIX[36][4] = {
|
||||
{ 3,3,0,0 }, { 3,2,1,0 }, { 3,2,0,1 }, { 2,3,1,0 }, { 2,3,0,1 }, { 2,2,1,1 },
|
||||
{ 3,1,2,0 }, { 3,0,3,0 }, { 3,0,2,1 }, { 2,1,3,0 }, { 2,1,2,1 }, { 2,0,3,1 },
|
||||
{ 3,1,0,2 }, { 3,0,1,2 }, { 3,0,0,3 }, { 2,1,1,2 }, { 2,1,0,3 }, { 2,0,1,3 },
|
||||
{ 1,3,2,0 }, { 1,2,3,0 }, { 1,2,2,1 }, { 0,3,3,0 }, { 0,3,2,1 }, { 0,2,3,1 },
|
||||
{ 1,3,0,2 }, { 1,2,1,2 }, { 1,2,0,3 }, { 0,3,1,2 }, { 0,3,0,3 }, { 0,2,1,3 },
|
||||
{ 1,1,2,2 }, { 1,0,3,2 }, { 1,0,2,3 }, { 0,1,3,2 }, { 0,1,2,3 }, { 0,0,3,3 }
|
||||
};
|
||||
|
||||
/* Handles the 4-state barcodes used in the UK by Royal Mail. Returns check_character */
|
||||
static int rm4scc_enc(struct zint_symbol *symbol, const int *const posns, char *const dest, const int length,
|
||||
int *p_dest_len) {
|
||||
static const char CheckCharTopBottom[36][2] = {
|
||||
{ 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 },
|
||||
{ 2, 5 }, { 2, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 0 }, { 4, 1 }, { 4, 2 },
|
||||
{ 4, 3 }, { 4, 4 }, { 4, 5 }, { 4, 0 }, { 5, 1 }, { 5, 2 }, { 5, 3 }, { 5, 4 }, { 5, 5 }, { 5, 0 },
|
||||
{ 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 0 }
|
||||
};
|
||||
int i;
|
||||
int top, bottom, row, column, check_digit;
|
||||
char *d = dest;
|
||||
|
||||
top = 0;
|
||||
bottom = 0;
|
||||
|
||||
/* Start character */
|
||||
*d++ = '1';
|
||||
*d++ = 1; /* Ascender */
|
||||
|
||||
for (i = 0; i < length; i++, d += 4) {
|
||||
const int p = posns[i];
|
||||
memcpy(d, RoyalTable[p], 4);
|
||||
top += RoyalValues[p][0];
|
||||
bottom += RoyalValues[p][1];
|
||||
memcpy(d, RM4KIX[p], 4);
|
||||
top += CheckCharTopBottom[p][0];
|
||||
bottom += CheckCharTopBottom[p][1];
|
||||
}
|
||||
|
||||
/* Calculate the check digit */
|
||||
@@ -456,30 +384,40 @@ static int rm4scc_enc(struct zint_symbol *symbol, const int *posns, char *d, con
|
||||
column = 5;
|
||||
}
|
||||
check_digit = (6 * row) + column;
|
||||
memcpy(d, RoyalTable[check_digit], 4);
|
||||
memcpy(d, RM4KIX[check_digit], 4);
|
||||
d += 4;
|
||||
|
||||
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check digit: %d\n", check_digit);
|
||||
|
||||
/* Stop character */
|
||||
memcpy(d, "0", 2); /* Include terminating NUL */
|
||||
*d++ = 0; /* Full */
|
||||
|
||||
*p_dest_len = d - dest;
|
||||
|
||||
return KRSET[check_digit];
|
||||
}
|
||||
|
||||
/* Puts RM4SCC into the data matrix */
|
||||
/* Royal Mail 4-State Customer Code (RM4SCC) */
|
||||
/* Also handles Dutch Post TNT KIX symbols
|
||||
The same as RM4SCC but without check digit or stop/start chars
|
||||
Specification at http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */
|
||||
INTERNAL int zint_rm4scc(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int i;
|
||||
char height_pattern[210];
|
||||
char dest[210];
|
||||
int posns[50];
|
||||
int loopey, h;
|
||||
int writer;
|
||||
int h;
|
||||
char check_digit;
|
||||
int error_number = 0;
|
||||
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
|
||||
|
||||
if (length > 50) {
|
||||
return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 488, "Input length %d too long (maximum 50)", length);
|
||||
if (symbol->symbology == BARCODE_KIX) {
|
||||
if (length > 18) {
|
||||
return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 490, "Input length %d too long (maximum 18)", length);
|
||||
}
|
||||
} else {
|
||||
if (length > 50) {
|
||||
return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 488, "Input length %d too long (maximum 50)", length);
|
||||
}
|
||||
}
|
||||
z_to_upper(source, length);
|
||||
if ((i = z_not_sane_lookup(KRSET, 36, source, length, posns))) {
|
||||
@@ -487,21 +425,20 @@ INTERNAL int zint_rm4scc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
"Invalid character at position %d in input (alphanumerics only)", i);
|
||||
}
|
||||
|
||||
check_digit = rm4scc_enc(symbol, posns, height_pattern, length);
|
||||
|
||||
writer = 0;
|
||||
h = (int) strlen(height_pattern);
|
||||
for (loopey = 0; loopey < h; loopey++) {
|
||||
if (height_pattern[loopey] == '1' || height_pattern[loopey] == '0') {
|
||||
z_set_module(symbol, 0, writer);
|
||||
/* Encode data */
|
||||
if (symbol->symbology == BARCODE_KIX) {
|
||||
char *d = dest;
|
||||
for (i = 0; i < length; i++, d += 4) {
|
||||
memcpy(d, RM4KIX[posns[i]], 4);
|
||||
}
|
||||
z_set_module(symbol, 1, writer);
|
||||
if (height_pattern[loopey] == '2' || height_pattern[loopey] == '0') {
|
||||
z_set_module(symbol, 2, writer);
|
||||
}
|
||||
writer += 2;
|
||||
h = (int) (d - dest);
|
||||
check_digit = '\xFF'; /* None */
|
||||
} else {
|
||||
check_digit = rm4scc_enc(symbol, posns, dest, length, &h);
|
||||
}
|
||||
|
||||
post_4state(symbol, dest, h);
|
||||
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* Royal Mail Know How User's Manual Appendix C: using CBC
|
||||
(https://web.archive.org/web/20120120060743/
|
||||
@@ -509,6 +446,7 @@ INTERNAL int zint_rm4scc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
Bar pitch and min/maxes same as Mailmark, so using recommendations from
|
||||
Royal Mail Mailmark Barcode Definition Document (15 Sept 2015) Section 3.5.1
|
||||
*/
|
||||
/* KIX same */
|
||||
const float min_height = 6.47952747f; /* (4.22 * 39) / 25.4 */
|
||||
const float max_height = 10.8062992f; /* (5.84 * 47) / 25.4 */
|
||||
symbol->row_height[0] = 3.16417313f; /* (1.9 * 42.3) / 25.4 */
|
||||
@@ -520,8 +458,6 @@ INTERNAL int zint_rm4scc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
symbol->row_height[1] = 2.0f;
|
||||
(void) zint_daft_set_height(symbol, 0.0f, 0.0f);
|
||||
}
|
||||
symbol->rows = 3;
|
||||
symbol->width = writer - 1;
|
||||
|
||||
if (content_segs && z_ct_cpy_cat(symbol, source, length, check_digit, NULL /*cat*/, 0)) {
|
||||
return ZINT_ERROR_MEMORY; /* `z_ct_cpy_cat()` only fails with OOM */
|
||||
@@ -530,67 +466,6 @@ INTERNAL int zint_rm4scc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Handles Dutch Post TNT KIX symbols
|
||||
The same as RM4SCC but without check digit or stop/start chars
|
||||
Specification at http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */
|
||||
INTERNAL int zint_kix(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
char height_pattern[75];
|
||||
char *d = height_pattern;
|
||||
int posns[18];
|
||||
int loopey;
|
||||
int writer, i, h;
|
||||
int error_number = 0;
|
||||
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
|
||||
|
||||
if (length > 18) {
|
||||
return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 490, "Input length %d too long (maximum 18)", length);
|
||||
}
|
||||
z_to_upper(source, length);
|
||||
if ((i = z_not_sane_lookup(KRSET, 36, source, length, posns))) {
|
||||
return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 491,
|
||||
"Invalid character at position %d in input (alphanumerics only)", i);
|
||||
}
|
||||
|
||||
/* Encode data */
|
||||
for (i = 0; i < length; i++, d += 4) {
|
||||
memcpy(d, RoyalTable[posns[i]], 4);
|
||||
}
|
||||
|
||||
writer = 0;
|
||||
h = (int) (d - height_pattern);
|
||||
for (loopey = 0; loopey < h; loopey++) {
|
||||
if (height_pattern[loopey] == '1' || height_pattern[loopey] == '0') {
|
||||
z_set_module(symbol, 0, writer);
|
||||
}
|
||||
z_set_module(symbol, 1, writer);
|
||||
if (height_pattern[loopey] == '2' || height_pattern[loopey] == '0') {
|
||||
z_set_module(symbol, 2, writer);
|
||||
}
|
||||
writer += 2;
|
||||
}
|
||||
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* Dimensions same as RM4SCC */
|
||||
const float min_height = 6.47952747f; /* (4.22 * 39) / 25.4 */
|
||||
const float max_height = 10.8062992f; /* (5.84 * 47) / 25.4 */
|
||||
symbol->row_height[0] = 3.16417313f; /* (1.9 * 42.3) / 25.4 */
|
||||
symbol->row_height[1] = 2.16496062f; /* (1.3 * 42.3) / 25.4 */
|
||||
/* Note using max X for minimum and min X for maximum */
|
||||
error_number = zint_daft_set_height(symbol, min_height, max_height);
|
||||
} else {
|
||||
symbol->row_height[0] = 3.0f;
|
||||
symbol->row_height[1] = 2.0f;
|
||||
(void) zint_daft_set_height(symbol, 0.0f, 0.0f);
|
||||
}
|
||||
symbol->rows = 3;
|
||||
symbol->width = writer - 1;
|
||||
|
||||
if (content_segs && z_ct_cpy(symbol, source, length)) {
|
||||
return ZINT_ERROR_MEMORY; /* `z_ct_cpy()` only fails with OOM */
|
||||
}
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Handles DAFT Code symbols */
|
||||
INTERNAL int zint_daft(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
@@ -610,17 +485,17 @@ INTERNAL int zint_daft(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
"Invalid character at position %d in input (\"D\", \"A\", \"F\" and \"T\" only)", i);
|
||||
}
|
||||
|
||||
writer = 0;
|
||||
for (loopey = 0; loopey < length; loopey++) {
|
||||
if (posns[loopey] == 1 || posns[loopey] == 0) {
|
||||
for (loopey = 0, writer = 0; loopey < length; loopey++, writer += 2) {
|
||||
if (posns[loopey] == 1 || posns[loopey] == 0) { /* Ascender/full */
|
||||
z_set_module(symbol, 0, writer);
|
||||
}
|
||||
z_set_module(symbol, 1, writer);
|
||||
if (posns[loopey] == 2 || posns[loopey] == 0) {
|
||||
z_set_module(symbol, 1, writer); /* Tracker */
|
||||
if (posns[loopey] == 2 || posns[loopey] == 0) { /* Descender/full */
|
||||
z_set_module(symbol, 2, writer);
|
||||
}
|
||||
writer += 2;
|
||||
}
|
||||
symbol->rows = 3;
|
||||
symbol->width = writer - 1;
|
||||
|
||||
/* Allow ratio of tracker to be specified in thousandths */
|
||||
if (symbol->option_2 >= 50 && symbol->option_2 <= 900) {
|
||||
@@ -637,8 +512,6 @@ INTERNAL int zint_daft(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
|
||||
/* DAFT generic barcode so no dimensions/height specification */
|
||||
(void) zint_daft_set_height(symbol, 0.0f, 0.0f);
|
||||
symbol->rows = 3;
|
||||
symbol->width = writer - 1;
|
||||
|
||||
if (content_segs && z_ct_cpy(symbol, source, length)) {
|
||||
return ZINT_ERROR_MEMORY; /* `z_ct_cpy()` only fails with OOM */
|
||||
@@ -649,6 +522,10 @@ INTERNAL int zint_daft(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
|
||||
/* Flattermarken - Not really a barcode symbology! */
|
||||
INTERNAL int zint_flat(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
static const char FlatTable[10][4] = {
|
||||
{'0','5','0','4'}, { "18" }, {'0','1','1','7'}, {'0','2','1','6'}, {'0','3','1','5'},
|
||||
{'0','4','1','4'}, {'0','5','1','3'}, {'0','6','1','2'}, {'0','7','1','1'}, {'0','8','1','0'}
|
||||
};
|
||||
int i, error_number = 0;
|
||||
char dest[512]; /* 128 * 4 = 512 */
|
||||
char *d = dest;
|
||||
@@ -681,10 +558,17 @@ INTERNAL int zint_flat(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
|
||||
/* Japanese Postal Code (Kasutama Barcode) */
|
||||
INTERNAL int zint_japanpost(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int error_number = 0, h;
|
||||
char pattern[69];
|
||||
char *d = pattern;
|
||||
int writer, loopey, inter_posn, i, sum, check;
|
||||
static const char JapanTable[19][3] = {
|
||||
{ 0,0,3 }, { 0,2,1 }, { 2,0,1 }, { 0,1,2 }, { 0,3,0 },
|
||||
{ 2,1,0 }, { 1,0,2 }, { 1,2,0 }, { 3,0,0 }, { 0,3,3 },
|
||||
{ 3,0,3 }, { 2,1,3 }, { 2,3,1 }, { 1,2,3 }, { 3,2,1 },
|
||||
{ 1,3,2 }, { 3,1,2 }, { 3,3,0 }, { 0,0,0 }
|
||||
};
|
||||
static const char start_stop[3] = { 0,2,0 }; /* 1st 2 chars start, last 2 chars stop */
|
||||
int error_number = 0;
|
||||
char dest[69];
|
||||
char *d = dest;
|
||||
int inter_posn, i, sum, check;
|
||||
char check_char;
|
||||
unsigned char inter[20 + 1];
|
||||
const int content_segs = symbol->output_options & BARCODE_CONTENT_SEGS;
|
||||
@@ -729,7 +613,7 @@ INTERNAL int zint_japanpost(struct zint_symbol *symbol, unsigned char source[],
|
||||
"Input too long, requires too many symbol characters (maximum 20)");
|
||||
}
|
||||
|
||||
memcpy(d, "13", 2); /* Start */
|
||||
memcpy(d, start_stop, 2); /* Start */
|
||||
d += 2;
|
||||
|
||||
sum = 0;
|
||||
@@ -755,25 +639,11 @@ INTERNAL int zint_japanpost(struct zint_symbol *symbol, unsigned char source[],
|
||||
|
||||
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check: %d, char: %c\n", check, check_char);
|
||||
|
||||
memcpy(d, "31", 2); /* Stop */
|
||||
memcpy(d, start_stop + 1, 2); /* Stop */
|
||||
d += 2;
|
||||
|
||||
/* Resolve pattern to 4-state symbols */
|
||||
writer = 0;
|
||||
h = (int) (d - pattern);
|
||||
for (loopey = 0; loopey < h; loopey++) {
|
||||
if (pattern[loopey] == '2' || pattern[loopey] == '1') {
|
||||
z_set_module(symbol, 0, writer);
|
||||
}
|
||||
z_set_module(symbol, 1, writer);
|
||||
if (pattern[loopey] == '3' || pattern[loopey] == '1') {
|
||||
z_set_module(symbol, 2, writer);
|
||||
}
|
||||
writer += 2;
|
||||
}
|
||||
|
||||
symbol->rows = 3;
|
||||
symbol->width = writer - 1;
|
||||
post_4state(symbol, dest, (int) (d - dest));
|
||||
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* Japan Post Zip/Barcode Manual pp.11-12 https://www.post.japanpost.jp/zipcode/zipmanual/p11.html
|
||||
|
||||
Reference in New Issue
Block a user