int code_128(struct zint_symbol *symbol, unsigned char source[], int length) { /* Handle Code 128 and NVE-18 */ int i, j, k,values[170] = { 0 }, bar_characters, read, total_sum; int error_number, indexchaine, indexliste, sourcelen, f_state; char set[170] = { ' ' }, fset[170] = { ' ' }, mode, last_set, current_set = ' '; float glyph_count; char dest[1000]; error_number = 0; strcpy(dest, ""); sourcelen = length; j = 0; bar_characters = 0; f_state = 0; if(sourcelen > 160) { /* This only blocks rediculously long input - the actual length of the resulting barcode depends on the type of data, so this is trapped later */ strcpy(symbol->errtxt, "Input too long"); return ZINT_ERROR_TOO_LONG; } /* Detect extended ASCII characters */ for(i = 0; i < sourcelen; i++) { if(source[i] >= 128) fset[i] = 'f'; } fset[i] = '\0'; /* Decide when to latch to extended mode - Annex E note 3 */ j = 0; for(i = 0; i < sourcelen; i++) { if(fset[i] == 'f') { j++; } else { j = 0; } if(j >= 5) { for(k = i; k > (i - 5); k--) { fset[k] = 'F'; } } if((j >= 3) && (i == (sourcelen - 1))) { for(k = i; k > (i - 3); k--) { fset[k] = 'F'; } } } /* Decide if it is worth reverting to 646 encodation for a few characters as described in 4.3.4.2 (d) */ for(i = 1; i < sourcelen; i++) { if((fset[i - 1] == 'F') && (fset[i] == ' ')) { /* Detected a change from 8859-1 to 646 - count how long for */ for(j = 0; (fset[i + j] == ' ') && ((i + j) < sourcelen); j++); if((j < 5) || ((j < 3) && ((i + j) == (sourcelen - 1)))) { /* Uses the same figures recommended by Annex E note 3 */ /* Change to shifting back rather than latching back */ for(k = 0; k < j; k++) { fset[i + k] = 'n'; } } } } /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ indexliste = 0; indexchaine = 0; mode = parunmodd(source[indexchaine]); if((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) { mode = AORB; } for(i = 0; i < 170; i++) { list[0][i] = 0; } do { list[1][indexliste] = mode; while ((list[1][indexliste] == mode) && (indexchaine < sourcelen)) { list[0][indexliste]++; indexchaine++; mode = parunmodd(source[indexchaine]); if((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) { mode = AORB; } } indexliste++; } while (indexchaine < sourcelen); dxsmooth(&indexliste); /* Resolve odd length LATCHC blocks */ if((list[1][0] == LATCHC) && (list[0][0] & 1)) { /* Rule 2 */ list[0][1]++; list[0][0]--; if(indexliste == 1) { list[0][1] = 1; list[1][1] = LATCHB; indexliste = 2; } } if(indexliste > 1) { for(i = 1; i < indexliste; i++) { if((list[1][i] == LATCHC) && (list[0][i] & 1)) { /* Rule 3b */ list[0][i - 1]++; list[0][i]--; } } } /* Put set data into set[] */ read = 0; for(i = 0; i < indexliste; i++) { for(j = 0; j < list[0][i]; j++) { switch(list[1][i]) { case SHIFTA: set[read] = 'a'; break; case LATCHA: set[read] = 'A'; break; case SHIFTB: set[read] = 'b'; break; case LATCHB: set[read] = 'B'; break; case LATCHC: set[read] = 'C'; break; } read++; } } /* Adjust for strings which start with shift characters - make them latch instead */ if(set[0] == 'a') { i = 0; do { set[i] = 'A'; i++; } while (set[i] == 'a'); } if(set[0] == 'b') { i = 0; do { set[i] = 'B'; i++; } while (set[i] == 'b'); } /* Now we can calculate how long the barcode is going to be - and stop it from being too long */ last_set = ' '; glyph_count = 0.0; for(i = 0; i < sourcelen; i++) { if((set[i] == 'a') || (set[i] == 'b')) { glyph_count = glyph_count + 1.0; } if((fset[i] == 'f') || (fset[i] == 'n')) { glyph_count = glyph_count + 1.0; } if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { if(set[i] != last_set) { last_set = set[i]; glyph_count = glyph_count + 1.0; } } if(i == 0) { if(fset[i] == 'F') { glyph_count = glyph_count + 2.0; } } else { if((fset[i] == 'F') && (fset[i - 1] != 'F')) { glyph_count = glyph_count + 2.0; } if((fset[i] != 'F') && (fset[i - 1] == 'F')) { glyph_count = glyph_count + 2.0; } } if(set[i] == 'C') { glyph_count = glyph_count + 0.5; } else { glyph_count = glyph_count + 1.0; } } if(glyph_count > 80.0) { strcpy(symbol->errtxt, "Input too long"); return ZINT_ERROR_TOO_LONG; } /* So now we know what start character to use - we can get on with it! */ if(symbol->output_options & READER_INIT) { /* Reader Initialisation mode */ switch(set[0]) { case 'A': /* Start A */ concat(dest, C128Table[103]); values[0] = 103; current_set = 'A'; concat(dest, C128Table[96]); /* FNC3 */ values[1] = 96; bar_characters++; break; case 'B': /* Start B */ concat(dest, C128Table[104]); values[0] = 104; current_set = 'B'; concat(dest, C128Table[96]); /* FNC3 */ values[1] = 96; bar_characters++; break; case 'C': /* Start C */ concat(dest, C128Table[104]); /* Start B */ values[0] = 105; concat(dest, C128Table[96]); /* FNC3 */ values[1] = 96; concat(dest, C128Table[99]); /* Code C */ values[2] = 99; bar_characters += 2; current_set = 'C'; break; } } else { /* Normal mode */ switch(set[0]) { case 'A': /* Start A */ concat(dest, C128Table[103]); values[0] = 103; current_set = 'A'; break; case 'B': /* Start B */ concat(dest, C128Table[104]); values[0] = 104; current_set = 'B'; break; case 'C': /* Start C */ concat(dest, C128Table[105]); values[0] = 105; current_set = 'C'; break; } } bar_characters++; last_set = set[0]; if(fset[0] == 'F') { switch(current_set) { case 'A': concat(dest, C128Table[101]); concat(dest, C128Table[101]); values[bar_characters] = 101; values[bar_characters + 1] = 101; break; case 'B': concat(dest, C128Table[100]); concat(dest, C128Table[100]); values[bar_characters] = 100; values[bar_characters + 1] = 100; break; } bar_characters += 2; f_state = 1; } /* Encode the data */ read = 0; do { if((read != 0) && (set[read] != current_set)) { /* Latch different code set */ switch(set[read]) { case 'A': concat(dest, C128Table[101]); values[bar_characters] = 101; bar_characters++; current_set = 'A'; break; case 'B': concat(dest, C128Table[100]); values[bar_characters] = 100; bar_characters++; current_set = 'B'; break; case 'C': concat(dest, C128Table[99]); values[bar_characters] = 99; bar_characters++; current_set = 'C'; break; } } if(read != 0) { if((fset[read] == 'F') && (f_state == 0)) { /* Latch beginning of extended mode */ switch(current_set) { case 'A': concat(dest, C128Table[101]); concat(dest, C128Table[101]); values[bar_characters] = 101; values[bar_characters + 1] = 101; break; case 'B': concat(dest, C128Table[100]); concat(dest, C128Table[100]); values[bar_characters] = 100; values[bar_characters + 1] = 100; break; } bar_characters += 2; f_state = 1; } if((fset[read] == ' ') && (f_state == 1)) { /* Latch end of extended mode */ switch(current_set) { case 'A': concat(dest, C128Table[101]); concat(dest, C128Table[101]); values[bar_characters] = 101; values[bar_characters + 1] = 101; break; case 'B': concat(dest, C128Table[100]); concat(dest, C128Table[100]); values[bar_characters] = 100; values[bar_characters + 1] = 100; break; } bar_characters += 2; f_state = 0; } } if((fset[read] == 'f') || (fset[read] == 'n')) { /* Shift to or from extended mode */ switch(current_set) { case 'A': concat(dest, C128Table[101]); /* FNC 4 */ values[bar_characters] = 101; break; case 'B': concat(dest, C128Table[100]); /* FNC 4 */ values[bar_characters] = 100; break; } bar_characters++; } if((set[read] == 'a') || (set[read] == 'b')) { /* Insert shift character */ concat(dest, C128Table[98]); values[bar_characters] = 98; bar_characters++; } switch(set[read]) { /* Encode data characters */ case 'a': case 'A': c128_set_a(source[read], dest, values, &bar_characters); read++; break; case 'b': case 'B': c128_set_b(source[read], dest, values, &bar_characters); read++; break; case 'C': c128_set_c(source[read], source[read + 1], dest, values, &bar_characters); read += 2; break; } } while (read < sourcelen); /* check digit calculation */ total_sum = 0; /*for(i = 0; i < bar_characters; i++) { printf("%d\n", values[i]); }*/ for(i = 0; i < bar_characters; i++) { if(i > 0) { values[i] *= i; } total_sum += values[i]; } concat(dest, C128Table[total_sum%103]); /* Stop character */ concat(dest, C128Table[106]); expand(symbol, dest); return error_number; }
int ean_128(struct zint_symbol *symbol, unsigned char source[], int length) { /* Handle EAN-128 (Now known as GS1-128) */ int i, j,values[170], bar_characters, read, total_sum; int error_number, indexchaine, indexliste; char set[170], mode, last_set; float glyph_count; char dest[1000]; int separator_row, linkage_flag, c_count; #ifndef _MSC_VER char reduced[length + 1]; #else char* reduced = (char*)_alloca(length + 1); #endif error_number = 0; strcpy(dest, ""); linkage_flag = 0; j = 0; bar_characters = 0; separator_row = 0; memset(values, 0, sizeof(values)); memset(set, ' ', sizeof(set)); if(length > 160) { /* This only blocks rediculously long input - the actual length of the resulting barcode depends on the type of data, so this is trapped later */ strcpy(symbol->errtxt, "Input too long"); return ZINT_ERROR_TOO_LONG; } for(i = 0; i < length; i++) { if(source[i] == '\0') { /* Null characters not allowed! */ strcpy(symbol->errtxt, "NULL character in input data"); return ZINT_ERROR_INVALID_DATA; } } /* if part of a composite symbol make room for the separator pattern */ if(symbol->symbology == BARCODE_EAN128_CC) { separator_row = symbol->rows; symbol->row_height[symbol->rows] = 1; symbol->rows += 1; } if(symbol->input_mode != GS1_MODE) { /* GS1 data has not been checked yet */ error_number = gs1_verify(symbol, source, length, reduced); if(error_number != 0) { return error_number; } } /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ indexliste = 0; indexchaine = 0; mode = parunmodd(reduced[indexchaine]); if(reduced[indexchaine] == '[') { mode = ABORC; } for(i = 0; i < 170; i++) { list[0][i] = 0; } do { list[1][indexliste] = mode; while ((list[1][indexliste] == mode) && (indexchaine < strlen(reduced))) { list[0][indexliste]++; indexchaine++; mode = parunmodd(reduced[indexchaine]); if(reduced[indexchaine] == '[') { mode = ABORC; } } indexliste++; } while (indexchaine < strlen(reduced)); dxsmooth(&indexliste); /* Put set data into set[] */ read = 0; for(i = 0; i < indexliste; i++) { for(j = 0; j < list[0][i]; j++) { switch(list[1][i]) { case SHIFTA: set[read] = 'a'; break; case LATCHA: set[read] = 'A'; break; case SHIFTB: set[read] = 'b'; break; case LATCHB: set[read] = 'B'; break; case LATCHC: set[read] = 'C'; break; } read++; } } /* Watch out for odd-length Mode C blocks */ c_count = 0; for(i = 0; i < read; i++) { if(set[i] == 'C') { if(reduced[i] == '[') { if(c_count & 1) { if((i - c_count) != 0) { set[i - c_count] = 'B'; } else { set[i - 1] = 'B'; } } c_count = 0; } else { c_count++; } } else { if(c_count & 1) { if((i - c_count) != 0) { set[i - c_count] = 'B'; } else { set[i - 1] = 'B'; } } c_count = 0; } } if(c_count & 1) { if((i - c_count) != 0) { set[i - c_count] = 'B'; } else { set[i - 1] = 'B'; } } for(i = 1; i < read - 1; i++) { if((set[i] == 'C') && ((set[i - 1] == 'B') && (set[i + 1] == 'B'))) { set[i] = 'B'; } } /* for(i = 0; i < read; i++) { printf("char %c mode %c\n", reduced[i], set[i]); } */ /* Now we can calculate how long the barcode is going to be - and stop it from being too long */ last_set = ' '; glyph_count = 0.0; for(i = 0; i < strlen(reduced); i++) { if((set[i] == 'a') || (set[i] == 'b')) { glyph_count = glyph_count + 1.0; } if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { if(set[i] != last_set) { last_set = set[i]; glyph_count = glyph_count + 1.0; } } if((set[i] == 'C') && (reduced[i] != '[')) { glyph_count = glyph_count + 0.5; } else { glyph_count = glyph_count + 1.0; } } if(glyph_count > 80.0) { strcpy(symbol->errtxt, "Input too long"); return ZINT_ERROR_TOO_LONG; } /* So now we know what start character to use - we can get on with it! */ switch(set[0]) { case 'A': /* Start A */ concat(dest, C128Table[103]); values[0] = 103; break; case 'B': /* Start B */ concat(dest, C128Table[104]); values[0] = 104; break; case 'C': /* Start C */ concat(dest, C128Table[105]); values[0] = 105; break; } bar_characters++; concat(dest, C128Table[102]); values[1] = 102; bar_characters++; /* Encode the data */ read = 0; do { if((read != 0) && (set[read] != set[read - 1])) { /* Latch different code set */ switch(set[read]) { case 'A': concat(dest, C128Table[101]); values[bar_characters] = 101; bar_characters++; break; case 'B': concat(dest, C128Table[100]); values[bar_characters] = 100; bar_characters++; break; case 'C': concat(dest, C128Table[99]); values[bar_characters] = 99; bar_characters++; break; } } if((set[read] == 'a') || (set[read] == 'b')) { /* Insert shift character */ concat(dest, C128Table[98]); values[bar_characters] = 98; bar_characters++; } if(reduced[read] != '[') { switch(set[read]) { /* Encode data characters */ case 'A': case 'a': c128_set_a(reduced[read], dest, values, &bar_characters); read++; break; case 'B': case 'b': c128_set_b(reduced[read], dest, values, &bar_characters); read++; break; case 'C': c128_set_c(reduced[read], reduced[read + 1], dest, values, &bar_characters); read += 2; break; } } else { concat(dest, C128Table[102]); values[bar_characters] = 102; bar_characters++; read++; } } while (read < strlen(reduced)); /* "...note that the linkage flag is an extra code set character between the last data character and the Symbol Check Character" (GS1 Specification) */ /* Linkage flags in GS1-128 are determined by ISO/IEC 24723 section 7.4 */ switch(symbol->option_1) { case 1: case 2: /* CC-A or CC-B 2D component */ switch(set[strlen(reduced) - 1]) { case 'A': linkage_flag = 100; break; case 'B': linkage_flag = 99; break; case 'C': linkage_flag = 101; break; } break; case 3: /* CC-C 2D component */ switch(set[strlen(reduced) - 1]) { case 'A': linkage_flag = 99; break; case 'B': linkage_flag = 101; break; case 'C': linkage_flag = 100; break; } break; } if(linkage_flag != 0) { concat(dest, C128Table[linkage_flag]); values[bar_characters] = linkage_flag; bar_characters++; } /*for(i = 0; i < bar_characters; i++) { printf("[%d] ", values[i]); } printf("\n");*/ /* check digit calculation */ total_sum = 0; for(i = 0; i < bar_characters; i++) { if(i > 0) { values[i] *= i; } total_sum += values[i]; } concat(dest, C128Table[total_sum%103]); values[bar_characters] = total_sum % 103; bar_characters++; /* Stop character */ concat(dest, C128Table[106]); values[bar_characters] = 106; bar_characters++; expand(symbol, dest); /* Add the separator pattern for composite symbols */ if(symbol->symbology == BARCODE_EAN128_CC) { for(i = 0; i < symbol->width; i++) { if(!(module_is_set(symbol, separator_row + 1, i))) { set_module(symbol, separator_row, i); } } } for(i = 0; i < length; i++) { if((source[i] != '[') && (source[i] != ']')) { symbol->text[i] = source[i]; } if(source[i] == '[') { symbol->text[i] = '('; } if(source[i] == ']') { symbol->text[i] = ')'; } } return error_number; }
int code16k(struct zint_symbol *symbol, uint8_t source[], int length) { char width_pattern[100]; int current_row, rows_needed, flip_flop, looper, first_check, second_check; int indexliste, indexchaine, pads_needed, f_state; char set[160] = { ' ' }, fset[160] = { ' ' }, mode, last_set, current_set; unsigned int i, j, k, m, read, mx_reader, writer; unsigned int values[160] = { 0 }; unsigned int bar_characters; float glyph_count; int errornum, first_sum, second_sum; int input_length; int gs1, c_count; errornum = 0; strcpy(width_pattern, ""); input_length = length; if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } if(input_length > 157) { strcpy(symbol->errtxt, "Input too long"); return ZERROR_TOO_LONG; } bar_characters = 0; /* Detect extended ASCII characters */ for(i = 0; i < input_length; i++) { if(source[i] >=128) { fset[i] = 'f'; } } fset[i] = '\0'; /* Decide when to latch to extended mode */ for(i = 0; i < input_length; i++) { j = 0; if(fset[i] == 'f') { do { j++; } while(fset[i + j] == 'f'); if((j >= 5) || ((j >= 3) && ((i + j) == (input_length - 1)))) { for(k = 0; k <= j; k++) { fset[i + k] = 'F'; } } } } /* Decide if it is worth reverting to 646 encodation for a few characters */ if(input_length > 1) { for(i = 1; i < input_length; i++) { if((fset[i - 1] == 'F') && (fset[i] == ' ')) { /* Detected a change from 8859-1 to 646 - count how long for */ for(j = 0; (fset[i + j] == ' ') && ((i + j) < input_length); j++); if((j < 5) || ((j < 3) && ((i + j) == (input_length - 1)))) { /* Change to shifting back rather than latching back */ for(k = 0; k < j; k++) { fset[i + k] = 'n'; } } } } } /* Detect mode A, B and C characters */ indexliste = 0; indexchaine = 0; mode = parunmodd(source[indexchaine]); if((gs1) && (source[indexchaine] == '[')) { mode = ABORC; } /* FNC1 */ for(i = 0; i < 160; i++) { list[0][i] = 0; } do { list[1][indexliste] = mode; while ((list[1][indexliste] == mode) && (indexchaine < input_length)) { list[0][indexliste]++; indexchaine++; mode = parunmodd(source[indexchaine]); if((gs1) && (source[indexchaine] == '[')) { mode = ABORC; } /* FNC1 */ } indexliste++; } while (indexchaine < input_length); dxsmooth16(&indexliste); /* Put set data into set[] */ read = 0; for(i = 0; i < indexliste; i++) { for(j = 0; j < list[0][i]; j++) { switch(list[1][i]) { case SHIFTA: set[read] = 'a'; break; case LATCHA: set[read] = 'A'; break; case SHIFTB: set[read] = 'b'; break; case LATCHB: set[read] = 'B'; break; case LATCHC: set[read] = 'C'; break; } read++; } } /* Adjust for strings which start with shift characters - make them latch instead */ if(set[0] == 'a') { i = 0; do { set[i] = 'A'; i++; } while (set[i] == 'a'); } if(set[0] == 'b') { i = 0; do { set[i] = 'B'; i++; } while (set[i] == 'b'); } /* Watch out for odd-length Mode C blocks */ c_count = 0; for(i = 0; i < read; i++) { if(set[i] == 'C') { if(source[i] == '[') { if(c_count & 1) { if((i - c_count) != 0) { set[i - c_count] = 'B'; } else { set[i - 1] = 'B'; } } c_count = 0; } else { c_count++; } } else { if(c_count & 1) { if((i - c_count) != 0) { set[i - c_count] = 'B'; } else { set[i - 1] = 'B'; } } c_count = 0; } } if(c_count & 1) { if((i - c_count) != 0) { set[i - c_count] = 'B'; } else { set[i - 1] = 'B'; } } for(i = 1; i < read - 1; i++) { if((set[i] == 'C') && ((set[i - 1] == 'B') && (set[i + 1] == 'B'))) { set[i] = 'B'; } } /* Make sure the data will fit in the symbol */ last_set = ' '; glyph_count = 0.0; for(i = 0; i < input_length; i++) { if((set[i] == 'a') || (set[i] == 'b')) { glyph_count = glyph_count + 1.0; } if((fset[i] == 'f') || (fset[i] == 'n')) { glyph_count = glyph_count + 1.0; } if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { if(set[i] != last_set) { last_set = set[i]; glyph_count = glyph_count + 1.0; } } if(i == 0) { if((set[i] == 'B') && (set[1] == 'C')) { glyph_count = glyph_count - 1.0; } if((set[i] == 'B') && (set[1] == 'B')) { if(set[2] == 'C') { glyph_count = glyph_count - 1.0; } } if(fset[i] == 'F') { glyph_count = glyph_count + 2.0; } } else { if((fset[i] == 'F') && (fset[i - 1] != 'F')) { glyph_count = glyph_count + 2.0; } if((fset[i] != 'F') && (fset[i - 1] == 'F')) { glyph_count = glyph_count + 2.0; } } if((set[i] == 'C') && (!((gs1) && (source[i] == '[')))) { glyph_count = glyph_count + 0.5; } else { glyph_count = glyph_count + 1.0; } } if((gs1) && (set[0] != 'A')) { /* FNC1 can be integrated with mode character */ glyph_count--; } if(glyph_count > 77.0) { strcpy(symbol->errtxt, "Input too long"); return ZERROR_TOO_LONG; } /* Calculate how tall the symbol will be */ glyph_count = glyph_count + 2.0; i = glyph_count; rows_needed = (i/5); if(i%5 > 0) { rows_needed++; } if(rows_needed == 1) { rows_needed = 2; } /* start with the mode character - Table 2 */ m = 0; switch(set[0]) { case 'A': m = 0; break; case 'B': m = 1; break; case 'C': m = 2; break; } if(symbol->output_options & READER_INIT) { if(m == 2) { m = 5; } if(gs1) { strcpy(symbol->errtxt, "Cannot use both GS1 mode and Reader Initialisation"); return ZERROR_INVALID_OPTION; } else { if((set[0] == 'B') && (set[1] == 'C')) { m = 6; } } values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */ values[bar_characters + 1] = 96; /* FNC3 */ bar_characters += 2; } else { if(gs1) { /* Integrate FNC1 */ switch(set[0]) { case 'B': m = 3; break; case 'C': m = 4; break; } } else { if((set[0] == 'B') && (set[1] == 'C')) { m = 5; } if(((set[0] == 'B') && (set[1] == 'B')) && (set[2] == 'C')) { m = 6; } } values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */ bar_characters++; } current_set = set[0]; f_state = 0; /* f_state remembers if we are in Extended ASCII mode (value 1) or in ISO/IEC 646 mode (value 0) */ if(fset[0] == 'F') { switch(current_set) { case 'A': values[bar_characters] = 101; values[bar_characters + 1] = 101; break; case 'B': values[bar_characters] = 100; values[bar_characters + 1] = 100; break; } bar_characters += 2; f_state = 1; } read = 0; /* Encode the data */ do { if((read != 0) && (set[read] != set[read - 1])) { /* Latch different code set */ switch(set[read]) { case 'A': values[bar_characters] = 101; bar_characters++; current_set = 'A'; break; case 'B': values[bar_characters] = 100; bar_characters++; current_set = 'B'; break; case 'C': if(!((read == 1) && (set[0] == 'B'))) { /* Not Mode C/Shift B */ if(!((read == 2) && ((set[0] == 'B') && (set[1] == 'B')))) { /* Not Mode C/Double Shift B */ values[bar_characters] = 99; bar_characters++; } } current_set = 'C'; break; } } /* printf("tp8\n"); */ if(read != 0) { if((fset[read] == 'F') && (f_state == 0)) { /* Latch beginning of extended mode */ switch(current_set) { case 'A': values[bar_characters] = 101; values[bar_characters + 1] = 101; break; case 'B': values[bar_characters] = 100; values[bar_characters + 1] = 100; break; } bar_characters += 2; f_state = 1; } if((fset[read] == ' ') && (f_state == 1)) { /* Latch end of extended mode */ switch(current_set) { case 'A': values[bar_characters] = 101; values[bar_characters + 1] = 101; break; case 'B': values[bar_characters] = 100; values[bar_characters + 1] = 100; break; } bar_characters += 2; f_state = 0; } } if((fset[i] == 'f') || (fset[i] == 'n')) { /* Shift extended mode */ switch(current_set) { case 'A': values[bar_characters] = 101; /* FNC 4 */ break; case 'B': values[bar_characters] = 100; /* FNC 4 */ break; } bar_characters++; } if((set[i] == 'a') || (set[i] == 'b')) { /* Insert shift character */ values[bar_characters] = 98; bar_characters++; } if(!((gs1) && (source[read] == '['))) { switch(set[read]) { /* Encode data characters */ case 'A': case 'a': c16k_set_a(source[read], values, &bar_characters); read++; break; case 'B': case 'b': c16k_set_b(source[read], values, &bar_characters); read++; break; case 'C': c16k_set_c(source[read], source[read + 1], values, &bar_characters); read += 2; break; } } else { values[bar_characters] = 102; bar_characters++; read++; } /* printf("tp9 read=%d surrent set=%c\n", read, set[read]); */ } while (read < ustrlen(source)); pads_needed = 5 - ((bar_characters + 2) % 5); if(pads_needed == 5) { pads_needed = 0; } if((bar_characters + pads_needed) < 8) { pads_needed += 8 - (bar_characters + pads_needed); } for(i = 0; i < pads_needed; i++) { values[bar_characters] = 106; bar_characters++; } /* Calculate check digits */ first_sum = 0; second_sum = 0; for(i = 0; i < bar_characters; i++) { first_sum += (i+2) * values[i]; second_sum += (i+1) * values[i]; } first_check = first_sum % 107; second_sum += first_check * (bar_characters + 1); second_check = second_sum % 107; values[bar_characters] = first_check; values[bar_characters + 1] = second_check; bar_characters += 2; for(current_row = 0; current_row < rows_needed; current_row++) { strcpy(width_pattern, ""); concat(width_pattern, C16KStartStop[C16KStartValues[current_row]]); concat(width_pattern, "1"); for(i = 0; i < 5; i++) { concat(width_pattern, C16KTable[values[(current_row * 5) + i]]); /* printf("[%d] ", values[(current_row * 5) + i]); */ } concat(width_pattern, C16KStartStop[C16KStopValues[current_row]]); /* printf("\n"); */ /* Write the information into the symbol */ writer = 0; flip_flop = 1; for (mx_reader = 0; mx_reader < strlen(width_pattern); mx_reader++) { for(looper = 0; looper < ctoi(width_pattern[mx_reader]); looper++) { if(flip_flop == 1) { set_module(symbol, current_row, writer); writer++; } else { writer++; } } if(flip_flop == 0) { flip_flop = 1; } else { flip_flop = 0; } } symbol->row_height[current_row] = 10; } symbol->rows = rows_needed; symbol->width = 70; return errornum; }