in Sharing/Src/External/zint-2.4.3/src/backend/gridmtx.c [345:742]
int gm_encode(int gbdata[], int length, char binary[], int reader)
{
/* Create a binary stream representation of the input data.
7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters,
Mixed numerals and latters, Control characters and 8-bit binary data */
int sp, current_mode, next_mode, last_mode, glyph = 0;
int c1, c2, done;
int p = 0, ppos;
int numbuf[3], punt = 0;
int number_pad_posn, debug = 0;
int byte_count_posn = 0, byte_count = 0;
int shift, i;
strcpy(binary, "");
sp = 0;
current_mode = 0;
last_mode = 0;
number_pad_posn = 0;
if(reader) {
concat(binary, "1010"); /* FNC3 - Reader Initialisation */
}
do {
next_mode = seek_forward(gbdata, length, sp, current_mode);
if(next_mode != current_mode) {
switch(current_mode) {
case 0:
switch(next_mode) {
case GM_CHINESE: concat(binary, "0001"); break;
case GM_NUMBER: concat(binary, "0010"); break;
case GM_LOWER: concat(binary, "0011"); break;
case GM_UPPER: concat(binary, "0100"); break;
case GM_MIXED: concat(binary, "0101"); break;
case GM_BYTE: concat(binary, "0111"); break;
}
break;
case GM_CHINESE:
switch(next_mode) {
case GM_NUMBER: concat(binary, "1111111100001"); break; // 8161
case GM_LOWER: concat(binary, "1111111100010"); break; // 8162
case GM_UPPER: concat(binary, "1111111100011"); break; // 8163
case GM_MIXED: concat(binary, "1111111100100"); break; // 8164
case GM_BYTE: concat(binary, "1111111100101"); break; // 8165
}
break;
case GM_NUMBER:
/* add numeric block padding value */
switch(p) {
case 1: binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; // 2 pad digits
case 2: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; // 1 pad digit
case 3: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; // 0 pad digits
}
switch(next_mode) {
case GM_CHINESE: concat(binary, "1111111011"); break; // 1019
case GM_LOWER: concat(binary, "1111111100"); break; // 1020
case GM_UPPER: concat(binary, "1111111101"); break; // 1021
case GM_MIXED: concat(binary, "1111111110"); break; // 1022
case GM_BYTE: concat(binary, "1111111111"); break; // 1023
}
break;
case GM_LOWER:
case GM_UPPER:
switch(next_mode) {
case GM_CHINESE: concat(binary, "11100"); break; // 28
case GM_NUMBER: concat(binary, "11101"); break; // 29
case GM_LOWER:
case GM_UPPER: concat(binary, "11110"); break; // 30
case GM_MIXED: concat(binary, "1111100"); break; // 124
case GM_BYTE: concat(binary, "1111110"); break; // 126
}
break;
case GM_MIXED:
switch(next_mode) {
case GM_CHINESE: concat(binary, "1111110001"); break; // 1009
case GM_NUMBER: concat(binary, "1111110010"); break; // 1010
case GM_LOWER: concat(binary, "1111110011"); break; // 1011
case GM_UPPER: concat(binary, "1111110100"); break; // 1012
case GM_BYTE: concat(binary, "1111110111"); break; // 1015
}
break;
case GM_BYTE:
/* add byte block length indicator */
add_byte_count(binary, byte_count_posn, byte_count);
byte_count = 0;
switch(next_mode) {
case GM_CHINESE: concat(binary, "0001"); break; // 1
case GM_NUMBER: concat(binary, "0010"); break; // 2
case GM_LOWER: concat(binary, "0011"); break; // 3
case GM_UPPER: concat(binary, "0100"); break; // 4
case GM_MIXED: concat(binary, "0101"); break; // 5
}
break;
}
if(debug) {
switch(next_mode) {
case GM_CHINESE: printf("CHIN "); break;
case GM_NUMBER: printf("NUMB "); break;
case GM_LOWER: printf("LOWR "); break;
case GM_UPPER: printf("UPPR "); break;
case GM_MIXED: printf("MIXD "); break;
case GM_BYTE: printf("BYTE "); break;
}
}
}
last_mode = current_mode;
current_mode = next_mode;
switch(current_mode) {
case GM_CHINESE:
done = 0;
if(gbdata[sp] > 0xff) {
/* GB2312 character */
c1 = (gbdata[sp] & 0xff00) >> 8;
c2 = gbdata[sp] & 0xff;
if((c1 >= 0xa0) && (c1 <= 0xa9)) {
glyph = (0x60 * (c1 - 0xa1)) + (c2 - 0xa0);
}
if((c1 >= 0xb0) && (c1 <= 0xf7)) {
glyph = (0x60 * (c1 - 0xb0 + 9)) + (c2 - 0xa0);
}
done = 1;
}
if(!(done)) {
if(sp != (length - 1)) {
if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) {
/* End of Line */
glyph = 7776;
sp++;
}
done = 1;
}
}
if(!(done)) {
if(sp != (length - 1)) {
if(((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) &&
((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) {
/* Two digits */
glyph = 8033 + (10 * (gbdata[sp] - '0')) + (gbdata[sp + 1] - '0');
sp++;
}
}
}
if(!(done)) {
/* Byte value */
glyph = 7777 + gbdata[sp];
}
if(debug) { printf("[%d] ", glyph); }
if(glyph & 0x1000) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); }
sp++;
break;
case GM_NUMBER:
if(last_mode != current_mode) {
/* Reserve a space for numeric digit padding value (2 bits) */
number_pad_posn = strlen(binary);
concat(binary, "XX");
}
p = 0;
ppos = -1;
/* Numeric compression can also include certain combinations of
non-numeric character */
numbuf[0] = '0';
numbuf[1] = '0';
numbuf[2] = '0';
do {
if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) {
numbuf[p] = gbdata[sp];
sp++;
p++;
}
switch(gbdata[sp]) {
case ' ':
case '+':
case '-':
case '.':
case ',':
punt = gbdata[sp];
sp++;
ppos = p;
break;
}
if(sp < (length - 1)) {
if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) {
/* <end of line> */
punt = gbdata[sp];
sp += 2;
ppos = p;
}
}
} while ((p < 3) && (sp < length));
if(ppos != -1) {
switch(punt) {
case ' ': glyph = 0; break;
case '+': glyph = 3; break;
case '-': glyph = 6; break;
case '.': glyph = 9; break;
case ',': glyph = 12; break;
case 0x13: glyph = 15; break;
}
glyph += ppos;
glyph += 1000;
if(debug) { printf("[%d] ", glyph); }
if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); }
}
glyph = (100 * (numbuf[0] - '0')) + (10 * (numbuf[1] - '0')) + (numbuf[2] - '0');
if(debug) { printf("[%d] ", glyph); }
if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); }
break;
case GM_BYTE:
if(last_mode != current_mode) {
/* Reserve space for byte block length indicator (9 bits) */
byte_count_posn = strlen(binary);
concat(binary, "LLLLLLLLL");
}
if(byte_count == 512) {
/* Maximum byte block size is 512 bytes. If longer is needed then start a new block */
add_byte_count(binary, byte_count_posn, byte_count);
concat(binary, "0111");
byte_count_posn = strlen(binary);
concat(binary, "LLLLLLLLL");
byte_count = 0;
}
glyph = gbdata[sp];
if(debug) { printf("[%d] ", glyph); }
if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); }
sp++;
byte_count++;
break;
case GM_MIXED:
shift = 1;
if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { shift = 0; }
if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { shift = 0; }
if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { shift = 0; }
if(gbdata[sp] == ' ') { shift = 0; }
if(shift == 0) {
/* Mixed Mode character */
glyph = posn(EUROPIUM, gbdata[sp]);
if(debug) { printf("[%d] ", glyph); }
if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); }
} else {
/* Shift Mode character */
concat(binary, "1111110110"); /* 1014 - shift indicator */
add_shift_char(binary, gbdata[sp]);
}
sp++;
break;
case GM_UPPER:
shift = 1;
if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { shift = 0; }
if(gbdata[sp] == ' ') { shift = 0; }
if(shift == 0) {
/* Upper Case character */
glyph = posn("ABCDEFGHIJKLMNOPQRSTUVWXYZ ", gbdata[sp]);
if(debug) { printf("[%d] ", glyph); }
if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); }
} else {
/* Shift Mode character */
concat(binary, "1111101"); /* 127 - shift indicator */
add_shift_char(binary, gbdata[sp]);
}
sp++;
break;
case GM_LOWER:
shift = 1;
if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { shift = 0; }
if(gbdata[sp] == ' ') { shift = 0; }
if(shift == 0) {
/* Lower Case character */
glyph = posn("abcdefghijklmnopqrstuvwxyz ", gbdata[sp]);
if(debug) { printf("[%d] ", glyph); }
if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); }
if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); }
} else {
/* Shift Mode character */
concat(binary, "1111101"); /* 127 - shift indicator */
add_shift_char(binary, gbdata[sp]);
}
sp++;
break;
}
if(strlen(binary) > 9191) {
return ZINT_ERROR_TOO_LONG;
}
} while(sp < length);
if(current_mode == GM_NUMBER) {
/* add numeric block padding value */
switch(p) {
case 1: binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; // 2 pad digits
case 2: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; // 1 pad digit
case 3: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; // 0 pad digits
}
}
if(current_mode == GM_BYTE) {
/* Add byte block length indicator */
add_byte_count(binary, byte_count_posn, byte_count);
}
/* Add "end of data" character */
switch(current_mode) {
case GM_CHINESE: concat(binary, "1111111100000"); break; // 8160
case GM_NUMBER: concat(binary, "1111111010"); break; // 1018
case GM_LOWER:
case GM_UPPER: concat(binary, "11011"); break; // 27
case GM_MIXED: concat(binary, "1111110000"); break; // 1008
case GM_BYTE: concat(binary, "0000"); break; // 0
}
/* Add padding bits if required */
p = 7 - (strlen(binary) % 7);
if(p == 7) { p = 0; }
for(i = 0; i < p; i++) {
concat(binary, "0");
}
if(strlen(binary) > 9191) {
return ZINT_ERROR_TOO_LONG;
}
return 0;
}