Make mv's use signed chars explicitly.
[xiph/unicode.git] / sushivision / objective.c
blobde226cc53743afc52dbd4f46f80e8078539f3a0d
1 /*
3 * sushivision copyright (C) 2006-2007 Monty <monty@xiph.org>
5 * sushivision is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * sushivision is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with sushivision; see the file COPYING. If not, write to the
17 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include "internal.h"
28 int _sv_objectives=0;
29 sv_obj_t **_sv_objective_list=NULL;
31 static char *objective_axismap[]={
32 "X","Y","Z"
35 #define map_axes ((int)sizeof(objective_axismap)/(int)sizeof(*objective_axismap))
37 int sv_obj_new(char *name,
38 void(*function)(double *,double *),
39 char *input_map,
40 char *output_map){
42 sv_obj_t *o = NULL;
43 int i,j;
44 int number;
45 _sv_token *decl = _sv_tokenize_declparam(name);
46 _sv_tokenlist *in = NULL;
47 _sv_tokenlist *out = NULL;
49 if(!decl){
50 fprintf(stderr,"sushivision: Unable to parse objective declaration \"%s\".\n",name);
51 goto err;
54 if(_sv_objectives == 0){
55 number=0;
56 _sv_objective_list = calloc (number+1,sizeof(*_sv_objective_list));
57 _sv_objectives=1;
58 }else{
59 for(number=0;number<_sv_objectives;number++)
60 if(!_sv_objective_list[number])break;
61 if(number==_sv_objectives){
62 _sv_objectives=number+1;
63 _sv_objective_list = realloc (_sv_objective_list,_sv_objectives * sizeof(*_sv_objective_list));
67 o = _sv_objective_list[number] = calloc(1, sizeof(**_sv_objective_list));
68 o->name = strdup(decl->name);
69 o->legend = strdup(decl->label);
70 o->number = number;
71 o->function = function;
73 /* parse and sanity check the maps */
74 in = _sv_tokenize_noparamlist(input_map);
75 out = _sv_tokenize_noparamlist(output_map);
77 /* input dimensions */
78 if(!in){
79 fprintf(stderr,"sushivision: Unable to parse objective \"%s\" dimenension list \"%s\".\n",
80 o->name,input_map);
81 goto err;
84 o->inputs = in->n;
85 o->input_dims = calloc(in->n,sizeof(*o->input_dims));
86 for(i=0;i<in->n;i++){
87 sv_dim_t *id = sv_dim(in->list[i]->name);
88 if(!id){
89 fprintf(stderr,"sushivision: Dimension \"%s\" does not exist in declaration of objective \"%s\".\n",
90 in->list[i]->name,o->name);
91 goto err;
93 o->input_dims[i] = id;
96 /* output axes */
97 o->outputs = out->n;
98 o->output_axes = malloc(map_axes * sizeof(*o->output_axes));
99 for(i=0;i<map_axes;i++)
100 o->output_axes[i]=-1;
102 for(i=0;i<out->n;i++){
103 char *s = out->list[i]->name;
104 if(!s || !strcasecmp(s,"*")){
105 // output unused by objective
106 // do nothing
107 }else{
108 for(j=0;j<map_axes;j++){
109 if(!strcasecmp(s,objective_axismap[j])){
111 if(o->output_axes[j] != -1){
112 fprintf(stderr,"sushivision: Objective \"%s\" declares multiple %s axis outputs.\n",
113 o->name,objective_axismap[j]);
114 goto err;
116 o->output_axes[j] = i;
119 if(j==map_axes){
120 fprintf(stderr,"sushivision: No such output axis \"%s\" in declaration of objective \"%s\"\n",
121 s,o->name);
126 pthread_setspecific(_sv_obj_key, (void *)o);
128 _sv_token_free(decl);
129 _sv_tokenlist_free(in);
130 _sv_tokenlist_free(out);
132 return 0;
134 err:
135 // XXXXX
137 return -EINVAL;
140 // XXXX need to recompute after
141 // XXXX need to add scale cloning to compute to make this safe in callbacks
142 int sv_obj_set_scale(sv_scale_t *scale){
143 sv_obj_t *o = _sv_obj(0);
145 if(o->scale)
146 sv_scale_free(o->scale); // always a deep copy we own
148 o->scale = (sv_scale_t *)sv_scale_copy(scale);
150 // redraw the slider
152 return 0;
155 // XXXX need to recompute after
156 // XXXX need to add scale cloning to compute to make this safe in callbacks
157 int sv_obj_make_scale(char *format){
158 sv_obj_t *o = _sv_obj(0);
159 sv_scale_t *scale;
160 int ret;
162 char *name=_sv_tokenize_escape(o->name);
163 char *label=_sv_tokenize_escape(o->legend);
164 char *arg=calloc(strlen(name)+strlen(label)+2,sizeof(*arg));
166 strcat(arg,name);
167 strcat(arg,":");
168 strcat(arg,label);
169 free(name);
170 free(label);
172 if(!o){
173 free(arg);
174 return -EINVAL;
176 scale = sv_scale_new(arg,format);
177 free(arg);
178 if(!scale)return errno;
180 o->scale = scale;
181 return ret;
184 sv_obj_t *_sv_obj(char *name){
185 int i;
187 if(name == NULL || name == 0 || !strcmp(name,"")){
188 return (sv_obj_t *)pthread_getspecific(_sv_obj_key);
191 for(i=0;i<_sv_objectives;i++){
192 sv_obj_t *o=_sv_objective_list[i];
193 if(o && o->name && !strcmp(name,o->name)){
194 pthread_setspecific(_sv_obj_key, (void *)o);
195 return o;
198 return NULL;
201 int sv_obj(char *name){
202 sv_obj_t *o = _sv_obj(name);
203 if(o)return 0;
204 return -EINVAL;