in Sharing/Src/External/zint-2.4.3/src/backend/aztec.c [69:665]
int aztec_text_process(unsigned char source[], const unsigned int src_len, char binary_string[], int gs1)
{
int i, j, k, bytes;
int curtable, newtable, lasttable, chartype, maplength, blocks, debug;
#ifndef _MSC_VER
int charmap[src_len * 2], typemap[src_len * 2];
int blockmap[2][src_len];
#else
int* charmap = (int*)_alloca(src_len * 2 * sizeof(int));
int* typemap = (int*)_alloca(src_len * 2 * sizeof(int));
int* blockmap[2];
blockmap[0] = (int*)_alloca(src_len * sizeof(int));
blockmap[1] = (int*)_alloca(src_len * sizeof(int));
#endif
/* Lookup input string in encoding table */
maplength = 0;
debug = 0;
for(i = 0; i < src_len; i++) {
if(gs1 && (i == 0)) {
/* Add FNC1 to beginning of GS1 messages */
charmap[maplength] = 0;
typemap[maplength++] = PUNC;
charmap[maplength] = 400;
typemap[maplength++] = PUNC;
}
if((gs1) && (source[i] == '[')) {
/* FNC1 represented by FLG(0) */
charmap[maplength] = 0;
typemap[maplength++] = PUNC;
charmap[maplength] = 400;
typemap[maplength++] = PUNC;
} else {
if(source[i] > 127) {
charmap[maplength] = source[i];
typemap[maplength++] = BINARY;
} else {
charmap[maplength] = AztecSymbolChar[source[i]];
typemap[maplength++] = AztecCodeSet[source[i]];
}
}
}
/* Look for double character encoding possibilities */
i = 0;
do{
if(((charmap[i] == 300) && (charmap[i + 1] == 11)) && ((typemap[i] == PUNC) && (typemap[i + 1] == PUNC))) {
/* CR LF combination */
charmap[i] = 2;
typemap[i] = PUNC;
mapshorten(charmap, typemap, i, maplength);
maplength--;
}
if(((charmap[i] == 302) && (charmap[i + 1] == 1)) && ((typemap[i] == 24) && (typemap[i + 1] == 23))) {
/* . SP combination */
charmap[i] = 3;
typemap[i] = PUNC;
mapshorten(charmap, typemap, i, maplength);
maplength--;
}
if(((charmap[i] == 301) && (charmap[i + 1] == 1)) && ((typemap[i] == 24) && (typemap[i + 1] == 23))) {
/* , SP combination */
charmap[i] = 4;
typemap[i] = PUNC;
mapshorten(charmap, typemap, i, maplength);
maplength--;
}
if(((charmap[i] == 21) && (charmap[i + 1] == 1)) && ((typemap[i] == PUNC) && (typemap[i + 1] == 23))) {
/* : SP combination */
charmap[i] = 5;
typemap[i] = PUNC;
mapshorten(charmap, typemap, i, maplength);
maplength--;
}
i++;
}while(i < (maplength - 1));
/* look for blocks of characters which use the same table */
blocks = 1;
blockmap[0][0] = typemap[0];
blockmap[1][0] = 1;
for(i = 1; i < maplength; i++) {
if(typemap[i] == typemap[i - 1]) {
blockmap[1][blocks - 1]++;
} else {
blocks++;
blockmap[0][blocks - 1] = typemap[i];
blockmap[1][blocks - 1] = 1;
}
}
if(blockmap[0][0] & 1) { blockmap[0][0] = 1; }
if(blockmap[0][0] & 2) { blockmap[0][0] = 2; }
if(blockmap[0][0] & 4) { blockmap[0][0] = 4; }
if(blockmap[0][0] & 8) { blockmap[0][0] = 8; }
if(blocks > 1) {
/* look for adjacent blocks which can use the same table (left to right search) */
for(i = 1; i < blocks; i++) {
if(blockmap[0][i] & blockmap[0][i - 1]) {
blockmap[0][i] = (blockmap[0][i] & blockmap[0][i - 1]);
}
}
if(blockmap[0][blocks - 1] & 1) { blockmap[0][blocks - 1] = 1; }
if(blockmap[0][blocks - 1] & 2) { blockmap[0][blocks - 1] = 2; }
if(blockmap[0][blocks - 1] & 4) { blockmap[0][blocks - 1] = 4; }
if(blockmap[0][blocks - 1] & 8) { blockmap[0][blocks - 1] = 8; }
/* look for adjacent blocks which can use the same table (right to left search) */
for(i = blocks - 1; i > 0; i--) {
if(blockmap[0][i] & blockmap[0][i + 1]) {
blockmap[0][i] = (blockmap[0][i] & blockmap[0][i + 1]);
}
}
/* determine the encoding table for characters which do not fit with adjacent blocks */
for(i = 1; i < blocks; i++) {
if(blockmap[0][i] & 8) { blockmap[0][i] = 8; }
if(blockmap[0][i] & 4) { blockmap[0][i] = 4; }
if(blockmap[0][i] & 2) { blockmap[0][i] = 2; }
if(blockmap[0][i] & 1) { blockmap[0][i] = 1; }
}
/* Combine blocks of the same type */
i = 0;
do{
if(blockmap[0][i] == blockmap[0][i + 1]) {
blockmap[1][i] += blockmap[1][i + 1];
for(j = i + 1; j < blocks; j++) {
blockmap[0][j] = blockmap[0][j + 1];
blockmap[1][j] = blockmap[1][j + 1];
}
blocks--;
} else {
i++;
}
} while (i < blocks);
}
/* Put the adjusted block data back into typemap */
j = 0;
for(i = 0; i < blocks; i++) {
if((blockmap[1][i] < 3) && (blockmap[0][i] != 32)) { /* Shift character(s) needed */
for(k = 0; k < blockmap[1][i]; k++) {
typemap[j + k] = blockmap[0][i] + 64;
}
} else { /* Latch character (or byte mode) needed */
for(k = 0; k < blockmap[1][i]; k++) {
typemap[j + k] = blockmap[0][i];
}
}
j += blockmap[1][i];
}
/* Don't shift an initial capital letter */
if(typemap[0] == 65) { typemap[0] = 1; };
/* Problem characters (those that appear in different tables with different values) can now be resolved into their tables */
for(i = 0; i < maplength; i++) {
if((charmap[i] >= 300) && (charmap[i] < 400)) {
curtable = typemap[i];
if(curtable > 64) {
curtable -= 64;
}
switch(charmap[i]) {
case 300: /* Carriage Return */
switch(curtable) {
case PUNC: charmap[i] = 1; break;
case MIXED: charmap[i] = 14; break;
}
break;
case 301: /* Comma */
switch(curtable) {
case PUNC: charmap[i] = 17; break;
case DIGIT: charmap[i] = 12; break;
}
break;
case 302: /* Full Stop */
switch(curtable) {
case PUNC: charmap[i] = 19; break;
case DIGIT: charmap[i] = 13; break;
}
break;
}
}
}
*binary_string = '\0';
curtable = UPPER; /* start with UPPER table */
lasttable = UPPER;
for(i = 0; i < maplength; i++) {
newtable = curtable;
if((typemap[i] != curtable) && (charmap[i] < 400)) {
/* Change table */
if(curtable == BINARY) {
/* If ending binary mode the current table is the same as when entering binary mode */
curtable = lasttable;
newtable = lasttable;
}
if(typemap[i] > 64) {
/* Shift character */
switch(typemap[i]) {
case (64 + UPPER): /* To UPPER */
switch(curtable) {
case LOWER: /* US */
concat(binary_string, hexbit[28]);
if(debug) printf("US ");
break;
case MIXED: /* UL */
concat(binary_string, hexbit[29]);
if(debug) printf("UL ");
newtable = UPPER;
break;
case PUNC: /* UL */
concat(binary_string, hexbit[31]);
if(debug) printf("UL ");
newtable = UPPER;
break;
case DIGIT: /* US */
concat(binary_string, pentbit[15]);
if(debug) printf("US ");
break;
}
break;
case (64 + LOWER): /* To LOWER */
switch(curtable) {
case UPPER: /* LL */
concat(binary_string, hexbit[28]);
if(debug) printf("LL ");
newtable = LOWER;
break;
case MIXED: /* LL */
concat(binary_string, hexbit[28]);
if(debug) printf("LL ");
newtable = LOWER;
break;
case PUNC: /* UL LL */
concat(binary_string, hexbit[31]);
if(debug) printf("UL ");
concat(binary_string, hexbit[28]);
if(debug) printf("LL ");
newtable = LOWER;
break;
case DIGIT: /* UL LL */
concat(binary_string, pentbit[14]);
if(debug) printf("UL ");
concat(binary_string, hexbit[28]);
if(debug) printf("LL ");
newtable = LOWER;
break;
}
break;
case (64 + MIXED): /* To MIXED */
switch(curtable) {
case UPPER: /* ML */
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
newtable = MIXED;
break;
case LOWER: /* ML */
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
newtable = MIXED;
break;
case PUNC: /* UL ML */
concat(binary_string, hexbit[31]);
if(debug) printf("UL ");
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
newtable = MIXED;
break;
case DIGIT: /* UL ML */
concat(binary_string, pentbit[14]);
if(debug) printf("UL ");
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
newtable = MIXED;
break;
}
break;
case (64 + PUNC): /* To PUNC */
switch(curtable) {
case UPPER: /* PS */
concat(binary_string, hexbit[0]);
if(debug) printf("PS ");
break;
case LOWER: /* PS */
concat(binary_string, hexbit[0]);
if(debug) printf("PS ");
break;
case MIXED: /* PS */
concat(binary_string, hexbit[0]);
if(debug) printf("PS ");
break;
case DIGIT: /* PS */
concat(binary_string, pentbit[0]);
if(debug) printf("PS ");
break;
}
break;
case (64 + DIGIT): /* To DIGIT */
switch(curtable) {
case UPPER: /* DL */
concat(binary_string, hexbit[30]);
if(debug) printf("DL ");
newtable = DIGIT;
break;
case LOWER: /* DL */
concat(binary_string, hexbit[30]);
if(debug) printf("DL ");
newtable = DIGIT;
break;
case MIXED: /* UL DL */
concat(binary_string, hexbit[29]);
if(debug) printf("UL ");
concat(binary_string, hexbit[30]);
if(debug) printf("DL ");
newtable = DIGIT;
break;
case PUNC: /* UL DL */
concat(binary_string, hexbit[31]);
if(debug) printf("UL ");
concat(binary_string, hexbit[30]);
if(debug) printf("DL ");
newtable = DIGIT;
break;
}
break;
}
} else {
/* Latch character */
switch(typemap[i]) {
case UPPER: /* To UPPER */
switch(curtable) {
case LOWER: /* ML UL */
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
concat(binary_string, hexbit[29]);
if(debug) printf("UL ");
newtable = UPPER;
break;
case MIXED: /* UL */
concat(binary_string, hexbit[29]);
if(debug) printf("UL ");
newtable = UPPER;
break;
case PUNC: /* UL */
concat(binary_string, hexbit[31]);
if(debug) printf("UL ");
newtable = UPPER;
break;
case DIGIT: /* UL */
concat(binary_string, pentbit[14]);
if(debug) printf("UL ");
newtable = UPPER;
break;
}
break;
case LOWER: /* To LOWER */
switch(curtable) {
case UPPER: /* LL */
concat(binary_string, hexbit[28]);
if(debug) printf("LL ");
newtable = LOWER;
break;
case MIXED: /* LL */
concat(binary_string, hexbit[28]);
if(debug) printf("LL ");
newtable = LOWER;
break;
case PUNC: /* UL LL */
concat(binary_string, hexbit[31]);
if(debug) printf("UL ");
concat(binary_string, hexbit[28]);
if(debug) printf("LL ");
newtable = LOWER;
break;
case DIGIT: /* UL LL */
concat(binary_string, pentbit[14]);
if(debug) printf("UL ");
concat(binary_string, hexbit[28]);
if(debug) printf("LL ");
newtable = LOWER;
break;
}
break;
case MIXED: /* To MIXED */
switch(curtable) {
case UPPER: /* ML */
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
newtable = MIXED;
break;
case LOWER: /* ML */
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
newtable = MIXED;
break;
case PUNC: /* UL ML */
concat(binary_string, hexbit[31]);
if(debug) printf("UL ");
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
newtable = MIXED;
break;
case DIGIT: /* UL ML */
concat(binary_string, pentbit[14]);
if(debug) printf("UL ");
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
newtable = MIXED;
break;
}
break;
case PUNC: /* To PUNC */
switch(curtable) {
case UPPER: /* ML PL */
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
concat(binary_string, hexbit[30]);
if(debug) printf("PL ");
newtable = PUNC;
break;
case LOWER: /* ML PL */
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
concat(binary_string, hexbit[30]);
if(debug) printf("PL ");
newtable = PUNC;
break;
case MIXED: /* PL */
concat(binary_string, hexbit[30]);
if(debug) printf("PL ");
newtable = PUNC;
break;
case DIGIT: /* UL ML PL */
concat(binary_string, pentbit[14]);
if(debug) printf("UL ");
concat(binary_string, hexbit[29]);
if(debug) printf("ML ");
concat(binary_string, hexbit[30]);
if(debug) printf("PL ");
newtable = PUNC;
break;
}
break;
case DIGIT: /* To DIGIT */
switch(curtable) {
case UPPER: /* DL */
concat(binary_string, hexbit[30]);
if(debug) printf("DL ");
newtable = DIGIT;
break;
case LOWER: /* DL */
concat(binary_string, hexbit[30]);
if(debug) printf("DL ");
newtable = DIGIT;
break;
case MIXED: /* UL DL */
concat(binary_string, hexbit[29]);
if(debug) printf("UL ");
concat(binary_string, hexbit[30]);
if(debug) printf("DL ");
newtable = DIGIT;
break;
case PUNC: /* UL DL */
concat(binary_string, hexbit[31]);
if(debug) printf("UL ");
concat(binary_string, hexbit[30]);
if(debug) printf("DL ");
newtable = DIGIT;
break;
}
break;
case BINARY: /* To BINARY */
lasttable = curtable;
switch(curtable) {
case UPPER: /* BS */
concat(binary_string, hexbit[31]);
if(debug) printf("BS ");
newtable = BINARY;
break;
case LOWER: /* BS */
concat(binary_string, hexbit[31]);
if(debug) printf("BS ");
newtable = BINARY;
break;
case MIXED: /* BS */
concat(binary_string, hexbit[31]);
if(debug) printf("BS ");
newtable = BINARY;
break;
case PUNC: /* UL BS */
concat(binary_string, hexbit[31]);
if(debug) printf("UL ");
concat(binary_string, hexbit[31]);
if(debug) printf("BS ");
newtable = BINARY;
break;
case DIGIT: /* UL BS */
concat(binary_string, pentbit[14]);
if(debug) printf("UL ");
concat(binary_string, hexbit[31]);
if(debug) printf("BS ");
newtable = BINARY;
break;
}
bytes = 0;
do{
bytes++;
}while(typemap[i + (bytes - 1)] == BINARY);
bytes--;
if(bytes > 2079) {
return ZINT_ERROR_TOO_LONG;
}
if(bytes > 31) { /* Put 00000 followed by 11-bit number of bytes less 31 */
int adjusted;
adjusted = bytes - 31;
concat(binary_string, "00000");
if(adjusted & 0x400) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(adjusted & 0x200) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(adjusted & 0x100) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(adjusted & 0x80) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(adjusted & 0x40) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(adjusted & 0x20) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(adjusted & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(adjusted & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(adjusted & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(adjusted & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(adjusted & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
} else { /* Put 5-bit number of bytes */
if(bytes & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(bytes & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(bytes & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(bytes & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(bytes & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
}
if(debug) printf("(%d bytes) ", bytes);
break;
}
}
}
/* Add data to the binary string */
curtable = newtable;
chartype = typemap[i];
if(chartype > 64) { chartype -= 64; }
switch(chartype) {
case UPPER:
case LOWER:
case MIXED:
case PUNC:
if(charmap[i] >= 400) {
concat(binary_string, tribit[charmap[i] - 400]);
if(debug) printf("FLG(%d) ",charmap[i] - 400);
} else {
concat(binary_string, hexbit[charmap[i]]);
if(!((chartype == PUNC) && (charmap[i] == 0)))
if(debug) printf("%d ",charmap[i]);
}
break;
case DIGIT:
concat(binary_string, pentbit[charmap[i]]);
if(debug) printf("%d ",charmap[i]);
break;
case BINARY:
if(charmap[i] & 0x80) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(charmap[i] & 0x40) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(charmap[i] & 0x20) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(charmap[i] & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(charmap[i] & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(charmap[i] & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(charmap[i] & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(charmap[i] & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); }
if(debug) printf("%d ",charmap[i]);
break;
}
}
if(debug) printf("\n");
if(strlen(binary_string) > 14970) {
return ZINT_ERROR_TOO_LONG;
}
return 0;
}