diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..b8bf074 --- /dev/null +++ b/src/main.c @@ -0,0 +1,235 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <math.h> +#include <string.h> + +#include "bitmap.h" +#include "character.h" +#include "m.h" +#include "color.h" + +#ifdef _DEBUG +#warning "Compiling with DEBUG" +#define DEBUG_PRINTF(...) { printf(__VA_ARGS__); } +#else +#define DEBUG_PRINTF(...) { } +#endif + +#define CHAR_SIZE_X 2 //How many pixels should form one ASCII char? +#define CHAR_SIZE_Y (2 * CHAR_SIZE_X) + +struct prog_param +{ + char *filename; + unsigned int charsize_x; + unsigned int charsize_y; + uint8_t color; +}; + +struct prog_param parse_args(int argc, char *argv[]); + +void print_help( void ); + +int main(int argc, char *argv[]) +{ + struct prog_param args = parse_args(argc, argv); + + //Stores a luminance array + uint8_t **ascii_buff; + //Stores a color array + char* **col_buff; + + uint8_t b_max = 0x00; + uint8_t b_min = 0xff; + + struct bitmap_pixel_data bitmap; + + bitmap = bitmap_read(args.filename); + + if(bitmap.error) { + printf("Error reading file\n"); + return 1; + } + + //x and y size of ASCII-image + unsigned int size_x,size_y; + size_x = bitmap.x / args.charsize_x; + size_y = bitmap.y / args.charsize_y; + + DEBUG_PRINTF("Output size: %u x %u\n", size_x, size_y); + + //Where the chars are stored + ascii_buff = malloc(sizeof(*ascii_buff) * size_x); + for (int i = 0; i < size_x; i++) + ascii_buff[i] = malloc(sizeof(ascii_buff[i]) * size_y); + + //Where the color is stored, if activated + if(args.color) { + col_buff = malloc(sizeof(*col_buff) * size_x); + for (int i = 0; i < size_x; i++) + col_buff[i] = malloc(sizeof(col_buff[i]) * size_y); + } + + //Nest thine Lööps + //Very not optimal Variable names!!!!!!!!!!!!! + // + //For every size_x * size_y block: calculate average values of pixel blocks + for(unsigned int x = 0; x < size_x; x++) { + for(unsigned int y = 0; y < size_y; y++) { + uint8_t brightness [ args.charsize_x ][ args.charsize_y ]; //Average brightness of every pixel + uint8_t cc[ 3 ][ args.charsize_x * args.charsize_y ]; //RGB Values of Pixels + unsigned int cc_counter = 0; + + //Iterate through Pixel block + for(unsigned int row_c = 0; row_c < args.charsize_y; row_c++) { + unsigned int row = y * args.charsize_y + row_c; //Actual position in Bitmap + + for(unsigned int col_c = 0; col_c < args.charsize_x; col_c++) { + unsigned int col = x * args.charsize_x + col_c; //Actual position in bitmap + + brightness[col_c][row_c] = rgb_avg( + bitmap.R[col][row], + bitmap.G[col][row], + bitmap.B[col][row]); + + if(args.color) { + cc[0][cc_counter] = bitmap.R[col][row]; + cc[1][cc_counter] = bitmap.G[col][row]; + cc[2][cc_counter] = bitmap.B[col][row]; + cc_counter++; + }//if + }//for col_c + }//for row_c + + ascii_buff[x][y] = avg(args.charsize_x * args.charsize_y, *brightness); + if(args.color == 1) { + col_buff[x][y] = calc_col( + (uint8_t)avg(args.charsize_x * args.charsize_y, cc[0]), + (uint8_t)avg(args.charsize_x * args.charsize_y, cc[1]), + (uint8_t)avg(args.charsize_x * args.charsize_y, cc[2])); + } else if(args.color == 2) { + col_buff[x][y] = calc_col_ansi( + (uint8_t)avg(args.charsize_x * args.charsize_y, cc[0]), + (uint8_t)avg(args.charsize_x * args.charsize_y, cc[1]), + (uint8_t)avg(args.charsize_x * args.charsize_y, cc[2])); + } + + if((uint8_t)ascii_buff[x][y] < b_min) + b_min = ascii_buff[x][y]; + if((uint8_t)ascii_buff[x][y] > b_max) + b_max = ascii_buff[x][y]; + }//for y + }//for x + + DEBUG_PRINTF("Brightness Values: Min: %u Max: %u\n", b_min, b_max); + + if(args.color) + printf("\e[0m");//Default colors + + //Print buffer + for(int y = 0; y<size_y; y++) { + for(int x = 0; x < size_x; x++) { + if(args.color) + printf("\e[%sm", col_buff[x][y]); + + printf("%c", calc_char(ascii_buff[x][y], 0,255));//b_min, b_max)); + } + printf("\n"); + } + + if(args.color) + printf("\e[0m");//Default colors + + DEBUG_PRINTF("Finished!\n"); + + //Cleanup + for(int i = 0; i < size_x; i++) + free (ascii_buff[i]); + free(ascii_buff); + + for(int i = 0; i < bitmap.x; i++) { + free(bitmap.R[i]); + free(bitmap.G[i]); + free(bitmap.B[i]); + } + free(bitmap.R); + free(bitmap.G); + free(bitmap.B); + + return 0; +}//main + +struct prog_param parse_args(int argc, char *argv[]) +{ + struct prog_param ret; + + ret.filename = NULL; + ret.charsize_x = CHAR_SIZE_X; + ret.charsize_y = 0; + ret.color = 0; + + for (int i = 1; i < argc; i++) { + if(argv[i][0] == '-') { + int icpy = i; + for(int o = 1; o < strlen(argv[icpy]); o++) { + switch(argv[icpy][o]) { + case 'h': + print_help(); + exit(1); + break; + case 'x': + DEBUG_PRINTF("x\n"); + i++; + ret.charsize_x = atoi(argv[i]); + break; + case 'y': + DEBUG_PRINTF("y\n"); + i++; + ret.charsize_y = atoi(argv[i]); + break; + case 'c': + ret.color = 1; + break; + case 'C': + ret.color = 2; + break; + default: + printf("Unrecognized Option\n"); + print_help(); + exit(1); + };//switch + }//for o + }//if + else if(ret.filename == NULL) { + ret.filename = argv[i]; + } else { + printf("Wrong number of arguments\n"); + print_help(); + exit(1); + } + }//for i + + if(ret.filename == NULL) + { + printf("No input file.\n"); + print_help(); + exit(1); + } + + if(!ret.charsize_y) + ret.charsize_y = 2 * ret.charsize_x; + + return ret; +} + +void print_help( void ) +{ + printf("ASCIIMap\n(c) 2019 Jonas Gunz, github.com/kompetenzbolzen/AsciiMap\n"); + printf("ASCIIMap prints a ASCII representation of a bitmap image\n\nUsage: [OPTIONS] FILENAME\n"); + printf("Options:\n -h: Print this help message\n -x VAL: set the width of block wich makes up one character. Default: %i\n", CHAR_SIZE_X); + printf(" -y VAL: set the height of block wich makes up one character. Default: 2*x\n -c: Print in 7 color mode. Default: OFF\n"); + printf(" -C: Print in ANSI 256 color mode. Default: OFF\n"); +} + + |