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