--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/render_file.c Fri May 30 14:24:23 2008 +0300
@@ -0,0 +1,173 @@
+#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 "mandelbrot.h"
+#include "common.h"
+
+static int verbose;
+
+int file_write (const unsigned char *data, size_t length, void *arg) {
+ size_t ret = fwrite(data, length, 1, (FILE *) arg);
+
+ return (ret == 1) ? RENDER_CB_OK : RENDER_CB_ERR;
+}
+
+void render_local (int img_w, int img_h, FILE *output) {
+ struct render_ctx ctx;
+
+ render_ctx_set(&ctx, &file_write, NULL, output);
+
+ double duration;
+
+ if (mandelbrot_render_full_timed(
+ &ctx,
+ img_w, img_h,
+ &duration
+ ) != MANDELBROT_OK)
+ err_exit("mandelbrot_render_region failed");
+
+ if (verbose)
+ fprintf(stdout, "rendered %dx%d mandelbrot in %f seconds\n", img_w, img_h, duration);
+}
+
+void render_remote (int img_w, int img_h, FILE *output, FILE *remote) {
+ struct render_cmd cmd;
+
+ if (render_cmd_set_full(&cmd, img_w, img_h) != MANDELBROT_OK) {
+ 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;
+}
+
+int main (int argc, char **argv) {
+ int opt;
+
+ FILE *output = NULL, *remote = NULL;
+ int img_w = 256, img_h = 256;
+
+
+ while ((opt = getopt(argc, argv, "w:h:o:vr:")) != -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)
+ die(optarg);
+
+ break;
+
+ case 'v' :
+ verbose = 1;
+ break;
+
+ case 'r' :
+ if (remote)
+ err_exit("Only use -r once");
+
+ remote = open_remote(optarg);
+
+ break;
+
+ default :
+ err_exit("Usage: %s [-w img_w] [-h img_h] [-o output_file] [-v] [-r host[:port]]", argv[0]);
+ }
+ }
+
+ if (!output)
+ output = stdout;
+
+ if (remote) {
+ if (verbose)
+ fprintf(stderr, "Render [%dx%d] mandelbrot remotely\n", img_w, img_h);
+
+ render_remote(img_w, img_h, output, remote);
+
+ fclose(remote);
+ } else {
+ if (verbose)
+ fprintf(stderr, "Render [%dx%d] mandelbrot locally\n", img_w, img_h);
+
+ render_local(img_w, img_h, output);
+ }
+
+ fclose(output);
+
+ return 0;
+}