zint/backend/postal.c

590 lines
15 KiB
C
Raw Normal View History

2008-07-14 09:15:55 +12:00
/* postal.c - Handles PostNet, PLANET, FIM. RM4SCC and Flattermarken */
/* Zint - A barcode generating program using libpng
2008-11-17 21:47:42 +13:00
Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
2008-07-19 02:35:32 +12:00
Including bug fixes by Bryan Hatton
2008-07-14 09:15:55 +12:00
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif
2008-07-14 09:15:55 +12:00
#include "common.h"
2009-03-15 00:04:52 +13: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 */
2012-12-30 07:33:43 +13:00
static const char *PNTable[10] = {"LLSSS", "SSSLL", "SSLSL", "SSLLS", "SLSSL", "SLSLS", "SLLSS", "LSSSL",
2008-07-14 09:15:55 +12:00
"LSSLS", "LSLSS"};
2012-12-30 07:33:43 +13:00
static const char *PLTable[10] = {"SSLLL", "LLLSS", "LLSLS", "LLSSL", "LSLLS", "LSLSL", "LSSLL", "SLLLS",
2008-07-14 09:15:55 +12:00
"SLLSL", "SLSLL"};
2012-12-30 07:33:43 +13:00
static const char *RoyalValues[36] = {"11", "12", "13", "14", "15", "10", "21", "22", "23", "24", "25",
2008-07-14 09:15:55 +12:00
"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-09-16 19:46:22 +12:00
/* 0 = Full, 1 = Ascender, 2 = Descender, 3 = Tracker */
2012-12-30 07:33:43 +13:00
static const char *RoyalTable[36] = {"3300", "3210", "3201", "2310", "2301", "2211", "3120", "3030", "3021",
2008-07-14 09:15:55 +12:00
"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"};
2008-09-03 07:47:26 +12:00
2012-12-30 07:33:43 +13:00
static const char *FlatTable[10] = {"0504", "18", "0117", "0216", "0315", "0414", "0513", "0612", "0711",
2008-07-14 09:15:55 +12:00
"0810"};
2012-12-30 07:33:43 +13:00
static const char *KoreaTable[10] = {"1313150613", "0713131313", "0417131313", "1506131313",
2008-12-08 09:11:50 +13:00
"0413171313", "17171313", "1315061313", "0413131713", "17131713", "13171713"};
2012-12-30 07:33:43 +13:00
static const char *JapanTable[19] = {"114", "132", "312", "123", "141", "321", "213", "231", "411", "144",
2009-03-15 00:04:52 +13:00
"414", "324", "342", "234", "432", "243", "423", "441", "111"};
2013-01-01 02:41:59 +13:00
int postnet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length)
2008-07-14 09:15:55 +12:00
{
/* Handles the PostNet system used for Zip codes in the US */
unsigned int i, sum, check_digit;
2009-02-20 08:09:57 +13:00
int error_number;
2013-01-01 02:41:59 +13:00
2008-09-16 19:46:22 +12:00
error_number = 0;
2008-07-14 09:15:55 +12:00
if(length > 38) {
strcpy(symbol->errtxt, "Input too long");
2008-07-14 09:15:55 +12:00
return ERROR_TOO_LONG;
}
2009-10-07 08:03:00 +13:00
error_number = is_sane(NEON, source, length);
2008-09-16 19:46:22 +12:00
if(error_number == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "Invalid characters in data");
2008-09-16 19:46:22 +12:00
return error_number;
2008-07-14 09:15:55 +12:00
}
sum = 0;
/* start character */
2009-10-07 08:03:00 +13:00
strcpy(dest, "L");
2008-07-14 09:15:55 +12:00
for (i=0; i < length; i++)
2008-07-14 09:15:55 +12:00
{
2009-10-07 08:03:00 +13:00
lookup(NEON, PNTable, source[i], dest);
2008-07-14 09:15:55 +12:00
sum += ctoi(source[i]);
}
2009-10-07 08:03:00 +13:00
check_digit = (10 - (sum % 10)) % 10;
2008-07-14 09:15:55 +12:00
concat(dest, PNTable[check_digit]);
/* stop character */
concat (dest, "L");
2013-01-01 02:41:59 +13:00
2008-09-16 19:46:22 +12:00
return error_number;
2008-07-14 09:15:55 +12:00
}
2013-01-01 02:41:59 +13:00
int post_plot(struct zint_symbol *symbol, unsigned char source[], int length)
2008-07-14 09:15:55 +12:00
{
/* Puts PostNet barcodes into the pattern matrix */
2009-10-07 08:03:00 +13:00
char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */
unsigned int loopey, h;
2008-07-14 09:15:55 +12:00
int writer;
2008-09-16 19:46:22 +12:00
int error_number;
2013-01-01 02:41:59 +13:00
2008-09-16 19:46:22 +12:00
error_number = 0;
2008-07-14 09:15:55 +12:00
error_number = postnet(symbol, source, height_pattern, length);
2008-09-16 19:46:22 +12:00
if(error_number != 0) {
return error_number;
2008-07-14 09:15:55 +12:00
}
writer = 0;
2009-10-07 08:03:00 +13:00
h = strlen(height_pattern);
for(loopey = 0; loopey < h; loopey++)
2008-07-14 09:15:55 +12:00
{
if(height_pattern[loopey] == 'L')
{
set_module(symbol, 0, writer);
2008-07-14 09:15:55 +12:00
}
set_module(symbol, 1, writer);
2008-07-19 02:35:32 +12:00
writer += 3;
2008-07-14 09:15:55 +12:00
}
symbol->row_height[0] = 6;
symbol->row_height[1] = 6;
symbol->rows = 2;
symbol->width = writer - 1;
2013-01-01 02:41:59 +13:00
2008-09-16 19:46:22 +12:00
return error_number;
2008-07-14 09:15:55 +12:00
}
int planet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length)
2008-07-14 09:15:55 +12:00
{
/* Handles the PLANET system used for item tracking in the US */
unsigned int i, sum, check_digit;
2009-02-20 08:09:57 +13:00
int error_number;
2013-01-01 02:41:59 +13:00
2008-09-16 19:46:22 +12:00
error_number = 0;
2013-01-01 02:41:59 +13:00
if(length > 38) {
strcpy(symbol->errtxt, "Input too long");
2008-07-14 09:15:55 +12:00
return ERROR_TOO_LONG;
}
2009-10-07 08:03:00 +13:00
error_number = is_sane(NEON, source, length);
2008-09-16 19:46:22 +12:00
if(error_number == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "Invalid characters in data");
2008-09-16 19:46:22 +12:00
return error_number;
2008-07-14 09:15:55 +12:00
}
sum = 0;
/* start character */
2009-10-07 08:03:00 +13:00
strcpy(dest, "L");
2008-07-14 09:15:55 +12:00
for (i=0; i < length; i++)
2008-07-14 09:15:55 +12:00
{
2009-10-07 08:03:00 +13:00
lookup(NEON, PLTable, source[i], dest);
2008-07-14 09:15:55 +12:00
sum += ctoi(source[i]);
}
2009-10-07 08:03:00 +13:00
check_digit = (10 - (sum % 10)) % 10;
2008-07-14 09:15:55 +12:00
concat(dest, PLTable[check_digit]);
/* stop character */
concat (dest, "L");
2008-09-16 19:46:22 +12:00
return error_number;
2008-07-14 09:15:55 +12:00
}
int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length)
2008-07-14 09:15:55 +12:00
{
/* Puts PLANET barcodes into the pattern matrix */
2009-10-07 08:03:00 +13:00
char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */
unsigned int loopey, h;
2008-07-14 09:15:55 +12:00
int writer;
2008-09-16 19:46:22 +12:00
int error_number;
2013-01-01 02:41:59 +13:00
2008-09-16 19:46:22 +12:00
error_number = 0;
2008-07-14 09:15:55 +12:00
error_number = planet(symbol, source, height_pattern, length);
2008-09-16 19:46:22 +12:00
if(error_number != 0) {
return error_number;
2008-07-14 09:15:55 +12:00
}
writer = 0;
2009-10-07 08:03:00 +13:00
h = strlen(height_pattern);
for(loopey = 0; loopey < h; loopey++)
2008-07-14 09:15:55 +12:00
{
if(height_pattern[loopey] == 'L')
{
set_module(symbol, 0, writer);
2008-07-14 09:15:55 +12:00
}
set_module(symbol, 1, writer);
2008-07-19 02:35:32 +12:00
writer += 3;
2008-07-14 09:15:55 +12:00
}
symbol->row_height[0] = 6;
symbol->row_height[1] = 6;
symbol->rows = 2;
symbol->width = writer - 1;
2008-09-16 19:46:22 +12:00
return error_number;
2008-07-14 09:15:55 +12:00
}
int korea_post(struct zint_symbol *symbol, unsigned char source[], int length)
2008-12-08 09:11:50 +13:00
{ /* Korean Postal Authority */
int total, loop, check, zeroes, error_number;
2009-10-07 08:03:00 +13:00
char localstr[8], dest[80];
2008-12-08 09:11:50 +13:00
error_number = 0;
if(length > 6) {
strcpy(symbol->errtxt, "Input too long");
2008-12-08 09:11:50 +13:00
return ERROR_TOO_LONG;
}
2009-10-07 08:03:00 +13:00
error_number = is_sane(NEON, source, length);
2008-12-08 09:11:50 +13:00
if(error_number == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "Invalid characters in data");
2008-12-08 09:11:50 +13:00
return error_number;
}
zeroes = 6 - length;
2009-10-07 08:03:00 +13:00
memset(localstr, '0', zeroes);
strcpy(localstr + zeroes, (char *)source);
2008-12-08 09:11:50 +13:00
total = 0;
for(loop = 0; loop < 6; loop++) {
total += ctoi(localstr[loop]);
}
check = 10 - (total % 10);
2008-12-16 20:41:35 +13:00
if(check == 10) { check = 0; }
2009-10-07 08:03:00 +13:00
localstr[6] = itoc(check);
localstr[7] = '\0';
*dest = '\0';
2008-12-08 09:11:50 +13:00
for(loop = 5; loop >= 0; loop--) {
2009-10-07 08:03:00 +13:00
lookup(NEON, KoreaTable, localstr[loop], dest);
2008-12-08 09:11:50 +13:00
}
2009-10-07 08:03:00 +13:00
lookup(NEON, KoreaTable, localstr[6], dest);
2008-12-08 09:11:50 +13:00
expand(symbol, dest);
2009-02-20 08:09:57 +13:00
ustrcpy(symbol->text, (unsigned char*)localstr);
2008-12-08 09:11:50 +13:00
return error_number;
}
int fim(struct zint_symbol *symbol, unsigned char source[], int length)
2008-07-14 09:15:55 +12:00
{
/* The simplest barcode symbology ever! Supported by MS Word, so here it is! */
/* glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */
2013-01-01 02:41:59 +13:00
2009-10-07 08:03:00 +13:00
char dest[16] = { 0 };
2013-01-01 02:41:59 +13:00
if(length > 1) {
strcpy(symbol->errtxt, "Input too long");
2008-07-14 09:15:55 +12:00
return ERROR_TOO_LONG;
}
2013-01-01 02:41:59 +13:00
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:
strcpy(symbol->errtxt, "Invalid characters in data");
return ERROR_INVALID_DATA;
break;
2008-07-14 09:15:55 +12:00
}
2013-01-01 02:41:59 +13:00
2008-07-14 09:15:55 +12:00
expand(symbol, dest);
return 0;
2008-07-14 09:15:55 +12:00
}
2009-10-07 08:03:00 +13:00
char rm4scc(char source[], unsigned char dest[], int length)
2008-07-14 09:15:55 +12:00
{
/* Handles the 4 State barcodes used in the UK by Royal Mail */
unsigned int i;
int top, bottom, row, column, check_digit;
2009-10-07 08:03:00 +13:00
char values[3], set_copy[] = KRSET;
2008-07-14 09:15:55 +12:00
top = 0;
bottom = 0;
/* start character */
2009-10-07 08:03:00 +13:00
strcpy((char*)dest, "1");
2008-07-14 09:15:55 +12:00
2009-10-07 08:03:00 +13:00
for (i = 0; i < length; i++) {
2008-10-03 21:31:53 +13:00
lookup(KRSET, RoyalTable, source[i], (char*)dest);
2008-07-14 09:15:55 +12: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;
2008-10-03 21:31:53 +13:00
concat((char*)dest, RoyalTable[check_digit]);
2008-07-14 09:15:55 +12:00
/* stop character */
2008-10-03 21:31:53 +13:00
concat ((char*)dest, "0");
2013-01-01 02:41:59 +13:00
2008-07-14 09:15:55 +12:00
return set_copy[check_digit];
}
int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length)
2008-07-14 09:15:55 +12:00
{
/* Puts RM4SCC into the data matrix */
2012-12-30 07:33:43 +13:00
char height_pattern[200];
2009-10-07 08:03:00 +13:00
unsigned int loopey, h;
int writer;
2009-02-20 08:09:57 +13:00
int error_number;
2008-07-14 09:15:55 +12:00
strcpy(height_pattern, "");
2008-09-16 19:46:22 +12:00
error_number = 0;
2013-01-01 02:41:59 +13:00
if(length > 120) {
strcpy(symbol->errtxt, "Input too long");
2008-07-14 09:15:55 +12:00
return ERROR_TOO_LONG;
}
2009-10-07 08:03:00 +13:00
to_upper(source);
error_number = is_sane(KRSET, source, length);
2008-09-16 19:46:22 +12:00
if(error_number == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "Invalid characters in data");
2008-09-16 19:46:22 +12:00
return error_number;
2008-07-14 09:15:55 +12:00
}
2012-12-30 07:33:43 +13:00
/*check = */rm4scc((char*)source, (unsigned char*)height_pattern, length);
2008-07-14 09:15:55 +12:00
writer = 0;
2009-10-07 08:03:00 +13:00
h = strlen(height_pattern);
for(loopey = 0; loopey < h; loopey++)
2008-07-14 09:15:55 +12:00
{
if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0'))
{
set_module(symbol, 0, writer);
2008-07-14 09:15:55 +12:00
}
set_module(symbol, 1, writer);
2008-07-14 09:15:55 +12:00
if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0'))
{
set_module(symbol, 2, writer);
2008-07-14 09:15:55 +12:00
}
writer += 2;
}
symbol->row_height[0] = 3;
2008-07-14 09:15:55 +12:00
symbol->row_height[1] = 2;
symbol->row_height[2] = 3;
2008-07-14 09:15:55 +12:00
symbol->rows = 3;
symbol->width = writer - 1;
2013-01-01 02:41:59 +13:00
2008-09-16 19:46:22 +12:00
return error_number;
2008-07-14 09:15:55 +12:00
}
int kix_code(struct zint_symbol *symbol, unsigned char source[], int length)
2008-09-03 07:47:26 +12: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 */
char height_pattern[50], localstr[20];
2008-09-03 07:47:26 +12:00
unsigned int loopey;
2009-10-07 08:03:00 +13:00
int writer, i, h;
int error_number; /* zeroes; */
2008-09-03 07:47:26 +12:00
strcpy(height_pattern, "");
2008-09-16 19:46:22 +12:00
error_number = 0;
2013-01-01 02:41:59 +13:00
if(length > 18) {
strcpy(symbol->errtxt, "Input too long");
2008-09-03 07:47:26 +12:00
return ERROR_TOO_LONG;
}
2009-10-07 08:03:00 +13:00
to_upper(source);
error_number = is_sane(KRSET, source, length);
2008-09-16 19:46:22 +12:00
if(error_number == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "Invalid characters in data");
2008-09-16 19:46:22 +12:00
return error_number;
2008-09-03 07:47:26 +12:00
}
2013-01-01 02:41:59 +13:00
2008-10-13 10:05:53 +13:00
/* Add leading zeroes */
/* zeroes = 11 - length;
2009-10-07 08:03:00 +13:00
memset(localstr, '0', zeroes);
strcpy(localstr + zeroes, (char *)source);*/
strcpy(localstr, (char *)source);
2013-01-01 02:41:59 +13:00
2008-10-13 10:05:53 +13:00
/* Encode data */
for (i = 0; i < 18; i++) {
2008-10-13 10:05:53 +13:00
lookup(KRSET, RoyalTable, localstr[i], height_pattern);
2008-09-03 07:47:26 +12:00
}
2013-01-01 02:41:59 +13:00
2008-09-03 07:47:26 +12:00
writer = 0;
2009-10-07 08:03:00 +13:00
h = strlen(height_pattern);
for(loopey = 0; loopey < h; loopey++)
2008-09-03 07:47:26 +12:00
{
if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0'))
{
set_module(symbol, 0, writer);
2008-09-03 07:47:26 +12:00
}
set_module(symbol, 1, writer);
2008-09-03 07:47:26 +12:00
if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0'))
{
set_module(symbol, 2, writer);
2008-09-03 07:47:26 +12:00
}
writer += 2;
}
symbol->row_height[0] = 3;
2008-09-03 07:47:26 +12:00
symbol->row_height[1] = 2;
symbol->row_height[2] = 3;
2008-09-03 07:47:26 +12:00
symbol->rows = 3;
symbol->width = writer - 1;
2013-01-01 02:41:59 +13:00
2008-09-16 19:46:22 +12:00
return error_number;
}
int daft_code(struct zint_symbol *symbol, unsigned char source[], int length)
2008-09-16 19:46:22 +12:00
{
/* Handles DAFT Code symbols */
/* Presumably 'daft' doesn't mean the same thing in Germany as it does in the UK! */
2009-10-07 08:03:00 +13:00
char height_pattern[100];
unsigned int loopey, h;
2009-03-15 00:04:52 +13:00
int writer, i, error_number;
2008-09-16 19:46:22 +12:00
strcpy(height_pattern, "");
2013-01-01 02:41:59 +13:00
2009-03-15 00:04:52 +13:00
error_number = 0;
if(length > 50) {
2009-03-15 00:04:52 +13:00
strcpy(symbol->errtxt, "Input too long");
2008-09-16 19:46:22 +12:00
return ERROR_TOO_LONG;
}
2009-10-07 08:03:00 +13:00
to_upper((unsigned char*)source);
error_number = is_sane(DAFTSET, (unsigned char*)source, length);
2009-03-15 00:04:52 +13:00
if(error_number == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "Invalid characters in data");
return error_number;
}
2013-01-01 02:41:59 +13:00
for (i = 0; i < length; i++) {
2009-10-07 08:03:00 +13:00
if(source[i] == 'D') { concat(height_pattern, "2"); }
if(source[i] == 'A') { concat(height_pattern, "1"); }
if(source[i] == 'F') { concat(height_pattern, "0"); }
if(source[i] == 'T') { concat(height_pattern, "3"); }
2008-09-16 19:46:22 +12:00
}
2013-01-01 02:41:59 +13:00
2008-09-16 19:46:22 +12:00
writer = 0;
2009-10-07 08:03:00 +13:00
h = strlen(height_pattern);
for(loopey = 0; loopey < h; loopey++)
2008-09-16 19:46:22 +12:00
{
if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0'))
{
set_module(symbol, 0, writer);
2008-09-16 19:46:22 +12:00
}
set_module(symbol, 1, writer);
2008-09-16 19:46:22 +12:00
if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0'))
{
set_module(symbol, 2, writer);
2008-09-16 19:46:22 +12:00
}
writer += 2;
}
2013-01-01 02:41:59 +13:00
symbol->row_height[0] = 3;
2008-09-16 19:46:22 +12:00
symbol->row_height[1] = 2;
symbol->row_height[2] = 3;
2008-09-16 19:46:22 +12:00
symbol->rows = 3;
symbol->width = writer - 1;
2013-01-01 02:41:59 +13:00
2009-03-15 00:04:52 +13:00
return error_number;
2008-09-03 07:47:26 +12:00
}
int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length)
2008-07-14 09:15:55 +12:00
{ /* Flattermarken - Not really a barcode symbology and (in my opinion) probably not much use
but it's supported by TBarCode so it's supported by Zint! */
2008-09-16 19:46:22 +12:00
int loop, error_number;
2009-10-07 08:03:00 +13:00
char dest[512]; /* 90 * 4 + 1 ~ */
2013-01-01 02:41:59 +13:00
2008-09-16 19:46:22 +12:00
error_number = 0;
2013-01-01 02:41:59 +13:00
if(length > 90) {
strcpy(symbol->errtxt, "Input too long");
2008-07-14 09:15:55 +12:00
return ERROR_TOO_LONG;
}
2009-10-07 08:03:00 +13:00
error_number = is_sane(NEON, source, length);
2008-09-16 19:46:22 +12:00
if(error_number == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "Invalid characters in data");
2008-09-16 19:46:22 +12:00
return error_number;
2008-07-14 09:15:55 +12:00
}
2009-10-07 08:03:00 +13:00
*dest = '\0';
for(loop = 0; loop < length; loop++) {
2009-10-07 08:03:00 +13:00
lookup(NEON, FlatTable, source[loop], dest);
2008-07-14 09:15:55 +12:00
}
2009-02-20 08:09:57 +13:00
expand(symbol, dest);
2008-09-16 19:46:22 +12:00
return error_number;
2008-07-14 09:15:55 +12:00
}
2009-03-15 00:04:52 +13:00
int japan_post(struct zint_symbol *symbol, unsigned char source[], int length)
2009-03-15 00:04:52 +13:00
{ /* Japanese Postal Code (Kasutama Barcode) */
2009-10-07 08:03:00 +13:00
int error_number, h;
2009-06-12 08:37:47 +12:00
char pattern[69];
int writer, loopey, inter_posn, i, sum, check;
2009-03-15 00:04:52 +13:00
char check_char;
2009-06-12 08:37:47 +12:00
char inter[23];
#ifndef _MSC_VER
char local_source[length + 1];
#else
2009-10-07 08:03:00 +13:00
char* local_source = (char*)_alloca(length + 1);
#endif
2009-03-15 00:04:52 +13:00
inter_posn = 0;
error_number = 0;
2009-05-17 21:27:43 +12:00
2009-03-15 00:04:52 +13:00
strcpy(local_source, (char*)source);
for(i = 0; i < length; i++) {
local_source[i] = source[i];
}
2009-03-15 00:04:52 +13:00
to_upper((unsigned char*)local_source);
error_number = is_sane(SHKASUTSET, (unsigned char*)local_source, length);
2009-05-17 21:27:43 +12:00
2009-03-15 00:04:52 +13:00
if(error_number == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "Invalid characters in data");
return error_number;
}
2009-10-07 08:03:00 +13:00
memset(inter, 'd', 20);/* Pad character CC4 */
2009-06-12 08:37:47 +12:00
inter[20] = '\0';
2009-03-15 00:04:52 +13:00
2009-06-12 08:37:47 +12:00
i = 0;
inter_posn = 0;
do {
2009-03-15 00:04:52 +13:00
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;
}
}
2009-06-12 08:37:47 +12:00
i++;
}while((i < length) && (inter_posn < 20));
2009-06-12 08:37:47 +12:00
inter[20] = '\0';
2009-05-17 21:27:43 +12:00
2009-03-15 00:04:52 +13:00
strcpy(pattern, "13"); /* Start */
2013-01-01 02:41:59 +13:00
2009-03-15 00:04:52 +13:00
sum = 0;
for(i = 0; i < 20; i++) {
concat(pattern, JapanTable[posn(KASUTSET, inter[i])]);
sum += posn(CHKASUTSET, inter[i]);
/* printf("%c (%d)\n", inter[i], posn(CHKASUTSET, inter[i])); */
}
2009-05-17 21:27:43 +12:00
2009-03-15 00:04:52 +13:00
/* Calculate check digit */
check = 19 - (sum % 19);
if(check == 19) { check = 0; }
if(check <= 9) { check_char = check + '0'; }
if(check == 10) { check_char = '-'; }
if(check >= 11) { check_char = (check - 11) + 'a'; }
concat(pattern, JapanTable[posn(KASUTSET, check_char)]);
/* printf("check %c (%d)\n", check_char, check); */
2013-01-01 02:41:59 +13:00
2009-03-15 00:04:52 +13:00
concat(pattern, "31"); /* Stop */
2013-01-01 02:41:59 +13:00
2009-03-15 00:04:52 +13:00
/* Resolve pattern to 4-state symbols */
writer = 0;
2009-10-07 08:03:00 +13:00
h = strlen(pattern);
for(loopey = 0; loopey < h; loopey++)
2009-03-15 00:04:52 +13:00
{
if((pattern[loopey] == '2') || (pattern[loopey] == '1'))
{
set_module(symbol, 0, writer);
2009-03-15 00:04:52 +13:00
}
set_module(symbol, 1, writer);
2009-03-15 00:04:52 +13:00
if((pattern[loopey] == '3') || (pattern[loopey] == '1'))
{
set_module(symbol, 2, writer);
2009-03-15 00:04:52 +13:00
}
writer += 2;
}
2013-01-01 02:41:59 +13:00
symbol->row_height[0] = 3;
2009-03-15 00:04:52 +13:00
symbol->row_height[1] = 2;
symbol->row_height[2] = 3;
2009-03-15 00:04:52 +13:00
symbol->rows = 3;
symbol->width = writer - 1;
2013-01-01 02:41:59 +13:00
2009-03-15 00:04:52 +13:00
return error_number;
}