Add ECI encoding

This commit is contained in:
Robin Stuart 2016-08-16 12:43:41 +01:00
parent fc657d5fe8
commit 9d1c20201d
17 changed files with 994 additions and 317 deletions

View File

@ -4,7 +4,7 @@ project(zint)
find_package(PNG) find_package(PNG)
set(zint_COMMON_SRCS common.c library.c render.c large.c reedsol.c gs1.c) set(zint_COMMON_SRCS common.c library.c render.c large.c reedsol.c gs1.c eci.c)
set(zint_ONEDIM_SRCS code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c) set(zint_ONEDIM_SRCS code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c)
set(zint_POSTAL_SRCS postal.c auspost.c imail.c) set(zint_POSTAL_SRCS postal.c auspost.c imail.c)
set(zint_TWODIM_SRCS code16k.c dmatrix.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c hanxin.c dotcode.c) set(zint_TWODIM_SRCS code16k.c dmatrix.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c hanxin.c dotcode.c)

View File

@ -64,7 +64,7 @@ void insert(char binary_string[], int posn, char newbit) {
/** /**
* Encode input data into a binary string * Encode input data into a binary string
*/ */
int aztec_text_process(unsigned char source[], const unsigned int src_len, char binary_string[], int gs1) { int aztec_text_process(unsigned char source[], const unsigned int src_len, char binary_string[], int gs1, int eci) {
int i, j, k, p, bytes; int i, j, k, p, bytes;
int curtable, newtable, lasttable, chartype, maplength, blocks, debug; int curtable, newtable, lasttable, chartype, maplength, blocks, debug;
#ifndef _MSC_VER #ifndef _MSC_VER
@ -81,14 +81,33 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
maplength = 0; maplength = 0;
debug = 0; debug = 0;
for (i = 0; i < (int) src_len; i++) { if (gs1) {
if (gs1 && (i == 0)) { /* Add FNC1 to beginning of GS1 messages */
/* Add FNC1 to beginning of GS1 messages */ charmap[maplength] = 0;
charmap[maplength] = 0; typemap[maplength++] = PUNC;
charmap[maplength] = 400;
typemap[maplength++] = PUNC;
} else if (eci != 3) {
/* Set ECI mode */
charmap[maplength] = 0;
typemap[maplength++] = PUNC;
if (eci < 10) {
charmap[maplength] = 401; // FLG(1)
typemap[maplength++] = PUNC; typemap[maplength++] = PUNC;
charmap[maplength] = 400; charmap[maplength] = 502 + eci;
typemap[maplength++] = PUNC;
} else {
charmap[maplength] = 402; // FLG(2)
typemap[maplength++] = PUNC;
charmap[maplength] = 502 + (eci / 10);
typemap[maplength++] = PUNC;
charmap[maplength] = 502 + (eci % 10);
typemap[maplength++] = PUNC; typemap[maplength++] = PUNC;
} }
}
for (i = 0; i < (int) src_len; i++) {
if ((gs1) && (source[i] == '[')) { if ((gs1) && (source[i] == '[')) {
/* FNC1 represented by FLG(0) */ /* FNC1 represented by FLG(0) */
charmap[maplength] = 0; charmap[maplength] = 0;
@ -311,21 +330,21 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case (64 + UPPER): /* To UPPER */ case (64 + UPPER): /* To UPPER */
switch (curtable) { switch (curtable) {
case LOWER: /* US */ case LOWER: /* US */
strcat(binary_string, hexbit[28]); strcat(binary_string, pentbit[28]);
if (debug) printf("US "); if (debug) printf("US ");
break; break;
case MIXED: /* UL */ case MIXED: /* UL */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("UL "); if (debug) printf("UL ");
newtable = UPPER; newtable = UPPER;
break; break;
case PUNC: /* UL */ case PUNC: /* UL */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("UL "); if (debug) printf("UL ");
newtable = UPPER; newtable = UPPER;
break; break;
case DIGIT: /* US */ case DIGIT: /* US */
strcat(binary_string, pentbit[15]); strcat(binary_string, quadbit[15]);
if (debug) printf("US "); if (debug) printf("US ");
break; break;
} }
@ -333,26 +352,26 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case (64 + LOWER): /* To LOWER */ case (64 + LOWER): /* To LOWER */
switch (curtable) { switch (curtable) {
case UPPER: /* LL */ case UPPER: /* LL */
strcat(binary_string, hexbit[28]); strcat(binary_string, pentbit[28]);
if (debug) printf("LL "); if (debug) printf("LL ");
newtable = LOWER; newtable = LOWER;
break; break;
case MIXED: /* LL */ case MIXED: /* LL */
strcat(binary_string, hexbit[28]); strcat(binary_string, pentbit[28]);
if (debug) printf("LL "); if (debug) printf("LL ");
newtable = LOWER; newtable = LOWER;
break; break;
case PUNC: /* UL LL */ case PUNC: /* UL LL */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[28]); strcat(binary_string, pentbit[28]);
if (debug) printf("LL "); if (debug) printf("LL ");
newtable = LOWER; newtable = LOWER;
break; break;
case DIGIT: /* UL LL */ case DIGIT: /* UL LL */
strcat(binary_string, pentbit[14]); strcat(binary_string, quadbit[14]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[28]); strcat(binary_string, pentbit[28]);
if (debug) printf("LL "); if (debug) printf("LL ");
newtable = LOWER; newtable = LOWER;
break; break;
@ -361,26 +380,26 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case (64 + MIXED): /* To MIXED */ case (64 + MIXED): /* To MIXED */
switch (curtable) { switch (curtable) {
case UPPER: /* ML */ case UPPER: /* ML */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
newtable = MIXED; newtable = MIXED;
break; break;
case LOWER: /* ML */ case LOWER: /* ML */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
newtable = MIXED; newtable = MIXED;
break; break;
case PUNC: /* UL ML */ case PUNC: /* UL ML */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
newtable = MIXED; newtable = MIXED;
break; break;
case DIGIT: /* UL ML */ case DIGIT: /* UL ML */
strcat(binary_string, pentbit[14]); strcat(binary_string, quadbit[14]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
newtable = MIXED; newtable = MIXED;
break; break;
@ -389,19 +408,19 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case (64 + PUNC): /* To PUNC */ case (64 + PUNC): /* To PUNC */
switch (curtable) { switch (curtable) {
case UPPER: /* PS */ case UPPER: /* PS */
strcat(binary_string, hexbit[0]); strcat(binary_string, pentbit[0]);
if (debug) printf("PS "); if (debug) printf("PS ");
break; break;
case LOWER: /* PS */ case LOWER: /* PS */
strcat(binary_string, hexbit[0]); strcat(binary_string, pentbit[0]);
if (debug) printf("PS "); if (debug) printf("PS ");
break; break;
case MIXED: /* PS */ case MIXED: /* PS */
strcat(binary_string, hexbit[0]); strcat(binary_string, pentbit[0]);
if (debug) printf("PS "); if (debug) printf("PS ");
break; break;
case DIGIT: /* PS */ case DIGIT: /* PS */
strcat(binary_string, pentbit[0]); strcat(binary_string, quadbit[0]);
if (debug) printf("PS "); if (debug) printf("PS ");
break; break;
} }
@ -409,26 +428,26 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case (64 + DIGIT): /* To DIGIT */ case (64 + DIGIT): /* To DIGIT */
switch (curtable) { switch (curtable) {
case UPPER: /* DL */ case UPPER: /* DL */
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("DL "); if (debug) printf("DL ");
newtable = DIGIT; newtable = DIGIT;
break; break;
case LOWER: /* DL */ case LOWER: /* DL */
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("DL "); if (debug) printf("DL ");
newtable = DIGIT; newtable = DIGIT;
break; break;
case MIXED: /* UL DL */ case MIXED: /* UL DL */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("DL "); if (debug) printf("DL ");
newtable = DIGIT; newtable = DIGIT;
break; break;
case PUNC: /* UL DL */ case PUNC: /* UL DL */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("DL "); if (debug) printf("DL ");
newtable = DIGIT; newtable = DIGIT;
break; break;
@ -441,24 +460,24 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case UPPER: /* To UPPER */ case UPPER: /* To UPPER */
switch (curtable) { switch (curtable) {
case LOWER: /* ML UL */ case LOWER: /* ML UL */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("UL "); if (debug) printf("UL ");
newtable = UPPER; newtable = UPPER;
break; break;
case MIXED: /* UL */ case MIXED: /* UL */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("UL "); if (debug) printf("UL ");
newtable = UPPER; newtable = UPPER;
break; break;
case PUNC: /* UL */ case PUNC: /* UL */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("UL "); if (debug) printf("UL ");
newtable = UPPER; newtable = UPPER;
break; break;
case DIGIT: /* UL */ case DIGIT: /* UL */
strcat(binary_string, pentbit[14]); strcat(binary_string, quadbit[14]);
if (debug) printf("UL "); if (debug) printf("UL ");
newtable = UPPER; newtable = UPPER;
break; break;
@ -467,26 +486,26 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case LOWER: /* To LOWER */ case LOWER: /* To LOWER */
switch (curtable) { switch (curtable) {
case UPPER: /* LL */ case UPPER: /* LL */
strcat(binary_string, hexbit[28]); strcat(binary_string, pentbit[28]);
if (debug) printf("LL "); if (debug) printf("LL ");
newtable = LOWER; newtable = LOWER;
break; break;
case MIXED: /* LL */ case MIXED: /* LL */
strcat(binary_string, hexbit[28]); strcat(binary_string, pentbit[28]);
if (debug) printf("LL "); if (debug) printf("LL ");
newtable = LOWER; newtable = LOWER;
break; break;
case PUNC: /* UL LL */ case PUNC: /* UL LL */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[28]); strcat(binary_string, pentbit[28]);
if (debug) printf("LL "); if (debug) printf("LL ");
newtable = LOWER; newtable = LOWER;
break; break;
case DIGIT: /* UL LL */ case DIGIT: /* UL LL */
strcat(binary_string, pentbit[14]); strcat(binary_string, quadbit[14]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[28]); strcat(binary_string, pentbit[28]);
if (debug) printf("LL "); if (debug) printf("LL ");
newtable = LOWER; newtable = LOWER;
break; break;
@ -495,26 +514,26 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case MIXED: /* To MIXED */ case MIXED: /* To MIXED */
switch (curtable) { switch (curtable) {
case UPPER: /* ML */ case UPPER: /* ML */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
newtable = MIXED; newtable = MIXED;
break; break;
case LOWER: /* ML */ case LOWER: /* ML */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
newtable = MIXED; newtable = MIXED;
break; break;
case PUNC: /* UL ML */ case PUNC: /* UL ML */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
newtable = MIXED; newtable = MIXED;
break; break;
case DIGIT: /* UL ML */ case DIGIT: /* UL ML */
strcat(binary_string, pentbit[14]); strcat(binary_string, quadbit[14]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
newtable = MIXED; newtable = MIXED;
break; break;
@ -523,30 +542,30 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case PUNC: /* To PUNC */ case PUNC: /* To PUNC */
switch (curtable) { switch (curtable) {
case UPPER: /* ML PL */ case UPPER: /* ML PL */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("PL "); if (debug) printf("PL ");
newtable = PUNC; newtable = PUNC;
break; break;
case LOWER: /* ML PL */ case LOWER: /* ML PL */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("PL "); if (debug) printf("PL ");
newtable = PUNC; newtable = PUNC;
break; break;
case MIXED: /* PL */ case MIXED: /* PL */
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("PL "); if (debug) printf("PL ");
newtable = PUNC; newtable = PUNC;
break; break;
case DIGIT: /* UL ML PL */ case DIGIT: /* UL ML PL */
strcat(binary_string, pentbit[14]); strcat(binary_string, quadbit[14]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("ML "); if (debug) printf("ML ");
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("PL "); if (debug) printf("PL ");
newtable = PUNC; newtable = PUNC;
break; break;
@ -555,26 +574,26 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case DIGIT: /* To DIGIT */ case DIGIT: /* To DIGIT */
switch (curtable) { switch (curtable) {
case UPPER: /* DL */ case UPPER: /* DL */
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("DL "); if (debug) printf("DL ");
newtable = DIGIT; newtable = DIGIT;
break; break;
case LOWER: /* DL */ case LOWER: /* DL */
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("DL "); if (debug) printf("DL ");
newtable = DIGIT; newtable = DIGIT;
break; break;
case MIXED: /* UL DL */ case MIXED: /* UL DL */
strcat(binary_string, hexbit[29]); strcat(binary_string, pentbit[29]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("DL "); if (debug) printf("DL ");
newtable = DIGIT; newtable = DIGIT;
break; break;
case PUNC: /* UL DL */ case PUNC: /* UL DL */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[30]); strcat(binary_string, pentbit[30]);
if (debug) printf("DL "); if (debug) printf("DL ");
newtable = DIGIT; newtable = DIGIT;
break; break;
@ -584,32 +603,32 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
lasttable = curtable; lasttable = curtable;
switch (curtable) { switch (curtable) {
case UPPER: /* BS */ case UPPER: /* BS */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("BS "); if (debug) printf("BS ");
newtable = BINARY; newtable = BINARY;
break; break;
case LOWER: /* BS */ case LOWER: /* BS */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("BS "); if (debug) printf("BS ");
newtable = BINARY; newtable = BINARY;
break; break;
case MIXED: /* BS */ case MIXED: /* BS */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("BS "); if (debug) printf("BS ");
newtable = BINARY; newtable = BINARY;
break; break;
case PUNC: /* UL BS */ case PUNC: /* UL BS */
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("BS "); if (debug) printf("BS ");
lasttable = UPPER; lasttable = UPPER;
newtable = BINARY; newtable = BINARY;
break; break;
case DIGIT: /* UL BS */ case DIGIT: /* UL BS */
strcat(binary_string, pentbit[14]); strcat(binary_string, quadbit[14]);
if (debug) printf("UL "); if (debug) printf("UL ");
strcat(binary_string, hexbit[31]); strcat(binary_string, pentbit[31]);
if (debug) printf("BS "); if (debug) printf("BS ");
lasttable = UPPER; lasttable = UPPER;
newtable = BINARY; newtable = BINARY;
@ -664,17 +683,20 @@ int aztec_text_process(unsigned char source[], const unsigned int src_len, char
case LOWER: case LOWER:
case MIXED: case MIXED:
case PUNC: case PUNC:
if (charmap[i] >= 400) { if ((charmap[i] >= 400) && (charmap[i] < 500)) {
strcat(binary_string, tribit[charmap[i] - 400]); strcat(binary_string, tribit[charmap[i] - 400]);
if (debug) printf("FLG(%d) ", charmap[i] - 400); if (debug) printf("FLG(%d) ", charmap[i] - 400);
} else if (charmap[i] >= 500) {
strcat(binary_string, quadbit[charmap[i] - 500]);
if (debug) printf("[%d] ", charmap[i] - 500);
} else { } else {
strcat(binary_string, hexbit[charmap[i]]); strcat(binary_string, pentbit[charmap[i]]);
if (!((chartype == PUNC) && (charmap[i] == 0))) if (!((chartype == PUNC) && (charmap[i] == 0)))
if (debug) printf("%d ", charmap[i]); if (debug) printf("%d ", charmap[i]);
} }
break; break;
case DIGIT: case DIGIT:
strcat(binary_string, pentbit[charmap[i]]); strcat(binary_string, quadbit[charmap[i]]);
if (debug) printf("%d ", charmap[i]); if (debug) printf("%d ", charmap[i]);
break; break;
case BINARY: case BINARY:
@ -865,10 +887,7 @@ int aztec(struct zint_symbol *symbol, unsigned char source[], int length) {
int debug = 0, reader = 0; int debug = 0, reader = 0;
int comp_loop = 4; int comp_loop = 4;
#ifndef _MSC_VER #ifdef _MSC_VER
unsigned char local_source[length + 1];
#else
unsigned char* local_source = (unsigned char*) _alloca(length + 1);
unsigned int* data_part; unsigned int* data_part;
unsigned int* ecc_part; unsigned int* ecc_part;
#endif #endif
@ -885,29 +904,14 @@ int aztec(struct zint_symbol *symbol, unsigned char source[], int length) {
reader = 1; reader = 1;
comp_loop = 1; comp_loop = 1;
} }
if ((gs1 == 1) && (reader == 1)) { if (gs1 && reader) {
strcpy(symbol->errtxt, "Cannot encode in GS1 and Reader Initialisation mode at the same time"); strcpy(symbol->errtxt, "Cannot encode in GS1 and Reader Initialisation mode at the same time");
return ZINT_ERROR_INVALID_OPTION; return ZINT_ERROR_INVALID_OPTION;
} }
switch (symbol->input_mode) {
case DATA_MODE:
case GS1_MODE:
memcpy(local_source, source, length);
local_source[length] = '\0';
break;
case UNICODE_MODE:
err_code = latin1_process(symbol, source, local_source, &length);
if (err_code != 0) {
return err_code;
}
break;
}
populate_map(); populate_map();
err_code = aztec_text_process(local_source, length, binary_string, gs1); err_code = aztec_text_process(source, length, binary_string, gs1, symbol->eci);
if (err_code != 0) { if (err_code != 0) {
strcpy(symbol->errtxt, "Input too long or too many extended ASCII characters"); strcpy(symbol->errtxt, "Input too long or too many extended ASCII characters");

View File

@ -98,13 +98,13 @@ const int AztecSymbolChar[128] = {
302: Full Stop (ASCII 46) 302: Full Stop (ASCII 46)
*/ */
static const char *hexbit[32] = { static const char *pentbit[32] = {
"00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001",
"01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101", "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101",
"10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111" "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111"
}; };
static const char *pentbit[16] = { static const char *quadbit[16] = {
"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001",
"1010", "1011", "1100", "1101", "1110", "1111" "1010", "1011", "1100", "1101", "1110", "1111"
}; };

View File

@ -238,42 +238,6 @@ int istwodigits(const unsigned char source[], const int position) {
return 0; return 0;
} }
/* Convert Unicode to Latin-1 for those symbologies which only support Latin-1 */
int latin1_process(struct zint_symbol *symbol, const unsigned char source[], unsigned char preprocessed[], int *length) {
int j, i, next;
j = 0;
i = 0;
do {
next = -1;
if (source[i] < 128) {
preprocessed[j] = source[i];
j++;
next = i + 1;
} else {
if (source[i] == 0xC2) {
preprocessed[j] = source[i + 1];
j++;
next = i + 2;
}
if (source[i] == 0xC3) {
preprocessed[j] = source[i + 1] + 64;
j++;
next = i + 2;
}
}
if (next == -1) {
strcpy(symbol->errtxt, "error: Invalid character in input string (only Latin-1 characters supported)");
return ZINT_ERROR_INVALID_DATA;
}
i = next;
} while (i < *length);
preprocessed[j] = '\0';
*length = j;
return 0;
}
int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], int *length) { int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], int *length) {
int bpos, jpos, error_number; int bpos, jpos, error_number;
int next; int next;

View File

@ -69,7 +69,6 @@ extern "C" {
extern int istwodigits(const unsigned char source[], const int position); extern int istwodigits(const unsigned char source[], const int position);
extern double froundup(const double input); extern double froundup(const double input);
extern int parunmodd(const unsigned char llyth); extern int parunmodd(const unsigned char llyth);
extern int latin1_process(struct zint_symbol *symbol, const unsigned char source[], unsigned char preprocessed[], int *length);
extern int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], int *length); extern int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], int *length);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -568,6 +568,14 @@ static int dm200encode(struct zint_symbol *symbol, const unsigned char source[],
if (debug) printf("RP "); if (debug) printf("RP ");
} }
} }
if (symbol->eci > 3) {
target[tp] = 241; /* ECI Character */
tp++;
target[tp] = symbol->eci + 1;
tp++;
if (debug) printf("ECI %d ", symbol->eci + 1);
}
/* Check for Macro05/Macro06 */ /* Check for Macro05/Macro06 */
/* "[)>[RS]05[GS]...[RS][EOT]" -> CW 236 */ /* "[)>[RS]05[GS]...[RS][EOT]" -> CW 236 */

View File

@ -388,6 +388,13 @@ int dotcode_encode_message(struct zint_symbol *symbol, unsigned char source[], i
codeword_array[array_length] = 107; // FNC1 codeword_array[array_length] = 107; // FNC1
array_length++; array_length++;
} }
if (symbol->eci > 3) {
codeword_array[array_length] = 108; // FNC2
array_length++;
codeword_array[array_length] = symbol->eci;
array_length++;
}
do { do {
done = 0; done = 0;

305
backend/eci.c Normal file
View File

@ -0,0 +1,305 @@
/* eci.c - Extended Channel Interpretations
libzint - the open source barcode library
Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
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
without specific prior written permission.
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
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#include <string.h>
#include <stdio.h>
#include "eci.h"
#include "zint.h"
/* Convert Unicode to other character encodings */
int utf_to_eci(int eci, const unsigned char source[], unsigned char dest[], int *length) {
int glyph;
int bytelen;
int in_posn;
int out_posn;
int ext;
int done;
if (eci == 26) {
/* Unicode mode, do not process - just copy data across */
for (in_posn = 0; in_posn < *length; in_posn++) {
dest[in_posn] = source[in_posn];
}
dest[*length] = '\0';
return 0;
}
in_posn = 0;
out_posn = 0;
do {
/* Single byte (ASCII) character */
bytelen = 1;
glyph = (int)source[in_posn];
if ((source[in_posn] >= 0x80) && (source[in_posn] < 0xc0)) {
/* Something has gone wrong, abort */
return ZINT_ERROR_INVALID_DATA;
}
if ((source[in_posn] >= 0xc0) && (source[in_posn] < 0xe0)) {
/* Two-byte character */
bytelen = 2;
glyph = (source[in_posn] & 0x1f) << 6;
if (*length < (in_posn + 2)) {
return ZINT_ERROR_INVALID_DATA;
}
if (source[in_posn + 1] > 0xc0) {
return ZINT_ERROR_INVALID_DATA;
}
glyph += (source[in_posn + 1] & 0x3f);
}
if ((source[in_posn] >= 0xe0) && (source[in_posn] < 0xf0)) {
/* Three-byte character */
bytelen = 3;
glyph = (source[in_posn] & 0x0f) << 12;
if (*length < (in_posn + 2)) {
return ZINT_ERROR_INVALID_DATA;
}
if (*length < (in_posn + 3)) {
return ZINT_ERROR_INVALID_DATA;
}
if (source[in_posn + 1] > 0xc0) {
return ZINT_ERROR_INVALID_DATA;
}
if (source[in_posn + 2] > 0xc0) {
return ZINT_ERROR_INVALID_DATA;
}
glyph += (source[in_posn + 1] & 0x3f) << 6;
glyph += (source[in_posn + 2] & 0x3f);
}
if ((source[in_posn] >= 0xf0) && (source[in_posn] < 0xf7)) {
/* Four-byte character */
bytelen = 4;
glyph = (source[in_posn] & 0x07) << 18;
if (*length < (in_posn + 2)) {
return ZINT_ERROR_INVALID_DATA;
}
if (*length < (in_posn + 3)) {
return ZINT_ERROR_INVALID_DATA;
}
if (*length < (in_posn + 4)) {
return ZINT_ERROR_INVALID_DATA;
}
if (source[in_posn + 1] > 0xc0) {
return ZINT_ERROR_INVALID_DATA;
}
if (source[in_posn + 2] > 0xc0) {
return ZINT_ERROR_INVALID_DATA;
}
if (source[in_posn + 3] > 0xc0) {
return ZINT_ERROR_INVALID_DATA;
}
glyph += (source[in_posn + 1] & 0x3f) << 12;
glyph += (source[in_posn + 2] & 0x3f) << 6;
glyph += (source[in_posn + 3] & 0x3f);
}
if (source[in_posn] >= 0xf7) {
/* More than 4 bytes not supported */
return ZINT_ERROR_INVALID_DATA;
}
if (glyph < 128) {
dest[out_posn] = glyph;
} else {
done = 0;
for (ext = 0; ext < 128; ext++) {
switch (eci) {
case 3: // Latin-1
if (glyph == iso_8859_1[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 4: // Latin-2
if (glyph == iso_8859_2[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 5: // Latin-3
if (glyph == iso_8859_3[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 6: // Latin-4
if (glyph == iso_8859_4[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 7: // Latin/Cyrillic
if (glyph == iso_8859_5[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 8: // Latin/Arabic
if (glyph == iso_8859_6[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 9: // Latin/Greek
if (glyph == iso_8859_7[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 10: // Latin/Hebrew
if (glyph == iso_8859_8[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 11: // Latin-5
if (glyph == iso_8859_9[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 12: // Latin-6
if (glyph == iso_8859_10[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 13: // Latin/Thai
if (glyph == iso_8859_11[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 15: // Latin-7
if (glyph == iso_8859_13[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 16: // Latin-8
if (glyph == iso_8859_14[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 17: // Latin-9
if (glyph == iso_8859_15[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 18: // Latin-10
if (glyph == iso_8859_16[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 21: // Windows-1250
if (glyph == windows_1250[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 22: // Windows-1251
if (glyph == windows_1251[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 23: // Windows-1252
if (glyph == windows_1252[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
case 24: // Windows-1256
if (glyph == windows_1256[ext]) {
dest[out_posn] = ext + 128;
done = 1;
}
break;
default:
break;
}
}
if (!(done)) {
return ZINT_ERROR_INVALID_DATA;
}
}
in_posn += bytelen;
out_posn++;
} while (in_posn < *length);
dest[out_posn] = '\0';
*length = out_posn;
return 0;
}
/* Find the lowest ECI mode which will encode a given set of Unicode text */
int get_best_eci(unsigned char source[], int length) {
int eci = 3;
#ifndef _MSC_VER
unsigned char local_source[length + 1];
#else
local_source = (unsigned char*) _alloca(length + 1);
#endif
do {
if (utf_to_eci(eci, source, local_source, &length) == 0) {
return eci;
}
eci++;
} while (eci < 25);
return 26; // If all of these fail, use Unicode!
}

252
backend/eci.h Normal file
View File

@ -0,0 +1,252 @@
/* eci.c - Extended Channel Interpretations to Unicode tables
libzint - the open source barcode library
Copyright (C) 2009-2016 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
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
without specific prior written permission.
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
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#ifndef ECI_H
#define ECI_H
#ifdef __cplusplus
extern "C" {
#endif
static int iso_8859_1[] = { // Latin alphabet No. 1
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
};
static int iso_8859_2[] = { // Latin alphabet No. 2
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,
0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9
};
static int iso_8859_3[] = { // Latin alphabet No. 3
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0x0000, 0x0124, 0x00a7, 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0x0000, 0x017b,
0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0x0000, 0x017c,
0x00c0, 0x00c1, 0x00c2, 0x0000, 0x00c4, 0x010a, 0x0108, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x0000, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x0000, 0x00e4, 0x010b, 0x0109, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x0000, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9
};
static int iso_8859_4[] = { // Latin alphabet No. 4
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x012b, 0x013b, 0x00a7, 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af,
0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b,
0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a,
0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df,
0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b,
0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9
};
static int iso_8859_5[] = { // Latin/Cyrillic alphabet
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f,
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f
};
static int iso_8859_6[] = { // Latin/Arabic alphabet
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x0000, 0x0000, 0x0000, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x060c, 0x00ad, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f,
0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f,
0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
static int iso_8859_7[] = { // Latin/Greek alphabet
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x2018, 0x2019, 0x00a3, 0x20ac, 0x20af, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x037a, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7, 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f,
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000
};
static int iso_8859_8[] = { // Latin/Hebrew alphabet
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017,
0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000
};
static int iso_8859_9[] = { // Latin alphabet No. 5
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff
};
static int iso_8859_10[] = { // Latin alphabet No. 6
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x012b, 0x0136, 0x00a7, 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a,
0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b,
0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf,
0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef,
0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138
};
static int iso_8859_11[] = { // Latin/Thai alphabet
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,
0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,
0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e36, 0x0e36, 0x0e37, 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f,
0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,
0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000
};
static int iso_8859_13[] = { // Latin alphabet No. 7
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7, 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7, 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6,
0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b,
0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df,
0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c,
0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019
};
static int iso_8859_14[] = { // Latin alphabet No. 8 (Celtic)
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178,
0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff
};
static int iso_8859_15[] = { // Latin alphabet No. 9
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
};
static int iso_8859_16[] = { // Latin alphabet No. 10
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b,
0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7, 0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c,
0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b, 0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff
};
static int windows_1250[] = {
0x20ac, 0x0000, 0x201a, 0x0000, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179,
0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a,
0x00a0, 0x02c7, 0x02db, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b,
0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c,
0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9
};
static int windows_1251[] = {
0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f,
0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f,
0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407,
0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457,
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f
};
static int windows_1252[] = {
0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000,
0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178,
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
};
static int windows_1256[] = {
0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba,
0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f,
0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643,
0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef,
0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2
};
#ifdef __cplusplus
}
#endif
#endif /* ECI_H */

View File

@ -348,7 +348,7 @@ void add_shift_char(char binary[], int shifty) {
} }
} }
int gm_encode(int gbdata[], int length, char binary[], int reader) { int gm_encode(int gbdata[], int length, char binary[], int reader, int eci) {
/* Create a binary stream representation of the input data. /* Create a binary stream representation of the input data.
7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters, 7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters,
Mixed numerals and latters, Control characters and 8-bit binary data */ Mixed numerals and latters, Control characters and 8-bit binary data */
@ -370,6 +370,17 @@ int gm_encode(int gbdata[], int length, char binary[], int reader) {
if (reader) { if (reader) {
strcat(binary, "1010"); /* FNC3 - Reader Initialisation */ strcat(binary, "1010"); /* FNC3 - Reader Initialisation */
} }
if (eci != 3) {
strcat(binary, "11000"); /* ECI */
for (q = 0; q < 10; q++) {
if (eci & (0x100 >> q)) {
strcat(binary, "1");
} else {
strcat(binary, "0");
}
}
}
do { do {
next_mode = seek_forward(gbdata, length, sp, current_mode); next_mode = seek_forward(gbdata, length, sp, current_mode);
@ -1053,44 +1064,41 @@ int grid_matrix(struct zint_symbol *symbol, const unsigned char source[], int le
word[i] = 0; word[i] = 0;
} }
switch (symbol->input_mode) { if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 3)) {
case DATA_MODE: for (i = 0; i < length; i++) {
for (i = 0; i < length; i++) { gbdata[i] = (int) source[i];
gbdata[i] = (int) source[i]; }
} } else {
break; /* Convert Unicode input to GB-2312 */
default: error_number = utf8toutf16(symbol, source, utfdata, &length);
/* Convert Unicode input to GB-2312 */ if (error_number != 0) {
error_number = utf8toutf16(symbol, source, utfdata, &length); return error_number;
if (error_number != 0) { }
return error_number;
}
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if (utfdata[i] <= 0xff) { if (utfdata[i] <= 0xff) {
gbdata[i] = utfdata[i]; gbdata[i] = utfdata[i];
} else { } else {
j = 0; j = 0;
glyph = 0; glyph = 0;
do { do {
if (gb2312_lookup[j * 2] == utfdata[i]) { if (gb2312_lookup[j * 2] == utfdata[i]) {
glyph = gb2312_lookup[(j * 2) + 1]; glyph = gb2312_lookup[(j * 2) + 1];
}
j++;
} while ((j < 7445) && (glyph == 0));
if (glyph == 0) {
strcpy(symbol->errtxt, "Invalid character in input data");
return ZINT_ERROR_INVALID_DATA;
} }
gbdata[i] = glyph; j++;
} while ((j < 7445) && (glyph == 0));
if (glyph == 0) {
strcpy(symbol->errtxt, "Invalid character in input data");
return ZINT_ERROR_INVALID_DATA;
} }
gbdata[i] = glyph;
} }
break; }
} }
if (symbol->output_options & READER_INIT) reader = 1; if (symbol->output_options & READER_INIT) reader = 1;
error_number = gm_encode(gbdata, length, binary, reader); error_number = gm_encode(gbdata, length, binary, reader, symbol->eci);
if (error_number != 0) { if (error_number != 0) {
strcpy(symbol->errtxt, "Input data too long"); strcpy(symbol->errtxt, "Input data too long");
return error_number; return error_number;

View File

@ -62,12 +62,16 @@ int getsubmode(char input) {
} }
/* Calculate the approximate length of the binary string */ /* Calculate the approximate length of the binary string */
int calculate_binlength(char mode[], int source[], int length) { int calculate_binlength(char mode[], int source[], int length, int eci) {
int i; int i;
char lastmode = 't'; char lastmode = 't';
int est_binlen = 0; int est_binlen = 0;
int submode = 1; int submode = 1;
if (eci != 3) {
est_binlen += 12;
}
i = 0; i = 0;
do { do {
switch (mode[i]) { switch (mode[i]) {
@ -323,7 +327,7 @@ int lookup_text2(char input) {
} }
/* Convert input data to binary stream */ /* Convert input data to binary stream */
void calculate_binary(char binary[], char mode[], int source[], int length) { void calculate_binary(char binary[], char mode[], int source[], int length, int eci) {
int block_length; int block_length;
int position = 0; int position = 0;
int i, p, count, encoding_value; int i, p, count, encoding_value;
@ -331,7 +335,18 @@ void calculate_binary(char binary[], char mode[], int source[], int length) {
int first_byte, second_byte; int first_byte, second_byte;
int third_byte, fourth_byte; int third_byte, fourth_byte;
int glyph; int glyph;
int submode; int submode;
if (eci != 3) {
strcat(binary, "1000"); // ECI
for (p = 0; p < 8; p++) {
if (eci & (0x80 >> p)) {
strcat(binary, "1");
} else {
strcat(binary, "0");
}
}
}
do { do {
block_length = 0; block_length = 0;
@ -1298,88 +1313,85 @@ int han_xin(struct zint_symbol *symbol, const unsigned char source[], int length
#ifndef _MSC_VER #ifndef _MSC_VER
int utfdata[length + 1]; int utfdata[length + 1];
int gbdata[(length + 1) * 2]; int gbdata[(length + 1) * 2];
char mode[length + 1]; char mode[length + 1];
#else #else
int* utfdata = (int *) _alloca((length + 1) * sizeof (int)); int* utfdata = (int *) _alloca((length + 1) * sizeof (int));
int* gbdata = (int *) _alloca(((length + 1) * 2) * sizeof (int)); int* gbdata = (int *) _alloca(((length + 1) * 2) * sizeof (int));
char* mode = (char *) _alloca((length + 1) * sizeof (char)); char* mode = (char *) _alloca((length + 1) * sizeof (char));
char* binary; char* binary;
unsigned char *datastream; unsigned char *datastream;
unsigned char *fullstream; unsigned char *fullstream;
unsigned char *picket_fence; unsigned char *picket_fence;
unsigned char *grid; unsigned char *grid;
#endif #endif
switch (symbol->input_mode) { if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 3)) {
case DATA_MODE: for (i = 0; i < length; i++) {
for (i = 0; i < length; i++) { gbdata[i] = (int) source[i];
gbdata[i] = (int) source[i]; }
} } else {
break; /* Convert Unicode input to GB-18030 */
default: error_number = utf8toutf16(symbol, source, utfdata, &length);
/* Convert Unicode input to GB-18030 */ if (error_number != 0) {
error_number = utf8toutf16(symbol, source, utfdata, &length); return error_number;
if (error_number != 0) { }
return error_number;
}
posn = 0; posn = 0;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if (utfdata[i] <= 0x7f) { if (utfdata[i] <= 0x7f) {
gbdata[posn] = utfdata[i]; gbdata[posn] = utfdata[i];
posn++; posn++;
} else { } else {
j = 0;
glyph = 0;
do {
if (gb18030_twobyte_lookup[j * 2] == utfdata[i]) {
glyph = gb18030_twobyte_lookup[(j * 2) + 1];
}
j++;
} while ((j < 23940) && (glyph == 0));
if (glyph == 0) {
j = 0; j = 0;
glyph = 0; glyph = 0;
glyph2 = 0;
do { do {
if (gb18030_twobyte_lookup[j * 2] == utfdata[i]) { if (gb18030_fourbyte_lookup[j * 3] == utfdata[i]) {
glyph = gb18030_twobyte_lookup[(j * 2) + 1]; glyph = gb18030_fourbyte_lookup[(j * 3) + 1];
glyph2 = gb18030_fourbyte_lookup[(j * 3) + 2];
} }
j++; j++;
} while ((j < 23940) && (glyph == 0)); } while ((j < 6793) && (glyph == 0));
if (glyph == 0) { if (glyph == 0) {
j = 0; strcpy(symbol->errtxt, "Unknown character in input data");
glyph = 0; return ZINT_ERROR_INVALID_DATA;
glyph2 = 0;
do {
if (gb18030_fourbyte_lookup[j * 3] == utfdata[i]) {
glyph = gb18030_fourbyte_lookup[(j * 3) + 1];
glyph2 = gb18030_fourbyte_lookup[(j * 3) + 2];
}
j++;
} while ((j < 6793) && (glyph == 0));
if (glyph == 0) {
strcpy(symbol->errtxt, "Unknown character in input data");
return ZINT_ERROR_INVALID_DATA;
} else {
gbdata[posn] = glyph;
gbdata[posn + 1] = glyph2;
posn += 2;
}
} else { } else {
gbdata[posn] = glyph; gbdata[posn] = glyph;
posn++; gbdata[posn + 1] = glyph2;
posn += 2;
} }
} else {
gbdata[posn] = glyph;
posn++;
} }
} }
break; }
} }
length = posn; length = posn;
hx_define_mode(mode, gbdata, length); hx_define_mode(mode, gbdata, length);
est_binlen = calculate_binlength(mode, gbdata, length); est_binlen = calculate_binlength(mode, gbdata, length, symbol->eci);
est_codewords = est_binlen / 8; est_codewords = est_binlen / 8;
if (est_binlen % 8 != 0) { if (est_binlen % 8 != 0) {
est_codewords++; est_codewords++;
} }
#ifndef _MSC_VER #ifndef _MSC_VER
char binary[est_binlen + 1]; char binary[est_binlen + 1];
#else #else
binary = (char *) _alloca((est_binlen + 1) * sizeof (char));; binary = (char *) _alloca((est_binlen + 1) * sizeof (char));;
#endif #endif
for (i = 0; i < est_binlen + 1; i++) { for (i = 0; i < est_binlen + 1; i++) {
binary[i] = '\0'; binary[i] = '\0';
} }
@ -1390,7 +1402,7 @@ int han_xin(struct zint_symbol *symbol, const unsigned char source[], int length
ecc_level = 1; ecc_level = 1;
} }
calculate_binary(binary, mode, gbdata, length); calculate_binary(binary, mode, gbdata, length, symbol->eci);
version = 85; version = 85;
for (i = 84; i > 0; i--) { for (i = 84; i > 0; i--) {

View File

@ -73,6 +73,7 @@ struct zint_symbol *ZBarcode_Create() {
symbol->bitmap = NULL; symbol->bitmap = NULL;
symbol->bitmap_width = 0; symbol->bitmap_width = 0;
symbol->bitmap_height = 0; symbol->bitmap_height = 0;
symbol->eci = 3;
return symbol; return symbol;
} }
@ -127,6 +128,9 @@ void ZBarcode_Delete(struct zint_symbol *symbol) {
free(symbol); free(symbol);
} }
extern int get_best_eci(unsigned char source[], int length); /* Calculate suitable ECI mode */
extern int utf_to_eci(int eci, const unsigned char source[], unsigned char dest[], int *length); /* Convert Unicode to other encodings */
extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */ extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */
extern int c39(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 3 from 9 (or Code 39) */ extern int c39(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 3 from 9 (or Code 39) */
extern int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */ extern int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */
@ -408,6 +412,29 @@ static int is_matrix(const int symbology) {
return result; return result;
} }
static int supports_eci(const int symbology) {
/* Returns 1 if symbology can encode the ECI character */
int result = 0;
switch (symbology) {
case BARCODE_AZTEC:
case BARCODE_DATAMATRIX:
case BARCODE_MAXICODE:
case BARCODE_MICROPDF417:
case BARCODE_PDF417:
case BARCODE_PDF417TRUNC:
case BARCODE_QRCODE:
case BARCODE_DOTCODE:
case BARCODE_GRIDMATRIX:
case BARCODE_HANXIN:
result = 1;
break;
}
return result;
}
int ZBarcode_ValidID(int symbol_id) { int ZBarcode_ValidID(int symbol_id) {
/* Checks whether a symbology is supported */ /* Checks whether a symbology is supported */
@ -552,8 +579,9 @@ static int reduced_charset(struct zint_symbol *symbol, const unsigned char *sour
preprocessed[length] = '\0'; preprocessed[length] = '\0';
break; break;
case UNICODE_MODE: case UNICODE_MODE:
error_number = latin1_process(symbol, source, preprocessed, &length); error_number = utf_to_eci(symbol->eci, source, preprocessed, &length);
if (error_number != 0) { if (error_number != 0) {
strcpy(symbol->errtxt, "Invalid characters in input data");
return error_number; return error_number;
} }
break; break;
@ -888,6 +916,16 @@ int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source, int lengt
} else { } else {
error_buffer = error_number; error_buffer = error_number;
} }
if ((!(supports_eci(symbol->symbology))) && (symbol->eci != 3)) {
strcpy(symbol->errtxt, "Symbology does not support ECI switching");
error_number = ZINT_ERROR_INVALID_OPTION;
}
if ((symbol->eci < 3) || (symbol->eci > 26) || (symbol->eci == 14) || (symbol->eci == 19) || (symbol->eci == 25)) {
strcpy(symbol->errtxt, "Invalid or unsupported ECI mode");
error_number = ZINT_ERROR_INVALID_OPTION;
}
if ((symbol->input_mode < 0) || (symbol->input_mode > 2)) { if ((symbol->input_mode < 0) || (symbol->input_mode > 2)) {
symbol->input_mode = DATA_MODE; symbol->input_mode = DATA_MODE;
@ -926,6 +964,30 @@ int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source, int lengt
error_number = reduced_charset(symbol, local_source, length); error_number = reduced_charset(symbol, local_source, length);
break; break;
} }
if ((error_number == ZINT_ERROR_INVALID_DATA) && (supports_eci(symbol->symbology)
&& (symbol->input_mode == UNICODE_MODE))) {
/* Try another ECI mode */
symbol->eci = get_best_eci(local_source, length);
if (symbol->eci >= 3) {
//printf("Data will encode with ECI %d\n", symbol->eci);
switch (symbol->symbology) {
case BARCODE_QRCODE:
case BARCODE_MICROQR:
case BARCODE_GRIDMATRIX:
case BARCODE_HANXIN:
error_number = utf_to_eci(symbol->eci, source, local_source, &length);
error_number = extended_charset(symbol, local_source, length);
break;
default:
error_number = reduced_charset(symbol, local_source, length);
break;
}
}
}
if ((symbol->symbology == BARCODE_CODE128) || (symbol->symbology == BARCODE_CODE128B)) { if ((symbol->symbology == BARCODE_CODE128) || (symbol->symbology == BARCODE_CODE128B)) {
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {

View File

@ -120,7 +120,7 @@ void maxi_bump(int set[], int character[], int bump_posn) {
} }
/* Format text according to Appendix A */ /* Format text according to Appendix A */
int maxi_text_process(int mode, unsigned char source[], int length) { int maxi_text_process(int mode, unsigned char source[], int length, int eci) {
/* This code doesn't make use of [Lock in C], [Lock in D] /* This code doesn't make use of [Lock in C], [Lock in D]
and [Lock in E] and so is not always the most efficient at and [Lock in E] and so is not always the most efficient at
compressing data, but should suffice for most applications */ compressing data, but should suffice for most applications */
@ -451,6 +451,15 @@ int maxi_text_process(int mode, unsigned char source[], int length) {
} }
} while (i <= 143); } while (i <= 143);
/* Insert ECI at the beginning of message if needed */
if (eci != 3) {
maxi_bump(set, character, 0);
character[0] = 27; // ECI
maxi_bump(set, character, 1);
character[1] = eci;
length += 2;
}
if (((mode == 2) || (mode == 3)) && (length > 84)) { if (((mode == 2) || (mode == 3)) && (length > 84)) {
return ZINT_ERROR_TOO_LONG; return ZINT_ERROR_TOO_LONG;
} }
@ -548,36 +557,16 @@ void maxi_do_primary_3(char postcode[], int country, int service) {
maxi_codeword[9] = ((service & 0x3f0) >> 4); maxi_codeword[9] = ((service & 0x3f0) >> 4);
} }
int maxicode(struct zint_symbol *symbol, unsigned char source[], int length) { int maxicode(struct zint_symbol *symbol, unsigned char local_source[], int length) {
int i, j, block, bit, mode, countrycode = 0, service = 0, lp = 0; int i, j, block, bit, mode, countrycode = 0, service = 0, lp = 0;
int bit_pattern[7], internal_error = 0, eclen, error_number; int bit_pattern[7], internal_error = 0, eclen;
char postcode[12], countrystr[4], servicestr[4]; char postcode[12], countrystr[4], servicestr[4];
#ifndef _MSC_VER
unsigned char local_source[length + 1];
#else
unsigned char* local_source = (unsigned char*) _alloca(length + 1);
#endif
mode = symbol->option_1; mode = symbol->option_1;
strcpy(postcode, ""); strcpy(postcode, "");
strcpy(countrystr, ""); strcpy(countrystr, "");
strcpy(servicestr, ""); strcpy(servicestr, "");
/* The following to be replaced by ECI handling */
switch (symbol->input_mode) {
case DATA_MODE:
case GS1_MODE:
memcpy(local_source, source, length);
local_source[length] = '\0';
break;
case UNICODE_MODE:
error_number = latin1_process(symbol, source, local_source, &length);
if (error_number != 0) {
return error_number;
}
break;
}
memset(maxi_codeword, 0, sizeof (maxi_codeword)); memset(maxi_codeword, 0, sizeof (maxi_codeword));
if (mode == -1) { /* If mode is unspecified */ if (mode == -1) { /* If mode is unspecified */
@ -652,7 +641,7 @@ int maxicode(struct zint_symbol *symbol, unsigned char source[], int length) {
maxi_codeword[0] = mode; maxi_codeword[0] = mode;
} }
i = maxi_text_process(mode, local_source, length); i = maxi_text_process(mode, local_source, length, symbol->eci);
if (i == ZINT_ERROR_TOO_LONG) { if (i == ZINT_ERROR_TOO_LONG) {
strcpy(symbol->errtxt, "Input data too long"); strcpy(symbol->errtxt, "Input data too long");
return i; return i;

View File

@ -609,10 +609,19 @@ int pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length) {
/* 541 - now compress the data */ /* 541 - now compress the data */
indexchaine = 0; indexchaine = 0;
mclength = 0; mclength = 0;
if (symbol->output_options & READER_INIT) { if (symbol->output_options & READER_INIT) {
chainemc[mclength] = 921; /* Reader Initialisation */ chainemc[mclength] = 921; /* Reader Initialisation */
mclength++; mclength++;
} }
if (symbol->eci != 3) {
chainemc[mclength] = 927; /* ECI */
mclength++;
chainemc[mclength] = symbol->eci;
mclength++;
}
for (i = 0; i < indexliste; i++) { for (i = 0; i < indexliste; i++) {
switch (liste[1][i]) { switch (liste[1][i]) {
case TEX: /* 547 - text mode */ case TEX: /* 547 - text mode */
@ -923,10 +932,19 @@ int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length)
/* 541 - now compress the data */ /* 541 - now compress the data */
indexchaine = 0; indexchaine = 0;
mclength = 0; mclength = 0;
if (symbol->output_options & READER_INIT) { if (symbol->output_options & READER_INIT) {
chainemc[mclength] = 921; /* Reader Initialisation */ chainemc[mclength] = 921; /* Reader Initialisation */
mclength++; mclength++;
} }
if (symbol->eci != 3) {
chainemc[mclength] = 927; /* ECI */
mclength++;
chainemc[mclength] = symbol->eci;
mclength++;
}
for (i = 0; i < indexliste; i++) { for (i = 0; i < indexliste; i++) {
switch (liste[1][i]) { switch (liste[1][i]) {
case TEX: /* 547 - text mode */ case TEX: /* 547 - text mode */

View File

@ -127,7 +127,7 @@ void define_mode(char mode[], int jisdata[], int length, int gs1) {
} }
/* Make an estimate (worst case scenario) of how long the binary string will be */ /* Make an estimate (worst case scenario) of how long the binary string will be */
int estimate_binary_length(char mode[], int length, int gs1) { int estimate_binary_length(char mode[], int length, int gs1, int eci) {
int i, count = 0; int i, count = 0;
char current = 0; char current = 0;
int a_count = 0; int a_count = 0;
@ -136,6 +136,10 @@ int estimate_binary_length(char mode[], int length, int gs1) {
if (gs1) { if (gs1) {
count += 4; count += 4;
} }
if (eci != 3) {
count += 12;
}
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if (mode[i] != current) { if (mode[i] != current) {
@ -193,7 +197,7 @@ static void qr_bscan(char *binary, int data, int h) {
} }
/* Convert input data to a binary stream and add padding */ /* Convert input data to a binary stream and add padding */
void qr_binary(int datastream[], int version, int target_binlen, char mode[], int jisdata[], int length, int gs1, int est_binlen) { void qr_binary(int datastream[], int version, int target_binlen, char mode[], int jisdata[], int length, int gs1, int eci, int est_binlen) {
int position = 0, debug = 0; int position = 0, debug = 0;
int short_data_block_length, i, scheme = 1; int short_data_block_length, i, scheme = 1;
char data_block, padbits; char data_block, padbits;
@ -210,6 +214,11 @@ void qr_binary(int datastream[], int version, int target_binlen, char mode[], in
if (gs1) { if (gs1) {
strcat(binary, "0101"); /* FNC1 */ strcat(binary, "0101"); /* FNC1 */
} }
if (eci != 3) {
strcat(binary, "0111"); /* ECI */
qr_bscan(binary, eci, 0x80);
}
if (version <= 9) { if (version <= 9) {
scheme = 1; scheme = 1;
@ -1423,7 +1432,7 @@ int blockLength(int start, char inputMode[], int inputLength) {
return count; return count;
} }
int getBinaryLength(int version, char inputMode[], int inputData[], int inputLength, int gs1) { int getBinaryLength(int version, char inputMode[], int inputData[], int inputLength, int gs1, int eci) {
/* Calculate the actual bitlength of the proposed binary string */ /* Calculate the actual bitlength of the proposed binary string */
char currentMode; char currentMode;
int i, j; int i, j;
@ -1436,6 +1445,10 @@ int getBinaryLength(int version, char inputMode[], int inputData[], int inputLen
if (gs1 == 1) { if (gs1 == 1) {
count += 4; count += 4;
} }
if (eci != 3) {
count += 12;
}
for (i = 0; i < inputLength; i++) { for (i = 0; i < inputLength; i++) {
if (inputMode[i] != currentMode) { if (inputMode[i] != currentMode) {
@ -1512,43 +1525,40 @@ int qr_code(struct zint_symbol *symbol, const unsigned char source[], int length
gs1 = (symbol->input_mode == GS1_MODE); gs1 = (symbol->input_mode == GS1_MODE);
switch (symbol->input_mode) { if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 3)) {
case DATA_MODE: for (i = 0; i < length; i++) {
for (i = 0; i < length; i++) { jisdata[i] = (int) source[i];
jisdata[i] = (int) source[i]; }
} } else {
break; /* Convert Unicode input to Shift-JIS */
default: error_number = utf8toutf16(symbol, source, utfdata, &length);
/* Convert Unicode input to Shift-JIS */ if (error_number != 0) {
error_number = utf8toutf16(symbol, source, utfdata, &length); return error_number;
if (error_number != 0) { }
return error_number;
}
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if (utfdata[i] <= 0xff) { if (utfdata[i] <= 0xff) {
jisdata[i] = utfdata[i]; jisdata[i] = utfdata[i];
} else { } else {
j = 0; j = 0;
glyph = 0; glyph = 0;
do { do {
if (sjis_lookup[j * 2] == utfdata[i]) { if (sjis_lookup[j * 2] == utfdata[i]) {
glyph = sjis_lookup[(j * 2) + 1]; glyph = sjis_lookup[(j * 2) + 1];
}
j++;
} while ((j < 6843) && (glyph == 0));
if (glyph == 0) {
strcpy(symbol->errtxt, "Invalid character in input data");
return ZINT_ERROR_INVALID_DATA;
} }
jisdata[i] = glyph; j++;
} while ((j < 6843) && (glyph == 0));
if (glyph == 0) {
strcpy(symbol->errtxt, "Invalid character in input data");
return ZINT_ERROR_INVALID_DATA;
} }
jisdata[i] = glyph;
} }
break; }
} }
define_mode(mode, jisdata, length, gs1); define_mode(mode, jisdata, length, gs1);
est_binlen = estimate_binary_length(mode, length, gs1); est_binlen = estimate_binary_length(mode, length, gs1, symbol->eci);
ecc_level = LEVEL_L; ecc_level = LEVEL_L;
max_cw = 2956; max_cw = 2956;
@ -1609,7 +1619,7 @@ int qr_code(struct zint_symbol *symbol, const unsigned char source[], int length
} else { } else {
if (tribus(autosize - 1, 1, 2, 3) != tribus(autosize, 1, 2, 3)) { if (tribus(autosize - 1, 1, 2, 3) != tribus(autosize, 1, 2, 3)) {
// Length of binary needed to encode the data in the smaller symbol is different, recalculate // Length of binary needed to encode the data in the smaller symbol is different, recalculate
est_binlen = getBinaryLength(autosize - 1, mode, jisdata, length, gs1); est_binlen = getBinaryLength(autosize - 1, mode, jisdata, length, gs1, symbol->eci);
} }
switch (ecc_level) { switch (ecc_level) {
@ -1641,7 +1651,7 @@ int qr_code(struct zint_symbol *symbol, const unsigned char source[], int length
} else { } else {
// Data did not fit in the smaller symbol, revert to original size // Data did not fit in the smaller symbol, revert to original size
if (tribus(autosize - 1, 1, 2, 3) != tribus(autosize, 1, 2, 3)) { if (tribus(autosize - 1, 1, 2, 3) != tribus(autosize, 1, 2, 3)) {
est_binlen = getBinaryLength(autosize, mode, jisdata, length, gs1); est_binlen = getBinaryLength(autosize, mode, jisdata, length, gs1, symbol->eci);
} }
} }
} }
@ -1656,7 +1666,7 @@ int qr_code(struct zint_symbol *symbol, const unsigned char source[], int length
*/ */
if (symbol->option_2 > version) { if (symbol->option_2 > version) {
version = symbol->option_2; version = symbol->option_2;
est_binlen = getBinaryLength(symbol->option_2, mode, jisdata, length, gs1); est_binlen = getBinaryLength(symbol->option_2, mode, jisdata, length, gs1, symbol->eci);
} }
} }
@ -1693,7 +1703,7 @@ int qr_code(struct zint_symbol *symbol, const unsigned char source[], int length
fullstream = (int *) _alloca((qr_total_codewords[version - 1] + 1) * sizeof (int)); fullstream = (int *) _alloca((qr_total_codewords[version - 1] + 1) * sizeof (int));
#endif #endif
qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1, est_binlen); qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1, symbol->eci, est_binlen);
add_ecc(fullstream, datastream, version, target_binlen, blocks); add_ecc(fullstream, datastream, version, target_binlen, blocks);
size = qr_sizes[version - 1]; size = qr_sizes[version - 1];
@ -2783,39 +2793,36 @@ int microqr(struct zint_symbol *symbol, const unsigned char source[], int length
version_valid[i] = 1; version_valid[i] = 1;
} }
switch (symbol->input_mode) { if (symbol->input_mode == DATA_MODE) {
case DATA_MODE: for (i = 0; i < length; i++) {
for (i = 0; i < length; i++) { jisdata[i] = (int) source[i];
jisdata[i] = (int) source[i]; }
} } else {
break; /* Convert Unicode input to Shift-JIS */
default: error_number = utf8toutf16(symbol, source, utfdata, &length);
/* Convert Unicode input to Shift-JIS */ if (error_number != 0) {
error_number = utf8toutf16(symbol, source, utfdata, &length); return error_number;
if (error_number != 0) { }
return error_number;
}
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if (utfdata[i] <= 0xff) { if (utfdata[i] <= 0xff) {
jisdata[i] = utfdata[i]; jisdata[i] = utfdata[i];
} else { } else {
j = 0; j = 0;
glyph = 0; glyph = 0;
do { do {
if (sjis_lookup[j * 2] == utfdata[i]) { if (sjis_lookup[j * 2] == utfdata[i]) {
glyph = sjis_lookup[(j * 2) + 1]; glyph = sjis_lookup[(j * 2) + 1];
}
j++;
} while ((j < 6843) && (glyph == 0));
if (glyph == 0) {
strcpy(symbol->errtxt, "Invalid character in input data");
return ZINT_ERROR_INVALID_DATA;
} }
jisdata[i] = glyph; j++;
} while ((j < 6843) && (glyph == 0));
if (glyph == 0) {
strcpy(symbol->errtxt, "Invalid character in input data");
return ZINT_ERROR_INVALID_DATA;
} }
jisdata[i] = glyph;
} }
break; }
} }
define_mode(mode, jisdata, length, 0); define_mode(mode, jisdata, length, 0);

View File

@ -82,6 +82,7 @@ extern "C" {
int option_3; int option_3;
int show_hrt; int show_hrt;
int input_mode; int input_mode;
int eci;
unsigned char text[128]; unsigned char text[128];
int rows; int rows;
int width; int width;

View File

@ -71,9 +71,10 @@ void types(void) {
/* Output usage information */ /* Output usage information */
void usage(void) { void usage(void) {
printf( "Zint version %s\n" printf( "Zint version %s\n"
"Encode input data in a barcode and save as a PNG, EPS or SVG file.\n\n" "Encode input data in a barcode and save as a PNG, BMP, GIF, PCX, EPS or SVG file.\n\n"
" -h, --help Display this message.\n" " -h, --help Display this message.\n"
" -t, --types Display table of barcode types\n" " -t, --types Display table of barcode types\n"
" -e, --ecinos Display table of ECI character encodings\n"
" -i, --input=FILE Read data from FILE.\n" " -i, --input=FILE Read data from FILE.\n"
" -o, --output=FILE Write image to FILE. (default is out.png)\n" " -o, --output=FILE Write image to FILE. (default is out.png)\n"
" -d, --data=DATA Barcode content.\n" " -d, --data=DATA Barcode content.\n"
@ -110,9 +111,35 @@ void usage(void) {
" --mirror Use batch data to determine filename (PNG output)\n" " --mirror Use batch data to determine filename (PNG output)\n"
" --mirroreps Use batch data to determine filename (EPS output)\n" " --mirroreps Use batch data to determine filename (EPS output)\n"
" --mirrorsvg Use batch data to determine filename (SVG output)\n" " --mirrorsvg Use batch data to determine filename (SVG output)\n"
" --eci=NUMBER Set the ECI mode for raw data\n"
, ZINT_VERSION); , ZINT_VERSION);
} }
/* Display supported ECI codes */
void show_eci(void) {
printf( " 3: ISO-8859-1 - Latin alphabet No. 1 (default)\n"
" 4: ISO-8859-2 - Latin alphabet No. 2\n"
" 5: ISO-8859-3 - Latin alphabet No. 3\n"
" 6: ISO-8859-4 - Latin alphabet No. 4\n"
" 7: ISO-8859-5 - Latin/Cyrillic alphabet\n"
" 8: ISO-8859-6 - Latin/Arabic alphabet\n"
" 9: ISO-8859-7 - Latin/Greek alphabet\n"
"10: ISO-8859-8 - Latin/Hebrew alphabet\n"
"11: ISO-8859-9 - Latin alphabet No. 5\n"
"12: ISO-8859-10 - Latin alphabet No. 6\n"
"13: ISO-8859-11 - Latin/Thai alphabet\n"
"15: ISO-8859-13 - Latin alphabet No. 7\n"
"16: ISO-8859-14 - Latin alphabet No. 8 (Celtic)\n"
"17: ISO-8859-15 - Latin alphabet No. 9\n"
"18: ISO-8859-16 - Latin alphabet No. 10\n"
"21: Windows-1250\n"
"22: Windows-1251\n"
"23: Windows-1252\n"
"24: Windows-1256\n"
"26: Unicode (UTF-8)\n"
);
}
/* Verifies that a string only uses valid characters */ /* Verifies that a string only uses valid characters */
int validator(char test_string[], char source[]) { int validator(char test_string[], char source[]) {
unsigned int i, j, latch; unsigned int i, j, latch;
@ -438,6 +465,7 @@ int main(int argc, char **argv) {
static struct option long_options[] = { static struct option long_options[] = {
{"help", 0, 0, 'h'}, {"help", 0, 0, 'h'},
{"types", 0, 0, 't'}, {"types", 0, 0, 't'},
{"ecinos", 0, 0, 'e'},
{"bind", 0, 0, 0}, {"bind", 0, 0, 0},
{"box", 0, 0, 0}, {"box", 0, 0, 0},
{"directeps", 0, 0, 0}, {"directeps", 0, 0, 0},
@ -477,9 +505,10 @@ int main(int argc, char **argv) {
{"mirroreps", 0, 0, 0}, {"mirroreps", 0, 0, 0},
{"mirrorsvg", 0, 0, 0}, {"mirrorsvg", 0, 0, 0},
{"dotty", 0, 0, 0}, {"dotty", 0, 0, 0},
{"eci", 1, 0, 'e'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
c = getopt_long(argc, argv, "htb:w:d:o:i:rcmp", long_options, &option_index); c = getopt_long(argc, argv, "htb:w:d:o:i:rcmpe", long_options, &option_index);
if (c == -1) break; if (c == -1) break;
switch (c) { switch (c) {
@ -660,6 +689,14 @@ int main(int argc, char **argv) {
/* Use filenames which reflect content, output to SVG */ /* Use filenames which reflect content, output to SVG */
filename_reflects_data = 3; filename_reflects_data = 3;
} }
if (!strcmp(long_options[option_index].name, "eci")) {
if ((atoi(optarg) >= 0) && (atoi(optarg) <= 30)) {
my_symbol->eci = atoi(optarg);
} else {
fprintf(stderr, "Invalid ECI code\n");
fflush(stderr);
}
}
break; break;
case 'h': case 'h':
@ -669,6 +706,10 @@ int main(int argc, char **argv) {
case 't': case 't':
types(); types();
break; break;
case 'e':
show_eci();
break;
case 'b': case 'b':
error_number = validator(NESET, optarg); error_number = validator(NESET, optarg);