]> git.sesse.net Git - vlc/blob - modules/visualization/galaktos/per_pixel_eqn.c
* all: first implementation of a MilkDrop-compatible visualization plugin,
[vlc] / modules / visualization / galaktos / per_pixel_eqn.c
1 /*****************************************************************************
2  * per_pixel_eqn.c:
3  *****************************************************************************
4  * Copyright (C) 2004 VideoLAN
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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30
31 #include "fatal.h"
32 #include "common.h"
33
34 #include "expr_types.h"
35 #include "eval.h"
36
37 #include "splaytree_types.h"
38 #include "splaytree.h"
39
40 #include "param_types.h"
41 #include "param.h"
42
43 #include "per_pixel_eqn.h"
44 #include "per_pixel_eqn_types.h"
45
46 #include "engine_vars.h"
47
48
49 extern preset_t * active_preset;
50
51 extern int mesh_i;
52 extern int mesh_j;
53
54
55
56 /* Evaluates a per pixel equation */
57 inline void evalPerPixelEqn(per_pixel_eqn_t * per_pixel_eqn) {
58
59   double ** param_matrix = NULL;
60   gen_expr_t * eqn_ptr = NULL;
61   int x,y;
62
63   eqn_ptr = per_pixel_eqn->gen_expr; 
64  if (per_pixel_eqn->param->matrix == NULL) {
65     if (PER_PIXEL_EQN_DEBUG) printf("evalPerPixelEqn: [begin initializing matrix] (index = %d) (name = %s)\n", 
66                           per_pixel_eqn->index, per_pixel_eqn->param->name);
67     
68     param_matrix = per_pixel_eqn->param->matrix = (double**)malloc(gx*sizeof(double*));
69     
70     for(x = 0; x < gx; x++)
71       param_matrix[x] = (double *)malloc(gy * sizeof(double));
72
73     for (x = 0; x < gx; x++)
74       for (y = 0; y < gy; y++)
75         param_matrix[x][y] = 0.0;
76
77     if (per_pixel_eqn->param->name == NULL)
78       printf("null parameter?\n");
79
80     //    printf("PARAM MATRIX: \"%s\" initialized.\n", per_pixel_eqn->param->name);
81   }
82   else 
83     param_matrix = (double**)per_pixel_eqn->param->matrix;
84  
85   if (eqn_ptr == NULL)
86     printf("something is seriously wrong...\n");
87   for (mesh_i = 0; mesh_i < gx; mesh_i++) {    
88     for (mesh_j = 0; mesh_j < gy; mesh_j++) {     
89       param_matrix[mesh_i][mesh_j] = eval_gen_expr(eqn_ptr);
90     }
91   }
92   
93   /* Now that this parameter has been referenced with a per
94      pixel equation, we let the evaluator know by setting
95      this flag */
96   per_pixel_eqn->param->matrix_flag = 1; 
97 }
98
99 inline void evalPerPixelEqns() {
100
101   /* Evaluate all per pixel equations using splay traversal */
102   splay_traverse(evalPerPixelEqn, active_preset->per_pixel_eqn_tree);
103
104   /* Set mesh i / j values to -1 so engine vars are used by default again */
105   mesh_i = mesh_j = -1;
106
107 }
108 /* Adds a per pixel equation according to its string name. This
109    will be used only by the parser */
110
111 int add_per_pixel_eqn(char * name, gen_expr_t * gen_expr, preset_t * preset) {
112
113   per_pixel_eqn_t * per_pixel_eqn;
114   int index;
115   param_t * param = NULL;
116
117   /* Argument checks */
118   if (preset == NULL)
119           return FAILURE;
120   if (gen_expr == NULL)
121           return FAILURE;
122   if (name == NULL)
123           return FAILURE;
124   
125  if (PER_PIXEL_EQN_DEBUG) printf("add_per_pixel_eqn: per pixel equation (name = \"%s\")\n", name);
126  
127  if (!strncmp(name, "dx", strlen("dx"))) 
128    preset->per_pixel_flag[DX_OP] = TRUE;
129  else if (!strncmp(name, "dy", strlen("dy"))) 
130    preset->per_pixel_flag[DY_OP] = TRUE;
131  else if (!strncmp(name, "cx", strlen("cx"))) 
132    preset->per_pixel_flag[CX_OP] = TRUE;
133  else if (!strncmp(name, "cy", strlen("cy"))) 
134    preset->per_pixel_flag[CX_OP] = TRUE;
135  else if (!strncmp(name, "zoom", strlen("zoom"))) 
136    preset->per_pixel_flag[ZOOM_OP] = TRUE;
137  else if (!strncmp(name, "zoomexp", strlen("zoomexp"))) 
138    preset->per_pixel_flag[ZOOMEXP_OP] = TRUE;
139  else if (!strncmp(name, "rot", strlen("rot")))
140    preset->per_pixel_flag[ROT_OP] = TRUE;
141  else if (!strncmp(name, "sx", strlen("sx")))
142    preset->per_pixel_flag[SX_OP] = TRUE;
143  else if (!strncmp(name, "sy", strlen("sy")))
144    preset->per_pixel_flag[SY_OP] = TRUE;
145  
146
147  /* Search for the parameter so we know what matrix the per pixel equation is referencing */
148
149  if ((param = find_param(name, preset, TRUE)) == NULL) {
150    if (PER_PIXEL_EQN_DEBUG) printf("add_per_pixel_eqn: failed to allocate a new parameter!\n");
151    return FAILURE;
152  
153  }       
154
155  /* Find most largest index in the splaytree */
156  // if ((per_pixel_eqn = splay_find_max(active_preset->per_pixel_eqn_tree)) == NULL)
157  // index = 0;
158  // else
159  index = splay_size(preset->per_pixel_eqn_tree);
160    
161  /* Create the per pixel equation given the index, parameter, and general expression */
162  if ((per_pixel_eqn = new_per_pixel_eqn(index, param, gen_expr)) == NULL) {
163    if (PER_PIXEL_EQN_DEBUG) printf("add_per_pixel_eqn: failed to create new per pixel equation!\n");
164    return FAILURE;
165
166  }
167
168  if (PER_PIXEL_EQN_DEBUG) printf("add_per_pixel_eqn: new equation (index = %d) (param = \"%s\")\n", 
169                                  per_pixel_eqn->index, per_pixel_eqn->param->name);
170  /* Insert the per pixel equation into the preset per pixel database */
171  if (splay_insert(per_pixel_eqn, &per_pixel_eqn->index, preset->per_pixel_eqn_tree) < 0) {
172    free_per_pixel_eqn(per_pixel_eqn);
173    printf("failed to add per pixel eqn!\n");
174    return FAILURE;       
175  }
176
177  /* Done */ 
178  return SUCCESS;
179 }
180
181 per_pixel_eqn_t * new_per_pixel_eqn(int index, param_t * param, gen_expr_t * gen_expr) {
182
183         per_pixel_eqn_t * per_pixel_eqn;
184         
185         if (index < 0)
186           return NULL;
187         if (param == NULL)
188           return NULL;
189         if (gen_expr == NULL)
190           return NULL;
191         
192         if ((per_pixel_eqn = (per_pixel_eqn_t*)malloc(sizeof(per_pixel_eqn_t))) == NULL)
193           return NULL;
194
195         
196         per_pixel_eqn->index = index;
197         per_pixel_eqn->param = param;
198         per_pixel_eqn->gen_expr = gen_expr;
199         
200         return per_pixel_eqn;   
201 }
202
203
204 void free_per_pixel_eqn(per_pixel_eqn_t * per_pixel_eqn) {
205
206         if (per_pixel_eqn == NULL)
207                 return;
208         
209         free_gen_expr(per_pixel_eqn->gen_expr);
210         
211         free(per_pixel_eqn);
212         
213         return;
214 }
215
216 inline int isPerPixelEqn(int op) {
217     
218   return active_preset->per_pixel_flag[op];
219
220 }
221
222 inline int resetPerPixelEqnFlags(preset_t * preset) {
223   int i;
224
225   for (i = 0; i < NUM_OPS;i++)
226     preset->per_pixel_flag[i] = FALSE;
227
228   return SUCCESS;
229 }