1 /* |
1 #include "render.h" |
2 * code to render a mandelbrot |
|
3 */ |
|
4 |
|
5 #include <sys/types.h> |
|
6 |
|
7 typedef int (*render_ctx_write_cb)(const unsigned char *data, size_t length, void *arg); |
|
8 typedef int (*render_ctx_flush_cb)(void *arg); |
|
9 |
|
10 #define RENDER_CB_OK 0 |
|
11 #define RENDER_CB_ERR 1 |
|
12 |
|
13 struct render_ctx { |
|
14 /* |
|
15 * If we just use normal FILE* stream operations |
|
16 */ |
|
17 FILE *stream; |
|
18 |
|
19 /* |
|
20 * These callback functions are used to handle the PNG data as it's rendered. |
|
21 * |
|
22 * If they return RENDER_CB_OK, all is fine and rendering will continue normally. |
|
23 * If they return RENDER_CB_ERR, rendering will abort. |
|
24 */ |
|
25 |
|
26 // called to handle the output data |
|
27 render_ctx_write_cb write_fn; |
|
28 |
|
29 // called when the output data should be flushed - can be safely ignored if not needed |
|
30 render_ctx_flush_cb flush_fn; |
|
31 |
|
32 // the callback argument |
|
33 void *cb_arg; |
|
34 |
|
35 // error status |
|
36 int _error; |
|
37 }; |
|
38 |
2 |
39 /* |
3 /* |
40 * initialize the given struct render_ctx |
4 * the mandelbrot-rendering algorithm |
41 */ |
5 */ |
42 void render_ctx_set (struct render_ctx *ctx, render_ctx_write_cb write_fn, render_ctx_flush_cb flush_fn, void *arg); |
|
43 void render_ctx_stream (struct render_ctx *ctx, FILE *fh); |
|
44 |
6 |
45 /* |
7 /* |
46 * return codes for mandelbrot_render |
8 * return codes for mandelbrot_render |
47 */ |
9 */ |
48 #define MANDELBROT_OK 0 |
10 #define MANDELBROT_OK 0 |
49 #define MANDELBROT_ERR_MALLOC 1 |
11 #define MANDELBROT_ERR 1 |
50 #define MANDELBROT_ERR_PNG_INIT 2 |
|
51 #define MANDELBROT_ERR_CB 3 |
|
52 #define MANDELBROT_ERR_INVALID 4 |
|
53 |
12 |
54 /* |
13 /* |
55 * render an <img_w>x<img_h> PNG image of the mandelbrot region bounded by (x1, y1) -> (x2, y2) |
14 * Render the image specified by the given render context |
56 */ |
15 */ |
57 int mandelbrot_render_region ( |
16 int mandelbrot_render (render_t *ctx); |
58 struct render_ctx *ctx, |
17 int mandelbrot_render_timed (render_t *ctx, double *duration); |
59 u_int32_t img_w, u_int32_t img_h, |
|
60 double x1, double y1, double x2, double y2 |
|
61 ); |
|
62 |
18 |
63 int mandelbrot_render_region_timed ( |
|
64 struct render_ctx *ctx, |
|
65 u_int32_t img_w, u_int32_t img_h, |
|
66 double x1, double y1, double x2, double y2, |
|
67 double *duration |
|
68 ); |
|
69 |
|
70 /* |
|
71 * remote rendering |
|
72 */ |
|
73 |
|
74 #pragma pack(push) |
|
75 #pragma pack(1) |
|
76 |
|
77 struct render_cmd { |
|
78 u_int32_t img_w; |
|
79 u_int32_t img_h; |
|
80 |
|
81 double x1; |
|
82 double y1; |
|
83 double x2; |
|
84 double y2; |
|
85 }; |
|
86 |
|
87 #pragma pack(pop) |
|
88 |
|
89 #define RENDER_PORT 6159 |
|
90 #define RENDER_CMD_SIZE sizeof(struct render_cmd) |
|
91 |
|
92 /* |
|
93 * build the command to send for remote rendering |
|
94 */ |
|
95 int render_cmd_set ( |
|
96 struct render_cmd *cmd, |
|
97 u_int32_t img_w, u_int32_t img_h, |
|
98 double x1, double y1, double x2, double y2 |
|
99 ); |
|
100 |
|
101 /* |
|
102 * The "full" mandelbrot region |
|
103 */ |
|
104 #define REGION_X1 -2.0 |
|
105 #define REGION_Y1 -1.5 |
|
106 #define REGION_X2 1.0 |
|
107 #define REGION_Y2 1.5 |
|
108 |
|
109 #define mandelbrot_render_full(ctx, img_w, img_h) \ |
|
110 mandelbrot_render_region(ctx, img_w, img_h, REGION_X1, REGION_Y1, REGION_X2, REGION_Y2) |
|
111 |
|
112 #define mandelbrot_render_full_timed(ctx, img_w, img_h, duration) \ |
|
113 mandelbrot_render_region_timed(ctx, img_w, img_h, REGION_X1, REGION_Y1, REGION_X2, REGION_Y2, duration) |
|
114 |
|
115 #define render_cmd_set_full(cmd, img_w, img_h) \ |
|
116 render_cmd_set(cmd, img_w, img_h, REGION_X1, REGION_Y1, REGION_X2, REGION_Y2) |
|
117 |
|