|
|
@ -18,12 +18,28 @@ typedef struct {
|
|
|
|
/* The maximum iteration count. */
|
|
|
|
/* The maximum iteration count. */
|
|
|
|
const int max_it = 170;
|
|
|
|
const int max_it = 170;
|
|
|
|
|
|
|
|
|
|
|
|
/* Compute the out-coloring based on the iteration counter. */
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Compute the out-coloring based on the iteration counter.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* Out-coloring means: coloring when a pixel is determined
|
|
|
|
|
|
|
|
* to be outside of the mandelbrot set.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param it iteration counter when diversion was determined.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return pixel color
|
|
|
|
|
|
|
|
*/
|
|
|
|
pixel_t outcolor(int it) {
|
|
|
|
pixel_t outcolor(int it) {
|
|
|
|
return 0x00010001 * ((it * 0xff) / max_it);
|
|
|
|
return 0x00010001 * ((it * 0xff) / max_it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* "Compute" the in-coloring. */
|
|
|
|
/**
|
|
|
|
|
|
|
|
* "Compute" the in-coloring.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* In-coloring means: coloring when a pixel is determined
|
|
|
|
|
|
|
|
* to be inside the mandelbrot set.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return pixel, i.e. color
|
|
|
|
|
|
|
|
*/
|
|
|
|
pixel_t incolor() {
|
|
|
|
pixel_t incolor() {
|
|
|
|
return 0x00000000; /* black */
|
|
|
|
return 0x00000000; /* black */
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -69,10 +85,14 @@ bitmap_t *mbrot;
|
|
|
|
/* Next line to compute. */
|
|
|
|
/* Next line to compute. */
|
|
|
|
size_t next_y = 0;
|
|
|
|
size_t next_y = 0;
|
|
|
|
|
|
|
|
|
|
|
|
/* Mutex for next_y. */
|
|
|
|
/* Mutex for accessing next_y. */
|
|
|
|
pthread_mutex_t next_y_mutex;
|
|
|
|
pthread_mutex_t next_y_mutex;
|
|
|
|
|
|
|
|
|
|
|
|
/* Thread to compute mandelbrot. */
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Thread to compute mandelbrot.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param arg (not used, but necessary for pthread_create.)
|
|
|
|
|
|
|
|
*/
|
|
|
|
void *compmandelbrot(void *arg) {
|
|
|
|
void *compmandelbrot(void *arg) {
|
|
|
|
size_t y = 0;
|
|
|
|
size_t y = 0;
|
|
|
|
while (y < mbrot->height) {
|
|
|
|
while (y < mbrot->height) {
|
|
|
@ -93,8 +113,14 @@ void *compmandelbrot(void *arg) {
|
|
|
|
pthread_exit(NULL);
|
|
|
|
pthread_exit(NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Write "bitmap" to a PNG file specified by "path"; returns 0 on
|
|
|
|
/**
|
|
|
|
success, non-zero on error. */
|
|
|
|
* Writes a bitmap to a PNG file.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param bitmap bitmap to save
|
|
|
|
|
|
|
|
* @param path PNG file to write to
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return 0 on success, non-zero on error.
|
|
|
|
|
|
|
|
*/
|
|
|
|
static int save_png_to_file(bitmap_t * bitmap, const char *path) {
|
|
|
|
static int save_png_to_file(bitmap_t * bitmap, const char *path) {
|
|
|
|
FILE *fp;
|
|
|
|
FILE *fp;
|
|
|
|
|
|
|
|
|
|
|
@ -219,17 +245,19 @@ int main(int argc, char *argv[]) {
|
|
|
|
assert(ret == 0);
|
|
|
|
assert(ret == 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Save PNG */
|
|
|
|
/* Save PNG. */
|
|
|
|
char *file = "multibrot.png";
|
|
|
|
char *file = "multibrot.png";
|
|
|
|
ret = save_png_to_file(mbrot, file);
|
|
|
|
ret = save_png_to_file(mbrot, file);
|
|
|
|
assert(ret == 0);
|
|
|
|
assert(ret == 0);
|
|
|
|
|
|
|
|
|
|
|
|
/* Quit. */
|
|
|
|
/* Clean up. */
|
|
|
|
pthread_exit(NULL);
|
|
|
|
|
|
|
|
free(threads);
|
|
|
|
free(threads);
|
|
|
|
free(mbrot->pixels);
|
|
|
|
free(mbrot->pixels);
|
|
|
|
free(mbrot);
|
|
|
|
free(mbrot);
|
|
|
|
ret = pthread_mutex_destroy(&next_y_mutex);
|
|
|
|
ret = pthread_mutex_destroy(&next_y_mutex);
|
|
|
|
assert(ret == 0);
|
|
|
|
assert(ret == 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Quit. */
|
|
|
|
|
|
|
|
pthread_exit(NULL);
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|