1 // Copyright 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifndef __render_parse_h__
22 #define __render_parse_h__
25 #include "render/combine.h"
26 #include "render/invariant.h"
27 #include "render/incremental.h"
28 #include "render/zero.h"
31 * Parse strings describing renderers, and return a renderer satisfying
37 static int strpfix(const char *a
, const char *b
) {
38 return strncmp(a
, b
, strlen(a
));
42 fprintf(stderr
, "\n\n*** Error: unable to allocate memory in render_parse. ***\n\n");
46 static void syntax_error(char *explanation
) {
47 fprintf(stderr
, "\n\n*** Error: Render syntax: %s ***\n\n", explanation
);
51 static filter::filter
*get_SF_atomic(const char *type
) {
54 if (!strcmp("sinc", type
)) {
55 return new filter::sinc();
56 } else if (!strpfix("lanc:", type
)) {
57 if (sscanf(type
+ strlen("lanc:"), "%lf", ¶m
) != 1)
58 syntax_error("Unable to get lanczos diameter.");
59 return new filter::lanczos(param
/2);
60 } else if (!strpfix("triangle:", type
)) {
61 if (sscanf(type
+ strlen("triangle:"), "%lf", ¶m
) != 1)
62 syntax_error("Unable to get triangle diameter.");
63 return new filter::triangle(param
/2);
64 } else if (!strpfix("box:", type
)) {
65 if (sscanf(type
+ strlen("box:"), "%lf", ¶m
) != 1)
66 syntax_error("Unable to get box diameter.");
67 return new filter::box(param
/2);
68 } else if (!strpfix("zero", type
)) {
69 return new filter::zero();
71 fprintf(stderr
, "get_SF_atomic type %s\n", type
);
72 syntax_error("Unable to get filter.");
76 static filter::filter
*get_SF(const char *orig_type
) {
77 char *type
= strdup(orig_type
);
81 char *star_index
= (char *) type
;
82 while (*star_index
!= '\0'
83 && *star_index
!= '*')
86 if (*star_index
== '\0') {
88 return get_SF_atomic(orig_type
);
92 filter::filter
*result
= new filter::mult(
94 get_SF(star_index
+ 1));
101 static filter::scaled_filter
*get_SSF(const char *type
) {
102 if (!strpfix("coarse:", type
)) {
103 return new filter::scaled_filter(get_SF(type
+ strlen("coarse:")), 1);
104 } else if (!strpfix("fine:", type
)) {
105 return new filter::scaled_filter(get_SF(type
+ strlen("fine:")), 0);
107 return new filter::scaled_filter(get_SF(type
), 1);
111 static filter::ssfe
*get_SSFE(const char *type
) {
112 if (!strpfix("ex:", type
)) {
113 return new filter::ssfe(get_SSF(type
+ strlen("ex:")), 1);
114 } else if (!strpfix("nex:", type
)) {
115 return new filter::ssfe(get_SSF(type
+ strlen("nex:")), 0);
117 return new filter::ssfe(get_SSF(type
), 1);
121 static render
*get_invariant(const char *type
) {
123 if (!strpfix("min:", type
)) {
124 i
= new invariant(get_SSFE(type
+ strlen("min:")));
126 } else if (!strpfix("max:", type
)) {
127 i
= new invariant(get_SSFE(type
+ strlen("max:")));
129 } else if (!strpfix("last:", type
)) {
130 i
= new invariant(get_SSFE(type
+ strlen("last:")));
132 } else if (!strpfix("first:", type
)) {
133 i
= new invariant(get_SSFE(type
+ strlen("first:")));
135 } else if (!strpfix("avg:", type
)) {
136 i
= new invariant(get_SSFE(type
+ strlen("avg:")));
138 } else if (!strpfix("median:", type
)) {
139 i
= new invariant(get_SSFE(type
+ strlen("median:")));
142 i
= new invariant(get_SSFE(type
));
146 for (int index
= 0; index
< render::render_count(); index
++)
147 if (typeid(*render::render_num(index
)) == typeid(incremental
)
148 && i
->equals(((incremental
*)render::render_num(index
))->get_invariant())) {
150 return (incremental
*)render::render_num(index
);
151 } else if (typeid(*i
->ssfe()->get_scaled_filter()->get_filter()) == typeid(filter::zero
)) {
155 // fprintf(stderr, " new '%s'.\n", type);
157 return new incremental(i
);
160 static render
*get_combination(const char *ptype
, const char *dtype
) {
161 render
*partial
= get_invariant(ptype
);
162 render
*_default
= get(dtype
);
163 for (int index
= 0; index
< render::render_count(); index
++)
164 if (typeid(*render::render_num(index
)) == typeid(combine
)
165 && _default
== ((combine
*)render::render_num(index
))->get_default()
166 && partial
== ((combine
*)render::render_num(index
))->get_partial()) {
167 return render::render_num(index
);
170 // fprintf(stderr, " new '%s,%s'.\n", ptype, dtype);
172 return new combine(_default
, partial
);
175 static render
*get(const char *orig_type
) {
176 char *type
= strdup(orig_type
);
180 char *comma_index
= (char *) type
;
181 while (*comma_index
!= '\0'
182 && *comma_index
!= ',')
185 if (*comma_index
== '\0') {
187 return get_invariant(orig_type
);
191 render
*result
= get_combination(type
, comma_index
+ 1);