#include #include #include #include #include // for getopt #include // for getopt_long #include // for strcpy #include "tricorn.h" void save_bmp(const char *filename, unsigned char *img, size_t width, ssize_t height); int main(int argc, char** argv) { int opt_long; // will be the returned optional character, // example: ./main -c -> opt_long here will be the optional 'c' const char* optstring = "V:B:s:d:n:r:o:Cht" ; // valid options that can be given to the programme. options with ":" after them expect an argument, which we'll later store in // example: B: -> optional B expects an argument after it, and is valid -> ./main -B 67 (optarg is now "67") // example: h -> optional h doesn't expect an argument -> ./main -h // optind -> keeps track of the next index. initialised as 1 in the beginning. calling opt_long updates it every time // optarg -> is a charptr. stores the arguments given to the optionals static struct option long_options[] = { {"color",0,0,'C'}, {"help",0,0,'h'}, {"test",0,0,'t'}, {0,0,0,0} }; // these are the long optionals, which we can call with double "--". "--help" or "--test". they are converted to the optionals "h" and "t" respectively // first argument is "name" -> name of the long. "--" // second is "has_arg" -> 0 if no arg, 1 if arg, 2 if optional arg // third is "*flag" -> sets a flag so that "--help" simply returns "h" and does nothing else // fourth is "val" -> what to return when "--help" is given, returns "h" int version_to_use = 0; unsigned amount_function_called; unsigned n; float starting_point_real; float starting_point_imaginary; size_t width; ssize_t height; float step_amount; char* output_data; _Bool colored = 0; opt_long = getopt_long(argc,argv,optstring, long_options, NULL); // first four arguments are self-explanatory, fifth argument is the index of which long_option we return in the struct "long_options", but it's irrelevant so we set it to NULL while (opt_long != -1) { switch (opt_long) { case 'V': // done, function needed version_to_use = strtol(optarg,NULL,10); printf("version is %d\n", version_to_use); // Die Implementierung, die verwendet werden soll. Hierbei soll mit // -V 0 Ihre Hauptimplementierung verwendet werden. Wenn diese Option nicht // gesetzt wird, soll ebenfalls die Hauptimplementierung ausgeführt werden break; case 'B': // done, function needed // wird die Laufzeit der angegebenen Implementierung gemessen und ausgegeben (do this later) amount_function_called = strtoul(optarg,NULL,10); printf("amount function called is %d\n", amount_function_called); // Das Argument dieser Option gibt die Anzahl an Wiederholungen des Funktionsaufrufs an, z. B.-B 5 . break; case 's': char* imaginary_string; starting_point_real = strtof(optarg,&imaginary_string); // split into two starting_point_imaginary = strtof(imaginary_string + 1,NULL); // this is horrible printf("real %d, img %d\n", starting_point_real,starting_point_imaginary); // s , — Startpunkt der Berechnung break; case 'd': char* height_string; width = strtol(optarg,&height_string,10); height = strtol(height_string + 1,NULL,10); printf("width %d, height %d\n", width,height); // -d , —Breite und Höhe des Bildausschnitts break; case 'n': n = strtol(optarg,NULL,10); printf("n:%d\n",n); // -n —MaximaleAnzahlanIterationen pro Bildpixel break; case 'r': step_amount = strtof(optarg,NULL); printf("r:%d\n", step_amount); // r —Schrittweite pro Bildpixel break; case 'o': output_data = malloc(strlen(optarg) + 1); strcpy(output_data,optarg); printf("%s\n", output_data); // test // -o —Ausgabedatei break; case 'C': colored = 1; printf("colored:%d\n",colored); // C|--color —Farbausgabe break; case 'h': // print help message // Eine Beschreibung aller Optionen des Programms und Verwendungsbeispiele werden ausgegeben und das Programm danach beendet. // Die Beschreibung soll mit "Help Message" anfangen. break; case 't': // do testing // Führt eine vordefinierte Testsuite aus, welche sämtliche von Ihnen // verwendete Benchmarking-Szenarien gesammelt durchläuft. Das Programm gibt // die jeweiligen Parameter, eine kurze Beschreibungen sowie die Ergebnisse in einer // übersichtlichen und gut lesbaren Form aus und terminiert anschließend. break; default: // case '?' -> when the argument is not valid // print error msg break; } opt_long = getopt_long(argc,argv,optstring, long_options, NULL); } float complex complexA = (starting_point_real + starting_point_imaginary*I); char tempArr[width*height*3]; printf("yashar\n"); tricorn(complexA,width,height,step_amount,n,colored,tempArr); printf("yashar\n"); save_bmp(output_data,tempArr,width,height); free(optarg); // return 0; } void save_bmp(const char *filename, unsigned char *img, size_t width, ssize_t height) { FILE *fptr = fopen(filename,"wb"); if(fptr == NULL) { fprintf(stderr,"ERROR: Could not open output file at %s\n.",filename); exit(EXIT_FAILURE); } int actual_height = (height < 0) ? -height : height; size_t row_padding = (4 - (width) * 3 % 4) % 4; size_t row_width = width * 3 + row_padding; size_t image_size = actual_height * row_width; size_t file_size = image_size + 54; unsigned char file_header[14] = { 'B', 'M', 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0 }; file_header[2] = (unsigned char)(file_size); file_header[3] = (unsigned char)(file_size >> 8); file_header[4] = (unsigned char)(file_size >> 16); file_header[5] = (unsigned char)(file_size >> 24); unsigned char info_header[40] = { 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x13, 0x0B, 0, 0, 0x13, 0x0B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; info_header[4] = (unsigned char)(width); info_header[5] = (unsigned char)(width >> 8); info_header[6] = (unsigned char)(width >> 16); info_header[7] = (unsigned char)(width >> 24); uint32_t h = (uint32_t)height; info_header[8] = (unsigned char)(h); info_header[9] = (unsigned char)(h >> 8); info_header[10] = (unsigned char)(h >> 16); info_header[11] = (unsigned char)(h >> 24); info_header[20] = (unsigned char)(image_size); info_header[21] = (unsigned char)(image_size >> 8); info_header[22] = (unsigned char)(image_size >> 16); info_header[23] = (unsigned char)(image_size >> 24); fwrite(file_header,1,14,fptr); fwrite(info_header,1,40,fptr); unsigned char padding_bytes[3] = {0, 0, 0}; for(int i = 0; i < actual_height; i++) { fwrite(img + (i * width * 3), 3, width, fptr); if(row_padding > 0) { fwrite(padding_bytes,1,row_padding,fptr); } } fclose(fptr); }