#include #include #include #include #include "./num.h" #include "./tga.h" #include "./upc.h" #define UPC_A_WIDTH 113 #define UPC_A_HEIGHT 79 typedef struct { int eflag; int nflag; char *ovalue; } opts; char *getInput( int index, char *argv[] ); opts parseOpts( int argc, char *argv[] ); void DrawBarcode( char *dst, const char *src ); void DrawNumbers( char *dst, const char *src ); int main(int argc, char *argv[]) { // Parse CLI options opts options = parseOpts( argc, argv ); // Parse CLI input char *input = getInput( optind, argv ); // Set final element of input array to the appropriate check digit input[11] = upc_a_calculate_check_digit( input ); // Create array of chars to represent 1D barcode const char *barcode = create_upc_a( input ); // Allocate memory to hold image data char *image = malloc( UPC_A_WIDTH * UPC_A_HEIGHT ); // Draw barcode to image data DrawBarcode( image, barcode ); // Draw human-readable interpretation if '-e' is used if( options.nflag ) { DrawNumbers( image, input ); } free( input ); // Create a .tga image file using image data CreateTGA( options.ovalue, UPC_A_WIDTH, UPC_A_HEIGHT, image ); free( image ); return 0; } char *getInput( int index, char *argv[] ) { char *result = malloc( 12 ); int k = 0; for( int i = index; argv[i] != NULL; ++i ) { for( int j = 0; j < strlen(argv[i]); ++j ) { if( argv[i][j] < 58 && argv[i][j] > 47 ) { result[k] = argv[i][j]; result[k] -= 48; ++k; } } } if( k != 11 ) { printf( "Inappropriate input detected!\nPlease provide an 11-digit number.\n" ); } return result; } opts parseOpts( int argc, char *argv[] ) { opts options = { 0, 0, NULL }; int c; while( ( c = getopt(argc, argv, "eno:")) != -1 ) { switch( c ) { case 'e': options.eflag = 1; break; case 'n': options.nflag = 1; break; case 'o': options.ovalue = optarg; break; } } return options; } void DrawBarcode( char *dst, const char *src ) { const char UPC_A_QUIET_ZONE[9] = {0}; for(int i = 0; i < UPC_A_HEIGHT; ++i) { memcpy( dst + (i * UPC_A_WIDTH), &UPC_A_QUIET_ZONE, sizeof(UPC_A_QUIET_ZONE) ); memcpy( dst + 9 + (i * UPC_A_WIDTH), src, 95 ); memcpy( dst + 104 + (i * UPC_A_WIDTH), &UPC_A_QUIET_ZONE, sizeof(UPC_A_QUIET_ZONE) ); } } void DrawNumbers( char *dst, const char *src ) { const int POSITION_0 = UPC_A_WIDTH * (UPC_A_HEIGHT - 16) + 1; const int POSITION_1 = UPC_A_WIDTH * (UPC_A_HEIGHT - 16) + 14; const int POSITION_2 = UPC_A_WIDTH * (UPC_A_HEIGHT - 16) + 59; const int POSITION_3 = UPC_A_WIDTH * (UPC_A_HEIGHT - 16) + 104; for(int i = 0; i < 16; ++i) { memcpy( dst + POSITION_0 + (i * UPC_A_WIDTH), NUMBER[src[0]][i], sizeof(NUMBER[0][i]) ); } for( int i = 0; i < 5; ++i ) { for(int j = 0; j < 16; ++j) { memcpy( dst + POSITION_1 + (j * UPC_A_WIDTH) + (i * 8), NUMBER[src[i + 1]][j], sizeof(NUMBER[0][j]) ); } } for( int i = 0; i < 5; ++i ) { for(int j = 0; j < 16; ++j) { memcpy( dst + POSITION_2 + (j * UPC_A_WIDTH) + (i * 8), NUMBER[src[i + 6]][j], sizeof(NUMBER[0][j]) ); } } for(int i = 0; i < 16; ++i) { memcpy( dst + POSITION_3 + (i * UPC_A_WIDTH), NUMBER[src[11]][i], sizeof(NUMBER[0][i]) ); } }