]> git.sesse.net Git - vlc/blob - modules/visualization/galaktos/param.c
Remove stdio while we're at it.
[vlc] / modules / visualization / galaktos / param.c
1 /*****************************************************************************
2  * param.c:
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet <asmax@videolan.org>
8  *          code from projectM http://xmms-projectm.sourceforge.net
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25
26
27 /* Basic Parameter Functions */
28
29 #include <math.h>
30 #include "fatal.h"
31 #include "common.h"
32
33 #include "splaytree_types.h"
34 #include "splaytree.h"
35 #include "tree_types.h"
36
37 #include "param_types.h"
38 #include "param.h"
39
40 #include "expr_types.h"
41 #include "eval.h"
42
43 #include "engine_vars.h" 
44
45 void reset_param(param_t * param);
46
47 int is_valid_param_string(char * string); /* true if string is valid variable or function name */
48
49
50 /* A splay tree of builtin parameters */
51 splaytree_t * builtin_param_tree = NULL;
52
53 int insert_param_alt_name(param_t * param, char * alt_name);
54
55 int insert_builtin_param(param_t * param);
56
57 /* Private function prototypes */
58 int compare_param(char * name, char * name2);
59
60 int load_builtin_param_double(char * name, void * engine_val, void * matrix, short int flags, 
61                                                                 double init_val, double upper_bound, double lower_bound, char * alt_name);
62
63 int load_builtin_param_int(char * name, void * engine_val, short int flags, 
64                                                                 int init_val, int upper_bound, int lower_bound, char * alt_name);
65                                                                 
66 int load_builtin_param_bool(char * name, void * engine_val, short int flags, 
67                                                                 int init_val, char * alt_name);
68                                                                 
69                                                                 
70                                                                 
71 param_t * create_param (char * name, short int type, short int flags, void * engine_val, void * matrix,
72                                                         value_t default_init_val, value_t upper_bound, value_t lower_bound) {
73
74   param_t * param = NULL;
75
76   param = (param_t*)malloc(sizeof(param_t));
77  
78   if (param == NULL) {
79         printf("create_param: out of memory!!!\n");
80         return NULL;
81   }
82   
83   /* Clear name space, think the strncpy statement makes this redundant */
84   //memset(param->name, 0, MAX_TOKEN_SIZE);
85
86   /* Copy given name into parameter structure */
87   strncpy(param->name, name, MAX_TOKEN_SIZE-1); 
88   
89   /* Assign other entries in a constructor like fashion */
90   param->type = type;
91   param->flags = flags;
92   param->matrix_flag = 0;
93   param->matrix = matrix;
94   param->engine_val = engine_val;
95   param->default_init_val = default_init_val;
96   //*param->init_val = default_init_val;
97   param->upper_bound = upper_bound;
98   param->lower_bound = lower_bound;
99   
100   /* Return instantiated parameter */
101   return param;
102
103 }
104
105 /* Creates a user defined parameter */
106 param_t * create_user_param(char * name) {
107
108   param_t * param;
109   value_t iv;
110   value_t ub;
111   value_t lb;
112   double * engine_val;
113   
114   /* Set initial values to default */
115   iv.double_val = DEFAULT_DOUBLE_IV;
116   ub.double_val = DEFAULT_DOUBLE_UB;
117   lb.double_val = DEFAULT_DOUBLE_LB;
118
119   /* Argument checks */
120   if (name == NULL)
121     return NULL;
122
123   /* Allocate space for the engine variable */
124   if ((engine_val = (double*)malloc(sizeof(double))) == NULL)
125     return NULL;
126
127   (*engine_val) = iv.double_val; /* set some default init value */
128   
129   /* Create the new user parameter */
130   if ((param = create_param(name, P_TYPE_DOUBLE, P_FLAG_USERDEF, engine_val, NULL, iv, ub, lb)) == NULL) {
131     free(engine_val);
132     return NULL;
133   }
134   if (PARAM_DEBUG) printf("create_param: \"%s\" initialized\n", param->name);
135   /* Return the instantiated parameter */
136   return param;
137 }
138
139 /* Initialize the builtin parameter database.
140    Should only be necessary once */
141 int init_builtin_param_db() {
142         
143   /* Create the builtin parameter splay tree (go Sleator...) */
144   if ((builtin_param_tree = create_splaytree(compare_string, copy_string, free_string)) == NULL) {
145           if (PARAM_DEBUG) printf("init_builtin_param_db: failed to initialize database (FATAL)\n");  
146           return OUTOFMEM_ERROR;
147   } 
148
149   if (PARAM_DEBUG) {
150           printf("init_builtin_param: loading database...");
151           fflush(stdout);
152   }
153   
154   /* Loads all builtin parameters into the database */
155   if (load_all_builtin_param() < 0) {
156         if (PARAM_DEBUG) printf("failed loading builtin parameters (FATAL)\n");
157     return ERROR;
158   }
159   
160   if (PARAM_DEBUG) printf("success!\n");
161           
162   /* Finished, no errors */
163   return SUCCESS;
164 }
165
166 /* Destroy the builtin parameter database.
167    Generally, do this on projectm exit */
168 int destroy_builtin_param_db() {
169   
170   splay_traverse(free_param, builtin_param_tree);
171   destroy_splaytree(builtin_param_tree);
172   builtin_param_tree = NULL;
173   return SUCCESS;       
174
175 }
176
177
178 /* Insert a parameter into the database with an alternate name */
179 int insert_param_alt_name(param_t * param, char * alt_name) {
180   
181   if (param == NULL)
182     return ERROR;
183   if (alt_name == NULL)
184           return ERROR;
185         
186   splay_insert_link(alt_name, param->name, builtin_param_tree);
187
188   return SUCCESS;
189 }
190
191
192 param_t * find_builtin_param(char * name) {
193
194   /* Null argument checks */
195   if (name == NULL)
196           return NULL;
197     
198   return splay_find(name, builtin_param_tree);
199
200 }
201
202 /* Find a parameter given its name, will create one if not found */
203 param_t * find_param(char * name, preset_t * preset, int flags) {
204
205   param_t * param = NULL;
206
207   /* Null argument checks */
208   if (name == NULL)
209           return NULL;
210   if (preset == NULL)
211           return NULL;
212   
213   /* First look in the builtin database */
214   param = (param_t *)splay_find(name, builtin_param_tree);
215
216   /* If the search failed, check the user database */
217   if (param == NULL) {
218     param = (param_t*)splay_find(name, preset->user_param_tree);
219   }
220   /* If it doesn't exist in the user (or builtin) database and 
221           create_flag is set, then make it and insert into the database 
222   */
223   
224   if ((param == NULL) && (flags & P_CREATE)) {
225         
226         /* Check if string is valid */
227     if (!is_valid_param_string(name)) {
228       if (PARAM_DEBUG) printf("find_param: invalid parameter name:\"%s\"\n", name);
229       return NULL;
230     }
231     /* Now, create the user defined parameter given the passed name */
232     if ((param = create_user_param(name)) == NULL) {
233       if (PARAM_DEBUG) printf("find_param: failed to create a new user parameter!\n");
234       return NULL;
235     }
236     /* Finally, insert the new parameter into this preset's proper splaytree */
237     if (splay_insert(param, param->name, preset->user_param_tree) < 0) {
238       if (PARAM_DEBUG) printf("PARAM \"%s\" already exists in user parameter tree!\n", param->name);
239       free_param(param);
240       return NULL;
241     }    
242     
243   }       
244   
245   /* Return the found (or created) parameter. Note that if P_CREATE is not set, this could be null */
246   return param;
247   
248 }
249
250 /* Compare string name with parameter name */
251 int compare_param(char * name, char * name2) {
252
253   int cmpval;
254   printf("am i used\n");
255   /* Uses string comparison function */
256   cmpval = strncmp(name, name2, MAX_TOKEN_SIZE-1);
257   
258   return cmpval;
259 }
260
261 /* Loads all builtin parameters, limits are also defined here */
262 int load_all_builtin_param() {
263
264   load_builtin_param_double("fRating", (void*)&fRating, NULL, P_FLAG_NONE, 0.0 , 5.0, 0.0, NULL);
265   load_builtin_param_double("fWaveScale", (void*)&fWaveScale, NULL, P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
266   load_builtin_param_double("gamma", (void*)&fGammaAdj, NULL, P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE, 0, "fGammaAdj");
267   load_builtin_param_double("echo_zoom", (void*)&fVideoEchoZoom, NULL, P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE, 0, "fVideoEchoZoom");
268   load_builtin_param_double("echo_alpha", (void*)&fVideoEchoAlpha, NULL, P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE, 0, "fVideoEchoAlpha");
269   load_builtin_param_double("wave_a", (void*)&fWaveAlpha, NULL, P_FLAG_NONE, 0.0, 1.0, 0, "fWaveAlpha");
270   load_builtin_param_double("fWaveSmoothing", (void*)&fWaveSmoothing, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, NULL);  
271   load_builtin_param_double("fModWaveAlphaStart", (void*)&fModWaveAlphaStart, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, NULL);
272   load_builtin_param_double("fModWaveAlphaEnd", (void*)&fModWaveAlphaEnd, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, NULL);
273   load_builtin_param_double("fWarpAnimSpeed",  (void*)&fWarpAnimSpeed, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, NULL);
274   //  load_builtin_param_double("warp", (void*)&warp, warp_mesh, P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE, 0, NULL);
275         
276   load_builtin_param_double("fShader", (void*)&fShader, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, NULL);
277   load_builtin_param_double("decay", (void*)&decay, NULL, P_FLAG_NONE, 0.0, 1.0, 0, "fDecay");
278
279   load_builtin_param_int("echo_orient", (void*)&nVideoEchoOrientation, P_FLAG_NONE, 0, 3, 0, "nVideoEchoOrientation");
280   load_builtin_param_int("wave_mode", (void*)&nWaveMode, P_FLAG_NONE, 0, 7, 0, "nWaveMode");
281   
282   load_builtin_param_bool("wave_additive", (void*)&bAdditiveWaves, P_FLAG_NONE, FALSE, "bAdditiveWaves");
283   load_builtin_param_bool("bModWaveAlphaByVolume", (void*)&bModWaveAlphaByVolume, P_FLAG_NONE, FALSE, NULL);
284   load_builtin_param_bool("wave_brighten", (void*)&bMaximizeWaveColor, P_FLAG_NONE, FALSE, "bMaximizeWaveColor");
285   load_builtin_param_bool("wrap", (void*)&bTexWrap, P_FLAG_NONE, FALSE, "bTexWrap");
286   load_builtin_param_bool("darken_center", (void*)&bDarkenCenter, P_FLAG_NONE, FALSE, "bDarkenCenter");
287   load_builtin_param_bool("bRedBlueStereo", (void*)&bRedBlueStereo, P_FLAG_NONE, FALSE, NULL);
288   load_builtin_param_bool("brighten", (void*)&bBrighten, P_FLAG_NONE, FALSE, "bBrighten");
289   load_builtin_param_bool("darken", (void*)&bDarken, P_FLAG_NONE, FALSE, "bDarken");
290   load_builtin_param_bool("solarize", (void*)&bSolarize, P_FLAG_NONE, FALSE, "bSolarize");
291   load_builtin_param_bool("invert", (void*)&bInvert, P_FLAG_NONE, FALSE, "bInvert");
292   load_builtin_param_bool("bMotionVectorsOn", (void*)&bMotionVectorsOn, P_FLAG_NONE, FALSE, NULL);
293   load_builtin_param_bool("wave_dots", (void*)&bWaveDots, P_FLAG_NONE, FALSE, "bWaveDots");
294   load_builtin_param_bool("wave_thick", (void*)&bWaveThick, P_FLAG_NONE, FALSE, "bWaveThick");
295  
296   
297   
298   load_builtin_param_double("zoom", (void*)&zoom, zoom_mesh,  P_FLAG_PER_PIXEL |P_FLAG_DONT_FREE_MATRIX, 0.0, MAX_DOUBLE_SIZE, 0, NULL);
299   load_builtin_param_double("rot", (void*)&rot, rot_mesh,  P_FLAG_PER_PIXEL |P_FLAG_DONT_FREE_MATRIX, 0.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, NULL);
300   load_builtin_param_double("zoomexp", (void*)&zoomexp, zoomexp_mesh,  P_FLAG_PER_PIXEL |P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE, 0, "fZoomExponent");
301  
302   load_builtin_param_double("cx", (void*)&cx, cx_mesh, P_FLAG_PER_PIXEL | P_FLAG_DONT_FREE_MATRIX, 0.0, 1.0, 0, NULL);
303   load_builtin_param_double("cy", (void*)&cy, cy_mesh, P_FLAG_PER_PIXEL | P_FLAG_DONT_FREE_MATRIX, 0.0, 1.0, 0, NULL);
304   load_builtin_param_double("dx", (void*)&dx, dx_mesh,  P_FLAG_PER_PIXEL | P_FLAG_DONT_FREE_MATRIX, 0.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, NULL);
305   load_builtin_param_double("dy", (void*)&dy, dy_mesh,  P_FLAG_PER_PIXEL |P_FLAG_DONT_FREE_MATRIX, 0.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, NULL);
306   load_builtin_param_double("sx", (void*)&sx, sx_mesh,  P_FLAG_PER_PIXEL |P_FLAG_DONT_FREE_MATRIX, 0.0, MAX_DOUBLE_SIZE, 0, NULL);
307   load_builtin_param_double("sy", (void*)&sy, sy_mesh,  P_FLAG_PER_PIXEL |P_FLAG_DONT_FREE_MATRIX, 0.0, MAX_DOUBLE_SIZE, 0, NULL);
308
309   load_builtin_param_double("wave_r", (void*)&wave_r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
310   load_builtin_param_double("wave_g", (void*)&wave_g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
311   load_builtin_param_double("wave_b", (void*)&wave_b, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
312   load_builtin_param_double("wave_x", (void*)&wave_x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
313   load_builtin_param_double("wave_y", (void*)&wave_y, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
314   load_builtin_param_double("wave_mystery", (void*)&wave_mystery, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, "fWaveParam");
315   
316   load_builtin_param_double("ob_size", (void*)&ob_size, NULL, P_FLAG_NONE, 0.0, 0.5, 0, NULL);
317   load_builtin_param_double("ob_r", (void*)&ob_r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
318   load_builtin_param_double("ob_g", (void*)&ob_g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
319   load_builtin_param_double("ob_b", (void*)&ob_b, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
320   load_builtin_param_double("ob_a", (void*)&ob_a, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
321
322   load_builtin_param_double("ib_size", (void*)&ib_size,  NULL,P_FLAG_NONE, 0.0, .5, 0.0, NULL);
323   load_builtin_param_double("ib_r", (void*)&ib_r,  NULL,P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
324   load_builtin_param_double("ib_g", (void*)&ib_g,  NULL,P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
325   load_builtin_param_double("ib_b", (void*)&ib_b,  NULL,P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
326   load_builtin_param_double("ib_a", (void*)&ib_a,  NULL,P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
327
328   load_builtin_param_double("mv_r", (void*)&mv_r,  NULL,P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
329   load_builtin_param_double("mv_g", (void*)&mv_g,  NULL,P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
330   load_builtin_param_double("mv_b", (void*)&mv_b,  NULL,P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
331   load_builtin_param_double("mv_x", (void*)&mv_x,  NULL,P_FLAG_NONE, 0.0, 64.0, 0.0, "nMotionVectorsX");
332   load_builtin_param_double("mv_y", (void*)&mv_y,  NULL,P_FLAG_NONE, 0.0, 48.0, 0.0, "nMotionVectorsY");
333   load_builtin_param_double("mv_l", (void*)&mv_l,  NULL,P_FLAG_NONE, 0.0, 5.0, 0.0, NULL);
334   load_builtin_param_double("mv_dy", (void*)&mv_dy, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, NULL);
335   load_builtin_param_double("mv_dx", (void*)&mv_dx,  NULL,P_FLAG_NONE, 0.0, 1.0, -1.0, NULL);
336   load_builtin_param_double("mv_a", (void*)&mv_a,  NULL,P_FLAG_NONE, 0.0, 1.0, 0.0, NULL);
337
338   load_builtin_param_double("time", (void*)&Time,  NULL,P_FLAG_READONLY, 0.0, MAX_DOUBLE_SIZE, 0.0, NULL);        
339   load_builtin_param_double("bass", (void*)&bass,  NULL,P_FLAG_READONLY, 0.0, MAX_DOUBLE_SIZE, 0.0, NULL);
340   load_builtin_param_double("mid", (void*)&mid,  NULL,P_FLAG_READONLY, 0.0, MAX_DOUBLE_SIZE, 0, NULL);      
341   load_builtin_param_double("bass_att", (void*)&bass_att,  NULL,P_FLAG_READONLY, 0.0, MAX_DOUBLE_SIZE, 0, NULL);
342   load_builtin_param_double("mid_att", (void*)&mid_att,  NULL,P_FLAG_READONLY, 0.0, MAX_DOUBLE_SIZE, 0, NULL);
343   load_builtin_param_double("treb_att", (void*)&treb_att,  NULL,P_FLAG_READONLY, 0.0, MAX_DOUBLE_SIZE, 0, NULL);
344   load_builtin_param_int("frame", (void*)&frame, P_FLAG_READONLY, 0, MAX_INT_SIZE, 0, NULL);
345   load_builtin_param_double("progress", (void*)&progress,  NULL,P_FLAG_READONLY, 0.0, 1, 0, NULL);
346   load_builtin_param_int("fps", (void*)&fps, P_FLAG_NONE, 15, MAX_INT_SIZE, 0, NULL);
347
348
349
350   load_builtin_param_double("x", (void*)&x_per_pixel, x_mesh,  P_FLAG_PER_PIXEL |P_FLAG_ALWAYS_MATRIX | P_FLAG_READONLY | P_FLAG_DONT_FREE_MATRIX, 
351                             0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
352   load_builtin_param_double("y", (void*)&y_per_pixel, y_mesh,  P_FLAG_PER_PIXEL |P_FLAG_ALWAYS_MATRIX |P_FLAG_READONLY | P_FLAG_DONT_FREE_MATRIX, 
353                             0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
354   load_builtin_param_double("ang", (void*)&ang_per_pixel, theta_mesh,  P_FLAG_PER_PIXEL |P_FLAG_ALWAYS_MATRIX | P_FLAG_READONLY | P_FLAG_DONT_FREE_MATRIX, 
355                             0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);      
356   load_builtin_param_double("rad", (void*)&rad_per_pixel, rad_mesh,  P_FLAG_PER_PIXEL |P_FLAG_ALWAYS_MATRIX | P_FLAG_READONLY | P_FLAG_DONT_FREE_MATRIX, 
357                             0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
358
359
360   load_builtin_param_double("q1", (void*)&q1,  NULL, P_FLAG_PER_PIXEL |P_FLAG_QVAR, 0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
361   load_builtin_param_double("q2", (void*)&q2,  NULL, P_FLAG_PER_PIXEL |P_FLAG_QVAR, 0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
362   load_builtin_param_double("q3", (void*)&q3,  NULL, P_FLAG_PER_PIXEL |P_FLAG_QVAR, 0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
363   load_builtin_param_double("q4", (void*)&q4,  NULL, P_FLAG_PER_PIXEL |P_FLAG_QVAR, 0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
364   load_builtin_param_double("q5", (void*)&q5,  NULL, P_FLAG_PER_PIXEL |P_FLAG_QVAR, 0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
365   load_builtin_param_double("q6", (void*)&q6,  NULL, P_FLAG_PER_PIXEL |P_FLAG_QVAR, 0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
366   load_builtin_param_double("q7", (void*)&q7,  NULL, P_FLAG_PER_PIXEL |P_FLAG_QVAR, 0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
367   load_builtin_param_double("q8", (void*)&q8,  NULL, P_FLAG_PER_PIXEL |P_FLAG_QVAR, 0, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, NULL);
368
369
370
371   /* variables added in 1.04 */
372   load_builtin_param_int("meshx", (void*)&gx, P_FLAG_READONLY, 32, 96, 8, NULL);
373   load_builtin_param_int("meshy", (void*)&gy, P_FLAG_READONLY, 24, 72, 6, NULL);
374
375   return SUCCESS;  
376   
377 }
378
379 /* Free's a parameter type */
380 void free_param(param_t * param) {
381   int x;
382   if (param == NULL)
383         return;
384   
385   if (param->flags & P_FLAG_USERDEF) {
386     free(param->engine_val);
387
388   }
389
390   if (!(param->flags & P_FLAG_DONT_FREE_MATRIX)) {
391
392     if (param->flags & P_FLAG_PER_POINT)
393       free(param->matrix);
394
395     else if (param->flags & P_FLAG_PER_PIXEL) {
396        for(x = 0; x < gx; x++) 
397            free(((double**)param->matrix)[x]);
398        free(param->matrix);
399       }
400   }
401
402   if (PARAM_DEBUG) printf("free_param: freeing \"%s\".\n", param->name);
403   free(param);
404
405 }
406
407 /* Loads a double parameter into the builtin database */
408 int load_builtin_param_double(char * name, void * engine_val, void * matrix, short int flags, 
409                                                 double init_val, double upper_bound, double lower_bound, char * alt_name) {
410
411   param_t * param = NULL;
412   value_t iv, ub, lb;
413
414   iv.double_val = init_val;
415   ub.double_val = upper_bound;
416   lb.double_val = lower_bound;
417                                                         
418   /* Create new parameter of type double */
419   if (PARAM_DEBUG == 2) {
420           printf("load_builtin_param_double: (name \"%s\") (alt_name = \"%s\") ", name, alt_name);
421           fflush(stdout);
422   }  
423   
424  if ((param = create_param(name, P_TYPE_DOUBLE, flags, engine_val, matrix, iv, ub, lb)) == NULL) {
425     return OUTOFMEM_ERROR;
426   }
427   
428   if (PARAM_DEBUG == 2) {
429         printf("created...");
430         fflush(stdout);
431    }      
432    
433   /* Insert the paremeter into the database */
434
435   if (insert_builtin_param(param) < 0) {
436         free_param(param);
437     return ERROR;
438   }
439
440   if (PARAM_DEBUG == 2) {
441           printf("inserted...");
442           fflush(stdout);
443   }  
444   
445   /* If this parameter has an alternate name, insert it into the database as link */
446   
447   if (alt_name != NULL) {
448         insert_param_alt_name(param, alt_name); 
449
450   if (PARAM_DEBUG == 2) {
451           printf("alt_name inserted...");
452           fflush(stdout);
453         }
454   
455         
456   }       
457
458   if (PARAM_DEBUG == 2) printf("finished\n");     
459   /* Finished, return success */
460   return SUCCESS;
461 }
462
463
464
465 /* Loads a double parameter into the builtin database */
466 param_t * new_param_double(char * name, short int flags, void * engine_val, void * matrix,
467                                                 double upper_bound, double lower_bound, double init_val) {
468
469   param_t * param;
470   value_t iv, ub, lb;
471
472   iv.double_val = init_val;
473   ub.double_val = upper_bound;
474   lb.double_val = lower_bound;
475                                                 
476   if ((param = create_param(name, P_TYPE_DOUBLE, flags, engine_val, matrix,iv, ub, lb)) == NULL) 
477     return NULL;
478   
479   
480   /* Finished, return success */
481   return param;
482 }
483
484
485 /* Creates a new parameter of type int */
486 param_t * new_param_int(char * name, short int flags, void * engine_val,
487                                                 int upper_bound, int lower_bound, int init_val) {
488
489   param_t * param;
490   value_t iv, ub, lb;
491
492   iv.int_val = init_val;
493   ub.int_val = upper_bound;
494   lb.int_val = lower_bound;
495                                                         
496   if ((param = create_param(name, P_TYPE_INT, flags, engine_val, NULL, iv, ub, lb)) == NULL) 
497     return NULL;
498   
499  
500   /* Finished, return success */
501   return param;
502 }
503
504 /* Creates a new parameter of type bool */
505 param_t * new_param_bool(char * name, short int flags, void * engine_val,
506                                                 int upper_bound, int lower_bound, int init_val) {
507
508   param_t * param;
509   value_t iv, ub, lb;
510
511   iv.bool_val = init_val;
512   ub.bool_val = upper_bound;
513   lb.bool_val = lower_bound;
514                                                         
515   if ((param = create_param(name, P_TYPE_BOOL, flags, engine_val, NULL, iv, ub, lb)) == NULL)
516     return NULL;
517   
518  
519   /* Finished, return success */
520   return param;
521 }
522
523
524 /* Loads a integer parameter into the builtin database */
525 int load_builtin_param_int(char * name, void * engine_val, short int flags,
526                                                 int init_val, int upper_bound, int lower_bound, char * alt_name) {
527
528   param_t * param;
529   value_t iv, ub, lb;
530
531   iv.int_val = init_val;
532   ub.int_val = upper_bound;
533   lb.int_val = lower_bound;     
534                                                         
535   param = create_param(name, P_TYPE_INT, flags, engine_val, NULL, iv, ub, lb);
536
537   if (param == NULL) {
538     return OUTOFMEM_ERROR;
539   }
540
541   if (insert_builtin_param(param) < 0) {
542         free_param(param);
543     return ERROR;
544   }
545   
546   if (alt_name != NULL) {
547         insert_param_alt_name(param, alt_name);          
548   }  
549   
550   return SUCCESS;
551
552 }                                                       
553                                                         
554 /* Loads a boolean parameter */
555 int load_builtin_param_bool(char * name, void * engine_val, short int flags, 
556                                                                 int init_val, char * alt_name) {
557
558   param_t * param;
559   value_t iv, ub, lb;
560
561   iv.int_val = init_val;
562   ub.int_val = TRUE;
563   lb.int_val = FALSE;   
564                                                                                                                                 
565   param = create_param(name, P_TYPE_BOOL, flags, engine_val, NULL, iv, ub, lb);
566
567   if (param == NULL) {
568     return OUTOFMEM_ERROR;
569   }
570
571   if (insert_builtin_param(param) < 0) {
572         free_param(param);
573     return ERROR;
574   }
575   
576   if (alt_name != NULL) {
577         insert_param_alt_name(param, alt_name);          
578   }  
579   
580   return SUCCESS;
581
582 }
583
584
585         
586
587 /* Returns nonzero if the string is valid parameter name */
588 int is_valid_param_string(char * string) {
589   
590   if (string == NULL)
591     return FALSE;
592   
593   /* This ensures the first character is non numeric */
594   if( ((*string) >= 48) && ((*string) <= 57))
595     return FALSE; 
596
597   /* These probably should never happen */
598   if (*string == '.')
599         return FALSE;
600   
601   if (*string == '+')
602         return FALSE;
603   
604   if (*string == '-')
605         return FALSE;
606   
607   /* Could also add checks for other symbols. May do later */
608   
609   return TRUE;
610    
611 }
612
613 /* Inserts a parameter into the builtin database */
614 int insert_builtin_param(param_t * param) {
615
616         if (param == NULL)
617                 return FAILURE;
618         
619         return splay_insert(param, param->name, builtin_param_tree);    
620 }
621
622 /* Inserts a parameter into the builtin database */
623 int insert_param(param_t * param, splaytree_t * database) {
624
625         if (param == NULL)
626           return FAILURE;
627         if (database == NULL)
628           return FAILURE;
629
630         return splay_insert(param, param->name, database);      
631 }
632
633
634 /* Sets the parameter engine value to value val.
635         clipping occurs if necessary */
636 void set_param(param_t * param, double val) {
637
638         switch (param->type) {
639                 
640         case P_TYPE_BOOL:
641                 if (val < 0)
642                         *((int*)param->engine_val) = 0;
643                 else if (val > 0)
644                         *((int*)param->engine_val) = 1;
645                 else
646                         *((int*)param->engine_val) = 0;
647                 break;
648         case P_TYPE_INT:
649                 /* Make sure value is an integer */
650                 val = floor(val);
651                 if (val < param->lower_bound.int_val)
652                                 *((int*)param->engine_val) = param->lower_bound.int_val;
653                 else if (val > param->upper_bound.int_val)
654                                 *((int*)param->engine_val) = param->upper_bound.int_val;
655                 else
656                                 *((int*)param->engine_val) = val;
657                 break;
658         case P_TYPE_DOUBLE:
659           /* Make sure value is an integer */   
660
661          
662           if (val < param->lower_bound.double_val) 
663             *((double*)param->engine_val) = param->lower_bound.double_val;        
664           else if (val > param->upper_bound.double_val)
665             *((double*)param->engine_val) = param->upper_bound.double_val;
666           else
667             *((double*)param->engine_val) = val;
668           break;
669         default:
670           break;
671
672         }
673         
674         return;
675 }
676
677
678
679
680 /* Search for parameter 'name' in 'database', if create_flag is true, then generate the parameter 
681    and insert it into 'database' */
682 param_t * find_param_db(char * name, splaytree_t * database, int create_flag) {
683
684   param_t * param = NULL;
685
686   /* Null argument checks */
687   if (name == NULL)
688     return NULL;
689   if (database == NULL)
690     return NULL;
691   
692   /* First look in the builtin database */
693   param = (param_t *)splay_find(name, database);
694
695   
696   if (((param = (param_t *)splay_find(name, database)) == NULL) && (create_flag == TRUE)) {
697         
698         /* Check if string is valid */
699         if (!is_valid_param_string(name))
700                 return NULL;
701         
702         /* Now, create the user defined parameter given the passed name */
703         if ((param = create_user_param(name)) == NULL)
704                 return NULL;
705         
706         /* Finally, insert the new parameter into this preset's proper splaytree */
707         if (splay_insert(param, param->name, database) < 0) {
708                 free_param(param);
709                 return NULL;
710         }        
711         
712   }       
713   
714   /* Return the found (or created) parameter. Note that this could be null */
715   return param;
716
717 }
718