diff --git a/complex.c b/complex.c deleted file mode 100644 index 1b71c8b..0000000 --- a/complex.c +++ /dev/null @@ -1,54 +0,0 @@ -#include - - -typedef struct _mycomplex { - float re; - float im; -} Complex; - - -inline Complex complex_new(float re, float im) __attribute__ ((always_inline)); -inline Complex complex_add(Complex c1, Complex c2) __attribute__ ((always_inline)); -inline Complex complex_mult(Complex c1, Complex c2) __attribute__ ((always_inline)); -inline double complex_abs(Complex c) __attribute__ ((always_inline)); - -inline Complex complex_new(float re, float im) -{ - Complex c; - c.re = re; - c.im = im; - return c; -} - -inline Complex complex_mult(Complex c1, Complex c2) -{ - Complex ret; - ret.re = c1.re * c2.re - c1.im * c2.im; - ret.im = c1.re * c2.im + c1.im * c2.re; - return ret; -} - -inline Complex complex_add(Complex c1, Complex c2) -{ - c1.re += c2.re; - c1.im += c2.im; - return c1; -} - -inline Complex complex_conj(Complex c) { - c.im = -c.im; - return c; -} - -inline double complex_abs(Complex c) -{ - double re, im; - re = c.re; - im = c.im; - return sqrt(re * re + im * im); -} - -inline void complex_print(Complex c) { - printf("%.3f + i%.3f", c.re, c.im); -} - diff --git a/images/images.h b/images.h similarity index 67% rename from images/images.h rename to images.h index f6d32b5..6c16ae2 100644 --- a/images/images.h +++ b/images.h @@ -14,8 +14,7 @@ typedef struct _image { int height; } Image; -// basic image manipulation - +// basic image manipulation (src/images.c) int image_new(int width, int height, Image* image); int image_set_px(Image image, int x, int y, int r, int g, int b); @@ -25,8 +24,7 @@ int image_check_coords(Image image, int x, int y); int image_destroy(Image image); -// colors - +// colors (src/color.c) Color color_new(int r, int g, int b); Color color_new_alpha(int r, int g, int b, float alpha); @@ -34,20 +32,28 @@ void print_color(Color c); Color color_mix(Color c1, Color c2, float ratio); -// drawing - +// drawingn (src/drawing.c) int image_draw_rect(Image image, int x1, int y1, int x2, int y2, Color color); int image_draw_circ(Image image, int x, int y, int r, Color color); int image_draw_square(Image image, int x, int y, int s, Color color); -// bmp format specifics: +// bmp format specifics: (src/bmp-format.c) int image_save_bmp(Image image, const char* path); -#include "images.c" -#include "bmp-format.c" -#include "color.c" -#include "drawing.c" + +// multithreading enabled: (src/multithreading.c) +int image_new_shared(int width, int height, Image* img); + +void image_destroy_shared(Image img); + +void* create_shared_memory(size_t size); + +#include "src/images.c" +#include "src/bmp-format.c" +#include "src/color.c" +#include "src/drawing.c" +#include "src/multithreading.c" #endif \ No newline at end of file diff --git a/main.c b/main.c deleted file mode 100644 index 448070b..0000000 --- a/main.c +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "images/images.h" -#include "complex.c" - - -#define MB_THREADS 7 - -void draw_mandelbrot(int width, int height, int iterations); -void draw_mandelbrot_auto(int width, int iterations); -int test_mandelbrot(Complex c, int iterations); -void* create_shared_memory(size_t size); -int image_new_shared(int width, int height, Image* img); -void image_destroy_shared(Image img); - - -int main(int argc, char* argv[]) { - int width = 3000; - int iterations = 60; - if (argc > 1) { - width = atoi(argv[1]); - } - if (argc > 2) { - iterations = atoi(argv[2]); - } - - draw_mandelbrot_auto(width, iterations); -} - -void draw_mandelbrot_auto(int width, int iterations) { - draw_mandelbrot(width, 2.5f * width / 3, iterations); -} - -void draw_mandelbrot(int width, int height, int iterations) { - int center_x = 2 * width / 3; - int center_y = height / 2; - float step = 3.0f / width; - - Image img; - image_new_shared(width, height, &img); - - int thread_id = 0; - - for (int i = 0; i < MB_THREADS - 1; i++) { - if (fork() == 0) { - thread_id = i + 1; - break; - } - } - printf("Thread %i reporting for duty\n", thread_id); - - for (int x = 0; x < width; x++) { - if (x % MB_THREADS != thread_id) continue; - - for (int y = 0; y < height; y++) { - Complex c = complex_new( - (x - center_x) * step, - (y - center_y) * step - ); - int ret = test_mandelbrot(c, iterations); - //int r = (ret * 160 / iterations); - //int g = (ret * 9 / iterations); - //int b = (ret * 165 / iterations); - //image_set_px(img, x, y, r,g,b); - int color = 255 * sqrt(ret / (float) iterations); - image_set_px(img, x, y, color, color, color); - } - } - - printf("Thread %i is finished\n", thread_id); - if (thread_id != 0) { - exit(0); - } - - int status; - for (int i = 0; i < MB_THREADS - 1; i++) { - printf("Waiting for threads... %d/%d\n", i, MB_THREADS - 1); - while(wait(&status) > 0) {} - } - - printf("Got %d/%d threads\n", MB_THREADS - 1, MB_THREADS - 1); - - image_save_bmp(img, "mandelbrot.bmp"); - image_destroy_shared(img); -} - -int test_mandelbrot(Complex c, int iterations) { - Complex z = complex_new(0,0); - - for (int i = 0; i < iterations; i++) { - z = complex_add(complex_mult(z,z), c); // z^2 + c - if (complex_abs(z) > 2) return i; - } - return 0; -} - - - -int image_new_shared(int width, int height, Image* img) { - if (img == NULL) return 0; - - img->height = height; - img->width = width; - - if ((unsigned long int) width * height * 3 > (unsigned long int) UINT_MAX) { - printf("Image dimensions to large for a bitmap!\n"); - return 0; - } - - // initialize bitmap... - img->bitmap = create_shared_memory(height * sizeof(char*)); - for (int i = 0; i < height; i++) { - img->bitmap[i] = create_shared_memory(3 * width * sizeof(char)); - } - - return 1; -} - -void image_destroy_shared(Image img) { - for (int i = 0; i < img.height; i++) { - munmap(img.bitmap[i], 3 * img.width * sizeof(char)); - } - munmap(img.bitmap, img.height * sizeof(char*)); -} - -void* create_shared_memory(size_t size) { - // Our memory buffer will be readable and writable: - int protection = PROT_READ | PROT_WRITE; - - // The buffer will be shared (meaning other processes can access it), but - // anonymous (meaning third-party processes cannot obtain an address for it), - // so only this process and its children will be able to use it: - int visibility = MAP_SHARED | MAP_ANONYMOUS; - - // The remaining parameters to `mmap()` are not important for this use case, - // but the manpage for `mmap` explains their purpose. - return mmap(NULL, size, protection, visibility, -1, 0); -} \ No newline at end of file diff --git a/images/bmp-format.c b/src/bmp-format.c similarity index 99% rename from images/bmp-format.c rename to src/bmp-format.c index fd1f9ee..e0541b8 100644 --- a/images/bmp-format.c +++ b/src/bmp-format.c @@ -1,7 +1,6 @@ #include #include #include -#include "images.h" // write an int to a byte array void bmp__write_int(FILE *fp, int num) { diff --git a/images/color.c b/src/color.c similarity index 97% rename from images/color.c rename to src/color.c index 4e36cd2..578dac7 100644 --- a/images/color.c +++ b/src/color.c @@ -1,4 +1,3 @@ -#include "images.h" Color color_new(int r, int g, int b) { Color c; diff --git a/images/drawing.c b/src/drawing.c similarity index 97% rename from images/drawing.c rename to src/drawing.c index 5e8d001..5c13f39 100644 --- a/images/drawing.c +++ b/src/drawing.c @@ -1,4 +1,3 @@ -#include "images.h" int image_draw_rect(Image image, int x1, int y1, int x2, int y2, Color color) { int retval = 1; diff --git a/images/images.c b/src/images.c similarity index 98% rename from images/images.c rename to src/images.c index ecf8261..347e7ca 100644 --- a/images/images.c +++ b/src/images.c @@ -1,7 +1,6 @@ #include #include #include -#include "images.h" int image_new(int width, int height, Image* img) { diff --git a/src/multithreading.c b/src/multithreading.c new file mode 100644 index 0000000..589f507 --- /dev/null +++ b/src/multithreading.c @@ -0,0 +1,43 @@ +#include +#include + +int image_new_shared(int width, int height, Image* img) { + if (img == NULL) return 0; + + img->height = height; + img->width = width; + + if ((unsigned long int) width * height * 3 > (unsigned long int) UINT_MAX) { + printf("Image dimensions to large for a bitmap!\n"); + return 0; + } + + // initialize bitmap... + img->bitmap = create_shared_memory(height * sizeof(char*)); + for (int i = 0; i < height; i++) { + img->bitmap[i] = create_shared_memory(3 * width * sizeof(char)); + } + + return 1; +} + +void image_destroy_shared(Image img) { + for (int i = 0; i < img.height; i++) { + munmap(img.bitmap[i], 3 * img.width * sizeof(char)); + } + munmap(img.bitmap, img.height * sizeof(char*)); +} + +void* create_shared_memory(size_t size) { + // Our memory buffer will be readable and writable: + int protection = PROT_READ | PROT_WRITE; + + // The buffer will be shared (meaning other processes can access it), but + // anonymous (meaning third-party processes cannot obtain an address for it), + // so only this process and its children will be able to use it: + int visibility = MAP_SHARED | MAP_ANONYMOUS; + + // The remaining parameters to `mmap()` are not important for this use case, + // but the manpage for `mmap` explains their purpose. + return mmap(NULL, size, protection, visibility, -1, 0); +} \ No newline at end of file diff --git a/test.c b/test.c index 0c646e5..5ad9ef9 100644 --- a/test.c +++ b/test.c @@ -1,7 +1,15 @@ +#include +#include +#include "images.h" + void test_transparency(); void test_4k_gradient(); +void main() { + test_transparency(); +} + void test_transparency() { Image img; Color white = color_new(255,255,255);