int ugs1_verify(struct zint_symbol *symbol, uint8_t source[], const unsigned int src_len, uint8_t reduced[]) { /* Only to keep the compiler happy */ char temp[src_len + 5]; int error_number; error_number = gs1_verify(symbol, source, src_len, temp); if(error_number != 0) { return error_number; } if (strlen(temp) < src_len + 5) { ustrcpy(reduced, (uint8_t*)temp); return 0; } strcpy(symbol->errtxt, "ugs1_verify overflow"); return ZERROR_INVALID_DATA; }
int ugs1_verify(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, unsigned char reduced[]) { /* Only to keep the compiler happy */ #ifndef _MSC_VER char temp[src_len + 5]; #else char* temp = (char*)_alloca(src_len + 5); #endif int error_number; error_number = gs1_verify(symbol, source, src_len, temp); if(error_number != 0) { return error_number; } if (strlen(temp) < src_len + 5) { ustrcpy(reduced, (unsigned char*)temp); return 0; } strcpy(symbol->errtxt, "ugs1_verify overflow"); return ERROR_INVALID_DATA; }
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; }