static void add_define(char *name, int nargs, char *exps) { struct defn *p; unsigned int h; if ((p = lookup_define(name)) != NULL) { if (nargs != p->nargs || strcmp(exps, p->exps) != 0) { lexerror("Redefinition of #define %s", name); } return; } p = (struct defn *)xalloc(sizeof(struct defn)); p->name = xalloc(strlen(name)+1); (void)strcpy(p->name, name); p->undef = 0; p->nargs = nargs; p->exps = xalloc(strlen(exps)+1); (void)strcpy(p->exps, exps); h = defhash(name); p->next = defns[h]; defns[h] = p; /*(void)fprintf(stderr, "define '%s' %d '%s'\n", name, nargs, exps);*/ }
static int yylex1(void) { register char *yyp; register int c; register int c1, c2; for (;;) { if (lex_fatal) { return -1; } switch(c = mygetc()) { case EOF: if (inctop) { struct incstate *p; p = inctop; (void)fclose(yyin); /*(void)fprintf(stderr, "popping to %s\n", p->file);*/ free(current_file); nexpands = 0; current_file = p->file; current_line = p->line + 1; current_incfile = p->incfnum; pragma_strict_types = p->pragma_strict_types; yyin = p->yyin; slast = p->slast; lastchar = p->lastchar; inctop = p->next; if (p->nbuf) { nbuf = p->nbuf; outp = defbuf + DEFMAX - nbuf; memcpy(outp, p->outp, nbuf); free((char *)p->outp); } else { nbuf = 0; outp = defbuf + DEFMAX; } store_line_number_info(current_incfile, current_line); incdepth--; free((char *)p); break; } if (iftop) { struct ifstate *p = iftop; lexerror(p->state == EXPECT_ENDIF ? "Missing #endif" : "Missing #else"); while (iftop) { p = iftop; iftop = p->next; free((char *)p); } } return -1; case '\n': { nexpands=0; store_line_number_info(current_incfile, current_line); current_line++; total_lines++; } /* FALLTHROUGH */ case ' ': case '\t': case '\f': case '\v': break; case '+': TRY('+', F_INC); TRY('=', F_ADD_EQ); return c; case '-': TRY('>', F_ARROW); TRY('-', F_DEC); TRY('=', F_SUB_EQ); return c; case '&': TRY('&', F_LAND); TRY('=', F_AND_EQ); return c; case '|': TRY('|', F_LOR); TRY('=', F_OR_EQ); return c; case '^': TRY('=', F_XOR_EQ); return c; case '<': if (gobble('<')) { TRY('=', F_LSH_EQ); return F_LSH; } TRY('=', F_LE); return c; case '>': if (gobble('>')) { TRY('=', F_RSH_EQ); return F_RSH; } TRY('=', F_GE); return c; case '*': TRY('=', F_MULT_EQ); return c; case '%': TRY('=', F_MOD_EQ); return F_MOD; case '/': if (gobble('*')) { skip_comment(); break; } else if (gobble('/')) { skip_comment2(); break; } TRY('=', F_DIV_EQ); return c; case '=': TRY('=', F_EQ); return c; case ';': case '(': case ')': case ',': case '{': case '}': case '~': case '[': case ']': case '?': case '@': return c; case '!': TRY('=', F_NE); return F_NOT; case ':': TRY(':', F_COLON_COLON); return ':'; case '.': if (gobble('.')) { if (gobble('.')) return F_VARARG; else return F_RANGE; } return c; case '#': if (lastchar == '\n') { char *ssp = 0; int quote; yyp = yytext; do { c = mygetc(); } while (isspace(c)); for (quote = 0;;) { if (c == '"') quote ^= 1; /*gc - handle comments cpp-like! 1.6.91 @@@*/ while (!quote && c == '/') { if (gobble('*')) { skip_comment(); c = mygetc(); } else break; } if (!ssp && isspace(c)) ssp = yyp; if (c == '\n' || c == EOF) break; SAVEC; c = mygetc(); } if (ssp) { *ssp++ = 0; while (isspace(*ssp)) ssp++; } else { ssp = yyp; } *yyp = 0; if (strcmp("define", yytext) == 0) { handle_define(ssp); } else if (strcmp("if", yytext) == 0) { #if 0 short int nega=0; /*@@@ allow #if !VAR gc 1.6.91*/ if (*ssp=='!'){ ssp++; nega=1;} if (isdigit(*ssp)) { char *p; long l; l = strtol(ssp, &p, 10); while (isspace(*p)) p++; if (*p) lexerror("Condition too complex in #if"); else handle_cond(nega ? !(int)l : (int)l); } else if (isalunum(*ssp)) { char *p = ssp; while (isalunum(*p)) p++; if (*p) { *p++ = 0; while (isspace(*p)) p++; } if (*p) lexerror("Condition too complex in #if"); else { struct defn *d; d = lookup_define(ssp); if (d) { handle_cond(nega ? !atoi(d->exps) : atoi(d->exps));/* a hack! */ } else { handle_cond(nega?1:0); /* cpp-like gc*/ } } } else lexerror("Condition too complex in #if"); #else int cond; myungetc(0); add_input(ssp); cond = cond_get_exp(0); if (mygetc()) { lexerror("Condition too complex in #if"); while (mygetc()) ; } else handle_cond(cond); #endif } else if (strcmp("ifdef", yytext) == 0) { deltrail(ssp); handle_cond(lookup_define(ssp) != 0); } else if (strcmp("ifndef", yytext) == 0) { deltrail(ssp); handle_cond(lookup_define(ssp) == 0); } else if (strcmp("else", yytext) == 0) { if (iftop && iftop->state == EXPECT_ELSE) { struct ifstate *p = iftop; /*(void)fprintf(stderr, "found else\n");*/ iftop = p->next; free((char *)p); (void)skip_to("endif", (char *)0); store_line_number_info(current_incfile, current_line); current_line++; total_lines++; } else { lexerror("Unexpected #else"); } } else if (strcmp("endif", yytext) == 0) { if (iftop && (iftop->state == EXPECT_ENDIF || iftop->state == EXPECT_ELSE)) { struct ifstate *p = iftop; /*(void)fprintf(stderr, "found endif\n");*/ iftop = p->next; free((char *)p); } else { lexerror("Unexpected #endif"); } } else if (strcmp("undef", yytext) == 0) { struct defn *d; deltrail(ssp); if ((d = lookup_define(ssp)) != NULL ) d->undef++; } else if (strcmp("echo", yytext) == 0) { (void)fprintf(stderr, "%s\n", ssp); } else if (strcmp("include", yytext) == 0) { /*(void)fprintf(stderr, "including %s\n", ssp); */ handle_include(ssp, 0); } else if (strcmp("pragma", yytext) == 0) { deltrail(ssp); handle_pragma(ssp); } else if (strcmp("error", yytext) == 0) { handle_exception(ERROR, ssp); } else if (strcmp("warning", yytext) == 0) { handle_exception(WARNING, ssp); } else { lexerror("Unrecognised # directive"); } myungetc('\n'); break; } else goto badlex; case '\'': yylval.number = mygetc(); if (yylval.number == '\\') { int tmp = mygetc(); switch (tmp) { case 'n': yylval.number = '\n'; break; case 't': yylval.number = '\t'; break; case 'b': yylval.number = '\b'; break; case 'a': yylval.number = '\a'; break; case 'v': yylval.number = '\v'; break; case '\'': case '\\': case '"': yylval.number = tmp; break; default: lexwarning("Bad character escape sequence"); yylval.number = tmp; break; } } if (!gobble('\'')) lexerror("Illegal character constant"); return F_NUMBER; case '"': yyp = yytext; *yyp++ = c; for (;;) { c = mygetc(); if (c == EOF) { lexerror("End of file in string"); return string("\"\""); } else if (c == '\n') { lexerror("Newline in string"); return string("\"\""); } SAVEC; if (c == '"') break; if (c == '\\') { c = mygetc(); if ( c == '\n' ) { yyp--; store_line_number_info(current_incfile, current_line); current_line++; total_lines++; } else if ( c == EOF ) { /* some operating systems give EOF only once */ myungetc(c); } else *yyp++ = c; } } *yyp = 0; return string(yytext); case '0': c = mygetc(); if ( c == 'X' || c == 'x' || c == 'o') { char *endptr; long long value; int base = 16; if (c == 'o') base = 8; yyp = yytext; for (;;) { c = mygetc(); if (!isxdigit(c)) break; SAVEC; } myungetc(c); *yyp = '\0'; value = strtoll(yytext, &endptr, base); if (*endptr != '\0') { fprintf(stderr, "%s\n", yytext); lexwarning("Invalid digits in octal number number"); } return number(value); } myungetc(c); c = '0'; /* FALLTHROUGH */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': yyp = yytext; *yyp++ = c; for (;;) { c = mygetc(); if (!isdigit(c)) break; SAVEC; } if (c == '.') { if (isdigit(c1 = mygetc())) { SAVEC; c = c1; SAVEC; for (c = mygetc(); isdigit(c); c = mygetc()) SAVEC; if (c == 'e' || c == 'E') { c1 = mygetc(); if (c1 == '-' || c1 == '+') { c2 = mygetc(); if (isdigit(c2)) { SAVEC; c = c1; SAVEC; c = c2; SAVEC; for (c = mygetc(); isdigit(c); c = mygetc()) SAVEC; } else { myungetc(c2); myungetc(c1); } } else if (isdigit(c1)) { SAVEC; c = c1; SAVEC; for (c = mygetc(); isdigit(c); c = mygetc()) SAVEC; } else myungetc(c1); } myungetc(c); *yyp = 0; return real(strtod(yytext, NULL)); } myungetc(c1); } myungetc(c); *yyp = 0; if (*yytext == '0') { /* OCTALS */ char *endptr; long long value; value = strtoll(yytext, &endptr, 010); if (*endptr != '\0') lexwarning("Invalid digits in octal number"); if (value != 0) lexwarning("Obsolete octal format used. Use 0o111 syntax"); return number(value); } return number(atoll(yytext)); default: if (isalpha(c) || c == '_') { int r; yyp = yytext; *yyp++ = c; for (;;) { c = mygetc(); if (!isalunum(c)) break; SAVEC; } *yyp = 0; myungetc(c); if (!expand_define()) { r = lookup_resword(yytext); if (r >= 0) { return r; } else return ident(yytext); } break; } goto badlex; } } badlex: { lexerror("Illegal character (hex %02x) '%c'", c, c); return ' '; } }
int handle_include(char *name, int ignore_errors) { char *p; char buf[1024]; FILE *f; struct incstate *is; int delim; if (*name != '"' && *name != '<') { struct defn *d; if ((d = lookup_define(name)) && d->nargs == -1) { char *q; q = d->exps; while (isspace(*q)) q++; return handle_include(q, ignore_errors); } else { if (!ignore_errors) lexerror("Missing leading \" or < in #include"); return 0; } } delim = *name++ == '"' ? '"' : '>'; for (p = name; *p && *p != delim; p++) ; if (!*p) { if (!ignore_errors) lexerror("Missing trailing \" or > in #include"); return 0; } if (strlen(name) > sizeof(buf) - 100) { if (!ignore_errors) lexerror("Include name too long."); return 0; } *p = 0; if ((f = inc_open(buf, sizeof(buf), name)) == NULL) { if (!ignore_errors) { lexerror("Cannot #include %s\n", name); } return 0; } is = (struct incstate *)xalloc(sizeof(struct incstate)); is->yyin = yyin; is->line = current_line; is->file = current_file; is->incfnum = current_incfile; is->slast = slast; is->lastchar = lastchar; is->next = inctop; is->pragma_strict_types = pragma_strict_types; if (nbuf) { memcpy(is->outp = (char *)xalloc(nbuf + 1), outp, nbuf); is->nbuf = nbuf; nbuf = 0; outp = defbuf + DEFMAX; } else { is->nbuf = 0; is->outp = NULL; } pragma_strict_types = 0; inctop = is; current_line = 1; current_file = xalloc(strlen(buf)+1); current_incfile = ++num_incfiles; (void)strcpy(current_file, buf); slast = lastchar = '\n'; yyin = f; incdepth++; return 1; }
/* Stuff to evaluate expression. I havn't really checked it. /LA ** Written by "J\"orn Rennecke" <*****@*****.**> */ static int exgetc(void) { register char c, *yyp; c = mygetc(); while (isalpha(c) || c == '_') { yyp = yytext; do { SAVEC; c = mygetc(); } while (isalunum(c)); myungetc(c); *yyp = '\0'; if (strcmp(yytext, "defined") == 0) { /* handle the defined "function" in #if */ do c = mygetc(); while (isspace(c)); if (c != '(') { lexerror("Missing ( in defined"); continue; } do c = mygetc(); while (isspace(c)); yyp = yytext; while (isalunum(c)) { SAVEC; c = mygetc(); } *yyp = '\0'; while (isspace(c)) c = mygetc(); if (c != ')') { lexerror("Missing ) in defined"); continue; } /* Skip whitespace */ do c = mygetc(); while (isspace(c)); myungetc(c); if (lookup_define(yytext)) add_input(" 1 "); else add_input(" 0 "); } else { if (!expand_define()) add_input(" 0 "); } c = mygetc(); } return c; }
/* Check if yytext is a macro and expand if it is. */ static int expand_define(void) { struct defn *p; char expbuf[DEFMAX]; char *args[NARGS]; char buf[DEFMAX]; char *q, *e, *b; if (nexpands++ > EXPANDMAX) { lexerror("Too many macro expansions"); return 0; } p = lookup_define(yytext); if (!p) { return 0; } if (p->nargs == -1) { add_input(p->exps); } else { int c, parcnt = 0, dquote = 0, squote = 0; int n; SKIPW; if (c != '(') { lexerror("Missing '(' in macro call"); return 0; } SKIPW; if (c == ')') n = 0; else { q = expbuf; args[0] = q; for (n = 0; n < NARGS; ) { switch(c) { case '"': if (!squote) dquote ^= 1; break; case '\'': if (!dquote) squote ^= 1; break; case '(': if (!squote && !dquote) parcnt++; break; case ')': if (!squote && !dquote) parcnt--; break; case '\\': if (squote || dquote) { *q++ = c; c = mygetc();} break; case '\n': if (squote || dquote) { lexerror("Newline in string"); return 0; } break; } if (c == ',' && !parcnt && !dquote && !squote) { *q++ = 0; args[++n] = q; } else if (parcnt < 0) { *q++ = 0; n++; break; } else { if (c == EOF) { lexerror("Unexpected end of file"); return 0; } if (q >= expbuf + DEFMAX - 5) { lexerror("Macro argument overflow"); return 0; } else { *q++ = c; } } if (!squote && ! dquote) c = cmygetc(); else c = mygetc(); } if (n == NARGS) { lexerror("Maximum macro argument count exceeded"); return 0; } } if (n != p->nargs) { lexerror("Wrong number of macro arguments"); return 0; } /* Do expansion */ b = buf; e = p->exps; while (*e) { if (*e == MARKS) { if (*++e == MARKS) *b++ = *e++; else { for (q = args[*e++ - MARKS - 1]; *q; ) { *b++ = *q++; if (b >= buf+DEFMAX) { lexerror("Macro expansion overflow"); return 0; } } } } else { *b++ = *e++; if (b >= buf+DEFMAX) { lexerror("Macro expansion overflow"); return 0; } } } *b++ = 0; add_input(buf); } return 1; }
int cmdline_main (int argc, char *argv[]) { guchar *output; int num_frames = 1; #ifdef MOVIES int generate_movie = 0; quicktime_t *output_movie; guchar **rows; #endif int antialiasing = 0, supersampling = 0; int img_width, img_height; char *generator = 0; userval_info_t *userval_info; int num_input_drawables = 0; gboolean size_is_set = FALSE; char *script = NULL; char *output_filename; gboolean htmldoc = FALSE; define_t *defines = NULL; int bench_render_count = 1; int render_num; gboolean bench_no_output = FALSE; gboolean bench_no_backend = FALSE; int compile_time_limit = DEFAULT_OPTIMIZATION_TIMEOUT; for (;;) { static struct option long_options[] = { { "version", no_argument, 0, OPTION_VERSION }, { "help", no_argument, 0, OPTION_HELP }, { "intersampling", no_argument, 0, 'i' }, { "oversampling", no_argument, 0, 'o' }, { "cache", required_argument, 0, 'c' }, { "generator", required_argument, 0, 'g' }, { "size", required_argument, 0, 's' }, { "script-file", required_argument, 0, 'f' }, { "htmldoc", no_argument, 0, OPTION_HTMLDOC }, { "bench-no-output", no_argument, 0, OPTION_BENCH_NO_OUTPUT }, { "bench-only-compile", no_argument, 0, OPTION_BENCH_ONLY_COMPILE }, { "bench-no-compile-time-limit", no_argument, 0, OPTION_BENCH_NO_COMPILE_TIME_LIMIT }, { "bench-no-backend", no_argument, 0, OPTION_BENCH_NO_BACKEND }, { "bench-render-count", required_argument, 0, OPTION_BENCH_RENDER_COUNT }, #ifdef MOVIES { "frames", required_argument, 0, 'F' }, { "movie", required_argument, 0, 'M' }, #endif { 0, 0, 0, 0 } }; int option, option_index; option = getopt_long(argc, argv, #ifdef MOVIES "f:ioF:D:M:c:g:s:", #else "f:ioD:c:g:s:", #endif long_options, &option_index); if (option == -1) break; switch (option) { case OPTION_VERSION : printf("MathMap " MATHMAP_VERSION "\n" "\n" "Copyright (C) 1997-2009 Mark Probst\n" "\n" "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" "the Free Software Foundation; either version 2 of the License, or\n" "(at your option) any later version.\n" "\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "GNU General Public License for more details.\n" "\n" "You should have received a copy of the GNU General Public License\n" "along with this program; if not, write to the Free Software\n" "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"); return 0; case OPTION_HELP : usage(); return 0; case OPTION_HTMLDOC : htmldoc = TRUE; break; case 'f' : if (!g_file_get_contents(optarg, &script, NULL, NULL)) { fprintf(stderr, _("Error: The script file `%s' could not be read.\n"), optarg); return 1; } break; case 'i' : antialiasing = 1; break; case 'o' : supersampling = 1; break; case 'c' : cache_size = atoi(optarg); assert(cache_size > 0); break; case 'D' : append_define(optarg, &defines); break; case 'I' : alloc_cmdline_image_input_drawable(optarg); break; case 'g' : generator = optarg; break; case 's' : if (!parse_image_size(optarg, &img_width, &img_height)) { fprintf(stderr, _("Error: Invalid image size. Syntax is <width>x<height>. Example: 1024x768.\n")); exit(1); } size_is_set = 1; break; case OPTION_BENCH_RENDER_COUNT : bench_render_count = atoi(optarg); break; case OPTION_BENCH_ONLY_COMPILE : bench_render_count = 0; break; case OPTION_BENCH_NO_OUTPUT : bench_no_output = TRUE; break; case OPTION_BENCH_NO_COMPILE_TIME_LIMIT : compile_time_limit = -1; break; case OPTION_BENCH_NO_BACKEND : bench_no_backend = TRUE; break; #ifdef MOVIES case 'F' : generate_movie = 1; num_frames = atoi(optarg); assert(num_frames > 0); break; case 'M' : alloc_cmdline_movie_input_drawable(optarg); break; #endif } } if (script != NULL) { if (argc - optind != 1) { usage(); return 1; } output_filename = argv[optind]; } else { if (argc - optind != 2) { usage(); return 1; } script = argv[optind]; output_filename = argv[optind + 1]; } init_tags(); init_builtins(); init_macros(); init_compiler(); if (htmldoc) { mathmap_t *mathmap = parse_mathmap(script); filter_t *filter; FILE *out; if (mathmap == NULL) { fprintf(stderr, _("Error: Could not read MathMap script: %s\n"), error_string); return 1; } out = fopen(output_filename, "w"); if (out == NULL) { fprintf(stderr, _("Error: Cannot open file `%s' for writing: %s\n"), output_filename, strerror(errno)); return 1; } for (filter = mathmap->filters; filter != NULL; filter = filter->next) { if (filter->kind != FILTER_MATHMAP) continue; if (!write_filter_html_doc(out, filter->v.mathmap.decl)) return 1; } fclose(out); } else if (generator == 0) { char *support_paths[4]; mathmap_t *mathmap; mathmap_invocation_t *invocation; int current_frame; support_paths[0] = g_strdup_printf("%s/mathmap", GIMPDATADIR); support_paths[1] = g_strdup_printf("%s/.gimp-2.6/mathmap", getenv("HOME")); support_paths[2] = g_strdup_printf("%s/.gimp-2.4/mathmap", getenv("HOME")); support_paths[3] = NULL; mathmap = compile_mathmap(script, support_paths, compile_time_limit, bench_no_backend); if (bench_no_backend) return 0; if (mathmap == 0) { fprintf(stderr, _("Error: %s\n"), error_string); exit(1); } if (bench_render_count == 0) return 0; if (!size_is_set) for (userval_info = mathmap->main_filter->userval_infos; userval_info != NULL; userval_info = userval_info->next) { define_t *define; unsigned char *image; if (userval_info->type != USERVAL_IMAGE) continue; define = lookup_define(defines, userval_info->name); if (define == NULL) { fprintf(stderr, _("Error: No value defined for input image `%s'.\n"), userval_info->name); return 1; } image = read_image(define->value, &img_width, &img_height); if (image == NULL) { fprintf(stderr, _("Error: Could not read input image `%s'.\n"), define->value); return 1; } free(image); size_is_set = TRUE; break; } if (!size_is_set) { fprintf(stderr, _("Error: Image size not set and no input images given.\n")); exit(1); } invocation = invoke_mathmap(mathmap, NULL, img_width, img_height, TRUE); for (userval_info = mathmap->main_filter->userval_infos; userval_info != NULL; userval_info = userval_info->next) { userval_t *userval = &invocation->uservals[userval_info->index]; define_t *define = lookup_define(defines, userval_info->name); if (define == NULL) { if (userval_info->type == USERVAL_IMAGE) { fprintf(stderr, _("Error: No value defined for input image `%s'.\n"), userval_info->name); return 1; } } else switch (userval_info->type) { case USERVAL_INT_CONST : userval->v.int_const = atoi(define->value); break; case USERVAL_FLOAT_CONST : userval->v.float_const = g_ascii_strtod(define->value, NULL); break; case USERVAL_BOOL_CONST : userval->v.bool_const = (float)atoi(define->value); break; case USERVAL_IMAGE : assign_image_userval_drawable(userval_info, userval, alloc_cmdline_image_input_drawable(define->value)); ++num_input_drawables; break; default : fprintf(stderr, _("Error: Can only define user values for types int, float, bool and image.\n")); return 1; } } for (render_num = 0; render_num < bench_render_count; ++render_num) { #ifdef MOVIES for (i = 0; i < num_input_drawables; ++i) if (input_drawables[i].type == DRAWABLE_MOVIE) { assert(quicktime_video_width(input_drawables[i].v.movie, 0) == img_width); assert(quicktime_video_height(input_drawables[i].v.movie, 0) == img_height); } #endif invocation_set_antialiasing(invocation, antialiasing); invocation->supersampling = supersampling; invocation->output_bpp = 4; output = (guchar*)malloc((long)invocation->output_bpp * (long)img_width * (long)img_height); assert(output != 0); #ifdef MOVIES if (generate_movie) { output_movie = quicktime_open(output_filename, 0, 1); assert(output_movie != 0); quicktime_set_video(output_movie, 1, img_width, img_height, 25, QUICKTIME_JPEG); assert(quicktime_supported_video(output_movie, 0)); quicktime_seek_start(output_movie); rows = (guchar**)malloc(sizeof(guchar*) * img_height); for (i = 0; i < img_height; ++i) rows[i] = output + img_width * invocation->output_bpp * i; } #endif for (current_frame = 0; current_frame < num_frames; ++current_frame) { float current_t = (float)current_frame / (float)num_frames; image_t *closure = closure_image_alloc(&invocation->mathfuncs, NULL, invocation->mathmap->main_filter->num_uservals, invocation->uservals, img_width, img_height); mathmap_frame_t *frame = invocation_new_frame(invocation, closure, current_frame, current_t); call_invocation_parallel_and_join(frame, closure, 0, 0, img_width, img_height, output, 1); invocation_free_frame(frame); #ifdef MOVIES if (generate_movie && !bench_no_output) { fprintf(stderr, _("writing frame %d\n"), current_frame); assert(quicktime_encode_video(output_movie, rows, 0) == 0); } #endif closure_image_free(closure); } if (!bench_no_output) { #ifdef MOVIES if (generate_movie) quicktime_close(output_movie); else #endif write_image(output_filename, img_width, img_height, output, invocation->output_bpp, img_width * invocation->output_bpp, IMAGE_FORMAT_PNG); } free(output); } } else { if (strcmp(generator, "blender") == 0) { if (!blender_generate_plug_in(script, output_filename)) return 1; } /* else if (strcmp(generator, "pixeltree") == 0) { if (!pixeltree_generate_plug_in(argv[optind], argv[optind + 1])) return 1; } */ else { fprintf(stderr, _("Unknown generator `%s'\n"), generator); return 1; } } return 0; }