aboutsummaryrefslogtreecommitdiffstats
path: root/julia-c/julia.c
blob: 43e0f91741c036feed1c76b28b8d1fdf3a7cb7d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <stdio.h>
#include <math.h>
#include <complex.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

const char *HELP = "julia usage:\n" 
	"julia <complex num>[a+bj] <resolution>[integer] <depth>[integer] <bounds>[x-,x+,y-,y+]\n"
	"\n"
	"\tcomplex_num: a complex number in the form a + bj where j is the "
	"imaginary unit.\n"
	"\tresolution: resolution (in pixels) of the image\n"
	"\tdepth: iteration count for the julia function, warning: slow at high values >100\n"
	"\tbounds: the bounds of the graphs as a comma separated list without spaces "
	"in the form: minX,maxX,minY,maxY.\n"
	"\tBounds above 2 are generally not interesting.\n"
	"\n"
	"All arguments are required. This command prints bitmap directly to stdout which is "
	"(probably) not what you want. You should always pipe the output somewhere like:\n"
	"julia 1+1j 300 -1,1,-1,1 > file.bmp";
const int RGB_MODE = 3; // don't care about transparency, so we go for 8 bit channel

int julia(double complex z, double complex c, int d) {
	// z: coordinate
	// c: complex seed
	// d: depth, iteration count
	int ic = 0; // iteration count
	while(ic < d){
		if(cabs(z) > 2)
		       break;
		z = z * z + c;
		ic++;	
	}
	return ic;
}

int write_image(double complex seed, int r, int depth, float bounds[4]) {
	float x, y;
	int pixels = r * r;
	int cur_pixel = 3 * pixels - 1;
	char const *filename = "/dev/stdout";
	// In a bitmap: 3 bytes makes a pixel (RGB)
	uint8_t *img_data = (uint8_t *) STBI_MALLOC(pixels * 3 * sizeof(uint8_t));
	// In this image library, data is stored in a 
	// 1-D array separated by row, so you need to fill
	// the pixels horizontally first
	
	float dx = bounds[1] - bounds[0];
	float dy = bounds[3] - bounds[2];
	if (dx <= 0 || dy <= 0)
		return 0; // failure (to match stbi_write)	

	for(y = bounds[2]; y < bounds[3]; y += dy/((float) r - 1)) {
		for(x = bounds[0]; x < bounds[1]; x += dx/((float) r - 1)) {
			double complex z = x + y * I;
			int out = julia(z, seed, depth);
			img_data[cur_pixel - 2] = out % 32 * 8;
			img_data[cur_pixel - 1] = out % 16 * 16;
			img_data[cur_pixel] = out % 8 * 32;
			cur_pixel -= 3;	
		}
	}
	// returns 0 on failure	
	return stbi_write_bmp(filename, r, r, RGB_MODE, img_data);
}

int main(int argc, char *argv[]) {
	double complex seed;
	int res, depth;
	float b[4];
	
	if(argc != 5) {
		printf("%s\n", HELP);
		return 1;
	}
	else {
		float re, img;
		sscanf(argv[1], "%f+%fj", &re, &img);
		sscanf(argv[2], "%d", &res);
		sscanf(argv[3], "%d", &depth);
		sscanf(argv[4], "%f,%f,%f,%f", &b[0], &b[1], &b[2], &b[3]);
		seed = re + img * I;
		if (!write_image(seed, res, depth, b)) {
			printf("Error in arguments, could not make image\n");
			return 1;
		}
	}
	return 0;
}