mandelbrot 0.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/mandelbrot/bmp.c +63 -0
- data/ext/mandelbrot/bmp.h +26 -0
- data/ext/mandelbrot/mandelbrot.c +106 -15
- data/ext/mandelbrot/mandelbrot.h +13 -0
- metadata +4 -1
@@ -0,0 +1,63 @@
|
|
1
|
+
#include "bmp.h"
|
2
|
+
|
3
|
+
void new_bmp_header(int width, int height, char* header)
|
4
|
+
{
|
5
|
+
header[0] = 'B';
|
6
|
+
header[1] = 'M';
|
7
|
+
|
8
|
+
// file size
|
9
|
+
*(uint32_t*)&(header[2]) = 54 + (((24 * width + 31)/32) * 4) * height;
|
10
|
+
|
11
|
+
// reserved
|
12
|
+
*(uint32_t*)&(header[6]) = 0;
|
13
|
+
|
14
|
+
// offset
|
15
|
+
*(uint32_t*)&(header[10]) = 54;
|
16
|
+
|
17
|
+
// dib header size
|
18
|
+
*(uint32_t*)&(header[14]) = 40;
|
19
|
+
|
20
|
+
// width
|
21
|
+
*(uint32_t*)&(header[18]) = width;
|
22
|
+
|
23
|
+
// height
|
24
|
+
*(uint32_t*)&(header[22]) = height;
|
25
|
+
|
26
|
+
// planes
|
27
|
+
*(uint16_t*)&(header[26]) = 1;
|
28
|
+
|
29
|
+
// depth
|
30
|
+
*(uint16_t*)&(header[28]) = 24;
|
31
|
+
|
32
|
+
// compression
|
33
|
+
*(uint32_t*)&(header[30]) = 0;
|
34
|
+
|
35
|
+
// image size
|
36
|
+
*(uint32_t*)&(header[34]) = (((24 * width + 31)/32) * 4) * height;
|
37
|
+
|
38
|
+
// horiz resolution
|
39
|
+
*(uint32_t*)&(header[38]) = 72;
|
40
|
+
|
41
|
+
// vert resolution
|
42
|
+
*(uint32_t*)&(header[42]) = 72;
|
43
|
+
|
44
|
+
// colour palette
|
45
|
+
*(uint32_t*)&(header[46]) = 0;
|
46
|
+
|
47
|
+
// important colours
|
48
|
+
*(uint32_t*)&(header[50]) = 0;
|
49
|
+
|
50
|
+
/*
|
51
|
+
header->file_header.magic[0] = 'B';
|
52
|
+
header->file_header.magic[1] = 'M';
|
53
|
+
header->file_header.file_size = (uint32_t)sizeof(bmp_header_t) + (((24 * width + 31)/32) * 4) * height;
|
54
|
+
header->file_header.reserved = 0;
|
55
|
+
header->file_header.offset = sizeof(bmp_header_t);
|
56
|
+
|
57
|
+
header->dib_header.header_size = sizeof(bmp_dib_header_t);
|
58
|
+
header->dib_header.image_width = width;
|
59
|
+
header->dib_header.image_height = height;
|
60
|
+
header->dib_header.color_planes = 1;
|
61
|
+
header->dib_header.color_depth = 24;
|
62
|
+
*/
|
63
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <stdint.h>
|
3
|
+
|
4
|
+
/*
|
5
|
+
typedef struct {
|
6
|
+
char magic[2];
|
7
|
+
uint32_t file_size;
|
8
|
+
uint32_t reserved;
|
9
|
+
uint32_t offset;
|
10
|
+
} __attribute__((packed)) bmp_file_header_t;
|
11
|
+
|
12
|
+
typedef struct {
|
13
|
+
uint32_t header_size;
|
14
|
+
uint16_t image_width;
|
15
|
+
uint16_t image_height;
|
16
|
+
uint16_t color_planes; // must be 1
|
17
|
+
uint16_t color_depth;
|
18
|
+
} __attribute__((packed)) bmp_dib_header_t;
|
19
|
+
|
20
|
+
typedef struct {
|
21
|
+
bmp_file_header_t file_header;
|
22
|
+
bmp_dib_header_t dib_header;
|
23
|
+
} __attribute__((packed)) bmp_header_t;
|
24
|
+
*/
|
25
|
+
|
26
|
+
void new_bmp_header(int width, int height, char* header);
|
data/ext/mandelbrot/mandelbrot.c
CHANGED
@@ -1,17 +1,9 @@
|
|
1
|
-
#include
|
2
|
-
#include <stdbool.h>
|
3
|
-
#include <complex.h>
|
4
|
-
#include "ruby.h"
|
1
|
+
#include "mandelbrot.h"
|
5
2
|
|
6
3
|
static ID i_Complex = Qundef;
|
7
4
|
static ID i_to_f = Qundef;
|
8
5
|
static ID i_INFINITY = Qundef;
|
9
6
|
|
10
|
-
static VALUE Float_INFINITY = Qundef;
|
11
|
-
static VALUE Mandelbrot = Qundef;
|
12
|
-
static VALUE Mandelbrot_initialize(int argc, VALUE* argv, VALUE self);
|
13
|
-
static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height);
|
14
|
-
|
15
7
|
static double rb_complex_re(VALUE cplx)
|
16
8
|
{
|
17
9
|
_Complex ret;
|
@@ -42,6 +34,7 @@ void Init_mandelbrot()
|
|
42
34
|
Mandelbrot = rb_define_class("Mandelbrot", rb_cObject);
|
43
35
|
rb_define_method(Mandelbrot, "initialize", Mandelbrot_initialize, -1);
|
44
36
|
rb_define_method(Mandelbrot, "compute", Mandelbrot_compute, 2);
|
37
|
+
rb_define_method(Mandelbrot, "bmp", Mandelbrot_bmp, 2);
|
45
38
|
rb_define_attr(Mandelbrot, "min", true, false);
|
46
39
|
rb_define_attr(Mandelbrot, "max", true, false);
|
47
40
|
rb_define_attr(Mandelbrot, "max_iters", true, true);
|
@@ -64,7 +57,7 @@ static VALUE Mandelbrot_initialize(int argc, VALUE* argv, VALUE self)
|
|
64
57
|
|
65
58
|
rb_iv_set(self, "@min", min);
|
66
59
|
rb_iv_set(self, "@max", max);
|
67
|
-
rb_iv_set(self, "@max_iters", INT2NUM(
|
60
|
+
rb_iv_set(self, "@max_iters", INT2NUM(256));
|
68
61
|
|
69
62
|
return Qnil;
|
70
63
|
}
|
@@ -76,6 +69,7 @@ static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height)
|
|
76
69
|
int width, height;
|
77
70
|
int max_iters;
|
78
71
|
int x, y, iter;
|
72
|
+
int* grid;
|
79
73
|
VALUE ary, col, tmp;
|
80
74
|
VALUE r_min;
|
81
75
|
VALUE r_max;
|
@@ -96,10 +90,10 @@ static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height)
|
|
96
90
|
|
97
91
|
ary = rb_ary_new();
|
98
92
|
for(x = 0; x < width; x++) {
|
93
|
+
x0 = (max_re - min_re) * ((double)x / (double)width) + min_re;
|
99
94
|
col = rb_ary_new();
|
100
95
|
rb_ary_push(ary, col);
|
101
96
|
for(y = 0; y < height; y++) {
|
102
|
-
x0 = (max_re - min_re) * ((double)x / (double)width) + min_re;
|
103
97
|
y0 = (max_im - min_im) * ((double)y / (double)height) + min_im;
|
104
98
|
re = 0;
|
105
99
|
im = 0;
|
@@ -108,13 +102,110 @@ static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height)
|
|
108
102
|
im = 2*re*im + y0;
|
109
103
|
re = retemp;
|
110
104
|
}
|
111
|
-
|
112
|
-
|
105
|
+
rb_ary_push(col, INT2NUM(x*x + y*y < 2*2 ? -1 : iter));
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
return ary;
|
110
|
+
}
|
111
|
+
|
112
|
+
static inline void hsv_to_rgb(double h, double s, double v, char* r, char* g, char* b)
|
113
|
+
{
|
114
|
+
double chroma = v * s;
|
115
|
+
double h_dash = h / 60.0;
|
116
|
+
double x = chroma * (1 - fabs(fmod(h_dash, 2.0) - 1));
|
117
|
+
if(h_dash < 1) {
|
118
|
+
*r = (char)(255 * chroma);
|
119
|
+
*g = (char)(255 * x);
|
120
|
+
*b = 0;
|
121
|
+
} else if(h_dash < 2) {
|
122
|
+
*r = (char)(255 * x);
|
123
|
+
*g = (char)(255 * chroma);
|
124
|
+
*b = 0;
|
125
|
+
} else if(h_dash < 3) {
|
126
|
+
*r = 0;
|
127
|
+
*g = (char)(255 * chroma);
|
128
|
+
*b = (char)(255 * x);
|
129
|
+
} else if(h_dash < 4) {
|
130
|
+
*r = 0;
|
131
|
+
*g = (char)(255 * x);
|
132
|
+
*b = (char)(255 * chroma);
|
133
|
+
} else if(h_dash < 5) {
|
134
|
+
*r = (char)(255 * x);
|
135
|
+
*g = 0;
|
136
|
+
*b = (char)(255 * chroma);
|
137
|
+
} else if(h_dash < 5) {
|
138
|
+
*r = (char)(255 * chroma);
|
139
|
+
*g = 0;
|
140
|
+
*b = (char)(255 * x);
|
141
|
+
} else {
|
142
|
+
*r = 0;
|
143
|
+
*g = 0;
|
144
|
+
*b = 0;
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
static VALUE Mandelbrot_bmp(VALUE self, VALUE _width, VALUE _height)
|
149
|
+
{
|
150
|
+
char* bmp = NULL;
|
151
|
+
char* bmp_image_data = NULL;
|
152
|
+
|
153
|
+
double min_re, min_im, max_re, max_im;
|
154
|
+
double x0, y0, re, im, retemp;
|
155
|
+
int width, height;
|
156
|
+
int max_iters;
|
157
|
+
int x, y, iter;
|
158
|
+
int offset;
|
159
|
+
int* grid;
|
160
|
+
VALUE ary, col, tmp;
|
161
|
+
VALUE r_min;
|
162
|
+
VALUE r_max;
|
163
|
+
|
164
|
+
rb_check_type(_width, T_FIXNUM);
|
165
|
+
rb_check_type(_height, T_FIXNUM);
|
166
|
+
width = NUM2INT(_width);
|
167
|
+
height = NUM2INT(_height);
|
168
|
+
|
169
|
+
r_min = rb_iv_get(self, "@min");
|
170
|
+
r_max = rb_iv_get(self, "@max");
|
171
|
+
min_re = rb_complex_re(r_min);
|
172
|
+
min_im = rb_complex_im(r_min);
|
173
|
+
max_re = rb_complex_re(r_max);
|
174
|
+
max_im = rb_complex_im(r_max);
|
175
|
+
|
176
|
+
max_iters = NUM2INT(rb_iv_get(self, "@max_iters"));
|
177
|
+
|
178
|
+
|
179
|
+
bmp = malloc(54 + (((24 * width + 31)/32) * 4) * height);
|
180
|
+
new_bmp_header(width, height, bmp);
|
181
|
+
bmp_image_data = bmp + 54;
|
182
|
+
|
183
|
+
for(x = 0; x < width; x++) {
|
184
|
+
x0 = (max_re - min_re) * ((double)x / (double)width) + min_re;
|
185
|
+
for(y = 0; y < height; y++) {
|
186
|
+
y0 = (max_im - min_im) * ((double)y / (double)height) + min_im;
|
187
|
+
offset = (((24 * width + 31)/32) * 4) * y + x * 3;
|
188
|
+
re = 0;
|
189
|
+
im = 0;
|
190
|
+
for(iter = 0; iter < max_iters && (re*re + im*im < 2*2); iter++) {
|
191
|
+
retemp = re*re - im*im + x0;
|
192
|
+
im = 2*re*im + y0;
|
193
|
+
re = retemp;
|
194
|
+
}
|
195
|
+
if(re*re + im*im < 2*2) {
|
196
|
+
bmp_image_data[offset + 0] = 0;
|
197
|
+
bmp_image_data[offset + 1] = 0;
|
198
|
+
bmp_image_data[offset + 2] = 0;
|
113
199
|
} else {
|
114
|
-
|
200
|
+
hsv_to_rgb((iter / (double)max_iters) * 360, 1, /*1 - (iter / (double)max_iters),*/ 1 - (iter / (double)max_iters), &bmp_image_data[offset + 2], &bmp_image_data[offset + 1], &bmp_image_data[offset + 0]);
|
201
|
+
/*
|
202
|
+
bmp_image_data[offset + 0] = 255 - iter % 256;
|
203
|
+
bmp_image_data[offset + 1] = 255 - iter % 128;
|
204
|
+
bmp_image_data[offset + 2] = 255 - iter % 64;
|
205
|
+
*/
|
115
206
|
}
|
116
207
|
}
|
117
208
|
}
|
118
209
|
|
119
|
-
return
|
210
|
+
return rb_str_new(bmp, 54 + (((24 * width + 31)/32) * 4) * height);
|
120
211
|
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <stdbool.h>
|
3
|
+
#include <math.h>
|
4
|
+
#include "bmp.h"
|
5
|
+
#include "ruby.h"
|
6
|
+
|
7
|
+
static VALUE Float_INFINITY = Qundef;
|
8
|
+
static VALUE Mandelbrot = Qundef;
|
9
|
+
static VALUE Mandelbrot_initialize(int argc, VALUE* argv, VALUE self);
|
10
|
+
static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height);
|
11
|
+
static VALUE Mandelbrot_bmp(VALUE self, VALUE _width, VALUE _height);
|
12
|
+
|
13
|
+
int* mandelbrot_compute(int w, int h, double min_re, double min_im, double max_re, double max_im, int max_iter);
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mandelbrot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -18,7 +18,10 @@ extensions:
|
|
18
18
|
- ext/mandelbrot/extconf.rb
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
+
- ext/mandelbrot/bmp.c
|
21
22
|
- ext/mandelbrot/mandelbrot.c
|
23
|
+
- ext/mandelbrot/bmp.h
|
24
|
+
- ext/mandelbrot/mandelbrot.h
|
22
25
|
- ext/mandelbrot/extconf.rb
|
23
26
|
- lib/mandelbrot.rb
|
24
27
|
homepage: https://github.com/charliesome/mandelbrot
|