in Sharing/Src/External/zint-2.4.3/src/backend/code1.c [291:1010]
int c1_encode(struct zint_symbol *symbol, unsigned char source[], unsigned int target[], int length)
{
int current_mode, next_mode;
int sp, tp, gs1, i, j, latch;
int c40_buffer[6], c40_p;
int text_buffer[6], text_p;
int edi_buffer[6], edi_p;
char decimal_binary[40];
int byte_start = 0;
sp = 0;
tp = 0;
latch = 0;
memset(c40_buffer, 0, 6);
c40_p = 0;
memset(text_buffer, 0, 6);
text_p = 0;
memset(edi_buffer, 0, 6);
edi_p = 0;
strcpy(decimal_binary, "");
if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; }
if(gs1) { target[tp] = 232; tp++; } /* FNC1 */
/* Step A */
current_mode = C1_ASCII;
next_mode = C1_ASCII;
do {
if(current_mode != next_mode) {
/* Change mode */
switch(next_mode) {
case C1_C40: target[tp] = 230; tp++; break;
case C1_TEXT: target[tp] = 239; tp++; break;
case C1_EDI: target[tp] = 238; tp++; break;
case C1_BYTE: target[tp] = 231; tp++; break;
}
}
if((current_mode != C1_BYTE) && (next_mode == C1_BYTE)) { byte_start = tp; }
current_mode = next_mode;
if(current_mode == C1_ASCII) { /* Step B - ASCII encodation */
next_mode = C1_ASCII;
if((length - sp) >= 21) { /* Step B1 */
j = 0;
for(i = 0; i < 21; i++) {
if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; }
}
if (j == 21) {
next_mode = C1_DECIMAL;
strcpy(decimal_binary, "1111");
}
}
if((next_mode == C1_ASCII) && ((length - sp) >= 13)) { /* Step B2 */
j = 0;
for(i = 0; i < 13; i++) {
if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; }
}
if (j == 13) {
latch = 0;
for(i = sp + 13; i < length; i++) {
if(!((source[sp + i] >= '0') && (source[sp + i] <= '9'))) { latch = 1; }
}
if(!(latch)) {
next_mode = C1_DECIMAL;
strcpy(decimal_binary, "1111");
}
}
}
if(next_mode == C1_ASCII) { /* Step B3 */
if(istwodigits(source, sp) && ((sp + 1) != length)) {
target[tp] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130;
tp++;
sp += 2;
} else {
if((gs1) && (source[sp] == '[')) {
if((length - sp) >= 15) { /* Step B4 */
j = 0;
for(i = 0; i < 15; i++) {
if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; }
}
if (j == 15) {
target[tp] = 236; /* FNC1 and change to Decimal */
tp++; sp++;
next_mode = C1_DECIMAL;
}
}
if((length - sp) >= 7) { /* Step B5 */
j = 0;
for(i = 0; i < 7; i++) {
if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; }
}
if (j == 7) {
latch = 0;
for(i = sp + 7; i < length; i++) {
if(!((source[sp + i] >= '0') && (source[sp + i] <= '9'))) { latch = 1; }
}
if(!(latch)) {
target[tp] = 236; /* FNC1 and change to Decimal */
tp++; sp++;
next_mode = C1_DECIMAL;
}
}
}
}
if(next_mode == C1_ASCII) {
/* Step B6 */
next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1);
if(next_mode == C1_ASCII) {
if(source[sp] > 127) {
/* Step B7 */
target[tp] = 235; tp++; /* FNC4 */
target[tp] = (source[sp] - 128) + 1; tp++; sp++;
} else {
/* Step B8 */
if((gs1) && (source[sp] == '[')) {
target[tp] = 232; tp++; sp++; /* FNC1 */
} else {
target[tp] = source[sp] + 1; tp++; sp++;
}
}
}
}
}
}
}
if(current_mode == C1_C40) { /* Step C - C40 encodation */
int shift_set, value, done = 0, latch = 0;
next_mode = C1_C40;
if(c40_p == 0) {
if((length - sp) >= 12) {
j = 0;
for(i = 0; i < 12; i++) {
if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; }
}
if (j == 12) {
next_mode = C1_ASCII; done = 1;
}
}
if((length - sp) >= 8) {
j = 0;
for(i = 0; i < 8; i++) {
if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; }
}
if((length - sp) == 8) {
latch = 1;
} else {
latch = 1;
for(j = sp + 8; j < length; j++) {
if((source[j] <= '0') || (source[j] >= '9')) { latch = 0; }
}
}
if ((j == 8) && latch) {
next_mode = C1_ASCII; done = 1;
}
}
if(!(done)) {
next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1);
}
}
if(next_mode != C1_C40) {
target[tp] = 255; tp++; /* Unlatch */
} else {
if(source[sp] > 127) {
c40_buffer[c40_p] = 1; c40_p++;
c40_buffer[c40_p] = 30; c40_p++; /* Upper Shift */
shift_set = c40_shift[source[sp] - 128];
value = c40_value[source[sp] - 128];
} else {
shift_set = c40_shift[source[sp]];
value = c40_value[source[sp]];
}
if(gs1 && (source[sp] == '[')) {
shift_set = 2;
value = 27; /* FNC1 */
}
if(shift_set != 0) {
c40_buffer[c40_p] = shift_set - 1; c40_p++;
}
c40_buffer[c40_p] = value; c40_p++;
if(c40_p >= 3) {
int iv;
iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1;
target[tp] = iv / 256; tp++;
target[tp] = iv % 256; tp++;
c40_buffer[0] = c40_buffer[3];
c40_buffer[1] = c40_buffer[4];
c40_buffer[2] = c40_buffer[5];
c40_buffer[3] = 0;
c40_buffer[4] = 0;
c40_buffer[5] = 0;
c40_p -= 3;
}
sp++;
}
}
if(current_mode == C1_TEXT) { /* Step D - Text encodation */
int shift_set, value, done = 0, latch = 0;
next_mode = C1_TEXT;
if(text_p == 0) {
if((length - sp) >= 12) {
j = 0;
for(i = 0; i < 12; i++) {
if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; }
}
if (j == 12) {
next_mode = C1_ASCII; done = 1;
}
}
if((length - sp) >= 8) {
j = 0;
for(i = 0; i < 8; i++) {
if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; }
}
if((length - sp) == 8) {
latch = 1;
} else {
latch = 1;
for(j = sp + 8; j < length; j++) {
if((source[j] <= '0') || (source[j] >= '9')) { latch = 0; }
}
}
if ((j == 8) && latch) {
next_mode = C1_ASCII; done = 1;
}
}
if(!(done)) {
next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1);
}
}
if(next_mode != C1_TEXT) {
target[tp] = 255; tp++; /* Unlatch */
} else {
if(source[sp] > 127) {
text_buffer[text_p] = 1; text_p++;
text_buffer[text_p] = 30; text_p++; /* Upper Shift */
shift_set = text_shift[source[sp] - 128];
value = text_value[source[sp] - 128];
} else {
shift_set = text_shift[source[sp]];
value = text_value[source[sp]];
}
if(gs1 && (source[sp] == '[')) {
shift_set = 2;
value = 27; /* FNC1 */
}
if(shift_set != 0) {
text_buffer[text_p] = shift_set - 1; text_p++;
}
text_buffer[text_p] = value; text_p++;
if(text_p >= 3) {
int iv;
iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1;
target[tp] = iv / 256; tp++;
target[tp] = iv % 256; tp++;
text_buffer[0] = text_buffer[3];
text_buffer[1] = text_buffer[4];
text_buffer[2] = text_buffer[5];
text_buffer[3] = 0;
text_buffer[4] = 0;
text_buffer[5] = 0;
text_p -= 3;
}
sp++;
}
}
if(current_mode == C1_EDI) { /* Step E - EDI Encodation */
int value = 0,latch = 0;
next_mode = C1_EDI;
if(edi_p == 0) {
if((length - sp) >= 12) {
j = 0;
for(i = 0; i < 12; i++) {
if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; }
}
if (j == 12) {
next_mode = C1_ASCII;
}
}
if((length - sp) >= 8) {
j = 0;
for(i = 0; i < 8; i++) {
if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; }
}
if((length - sp) == 8) {
latch = 1;
} else {
latch = 1;
for(j = sp + 8; j < length; j++) {
if((source[j] <= '0') || (source[j] >= '9')) { latch = 0; }
}
}
if ((j == 8) && latch) {
next_mode = C1_ASCII;
}
}
if(!((isedi(source[sp]) && isedi(source[sp + 1])) && isedi(source[sp + 2]))) {
next_mode = C1_ASCII;
}
}
if(next_mode != C1_EDI) {
target[tp] = 255; tp++; /* Unlatch */
} else {
if(source[sp] == 13) { value = 0; }
if(source[sp] == '*') { value = 1; }
if(source[sp] == '>') { value = 2; }
if(source[sp] == ' ') { value = 3; }
if((source[sp] >= '0') && (source[sp] <= '9')) { value = source[sp] - '0' + 4; }
if((source[sp] >= 'A') && (source[sp] <= 'Z')) { value = source[sp] - 'A' + 14; }
edi_buffer[edi_p] = value; edi_p++;
if(edi_p >= 3) {
int iv;
iv = (1600 * edi_buffer[0]) + (40 * edi_buffer[1]) + (edi_buffer[2]) + 1;
target[tp] = iv / 256; tp++;
target[tp] = iv % 256; tp++;
edi_buffer[0] = edi_buffer[3];
edi_buffer[1] = edi_buffer[4];
edi_buffer[2] = edi_buffer[5];
edi_buffer[3] = 0;
edi_buffer[4] = 0;
edi_buffer[5] = 0;
edi_p -= 3;
}
sp++;
}
}
if(current_mode == C1_DECIMAL) { /* Step F - Decimal encodation */
int value, decimal_count, data_left;
next_mode = C1_DECIMAL;
data_left = length - sp;
decimal_count = 0;
if(data_left >= 1) {
if((source[sp] >= '0') && (source[sp] <= '9')) { decimal_count = 1; }
}
if(data_left >= 2) {
if((decimal_count == 1) && ((source[sp + 1] >= '0') && (source[sp + 1] <= '9'))) { decimal_count = 2; }
}
if(data_left >= 3) {
if((decimal_count == 2) && ((source[sp + 2] >= '0') && (source[sp + 2] <= '9'))) { decimal_count = 3; }
}
if(decimal_count != 3) {
int bits_left_in_byte, target_count;
int sub_target;
/* Finish Decimal mode and go back to ASCII */
concat(decimal_binary, "111111"); /* Unlatch */
target_count = 3;
if(strlen(decimal_binary) <= 16) { target_count = 2; }
if(strlen(decimal_binary) <= 8) { target_count = 1; }
bits_left_in_byte = (8 * target_count) - strlen(decimal_binary);
if(bits_left_in_byte == 8) { bits_left_in_byte = 0; }
if(bits_left_in_byte == 2) {
concat(decimal_binary, "01");
}
if((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) {
if(decimal_count >= 1) {
int sub_value = ctoi(source[sp]) + 1;
if(sub_value & 0x08) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(sub_value & 0x04) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(sub_value & 0x02) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(sub_value & 0x01) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
sp++;
} else {
concat(decimal_binary, "1111");
}
}
if(bits_left_in_byte == 6) {
concat(decimal_binary, "01");
}
/* Binary buffer is full - transfer to target */
if(target_count >= 1) {
sub_target = 0;
if(decimal_binary[0] == '1') { sub_target += 128; }
if(decimal_binary[1] == '1') { sub_target += 64; }
if(decimal_binary[2] == '1') { sub_target += 32; }
if(decimal_binary[3] == '1') { sub_target += 16; }
if(decimal_binary[4] == '1') { sub_target += 8; }
if(decimal_binary[5] == '1') { sub_target += 4; }
if(decimal_binary[6] == '1') { sub_target += 2; }
if(decimal_binary[7] == '1') { sub_target += 1; }
target[tp] = sub_target; tp++;
}
if(target_count >= 2) {
sub_target = 0;
if(decimal_binary[8] == '1') { sub_target += 128; }
if(decimal_binary[9] == '1') { sub_target += 64; }
if(decimal_binary[10] == '1') { sub_target += 32; }
if(decimal_binary[11] == '1') { sub_target += 16; }
if(decimal_binary[12] == '1') { sub_target += 8; }
if(decimal_binary[13] == '1') { sub_target += 4; }
if(decimal_binary[14] == '1') { sub_target += 2; }
if(decimal_binary[15] == '1') { sub_target += 1; }
target[tp] = sub_target; tp++;
}
if(target_count == 3) {
sub_target = 0;
if(decimal_binary[16] == '1') { sub_target += 128; }
if(decimal_binary[17] == '1') { sub_target += 64; }
if(decimal_binary[18] == '1') { sub_target += 32; }
if(decimal_binary[19] == '1') { sub_target += 16; }
if(decimal_binary[20] == '1') { sub_target += 8; }
if(decimal_binary[21] == '1') { sub_target += 4; }
if(decimal_binary[22] == '1') { sub_target += 2; }
if(decimal_binary[23] == '1') { sub_target += 1; }
target[tp] = sub_target; tp++;
}
next_mode = C1_ASCII;
} else {
/* There are three digits - convert the value to binary */
value = (100 * ctoi(source[sp])) + (10 * ctoi(source[sp + 1])) + ctoi(source[sp + 2]) + 1;
if(value & 0x200) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(value & 0x100) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(value & 0x80) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(value & 0x40) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(value & 0x20) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(value & 0x10) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(value & 0x08) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(value & 0x04) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(value & 0x02) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
if(value & 0x01) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); }
sp+= 3;
}
if(strlen(decimal_binary) >= 24) {
int target1 = 0, target2 = 0, target3 = 0;
char temp_binary[40];
/* Binary buffer is full - transfer to target */
if(decimal_binary[0] == '1') { target1 += 128; }
if(decimal_binary[1] == '1') { target1 += 64; }
if(decimal_binary[2] == '1') { target1 += 32; }
if(decimal_binary[3] == '1') { target1 += 16; }
if(decimal_binary[4] == '1') { target1 += 8; }
if(decimal_binary[5] == '1') { target1 += 4; }
if(decimal_binary[6] == '1') { target1 += 2; }
if(decimal_binary[7] == '1') { target1 += 1; }
if(decimal_binary[8] == '1') { target2 += 128; }
if(decimal_binary[9] == '1') { target2 += 64; }
if(decimal_binary[10] == '1') { target2 += 32; }
if(decimal_binary[11] == '1') { target2 += 16; }
if(decimal_binary[12] == '1') { target2 += 8; }
if(decimal_binary[13] == '1') { target2 += 4; }
if(decimal_binary[14] == '1') { target2 += 2; }
if(decimal_binary[15] == '1') { target2 += 1; }
if(decimal_binary[16] == '1') { target3 += 128; }
if(decimal_binary[17] == '1') { target3 += 64; }
if(decimal_binary[18] == '1') { target3 += 32; }
if(decimal_binary[19] == '1') { target3 += 16; }
if(decimal_binary[20] == '1') { target3 += 8; }
if(decimal_binary[21] == '1') { target3 += 4; }
if(decimal_binary[22] == '1') { target3 += 2; }
if(decimal_binary[23] == '1') { target3 += 1; }
target[tp] = target1; tp++;
target[tp] = target2; tp++;
target[tp] = target3; tp++;
strcpy(temp_binary, "");
if(strlen(decimal_binary) > 24) {
for(i = 0; i <= (strlen(decimal_binary) - 24); i++) {
temp_binary[i] = decimal_binary[i + 24];
}
strcpy(decimal_binary, temp_binary);
}
}
}
if(current_mode == C1_BYTE) {
next_mode = C1_BYTE;
if(gs1 && (source[sp] == '[')) {
next_mode = C1_ASCII;
} else {
if(source[sp] <= 127) {
next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1);
}
}
if(next_mode != C1_BYTE) {
/* Insert byte field length */
if((tp - byte_start) <= 249) {
for(i = tp; i >= byte_start; i--) {
target[i + 1] = target[i];
}
target[byte_start] = (tp - byte_start);
tp++;
} else {
for(i = tp; i >= byte_start; i--) {
target[i + 2] = target[i];
}
target[byte_start] = 249 + ((tp - byte_start) / 250);
target[byte_start + 1] = ((tp - byte_start) % 250);
tp += 2;
}
} else {
target[tp] = source[sp];
tp++;
sp++;
}
}
if(tp > 1480) {
/* Data is too large for symbol */
strcpy(symbol->errtxt, "Input data too long");
return 0;
}
} while (sp < length);
/* Empty buffers */
if(c40_p == 2) {
int iv;
c40_buffer[2] = 1;
iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1;
target[tp] = iv / 256; tp++;
target[tp] = iv % 256; tp++;
target[tp] = 255; tp++; /* Unlatch */
}
if(c40_p == 1) {
int iv;
c40_buffer[1] = 1;
c40_buffer[2] = 31; /* Pad */
iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1;
target[tp] = iv / 256; tp++;
target[tp] = iv % 256; tp++;
target[tp] = 255; tp++; /* Unlatch */
}
if(text_p == 2) {
int iv;
text_buffer[2] = 1;
iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1;
target[tp] = iv / 256; tp++;
target[tp] = iv % 256; tp++;
target[tp] = 255; tp++; /* Unlatch */
}
if(text_p == 1) {
int iv;
text_buffer[1] = 1;
text_buffer[2] = 31; /* Pad */
iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1;
target[tp] = iv / 256; tp++;
target[tp] = iv % 256; tp++;
target[tp] = 255; tp++; /* Unlatch */
}
if(current_mode == C1_DECIMAL) {
int bits_left_in_byte, target_count;
int sub_target;
/* Finish Decimal mode and go back to ASCII */
concat(decimal_binary, "111111"); /* Unlatch */
target_count = 3;
if(strlen(decimal_binary) <= 16) { target_count = 2; }
if(strlen(decimal_binary) <= 8) { target_count = 1; }
bits_left_in_byte = (8 * target_count) - strlen(decimal_binary);
if(bits_left_in_byte == 8) { bits_left_in_byte = 0; }
if(bits_left_in_byte == 2) {
concat(decimal_binary, "01");
}
if((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) {
concat(decimal_binary, "1111");
}
if(bits_left_in_byte == 6) {
concat(decimal_binary, "01");
}
/* Binary buffer is full - transfer to target */
if(target_count >= 1) {
sub_target = 0;
if(decimal_binary[0] == '1') { sub_target += 128; }
if(decimal_binary[1] == '1') { sub_target += 64; }
if(decimal_binary[2] == '1') { sub_target += 32; }
if(decimal_binary[3] == '1') { sub_target += 16; }
if(decimal_binary[4] == '1') { sub_target += 8; }
if(decimal_binary[5] == '1') { sub_target += 4; }
if(decimal_binary[6] == '1') { sub_target += 2; }
if(decimal_binary[7] == '1') { sub_target += 1; }
target[tp] = sub_target; tp++;
}
if(target_count >= 2) {
sub_target = 0;
if(decimal_binary[8] == '1') { sub_target += 128; }
if(decimal_binary[9] == '1') { sub_target += 64; }
if(decimal_binary[10] == '1') { sub_target += 32; }
if(decimal_binary[11] == '1') { sub_target += 16; }
if(decimal_binary[12] == '1') { sub_target += 8; }
if(decimal_binary[13] == '1') { sub_target += 4; }
if(decimal_binary[14] == '1') { sub_target += 2; }
if(decimal_binary[15] == '1') { sub_target += 1; }
target[tp] = sub_target; tp++;
}
if(target_count == 3) {
sub_target = 0;
if(decimal_binary[16] == '1') { sub_target += 128; }
if(decimal_binary[17] == '1') { sub_target += 64; }
if(decimal_binary[18] == '1') { sub_target += 32; }
if(decimal_binary[19] == '1') { sub_target += 16; }
if(decimal_binary[20] == '1') { sub_target += 8; }
if(decimal_binary[21] == '1') { sub_target += 4; }
if(decimal_binary[22] == '1') { sub_target += 2; }
if(decimal_binary[23] == '1') { sub_target += 1; }
target[tp] = sub_target; tp++;
}
}
if(current_mode == C1_BYTE) {
/* Insert byte field length */
if((tp - byte_start) <= 249) {
for(i = tp; i >= byte_start; i--) {
target[i + 1] = target[i];
}
target[byte_start] = (tp - byte_start);
tp++;
} else {
for(i = tp; i >= byte_start; i--) {
target[i + 2] = target[i];
}
target[byte_start] = 249 + ((tp - byte_start) / 250);
target[byte_start + 1] = ((tp - byte_start) % 250);
tp += 2;
}
}
/* Re-check length of data */
if(tp > 1480) {
/* Data is too large for symbol */
strcpy(symbol->errtxt, "Input data too long");
return 0;
}
/*
printf("targets:\n");
for(i = 0; i < tp; i++) {
printf("[%d]", target[i]);
}
printf("\n");
*/
return tp;
}