#include #include #include #include #include #include "bitmap.h" #include "character.h" #include "m.h" #include "color.h" /* #define CLEANUP 1 */ #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; char *character_map; unsigned int charsize_x; unsigned int charsize_y; uint8_t color; uint8_t use_stdin; uint8_t use_whitespace; uint8_t fit_width; uint8_t dynamic_range; }; 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 **image_monochrome; //Stores a color array char* **col_buff; uint8_t brightness_max = 0x00; uint8_t brightness_min = 0xff; struct bitmap_pixel_data bitmap; bitmap = bitmap_read(args.filename); if(bitmap.error) { printf("Error reading file\n"); return 1; } // Character count in x and y in final ASCII image unsigned int size_x,size_y; if(args.fit_width > 0) { args.charsize_x = (unsigned int)((float)bitmap.x / (float)args.fit_width); args.charsize_y = (unsigned int)(((float)bitmap.y / (float)bitmap.x) * (float)args.charsize_x * 2); } 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); //Allocate character sotrage image_monochrome = malloc(sizeof(*image_monochrome) * size_x); for (int i = 0; i < size_x; i++) image_monochrome[i] = malloc(sizeof(image_monochrome[i]) * size_y); //Allocate color storage if color enabled 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++) { /* Luminance for every pixel */ uint8_t brightness [ args.charsize_x ][ args.charsize_y ]; /* Color for every Pixel */ uint8_t color_list[ 3 ][ args.charsize_x * args.charsize_y ]; //RGB Values of Pixels, used for averaging unsigned int color_list_counter = 0; /* Iterate through pixel block, save brightness and color if set */ 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_luminance( bitmap.R[col][row], bitmap.G[col][row], bitmap.B[col][row]); if(args.color) { color_list[0][color_list_counter] = bitmap.R[col][row]; color_list[1][color_list_counter] = bitmap.G[col][row]; color_list[2][color_list_counter] = bitmap.B[col][row]; color_list_counter++; }//if }//for col_c }//for row_c /* Calculate average brightness in pixel block */ image_monochrome[x][y] = avg(args.charsize_x * args.charsize_y, *brightness); /* Calculate average color in pixel block */ if(args.color) { if(args.use_whitespace) col_buff[x][y] = calc_bg_col_ansi( (uint8_t)avg(args.charsize_x * args.charsize_y, color_list[0]), (uint8_t)avg(args.charsize_x * args.charsize_y, color_list[1]), (uint8_t)avg(args.charsize_x * args.charsize_y, color_list[2])); else col_buff[x][y] = calc_col_ansi( (uint8_t)avg(args.charsize_x * args.charsize_y, color_list[0]), (uint8_t)avg(args.charsize_x * args.charsize_y, color_list[1]), (uint8_t)avg(args.charsize_x * args.charsize_y, color_list[2])); } // if args.color /* Save min and max brightness values for dynamic range */ if((uint8_t)image_monochrome[x][y] < brightness_min) brightness_min = image_monochrome[x][y]; if((uint8_t)image_monochrome[x][y] > brightness_max) brightness_max = image_monochrome[x][y]; }//for y }//for x /* Apply Default Colors */ if(args.color) printf("\e[0m"); if(! args.dynamic_range) { brightness_min = 0; brightness_max = 255; } else { DEBUG_PRINTF("Dynamic Range: Brightness Values: Min: %u Max: %u\n", brightness_min, brightness_max); } /* Print the buffer */ for(int y = 0; y