// Copyright 2004 David Hilvert , // /* This file is part of the Anti-Lamenessing Engine. The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. The Anti-Lamenessing Engine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the Anti-Lamenessing Engine; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __psf_parse_h__ #define __psf_parse_h__ #include "psf.h" #include "box.h" #include "circle.h" #include "gauss.h" #include "sum.h" #include "convolution.h" #include "scalar_mult.h" #include "stdin.h" #include "stdin_vg.h" /* * Parse strings describing point-spread functions, and return a psf object * satisfying the string. */ class psf_parse { private: static int strpfix(const char *a, const char *b) { return strncmp(a, b, strlen(a)); } static void nomem() { fprintf(stderr, "\n\n*** Error: unable to allocate memory in psf_parse. ***\n\n"); exit(1); } static void syntax_error(const char *explanation) { fprintf(stderr, "\n\n*** Error: PSF syntax: %s ***\n\n", explanation); exit(1); } /* * Evaluate a type string having no remaining binary operators. */ static psf *get_atomic(int is_linear, const char *orig_type) { double param; if (!strcmp(orig_type, "stdin")) { fprintf(stderr, "\nInitializing "); fprintf(stderr, is_linear ? "linear" : "non-linear"); fprintf(stderr, " PSF.\n"); return new psf_stdin(); } else if (!strcmp(orig_type, "stdin_vg")) { fprintf(stderr, "\nInitializing "); fprintf(stderr, is_linear ? "linear" : "non-linear"); fprintf(stderr, " PSF.\n"); return new psf_stdin_vg(); } else if (!strpfix("box=", orig_type)) { if (sscanf(orig_type + strlen("box="), "%lf", ¶m) != 1) syntax_error("Unable to get box diameter."); return new box(param / 2); } else if (!strpfix("circle=", orig_type)) { if (sscanf(orig_type + strlen("circle="), "%lf", ¶m) != 1) syntax_error("Unable to get circle diameter."); return new circle(param / 2); } else if (!strpfix("gauss=", orig_type)) { if (sscanf(orig_type + strlen("gauss="), "%lf", ¶m) != 1) syntax_error("Unable to parse gauss std deviation."); return new gauss(param / 2); } else { fprintf(stderr, "get_atomic type %s\n", orig_type); syntax_error("Unable to get filter."); } assert(0); } /* * Get a scalar value */ static ale_real get_scalar(const char *orig_type) { double result; if (sscanf(orig_type, "%lf", &result) != 1) syntax_error("Unable to get scalar value."); return result; } /* * Split a type string with the binary operator having * third-lowest precedence (i.e., scalar multiplication). */ static psf *get_scalar_mult(int is_linear, const char *orig_type) { char *type = strdup(orig_type); char *operator_index = (char *) type; assert(type); if (!type) nomem(); while (*operator_index != '\0' && *operator_index != '*') operator_index++; if (*operator_index == '\0') { free(type); return get_atomic(is_linear, orig_type); } *operator_index = '\0'; psf *result = new scalar_mult(get_scalar(type), get_scalar_mult(is_linear, operator_index + 1)); *operator_index = '*'; free(type); return result; } /* * Split a type string with the binary operator having * second-lowest precedence (i.e., convolution). */ static psf *get_convolution(int is_linear, const char *orig_type) { char *type = strdup(orig_type); char *operator_index = (char *) type; assert(type); if (!type) nomem(); while (*operator_index != '\0' && *operator_index != '^') operator_index++; if (*operator_index == '\0') { free(type); return get_scalar_mult(is_linear, orig_type); } *operator_index = '\0'; psf *result = new convolution(get_scalar_mult(is_linear, type), get_convolution(is_linear, operator_index + 1)); *operator_index = '^'; free(type); return result; } /* * Split the type string using the binary operator with * lowest precedence (addition). */ static psf *get_summation(int is_linear, const char *orig_type) { char *type = strdup(orig_type); char *plus_index = (char *) type; assert(type); if (!type) nomem(); while (*plus_index != '\0' && *plus_index != '+') plus_index++; if (*plus_index == '\0') { free(type); return get_convolution(is_linear, orig_type); } *plus_index = '\0'; psf *result = new sum(get_convolution(is_linear, type), get_summation(is_linear, plus_index + 1)); *plus_index = '+'; free(type); return result; } public: static psf *get(int is_linear, const char *orig_type) { return get_summation(is_linear, orig_type); } }; #endif