#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "common.h"
#include "render.h"
#include "render_local.h"
static int verbose;
int render_file_local (struct render *ctx, FILE *fh) {
double duration;
if (render_io_stream(ctx, fh))
ERROR("render_io_stream");
if (render_local(ctx, &duration))
ERROR("render_local");
if (verbose) {
u_int32_t img_w, img_h;
if (render_get_size(ctx, &img_w, &img_h))
ERROR("render_get_size");
fprintf(stdout, "rendered %dx%d mandelbrot in %f seconds\n", img_w, img_h, duration);
}
return 0;
error:
return -1;
}
int main (int argc, char **argv) {
int error = 1;
struct render *ctx = NULL;
// parse arguments
int opt;
FILE *output = NULL;
int img_w = 256, img_h = 256;
while ((opt = getopt(argc, argv, "w:h:o:v")) != -1) {
switch(opt) {
case 'w' :
img_w = atoi(optarg);
break;
case 'h' :
img_h = atoi(optarg);
break;
case 'o' :
if (output)
err_exit("Only use -o once");
output = fopen(optarg, "w");
if (!output)
PFATAL("fopen: %s", optarg);
break;
case 'v' :
verbose = 1;
break;
default :
err_exit("Usage: %s [-w img_w] [-h img_h] [-o output_file] [-v]", argv[0]);
}
}
if (!output)
output = stdout;
// setup the struct render
if (!(ctx = render_alloc()))
ERROR("render_alloc");
if (render_set_mode(ctx, RENDER_PNG))
ERROR("render_set_mode");
if (render_set_size(ctx, img_w, img_h))
ERROR("render_set_size");
if (render_region_full(ctx))
ERROR("render_region_full");
// do the render!
if (verbose)
fprintf(stderr, "Render [%dx%d] mandelbrot locally...\n", img_w, img_h);
if (render_file_local(ctx, output))
ERROR("render_local");
// success
error = 0;
error:
if (output)
fclose(output);
free(ctx);
return error;
}
#if 0
void render_remote (int img_w, int img_h, FILE *output, FILE *remote) {
render_t ctx;
struct render_cmd cmd;
render_init(&ctx, RENDER_PNG);
render_set_size(&ctx, img_w, img_h);
render_region_full(&ctx);
if (render_cmd_build(&ctx, &cmd))
err_exit("mandelbrot_render_remote failed");
int ret = fwrite((void *) &cmd, sizeof(cmd), 1, remote);
if (ret != 1)
perr_exit("fwrite(remote)");
if (verbose)
printf("sent render command of %zu bytes\n", sizeof(cmd));
// shuffle data around
while (!feof(remote)) {
char buf[1024];
int bytes = fread(buf, 1, sizeof(buf), remote);
if (bytes)
if (fwrite(buf, bytes, 1, output) != 1)
perr_exit("fwrite(output)");
}
if (verbose)
printf("got PNG data\n");
if (ferror(remote))
perr_exit("fread(remote)");
}
FILE *open_remote (char *remote) {
char *addr_str, *port_str = NULL;
addr_str = strsep(&remote, ":");
if (remote)
port_str = remote;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port_str ? atoi(port_str) : RENDER_PORT);
if (inet_aton(addr_str, &addr.sin_addr) == 0)
err_exit("invalid address: %s", addr_str);
int sock;
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1)
perr_exit("socket");
if (verbose)
printf("connect(%s, %d)\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
if (connect(sock, (const struct sockaddr *) &addr, sizeof(addr)) == -1)
perr_exit("connect(%s, %d)", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
FILE *fh = fdopen(sock, "w+");
if (!fh || ferror(fh))
perr_exit("fdopen");
setbuffer(fh, NULL, 0);
return fh;
}
#endif