2008-07-14 09:15:55 +12:00
|
|
|
/* postal.c - Handles PostNet, PLANET, FIM. RM4SCC and Flattermarken */
|
|
|
|
|
2017-10-24 08:37:52 +13:00
|
|
|
/*
|
2016-02-20 23:50:15 +13:00
|
|
|
libzint - the open source barcode library
|
2020-06-05 05:45:25 +12:00
|
|
|
Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
|
2008-07-19 02:35:32 +12:00
|
|
|
Including bug fixes by Bryan Hatton
|
2013-05-17 05:26:38 +12:00
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
|
2017-10-24 08:37:52 +13:00
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
2013-05-17 05:26:38 +12:00
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in the
|
2017-10-24 08:37:52 +13:00
|
|
|
documentation and/or other materials provided with the distribution.
|
2013-05-17 05:26:38 +12:00
|
|
|
3. Neither the name of the project nor the names of its contributors
|
|
|
|
may be used to endorse or promote products derived from this software
|
2017-10-24 08:37:52 +13:00
|
|
|
without specific prior written permission.
|
2013-05-17 05:26:38 +12:00
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
|
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
2017-10-24 08:37:52 +13:00
|
|
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
2013-05-17 05:26:38 +12:00
|
|
|
SUCH DAMAGE.
|
2016-02-20 23:50:15 +13:00
|
|
|
*/
|
2019-11-28 05:16:14 +13:00
|
|
|
/* vim: set ts=4 sw=4 et : */
|
2008-07-14 09:15:55 +12:00
|
|
|
|
|
|
|
#include <stdio.h>
|
2009-06-03 08:23:38 +12:00
|
|
|
#ifdef _MSC_VER
|
2017-10-24 08:37:52 +13:00
|
|
|
#include <malloc.h>
|
2009-06-03 08:23:38 +12:00
|
|
|
#endif
|
2008-07-14 09:15:55 +12:00
|
|
|
#include "common.h"
|
|
|
|
|
2020-06-05 05:45:25 +12:00
|
|
|
#define DAFTSET "DAFT"
|
2008-07-14 09:15:55 +12:00
|
|
|
#define KRSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
2009-03-15 00:04:52 +13:00
|
|
|
#define KASUTSET "1234567890-abcdefgh"
|
|
|
|
#define CHKASUTSET "0123456789-abcdefgh"
|
|
|
|
#define SHKASUTSET "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
2008-07-14 09:15:55 +12:00
|
|
|
|
|
|
|
/* PostNet number encoding table - In this table L is long as S is short */
|
2016-02-20 23:50:15 +13:00
|
|
|
static const char *PNTable[10] = {
|
|
|
|
"LLSSS", "SSSLL", "SSLSL", "SSLLS", "SLSSL", "SLSLS", "SLLSS", "LSSSL",
|
|
|
|
"LSSLS", "LSLSS"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *PLTable[10] = {
|
|
|
|
"SSLLL", "LLLSS", "LLSLS", "LLSSL", "LSLLS", "LSLSL", "LSSLL", "SLLLS",
|
|
|
|
"SLLSL", "SLSLL"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *RoyalValues[36] = {
|
|
|
|
"11", "12", "13", "14", "15", "10", "21", "22", "23", "24", "25",
|
|
|
|
"20", "31", "32", "33", "34", "35", "30", "41", "42", "43", "44", "45", "40", "51", "52",
|
|
|
|
"53", "54", "55", "50", "01", "02", "03", "04", "05", "00"
|
|
|
|
};
|
2008-07-14 09:15:55 +12:00
|
|
|
|
2008-09-16 19:46:22 +12:00
|
|
|
/* 0 = Full, 1 = Ascender, 2 = Descender, 3 = Tracker */
|
2016-02-20 23:50:15 +13:00
|
|
|
static const char *RoyalTable[36] = {
|
|
|
|
"3300", "3210", "3201", "2310", "2301", "2211", "3120", "3030", "3021",
|
|
|
|
"2130", "2121", "2031", "3102", "3012", "3003", "2112", "2103", "2013", "1320", "1230",
|
|
|
|
"1221", "0330", "0321", "0231", "1302", "1212", "1203", "0312", "0303", "0213", "1122",
|
|
|
|
"1032", "1023", "0132", "0123", "0033"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *FlatTable[10] = {
|
|
|
|
"0504", "18", "0117", "0216", "0315", "0414", "0513", "0612", "0711", "0810"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *KoreaTable[10] = {
|
|
|
|
"1313150613", "0713131313", "0417131313", "1506131313",
|
|
|
|
"0413171313", "17171313", "1315061313", "0413131713", "17131713", "13171713"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *JapanTable[19] = {
|
|
|
|
"114", "132", "312", "123", "141", "321", "213", "231", "411", "144",
|
|
|
|
"414", "324", "342", "234", "432", "243", "423", "441", "111"
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Handles the PostNet system used for Zip codes in the US */
|
2019-12-19 13:37:55 +13:00
|
|
|
static int postnet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) {
|
2020-06-05 05:45:25 +12:00
|
|
|
int i, sum, check_digit;
|
2016-02-20 23:50:15 +13:00
|
|
|
int error_number;
|
|
|
|
|
2017-12-11 08:42:02 +13:00
|
|
|
if (length != 5 && length != 9 && length != 11) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 480;
|
|
|
|
strcpy(symbol->errtxt, _("Input wrong length"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return ZINT_ERROR_TOO_LONG;
|
|
|
|
}
|
|
|
|
error_number = is_sane(NEON, source, length);
|
|
|
|
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 481;
|
|
|
|
strcpy(symbol->errtxt, _("Invalid character in data"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return error_number;
|
|
|
|
}
|
|
|
|
sum = 0;
|
|
|
|
|
|
|
|
/* start character */
|
|
|
|
strcpy(dest, "L");
|
|
|
|
|
|
|
|
for (i = 0; i < length; i++) {
|
|
|
|
lookup(NEON, PNTable, source[i], dest);
|
|
|
|
sum += ctoi(source[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
check_digit = (10 - (sum % 10)) % 10;
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(dest, PNTable[check_digit]);
|
2016-02-20 23:50:15 +13:00
|
|
|
|
|
|
|
/* stop character */
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(dest, "L");
|
2016-02-20 23:50:15 +13:00
|
|
|
|
|
|
|
return error_number;
|
2008-07-14 09:15:55 +12:00
|
|
|
}
|
2013-01-01 02:41:59 +13:00
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* Puts PostNet barcodes into the pattern matrix */
|
2019-12-19 13:37:55 +13:00
|
|
|
INTERNAL int post_plot(struct zint_symbol *symbol, unsigned char source[], int length) {
|
2016-02-20 23:50:15 +13:00
|
|
|
char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */
|
|
|
|
unsigned int loopey, h;
|
|
|
|
int writer;
|
|
|
|
int error_number;
|
|
|
|
|
|
|
|
error_number = postnet(symbol, source, height_pattern, length);
|
|
|
|
if (error_number != 0) {
|
|
|
|
return error_number;
|
|
|
|
}
|
|
|
|
|
|
|
|
writer = 0;
|
|
|
|
h = strlen(height_pattern);
|
|
|
|
for (loopey = 0; loopey < h; loopey++) {
|
|
|
|
if (height_pattern[loopey] == 'L') {
|
|
|
|
set_module(symbol, 0, writer);
|
|
|
|
}
|
|
|
|
set_module(symbol, 1, writer);
|
2020-10-01 00:19:12 +13:00
|
|
|
writer += 2;
|
2016-02-20 23:50:15 +13:00
|
|
|
}
|
|
|
|
symbol->row_height[0] = 6;
|
|
|
|
symbol->row_height[1] = 6;
|
|
|
|
symbol->rows = 2;
|
|
|
|
symbol->width = writer - 1;
|
|
|
|
|
|
|
|
return error_number;
|
2008-07-14 09:15:55 +12:00
|
|
|
}
|
|
|
|
|
2020-10-01 00:19:12 +13:00
|
|
|
/* Handles the PLANET system used for item tracking in the US */
|
2019-12-19 13:37:55 +13:00
|
|
|
static int planet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) {
|
2020-06-05 05:45:25 +12:00
|
|
|
int i, sum, check_digit;
|
2016-02-20 23:50:15 +13:00
|
|
|
int error_number;
|
|
|
|
|
2017-12-11 08:42:02 +13:00
|
|
|
if (length != 11 && length != 13) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 482;
|
|
|
|
strcpy(symbol->errtxt, _("Input wrong length"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return ZINT_ERROR_TOO_LONG;
|
|
|
|
}
|
|
|
|
error_number = is_sane(NEON, source, length);
|
|
|
|
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 483;
|
|
|
|
strcpy(symbol->errtxt, _("Invalid character in data"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return error_number;
|
|
|
|
}
|
|
|
|
sum = 0;
|
|
|
|
|
|
|
|
/* start character */
|
|
|
|
strcpy(dest, "L");
|
|
|
|
|
|
|
|
for (i = 0; i < length; i++) {
|
|
|
|
lookup(NEON, PLTable, source[i], dest);
|
|
|
|
sum += ctoi(source[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
check_digit = (10 - (sum % 10)) % 10;
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(dest, PLTable[check_digit]);
|
2016-02-20 23:50:15 +13:00
|
|
|
|
|
|
|
/* stop character */
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(dest, "L");
|
2016-02-20 23:50:15 +13:00
|
|
|
|
|
|
|
return error_number;
|
2008-07-14 09:15:55 +12:00
|
|
|
}
|
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* Puts PLANET barcodes into the pattern matrix */
|
2019-12-19 13:37:55 +13:00
|
|
|
INTERNAL int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length) {
|
2016-02-20 23:50:15 +13:00
|
|
|
char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */
|
|
|
|
unsigned int loopey, h;
|
|
|
|
int writer;
|
|
|
|
int error_number;
|
|
|
|
|
|
|
|
error_number = planet(symbol, source, height_pattern, length);
|
|
|
|
if (error_number != 0) {
|
|
|
|
return error_number;
|
|
|
|
}
|
|
|
|
|
|
|
|
writer = 0;
|
|
|
|
h = strlen(height_pattern);
|
|
|
|
for (loopey = 0; loopey < h; loopey++) {
|
|
|
|
if (height_pattern[loopey] == 'L') {
|
|
|
|
set_module(symbol, 0, writer);
|
|
|
|
}
|
|
|
|
set_module(symbol, 1, writer);
|
2020-10-01 00:19:12 +13:00
|
|
|
writer += 2;
|
2016-02-20 23:50:15 +13:00
|
|
|
}
|
|
|
|
symbol->row_height[0] = 6;
|
|
|
|
symbol->row_height[1] = 6;
|
|
|
|
symbol->rows = 2;
|
|
|
|
symbol->width = writer - 1;
|
2020-10-01 00:19:12 +13:00
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
return error_number;
|
2008-07-14 09:15:55 +12:00
|
|
|
}
|
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* Korean Postal Authority */
|
2019-12-19 13:37:55 +13:00
|
|
|
INTERNAL int korea_post(struct zint_symbol *symbol, unsigned char source[], int length) {
|
2016-02-20 23:50:15 +13:00
|
|
|
int total, loop, check, zeroes, error_number;
|
|
|
|
char localstr[8], dest[80];
|
|
|
|
|
|
|
|
if (length > 6) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 484;
|
|
|
|
strcpy(symbol->errtxt, _("Input too long"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return ZINT_ERROR_TOO_LONG;
|
|
|
|
}
|
|
|
|
error_number = is_sane(NEON, source, length);
|
|
|
|
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 485;
|
|
|
|
strcpy(symbol->errtxt, _("Invalid character in data"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return error_number;
|
|
|
|
}
|
|
|
|
zeroes = 6 - length;
|
|
|
|
memset(localstr, '0', zeroes);
|
|
|
|
strcpy(localstr + zeroes, (char *) source);
|
|
|
|
|
|
|
|
total = 0;
|
|
|
|
for (loop = 0; loop < 6; loop++) {
|
|
|
|
total += ctoi(localstr[loop]);
|
|
|
|
}
|
|
|
|
check = 10 - (total % 10);
|
|
|
|
if (check == 10) {
|
|
|
|
check = 0;
|
|
|
|
}
|
|
|
|
localstr[6] = itoc(check);
|
|
|
|
localstr[7] = '\0';
|
|
|
|
*dest = '\0';
|
|
|
|
for (loop = 5; loop >= 0; loop--) {
|
|
|
|
lookup(NEON, KoreaTable, localstr[loop], dest);
|
|
|
|
}
|
|
|
|
lookup(NEON, KoreaTable, localstr[6], dest);
|
|
|
|
expand(symbol, dest);
|
|
|
|
ustrcpy(symbol->text, (unsigned char*) localstr);
|
2020-10-01 00:19:12 +13:00
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
return error_number;
|
2008-12-08 09:11:50 +13:00
|
|
|
}
|
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* The simplest barcode symbology ever! Supported by MS Word, so here it is!
|
|
|
|
glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */
|
2019-12-19 13:37:55 +13:00
|
|
|
INTERNAL int fim(struct zint_symbol *symbol, unsigned char source[], int length) {
|
2016-02-20 23:50:15 +13:00
|
|
|
char dest[16] = {0};
|
|
|
|
|
|
|
|
if (length > 1) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 486;
|
|
|
|
strcpy(symbol->errtxt, _("Input too long"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return ZINT_ERROR_TOO_LONG;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ((char) source[0]) {
|
|
|
|
case 'a':
|
|
|
|
case 'A':
|
|
|
|
strcpy(dest, "111515111");
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
case 'B':
|
|
|
|
strcpy(dest, "13111311131");
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
case 'C':
|
|
|
|
strcpy(dest, "11131313111");
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
case 'D':
|
|
|
|
strcpy(dest, "1111131311111");
|
|
|
|
break;
|
|
|
|
default:
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 487;
|
|
|
|
strcpy(symbol->errtxt, _("Invalid character in data"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return ZINT_ERROR_INVALID_DATA;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
expand(symbol, dest);
|
2020-10-01 00:19:12 +13:00
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
return 0;
|
2008-07-14 09:15:55 +12:00
|
|
|
}
|
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* Handles the 4 State barcodes used in the UK by Royal Mail */
|
2020-10-01 00:19:12 +13:00
|
|
|
static char rm4scc(unsigned char source[], char dest[], int length) {
|
2020-06-05 05:45:25 +12:00
|
|
|
int i;
|
2016-02-20 23:50:15 +13:00
|
|
|
int top, bottom, row, column, check_digit;
|
|
|
|
char values[3], set_copy[] = KRSET;
|
|
|
|
|
|
|
|
top = 0;
|
|
|
|
bottom = 0;
|
|
|
|
|
|
|
|
/* start character */
|
2020-10-01 00:19:12 +13:00
|
|
|
strcpy(dest, "1");
|
2016-02-20 23:50:15 +13:00
|
|
|
|
|
|
|
for (i = 0; i < length; i++) {
|
2020-10-01 00:19:12 +13:00
|
|
|
lookup(KRSET, RoyalTable, source[i], dest);
|
2016-02-20 23:50:15 +13:00
|
|
|
strcpy(values, RoyalValues[posn(KRSET, source[i])]);
|
|
|
|
top += ctoi(values[0]);
|
|
|
|
bottom += ctoi(values[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate the check digit */
|
|
|
|
row = (top % 6) - 1;
|
|
|
|
column = (bottom % 6) - 1;
|
|
|
|
if (row == -1) {
|
|
|
|
row = 5;
|
|
|
|
}
|
|
|
|
if (column == -1) {
|
|
|
|
column = 5;
|
|
|
|
}
|
|
|
|
check_digit = (6 * row) + column;
|
2020-10-01 00:19:12 +13:00
|
|
|
strcat(dest, RoyalTable[check_digit]);
|
2016-02-20 23:50:15 +13:00
|
|
|
|
|
|
|
/* stop character */
|
2020-10-01 00:19:12 +13:00
|
|
|
strcat(dest, "0");
|
2016-02-20 23:50:15 +13:00
|
|
|
|
|
|
|
return set_copy[check_digit];
|
2008-07-14 09:15:55 +12:00
|
|
|
}
|
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* Puts RM4SCC into the data matrix */
|
2019-12-19 13:37:55 +13:00
|
|
|
INTERNAL int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length) {
|
2016-08-30 05:45:58 +12:00
|
|
|
char height_pattern[210];
|
2020-06-05 05:45:25 +12:00
|
|
|
int loopey, h;
|
2016-02-20 23:50:15 +13:00
|
|
|
int writer;
|
|
|
|
int error_number;
|
|
|
|
strcpy(height_pattern, "");
|
|
|
|
|
2016-08-30 05:45:58 +12:00
|
|
|
if (length > 50) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 488;
|
|
|
|
strcpy(symbol->errtxt, _("Input too long"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return ZINT_ERROR_TOO_LONG;
|
|
|
|
}
|
|
|
|
to_upper(source);
|
|
|
|
error_number = is_sane(KRSET, source, length);
|
|
|
|
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 489;
|
|
|
|
strcpy(symbol->errtxt, _("Invalid character in data"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return error_number;
|
|
|
|
}
|
2020-10-01 00:19:12 +13:00
|
|
|
/*check = */rm4scc(source, height_pattern, length);
|
2017-10-24 08:37:52 +13:00
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
writer = 0;
|
|
|
|
h = strlen(height_pattern);
|
|
|
|
for (loopey = 0; loopey < h; loopey++) {
|
|
|
|
if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) {
|
|
|
|
set_module(symbol, 0, writer);
|
|
|
|
}
|
|
|
|
set_module(symbol, 1, writer);
|
|
|
|
if ((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) {
|
|
|
|
set_module(symbol, 2, writer);
|
|
|
|
}
|
|
|
|
writer += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
symbol->row_height[0] = 3;
|
|
|
|
symbol->row_height[1] = 2;
|
|
|
|
symbol->row_height[2] = 3;
|
|
|
|
symbol->rows = 3;
|
|
|
|
symbol->width = writer - 1;
|
|
|
|
|
|
|
|
return error_number;
|
2008-07-14 09:15:55 +12:00
|
|
|
}
|
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* Handles Dutch Post TNT KIX symbols
|
|
|
|
The same as RM4SCC but without check digit
|
|
|
|
Specification at http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */
|
2019-12-19 13:37:55 +13:00
|
|
|
INTERNAL int kix_code(struct zint_symbol *symbol, unsigned char source[], int length) {
|
2016-08-30 05:45:58 +12:00
|
|
|
char height_pattern[75], localstr[20];
|
2020-06-05 05:45:25 +12:00
|
|
|
int loopey;
|
2016-02-20 23:50:15 +13:00
|
|
|
int writer, i, h;
|
2020-06-05 05:45:25 +12:00
|
|
|
int error_number;
|
2016-02-20 23:50:15 +13:00
|
|
|
strcpy(height_pattern, "");
|
|
|
|
|
|
|
|
if (length > 18) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 490;
|
|
|
|
strcpy(symbol->errtxt, _("Input too long"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return ZINT_ERROR_TOO_LONG;
|
|
|
|
}
|
|
|
|
to_upper(source);
|
|
|
|
error_number = is_sane(KRSET, source, length);
|
|
|
|
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 491;
|
|
|
|
strcpy(symbol->errtxt, _("Invalid character in data"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return error_number;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(localstr, (char *) source);
|
2017-10-24 08:37:52 +13:00
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* Encode data */
|
2016-08-30 05:45:58 +12:00
|
|
|
for (i = 0; i < length; i++) {
|
2016-02-20 23:50:15 +13:00
|
|
|
lookup(KRSET, RoyalTable, localstr[i], height_pattern);
|
|
|
|
}
|
|
|
|
|
|
|
|
writer = 0;
|
|
|
|
h = strlen(height_pattern);
|
|
|
|
for (loopey = 0; loopey < h; loopey++) {
|
|
|
|
if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) {
|
|
|
|
set_module(symbol, 0, writer);
|
|
|
|
}
|
|
|
|
set_module(symbol, 1, writer);
|
|
|
|
if ((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) {
|
|
|
|
set_module(symbol, 2, writer);
|
|
|
|
}
|
|
|
|
writer += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
symbol->row_height[0] = 3;
|
|
|
|
symbol->row_height[1] = 2;
|
|
|
|
symbol->row_height[2] = 3;
|
|
|
|
symbol->rows = 3;
|
|
|
|
symbol->width = writer - 1;
|
|
|
|
|
|
|
|
return error_number;
|
2008-09-16 19:46:22 +12:00
|
|
|
}
|
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* Handles DAFT Code symbols */
|
2019-12-19 13:37:55 +13:00
|
|
|
INTERNAL int daft_code(struct zint_symbol *symbol, unsigned char source[], int length) {
|
2016-02-20 23:50:15 +13:00
|
|
|
char height_pattern[100];
|
|
|
|
unsigned int loopey, h;
|
|
|
|
int writer, i, error_number;
|
|
|
|
strcpy(height_pattern, "");
|
|
|
|
|
|
|
|
if (length > 50) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 492;
|
|
|
|
strcpy(symbol->errtxt, _("Input too long"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return ZINT_ERROR_TOO_LONG;
|
|
|
|
}
|
|
|
|
to_upper((unsigned char*) source);
|
|
|
|
error_number = is_sane(DAFTSET, (unsigned char*) source, length);
|
|
|
|
|
|
|
|
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 493;
|
|
|
|
strcpy(symbol->errtxt, _("Invalid character in data"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return error_number;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < length; i++) {
|
|
|
|
if (source[i] == 'D') {
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(height_pattern, "2");
|
2016-02-20 23:50:15 +13:00
|
|
|
}
|
|
|
|
if (source[i] == 'A') {
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(height_pattern, "1");
|
2016-02-20 23:50:15 +13:00
|
|
|
}
|
|
|
|
if (source[i] == 'F') {
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(height_pattern, "0");
|
2016-02-20 23:50:15 +13:00
|
|
|
}
|
|
|
|
if (source[i] == 'T') {
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(height_pattern, "3");
|
2016-02-20 23:50:15 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
writer = 0;
|
|
|
|
h = strlen(height_pattern);
|
|
|
|
for (loopey = 0; loopey < h; loopey++) {
|
|
|
|
if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) {
|
|
|
|
set_module(symbol, 0, writer);
|
|
|
|
}
|
|
|
|
set_module(symbol, 1, writer);
|
|
|
|
if ((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) {
|
|
|
|
set_module(symbol, 2, writer);
|
|
|
|
}
|
|
|
|
writer += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
symbol->row_height[0] = 3;
|
|
|
|
symbol->row_height[1] = 2;
|
|
|
|
symbol->row_height[2] = 3;
|
|
|
|
symbol->rows = 3;
|
|
|
|
symbol->width = writer - 1;
|
|
|
|
|
|
|
|
return error_number;
|
2008-09-03 07:47:26 +12:00
|
|
|
}
|
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* Flattermarken - Not really a barcode symbology! */
|
2019-12-19 13:37:55 +13:00
|
|
|
INTERNAL int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length) {
|
2016-02-20 23:50:15 +13:00
|
|
|
int loop, error_number;
|
|
|
|
char dest[512]; /* 90 * 4 + 1 ~ */
|
|
|
|
|
|
|
|
if (length > 90) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 494;
|
|
|
|
strcpy(symbol->errtxt, _("Input too long"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return ZINT_ERROR_TOO_LONG;
|
|
|
|
}
|
|
|
|
error_number = is_sane(NEON, source, length);
|
|
|
|
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 495;
|
|
|
|
strcpy(symbol->errtxt, _("Invalid character in data"));
|
2016-02-20 23:50:15 +13:00
|
|
|
return error_number;
|
|
|
|
}
|
|
|
|
*dest = '\0';
|
|
|
|
for (loop = 0; loop < length; loop++) {
|
|
|
|
lookup(NEON, FlatTable, source[loop], dest);
|
|
|
|
}
|
|
|
|
|
|
|
|
expand(symbol, dest);
|
2020-10-01 00:19:12 +13:00
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
return error_number;
|
2008-07-14 09:15:55 +12:00
|
|
|
}
|
2009-03-15 00:04:52 +13:00
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
/* Japanese Postal Code (Kasutama Barcode) */
|
2019-12-19 13:37:55 +13:00
|
|
|
INTERNAL int japan_post(struct zint_symbol *symbol, unsigned char source[], int length) {
|
2016-02-20 23:50:15 +13:00
|
|
|
int error_number, h;
|
|
|
|
char pattern[69];
|
|
|
|
int writer, loopey, inter_posn, i, sum, check;
|
|
|
|
char check_char;
|
|
|
|
char inter[23];
|
2009-09-29 22:45:46 +13:00
|
|
|
|
2009-06-03 08:23:38 +12:00
|
|
|
#ifndef _MSC_VER
|
2016-02-20 23:50:15 +13:00
|
|
|
char local_source[length + 1];
|
2009-06-03 08:23:38 +12:00
|
|
|
#else
|
2016-02-20 23:50:15 +13:00
|
|
|
char* local_source = (char*) _alloca(length + 1);
|
2009-06-03 08:23:38 +12:00
|
|
|
#endif
|
2016-02-20 23:50:15 +13:00
|
|
|
|
2016-08-30 05:45:58 +12:00
|
|
|
if (length > 20) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 496;
|
|
|
|
strcpy(symbol->errtxt, _("Input too long"));
|
2016-08-30 05:45:58 +12:00
|
|
|
return ZINT_ERROR_TOO_LONG;
|
|
|
|
}
|
2017-10-24 08:37:52 +13:00
|
|
|
|
2016-02-20 23:50:15 +13:00
|
|
|
error_number = 0;
|
|
|
|
|
|
|
|
strcpy(local_source, (char*) source);
|
|
|
|
to_upper((unsigned char*) local_source);
|
|
|
|
|
2018-02-07 09:57:01 +13:00
|
|
|
if (is_sane(SHKASUTSET, (unsigned char*) local_source, length) == ZINT_ERROR_INVALID_DATA) {
|
2020-11-08 08:26:10 +13:00
|
|
|
symbol->err_origin = 497;
|
|
|
|
strcpy(symbol->errtxt, _("Invalid character in data"));
|
2018-02-07 09:57:01 +13:00
|
|
|
return ZINT_ERROR_INVALID_DATA;
|
2016-02-20 23:50:15 +13:00
|
|
|
}
|
|
|
|
memset(inter, 'd', 20); /* Pad character CC4 */
|
|
|
|
inter[20] = '\0';
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
inter_posn = 0;
|
|
|
|
do {
|
|
|
|
if (((local_source[i] >= '0') && (local_source[i] <= '9')) || (local_source[i] == '-')) {
|
|
|
|
inter[inter_posn] = local_source[i];
|
|
|
|
inter_posn++;
|
|
|
|
} else {
|
|
|
|
if ((local_source[i] >= 'A') && (local_source[i] <= 'J')) {
|
|
|
|
inter[inter_posn] = 'a';
|
|
|
|
inter[inter_posn + 1] = local_source[i] - 'A' + '0';
|
|
|
|
inter_posn += 2;
|
|
|
|
}
|
|
|
|
if ((local_source[i] >= 'K') && (local_source[i] <= 'T')) {
|
|
|
|
inter[inter_posn] = 'b';
|
|
|
|
inter[inter_posn + 1] = local_source[i] - 'K' + '0';
|
|
|
|
inter_posn += 2;
|
|
|
|
}
|
|
|
|
if ((local_source[i] >= 'U') && (local_source[i] <= 'Z')) {
|
|
|
|
inter[inter_posn] = 'c';
|
|
|
|
inter[inter_posn + 1] = local_source[i] - 'U' + '0';
|
|
|
|
inter_posn += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
} while ((i < length) && (inter_posn < 20));
|
|
|
|
inter[20] = '\0';
|
|
|
|
|
|
|
|
strcpy(pattern, "13"); /* Start */
|
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
for (i = 0; i < 20; i++) {
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(pattern, JapanTable[posn(KASUTSET, inter[i])]);
|
2016-02-20 23:50:15 +13:00
|
|
|
sum += posn(CHKASUTSET, inter[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate check digit */
|
|
|
|
check = 19 - (sum % 19);
|
|
|
|
if (check == 19) {
|
|
|
|
check = 0;
|
|
|
|
}
|
|
|
|
if (check <= 9) {
|
|
|
|
check_char = check + '0';
|
2019-11-28 05:16:14 +13:00
|
|
|
} else if (check == 10) {
|
2016-02-20 23:50:15 +13:00
|
|
|
check_char = '-';
|
2019-11-28 05:16:14 +13:00
|
|
|
} else {
|
2016-02-20 23:50:15 +13:00
|
|
|
check_char = (check - 11) + 'a';
|
|
|
|
}
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(pattern, JapanTable[posn(KASUTSET, check_char)]);
|
2016-02-20 23:50:15 +13:00
|
|
|
|
2016-03-03 10:12:38 +13:00
|
|
|
strcat(pattern, "31"); /* Stop */
|
2016-02-20 23:50:15 +13:00
|
|
|
|
|
|
|
/* Resolve pattern to 4-state symbols */
|
|
|
|
writer = 0;
|
|
|
|
h = strlen(pattern);
|
|
|
|
for (loopey = 0; loopey < h; loopey++) {
|
|
|
|
if ((pattern[loopey] == '2') || (pattern[loopey] == '1')) {
|
|
|
|
set_module(symbol, 0, writer);
|
|
|
|
}
|
|
|
|
set_module(symbol, 1, writer);
|
|
|
|
if ((pattern[loopey] == '3') || (pattern[loopey] == '1')) {
|
|
|
|
set_module(symbol, 2, writer);
|
|
|
|
}
|
|
|
|
writer += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
symbol->row_height[0] = 3;
|
|
|
|
symbol->row_height[1] = 2;
|
|
|
|
symbol->row_height[2] = 3;
|
|
|
|
symbol->rows = 3;
|
|
|
|
symbol->width = writer - 1;
|
|
|
|
|
|
|
|
return error_number;
|
2009-03-15 00:04:52 +13:00
|
|
|
}
|