diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..b5e115e --- /dev/null +++ b/src/main.c @@ -0,0 +1,137 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#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]) ); + } +} |