Esempio n. 1
0
File: 2of5.c Progetto: ahippo/zint
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}