int interleaved_two_of_five(struct zint_symbol *symbol, uint8_t source[], int length) { /* Code 2 of 5 Interleaved */ int error_number; char bars[7], spaces[7], mixed[14], dest[1000]; uint8_t temp[length + 2]; error_number = 0; if(length > 89) { strcpy(symbol->errtxt, "Input too long"); return ZERROR_TOO_LONG; } error_number = is_sane(NEON, source, length); if (error_number == ZERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } ustrcpy(temp, (uint8_t *) ""); /* Input must be an even number of characters for Interlaced 2 of 5 to work: if an odd number of characters has been entered then add a leading zero */ if (length & 1) { ustrcpy(temp, (uint8_t *) "0"); length++; } uconcat(temp, source); /* start character */ strcpy(dest, "1111"); for(int i = 0; i < length; i+=2) { /* look up the bars and the spaces and put them in two strings */ strcpy(bars, ""); lookup(NEON, C25InterTable, temp[i], bars); strcpy(spaces, ""); lookup(NEON, C25InterTable, temp[i + 1], spaces); /* then merge (interlace) the strings together */ int k = 0; for(int j = 0; j <= 4; j++) { mixed[k] = bars[j]; k++; mixed[k] = spaces[j]; k++; } mixed[k] = '\0'; concat (dest, mixed); } /* Stop character */ concat (dest, "311"); expand(symbol, dest); ustrcpy(symbol->text, temp); return error_number; }
int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length) { /* Pharmazentral Nummer (PZN) */ int i, error_number, zeroes; unsigned int count, check_digit; char localstr[10]; error_number = 0; count = 0; if(length > 6) { strcpy(symbol->errtxt, "Input wrong length"); return ERROR_TOO_LONG; } error_number = is_sane(NEON, source, length); if(error_number == ERROR_INVALID_DATA1) { strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } localstr[0] = '-'; zeroes = 6 - length + 1; for(i = 1; i < zeroes; i++) localstr[i] = '0'; strcpy(localstr + zeroes, (char *)source); for (i = 1; i < 7; i++) { count += (i + 1) * ctoi(localstr[i]); } check_digit = count%11; if (check_digit == 11) { check_digit = 0; } localstr[7] = itoc(check_digit); localstr[8] = '\0'; if(localstr[7] == 'A') { strcpy(symbol->errtxt, "Invalid PZN Data"); return ERROR_INVALID_DATA1; } error_number = c39(symbol, (unsigned char *)localstr, strlen(localstr)); ustrcpy(symbol->text, (unsigned char *)"PZN"); uconcat(symbol->text, (unsigned char *)localstr); return error_number; }
int code32(struct zint_symbol *symbol, unsigned char source[], int length) { /* Italian Pharmacode */ int i, zeroes, error_number, checksum, checkpart, checkdigit; char localstr[10], risultante[7]; long int pharmacode, remainder, devisor; int codeword[6]; char tabella[34]; /* Validate the input */ if(length > 8) { strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } error_number = is_sane(NEON, source, length); if(error_number == ERROR_INVALID_DATA1) { strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } /* Add leading zeros as required */ zeroes = 8 - length; memset(localstr, '0', zeroes); strcpy(localstr + zeroes, (char*)source); /* Calculate the check digit */ checksum = 0; checkpart = 0; for(i = 0; i < 4; i++) { checkpart = ctoi(localstr[i * 2]); checksum += checkpart; checkpart = 2 * (ctoi(localstr[(i * 2) + 1])); if(checkpart >= 10) { checksum += (checkpart - 10) + 1; } else { checksum += checkpart; } } /* Add check digit to data string */ checkdigit = checksum % 10; localstr[8] = itoc(checkdigit); localstr[9] = '\0'; /* Convert string into an integer value */ pharmacode = atoi(localstr); /* Convert from decimal to base-32 */ devisor = 33554432; for(i = 5; i >= 0; i--) { codeword[i] = pharmacode / devisor; remainder = pharmacode % devisor; pharmacode = remainder; devisor /= 32; } /* Look up values in 'Tabella di conversione' */ strcpy(tabella, "0123456789BCDFGHJKLMNPQRSTUVWXYZ"); for(i = 5; i >= 0; i--) { risultante[5 - i] = tabella[codeword[i]]; } risultante[6] = '\0'; /* Plot the barcode using Code 39 */ error_number = c39(symbol, (unsigned char*)risultante, strlen(risultante)); if(error_number != 0) { return error_number; } /* Override the normal text output with the Pharmacode number */ ustrcpy(symbol->text, (unsigned char*)"A"); uconcat(symbol->text, (unsigned char*)localstr); return error_number; }
int code_11(struct zint_symbol *symbol, unsigned char source[], int length) { /* Code 11 */ int i; int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count; int weight[128], error_number; char dest[1024]; /* 6 + 121 * 6 + 2 * 6 + 5 + 1 ~ 1024*/ char checkstr[3]; error_number = 0; if(length > 121) { strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } error_number = is_sane(SODIUM, source, length); if(error_number == ERROR_INVALID_DATA1) { strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } c_weight = 1; c_count = 0; k_weight = 1; k_count = 0; /* start character */ strcpy(dest, "112211"); /* Draw main body of barcode */ for(i = 0; i < length; i++) { lookup(SODIUM, C11Table, source[i], dest); if(source[i] == '-') weight[i] = 10; else weight[i] = ctoi(source[i]); } /* Calculate C checksum */ for(h = length - 1; h >= 0; h--) { c_count += (c_weight * weight[h]); c_weight++; if(c_weight > 10) { c_weight = 1; } } c_digit = c_count % 11; weight[length] = c_digit; /* Calculate K checksum */ for(h = length; h >= 0; h--) { k_count += (k_weight * weight[h]); k_weight++; if(k_weight > 9) { k_weight = 1; } } k_digit = k_count % 11; checkstr[0] = itoc(c_digit); checkstr[1] = itoc(k_digit); if(checkstr[0] == 'A') { checkstr[0] = '-'; } if(checkstr[1] == 'A') { checkstr[1] = '-'; } checkstr[2] = '\0'; lookup(SODIUM, C11Table, checkstr[0], dest); lookup(SODIUM, C11Table, checkstr[1], dest); /* Stop character */ concat (dest, "11221"); expand(symbol, dest); ustrcpy(symbol->text, source); uconcat(symbol->text, (unsigned char*)checkstr); return error_number; }
int c39(struct zint_symbol *symbol, unsigned char source[], unsigned int length) { /* Code 39 */ unsigned int i; unsigned int counter = 0; char check_digit; int error_number = 0; char dest[775]; char localstr[2] = { 0 }; if((symbol->option_2 < 0) || (symbol->option_2 > 1)) { symbol->option_2 = 0; } if((symbol->symbology == BARCODE_LOGMARS) && (length > 59)) { strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } else if(length > 74) { strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } to_upper(source); error_number = is_sane(SILVER , source, length); if(error_number == ERROR_INVALID_DATA1) { strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } /* Start character */ strcpy(dest, "1211212111"); for(i = 0; i < length; i++) { lookup(SILVER, C39Table, source[i], dest); counter += posn(SILVER, source[i]); } if((symbol->symbology == BARCODE_LOGMARS) || (symbol->option_2 == 1)) { counter = counter % 43; if(counter < 10) { check_digit = itoc(counter); } else { if(counter < 36) { check_digit = (counter - 10) + 'A'; } else { switch(counter) { case 36: check_digit = '-'; break; case 37: check_digit = '.'; break; case 38: check_digit = ' '; break; case 39: check_digit = '$'; break; case 40: check_digit = '/'; break; case 41: check_digit = '+'; break; case 42: check_digit = 37; break; default: check_digit = ' '; break; /* Keep compiler happy */ } } } lookup(SILVER, C39Table, check_digit, dest); /* Display a space check digit as _, otherwise it looks like an error */ if(check_digit == ' ') { check_digit = '_'; } localstr[0] = check_digit; localstr[1] = '\0'; } /* Stop character */ concat (dest, "121121211"); if((symbol->symbology == BARCODE_LOGMARS) || (symbol->symbology == BARCODE_HIBC_39)) { /* LOGMARS uses wider 'wide' bars than normal Code 39 */ counter = strlen(dest); for(i = 0; i < counter; i++) { if(dest[i] == '2') { dest[i] = '3'; } } } expand(symbol, dest); if(symbol->symbology == BARCODE_CODE39) { ustrcpy(symbol->text, (unsigned char*)"*"); uconcat(symbol->text, source); uconcat(symbol->text, (unsigned char*)localstr); uconcat(symbol->text, (unsigned char*)"*"); } else { ustrcpy(symbol->text, source); uconcat(symbol->text, (unsigned char*)localstr); } return error_number; }
int eanx(struct zint_symbol *symbol, unsigned char source[], int src_len) { /* splits string to parts before and after '+' parts */ unsigned char first_part[20] = { 0 }, second_part[20] = { 0 }, dest[1000] = { 0 }; unsigned char local_source[20] = { 0 }; unsigned int latch, reader, writer, with_addon; int error_number, i; with_addon = FALSE; latch = FALSE; writer = 0; if(src_len > 19) { strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } if(symbol->symbology != BARCODE_ISBNX) { /* ISBN has it's own checking routine */ error_number = is_sane("0123456789+", source, src_len); if(error_number == ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } } else { error_number = is_sane("0123456789Xx", source, src_len); if(error_number == ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Invalid characters in input"); return error_number; } } /* Add leading zeroes */ ustrcpy(local_source, (unsigned char *)""); if(symbol->symbology == BARCODE_ISBNX) { to_upper(local_source); } ean_leading_zeroes(symbol, source, local_source); for(reader = 0; reader <= ustrlen(local_source); reader++) { if(source[reader] == '+') { with_addon = TRUE; } } reader = 0; if(with_addon) { do { if(local_source[reader] == '+') { first_part[writer] = '\0'; latch = TRUE; reader++; writer = 0; } if(latch) { second_part[writer] = local_source[reader]; reader++; writer++; } else { first_part[writer] = local_source[reader]; reader++; writer++; } } while (reader <= ustrlen(local_source)); } else { strcpy((char*)first_part, (char*)local_source); } switch(symbol->symbology) { case BARCODE_EANX: switch(ustrlen(first_part)) { case 2: add_on(first_part, (char*)dest, 0); ustrcpy(symbol->text, first_part); break; case 5: add_on(first_part, (char*)dest, 0); ustrcpy(symbol->text, first_part); break; case 7: ean8(symbol, first_part, (char*)dest); break; case 12: ean13(symbol, first_part, (char*)dest); break; default: strcpy(symbol->errtxt, "Invalid length input"); return ERROR_TOO_LONG; break; } break; case BARCODE_EANX_CC: switch(ustrlen(first_part)) { /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */ case 7: set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 67); set_module(symbol, symbol->rows + 1, 0); set_module(symbol, symbol->rows + 1, 68); set_module(symbol, symbol->rows + 2, 1); set_module(symbol, symbol->rows + 1, 67); symbol->row_height[symbol->rows] = 2; symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; ean8(symbol, first_part, (char*)dest); break; case 12:set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 95); set_module(symbol, symbol->rows + 1, 0); set_module(symbol, symbol->rows + 1, 96); set_module(symbol, symbol->rows + 2, 1); set_module(symbol, symbol->rows + 2, 95); symbol->row_height[symbol->rows] = 2; symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; ean13(symbol, first_part, (char*)dest); break; default: strcpy(symbol->errtxt, "Invalid length EAN input"); return ERROR_TOO_LONG; break; } break; case BARCODE_UPCA: if(ustrlen(first_part) == 11) { upca(symbol, first_part, (char*)dest); } else { strcpy(symbol->errtxt, "Input wrong length"); return ERROR_TOO_LONG; } break; case BARCODE_UPCA_CC: if(ustrlen(first_part) == 11) { set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 95); set_module(symbol, symbol->rows + 1, 0); set_module(symbol, symbol->rows + 1, 96); set_module(symbol, symbol->rows + 2, 1); set_module(symbol, symbol->rows + 2, 95); symbol->row_height[symbol->rows] = 2; symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; upca(symbol, first_part, (char*)dest); } else { strcpy(symbol->errtxt, "UPCA input wrong length"); return ERROR_TOO_LONG; } break; case BARCODE_UPCE: if((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) { upce(symbol, first_part, (char*)dest); } else { strcpy(symbol->errtxt, "Input wrong length"); return ERROR_TOO_LONG; } break; case BARCODE_UPCE_CC: if((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) { set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 51); set_module(symbol, symbol->rows + 1, 0); set_module(symbol, symbol->rows + 1, 52); set_module(symbol, symbol->rows + 2, 1); set_module(symbol, symbol->rows + 2, 51); symbol->row_height[symbol->rows] = 2; symbol->row_height[symbol->rows + 1] = 2; symbol->row_height[symbol->rows + 2] = 2; symbol->rows += 3; upce(symbol, first_part, (char*)dest); } else { strcpy(symbol->errtxt, "UPCE input wrong length"); return ERROR_TOO_LONG; } break; case BARCODE_ISBNX: error_number = isbn(symbol, first_part, ustrlen(first_part), (char*)dest); if(error_number > 4) { return error_number; } break; } switch(ustrlen(second_part)) { case 0: break; case 2: add_on(second_part, (char*)dest, 1); uconcat(symbol->text, (unsigned char*)"+"); uconcat(symbol->text, second_part); break; case 5: add_on(second_part, (char*)dest, 1); uconcat(symbol->text, (unsigned char*)"+"); uconcat(symbol->text, second_part); break; default: strcpy(symbol->errtxt, "Invalid length input"); return ERROR_TOO_LONG; break; } expand(symbol, (char*)dest); switch(symbol->symbology) { case BARCODE_EANX_CC: case BARCODE_UPCA_CC: case BARCODE_UPCE_CC: /* shift the symbol to the right one space to allow for separator bars */ for(i = (symbol->width + 1); i >= 1; i--) { if(module_is_set(symbol, symbol->rows - 1, i - 1)) { set_module(symbol, symbol->rows - 1, i); } else { unset_module(symbol, symbol->rows - 1, i); } } unset_module(symbol, symbol->rows - 1, 0); symbol->width += 2; break; } if((symbol->errtxt[0] == 'w') && (error_number == 0)) { error_number = 1; /* flag UPC-E warnings */ } return error_number; }
void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]) { /* Add leading zeroes to EAN and UPC strings */ unsigned char first_part[20], second_part[20], zfirst_part[20], zsecond_part[20]; int with_addon = 0; int first_len = 0, second_len = 0, zfirst_len = 0, zsecond_len = 0, i, h; h = ustrlen(source); for(i = 0; i < h; i++) { if(source[i] == '+') { with_addon = 1; } else { if(with_addon == 0) { first_len++; } else { second_len++; } } } ustrcpy(first_part, (unsigned char *)""); ustrcpy(second_part, (unsigned char *)""); ustrcpy(zfirst_part, (unsigned char *)""); ustrcpy(zsecond_part, (unsigned char *)""); /* Split input into two strings */ for(i = 0; i < first_len; i++) { first_part[i] = source[i]; first_part[i + 1] = '\0'; } for(i = 0; i < second_len; i++) { second_part[i] = source[i + first_len + 1]; second_part[i + 1] = '\0'; } /* Calculate target lengths */ if(second_len <= 5) { zsecond_len = 5; } if(second_len <= 2) { zsecond_len = 2; } if(second_len == 0) { zsecond_len = 0; } switch(symbol->symbology) { case BARCODE_EANX: case BARCODE_EANX_CC: if(first_len <= 12) { zfirst_len = 12; } if(first_len <= 7) { zfirst_len = 7; } if(second_len == 0) { if(first_len <= 5) { zfirst_len = 5; } if(first_len <= 2) { zfirst_len = 2; } } break; case BARCODE_UPCA: case BARCODE_UPCA_CC: zfirst_len = 11; break; case BARCODE_UPCE: case BARCODE_UPCE_CC: if(first_len == 7) { zfirst_len = 7; } if(first_len <= 6) { zfirst_len = 6; } break; case BARCODE_ISBNX: if(first_len <= 9) { zfirst_len = 9; } break; } /* Add leading zeroes */ for(i = 0; i < (zfirst_len - first_len); i++) { uconcat(zfirst_part, (unsigned char *)"0"); } uconcat(zfirst_part, first_part); for(i = 0; i < (zsecond_len - second_len); i++) { uconcat(zsecond_part, (unsigned char *)"0"); } uconcat(zsecond_part, second_part); /* Copy adjusted data back to local_source */ uconcat(local_source, zfirst_part); if(zsecond_len != 0) { uconcat(local_source, (unsigned char *)"+"); uconcat(local_source, zsecond_part); } }
int hibc(struct zint_symbol *symbol, unsigned char source[], int length) { int counter, error_number, i; char to_process[40], temp[2], check_digit; if(length > 36) { strcpy(symbol->errtxt, "Data too long for HIBC LIC"); return ERROR_TOO_LONG; } to_upper(source); error_number = is_sane(TECHNETIUM , source, length); if(error_number == ERROR_INVALID_DATA1) { strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } strcpy(to_process, "+"); counter = 41; for(i = 0; i < length; i++) { counter += posn(TECHNETIUM, source[i]); } counter = counter % 43; if(counter < 10) { check_digit = itoc(counter); } else { if(counter < 36) { check_digit = (counter - 10) + 'A'; } else { switch(counter) { case 36: check_digit = '-'; break; case 37: check_digit = '.'; break; case 38: check_digit = ' '; break; case 39: check_digit = '$'; break; case 40: check_digit = '/'; break; case 41: check_digit = '+'; break; case 42: check_digit = '%'; break; default: check_digit = ' '; break; /* Keep compiler happy */ } } } temp[0] = check_digit; temp[1] = '\0'; concat(to_process, (char *)source); concat(to_process, temp); length = strlen(to_process); switch(symbol->symbology) { case BARCODE_HIBC_128: error_number = code_128(symbol, (unsigned char *)to_process, length); ustrcpy(symbol->text, (unsigned char*)"*"); uconcat(symbol->text, (unsigned char*)to_process); uconcat(symbol->text, (unsigned char*)"*"); break; case BARCODE_HIBC_39: symbol->option_2 = 0; error_number = c39(symbol, (unsigned char *)to_process, length); ustrcpy(symbol->text, (unsigned char*)"*"); uconcat(symbol->text, (unsigned char*)to_process); uconcat(symbol->text, (unsigned char*)"*"); break; case BARCODE_HIBC_DM: error_number = dmatrix(symbol, (unsigned char *)to_process, length); break; case BARCODE_HIBC_QR: error_number = qr_code(symbol, (unsigned char *)to_process, length); break; case BARCODE_HIBC_PDF: error_number = pdf417enc(symbol, (unsigned char *)to_process, length); break; case BARCODE_HIBC_MICPDF: error_number = micro_pdf417(symbol, (unsigned char *)to_process, length); break; case BARCODE_HIBC_AZTEC: error_number = aztec(symbol, (unsigned char *)to_process, length); break; } return error_number; }