diff --git a/backend/library.c b/backend/library.c index 078faeb4..9eafc50e 100644 --- a/backend/library.c +++ b/backend/library.c @@ -714,3 +714,89 @@ int ZBarcode_Encode_and_Print_Rotated(struct zint_symbol *symbol, unsigned char error_number = ZBarcode_Print_Rotated(symbol, rotate_angle); return error_number; } + +int ZBarcode_Encode_from_File(struct zint_symbol *symbol, char *filename) +{ + int i; + FILE *file; + unsigned char *buffer; + unsigned long fileLen; + unsigned char used_characters[255]; + + file = fopen(filename, "rb"); + if (!file) { + strcpy(symbol->errtxt, "Unable to read input file"); + return ERROR_INVALID_DATA; + } + + /* Get file length */ + fseek(file, 0, SEEK_END); + fileLen = ftell(file); + fseek(file, 0, SEEK_SET); + + if(fileLen > 7100) { + /* The largest amount of data that can be encoded is 7089 numeric digits in QR Code */ + strcpy(symbol->errtxt, "Input file too long"); + fclose(file); + return ERROR_INVALID_DATA; + } + + /* Allocate memory */ + buffer = (unsigned char *)malloc((fileLen + 1)*sizeof(unsigned char)); + if(!buffer) { + strcpy(symbol->errtxt, "Internal memory error"); + fclose(file); + return ERROR_MEMORY; + } + + /* Read file contents into buffer */ + fread(buffer, fileLen, 1, file); + fclose(file); + + if(symbol->input_mode == DATA_MODE) { + /* Look for and correctly handle NULL characters */ + + for (i = 0; i <= 255; i++) { used_characters[i] = 0;} + for (i = 0; i < (int)fileLen; i++) { used_characters[(int)buffer[i]] = 1;} + + if (used_characters[0] == 1) { /* only if data contains a NULL */ + + /* determine first unused character > 0 */ + i = 1; + while (i < 255) { + if (used_characters[i] == 0) { + symbol->nullchar = (char)i; + break; + } + i++; + } + if(symbol->nullchar == 0x00) { + /* No candidate character could be found. Quit */ + strcpy(symbol->errtxt, "Could not encode NULL character"); + return ERROR_INVALID_OPTION; + } + + for(i = 0; i < fileLen; i++) { + if(buffer[i] == 0x00) { + buffer[i] = symbol->nullchar; + } + } + } + } + + return ZBarcode_Encode(symbol, buffer); +} + +int ZBarcode_Encode_from_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle) +{ + int error_number; + + error_number = 0; + + error_number = ZBarcode_Encode_from_File(symbol, filename); + if(error_number != 0) { + return error_number; + } + + return ZBarcode_Print_Rotated(symbol, rotate_angle); +} diff --git a/backend/zint.h b/backend/zint.h index a0b02c8d..89f76d00 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -177,9 +177,11 @@ struct zint_symbol { ZINT_EXTERN struct zint_symbol *ZBarcode_Create(void); ZINT_EXTERN int ZBarcode_Delete(struct zint_symbol *symbol); ZINT_EXTERN int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *input); +ZINT_EXTERN int ZBarcode_Encode_from_File(struct zint_symbol *symbol, char *filename); ZINT_EXTERN int ZBarcode_Print(struct zint_symbol *symbol); ZINT_EXTERN int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input); ZINT_EXTERN int ZBarcode_Encode_and_Print_Rotated(struct zint_symbol *symbol, unsigned char *input, int rotate_angle); +ZINT_EXTERN int ZBarcode_Encode_from_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle); #ifdef __cplusplus } diff --git a/frontend/main.c b/frontend/main.c index 72316da4..c4de2782 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -70,6 +70,7 @@ void usage(void) "Encode input data in a barcode and save as a PNG, EPS or SVG file.\n\n" " -h, --help Display this message.\n" " -t, --types Display table of barcode types\n" + " -i, --input=FILE Read data from FILE.\n" " -o, --output=FILE Write image to FILE. (default is out.png)\n" " -d, --data=DATA Barcode content.\n" " -b, --barcode=NUMBER Number of barcode type (default is 20 (=Code128)).\n" @@ -95,6 +96,7 @@ void usage(void) " --gs1 Treat input as GS1 data\n" " --kanji Treat input as Kanji characters in Unicode\n" " --sjis Treat input as Shift-JIS\n" + " --binary Treat input as Binary data\n" , ZINT_VERSION); } @@ -148,6 +150,7 @@ int main(int argc, char **argv) {"border", 1, 0, 0}, {"data", 1, 0, 'd'}, {"output", 1, 0, 'o'}, + {"input", 1, 0, 'i'}, {"fg", 1, 0, 0}, {"bg", 1, 0, 0}, {"cols", 1, 0, 0}, @@ -162,6 +165,7 @@ int main(int argc, char **argv) {"gs1", 0, 0, 0}, {"kanji", 0, 0, 0}, {"sjis", 0, 0, 0}, + {"binary", 0, 0, 0}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "htb:w:d:o:i:rcmp", long_options, &option_index); @@ -196,6 +200,9 @@ int main(int argc, char **argv) if(!strcmp(long_options[option_index].name, "sjis")) { my_symbol->input_mode = SJIS_MODE; } + if(!strcmp(long_options[option_index].name, "binary")) { + my_symbol->input_mode = DATA_MODE; + } if(!strcmp(long_options[option_index].name, "fg")) { strncpy(my_symbol->fgcolour, optarg, 7); } @@ -344,6 +351,16 @@ int main(int argc, char **argv) } break; + case 'i': /* Take data from file */ + error_number = ZBarcode_Encode_from_File_and_Print(my_symbol, optarg, rotate_angle); + generated = 1; + if(error_number != 0) { + fprintf(stderr, "%s\n", my_symbol->errtxt); + ZBarcode_Delete(my_symbol); + return 1; + } + break; + case 'o': strncpy(my_symbol->outfile, optarg, 250); break;