mandelbrot

mandelbrot.git
git clone git://git.lenczewski.org/mandelbrot.git
Log | Files | Refs

mandelbrot.h (2902B)


      1 #ifndef MANDELBROT_H
      2 #define MANDELBROT_H
      3 
      4 #include <assert.h>
      5 #include <inttypes.h>
      6 #include <limits.h>
      7 #include <stdint.h>
      8 #include <stdio.h>
      9 #include <stdlib.h>
     10 #include <string.h>
     11 #include <unistd.h>
     12 
     13 #include <math.h>
     14 
     15 #include <sys/socket.h>
     16 
     17 /* ===========================================================================
     18  */
     19 
     20 #define LERP(v0, v1, t) (((v0) * (1 - (t))) + ((v1) * (t)))
     21 
     22 #define MIN(a, b) ((a) < (b) ? (a) : (b))
     23 #define MAX(a, b) ((a) > (b) ? (a) : (b))
     24 #define CLAMP(v, v0, v1) MIN(MAX((v), (v0)), (v1))
     25 
     26 #define ARRLEN(arr) (sizeof (arr) / sizeof (arr)[0])
     27 
     28 #define FLATIDX(y, width, x) ((y) * (width) + (x))
     29 
     30 struct render_region {
     31 	uint32_t xres, yres;
     32 	uint32_t escape_val;
     33 	uint32_t max_iters;
     34 	float x0, y0, x1, y1; // TODO: store in fixed point?
     35 };
     36 
     37 static inline uint32_t
     38 pixel(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
     39 {
     40 	return (uint32_t) a << 24 |
     41 	       (uint32_t) r << 16 |
     42 	       (uint32_t) g << 8  |
     43 	       (uint32_t) b;
     44 }
     45 
     46 static inline uint32_t
     47 render_point(float x, float y, uint32_t max_iters, uint32_t escape_val, float *out)
     48 {
     49 	// z = 0+0i
     50 	// c = x + i*y
     51 	// z_i = z_j ^ 2 + c
     52 	//     = (re_j + i * im_j) ^ 2 + (x + i * y)
     53 	//     = ((re_j + i * im_j) * (re_j + i * im_j)) + (x + i * y)
     54 	//     = (re_j^2 + 2 * (re_j * i * im_j) + (i^2 + im_j^2)) + (x + i * y)
     55 	//     = (re_j^2 - im_j^2) + i * (2 * re_j * im_j) + (x + i * y)
     56 	//     = (re_j^2 - im_j^2 + x) + i * ((2 * re_j * im_j) + y)
     57 
     58 	float re = 0.0, im = 0.0, abs2 = 0.0, esc2 = (float) escape_val * escape_val;
     59 
     60 	uint32_t i = 0;
     61 	while (abs2 < esc2 && i < max_iters) {
     62 		float new_re = (re * re) - (im * im) + x;
     63 		float new_im = (2 * re * im) + y;
     64 
     65 		abs2 = (new_re * new_re) + (new_im * new_im);
     66 		re = new_re;
     67 		im = new_im;
     68 
     69 		i++;
     70 	}
     71 
     72 	*out = abs2;
     73 
     74 	return i;
     75 }
     76 
     77 static inline void
     78 render_region(struct render_region *region, uint32_t *iterbuf, float *abs2buf)
     79 {
     80 	for (uint32_t py = 0; py < region->yres; py++) {
     81 		float yfrac = ((float) py / region->yres);
     82 		float y = LERP(region->y0, region->y1, yfrac);
     83 
     84 		for (uint32_t px = 0; px < region->xres; px++) {
     85 			float xfrac = ((float) px / region->xres);
     86 			float x = LERP(region->x0, region->x1, xfrac);
     87 
     88 			float abs2;
     89 			uint32_t iters = render_point(x, y, region->max_iters,
     90 						      region->escape_val, &abs2);
     91 
     92 			iterbuf[FLATIDX(py, region->xres, px)] = iters;
     93 			abs2buf[FLATIDX(py, region->xres, px)] = abs2;
     94 		}
     95 	}
     96 }
     97 
     98 static inline size_t
     99 sendall(int fd, void *buf, size_t len)
    100 {
    101 	size_t total = 0;
    102 	do {
    103 		ssize_t curr = send(fd, (uint8_t *) buf + total, len - total, 0);
    104 		if (curr <= 0) break;
    105 		total += curr;
    106 	} while (total < len);
    107 
    108 	return total;
    109 }
    110 
    111 static inline size_t
    112 recvall(int fd, void *buf, size_t len)
    113 {
    114 	size_t total = 0;
    115 	do {
    116 		ssize_t curr = recv(fd, (uint8_t *) buf + total , len - total, 0);
    117 		if (curr <= 0) break;
    118 		total += curr;
    119 	} while (total < len);
    120 
    121 	return total;
    122 }
    123 
    124 #endif /* MANDELBROT_H */