configure.ac: Add checks for Flex/Yacc/Bison and other furry animals, for the new...
[platform/upstream/gst-plugins-good.git] / gst / goom / lines.c
1 /*
2  *  lines.c
3  */
4
5 #include "lines.h"
6 #include <math.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include "goom_tools.h"
10 #include "drawmethods.h"
11 #include "goom_plugin_info.h"
12
13 static inline unsigned char
14 lighten (unsigned char value, float power)
15 {
16   int val = value;
17   float t = (float) val * log10 (power) / 2.0;
18
19   if (t > 0) {
20     val = (int) t;              /* (32.0f * log (t)); */
21     if (val > 255)
22       val = 255;
23     if (val < 0)
24       val = 0;
25     return val;
26   } else {
27     return 0;
28   }
29 }
30
31 static void
32 lightencolor (guint32 * col, float power)
33 {
34   unsigned char *color;
35
36   color = (unsigned char *) col;
37   *color = lighten (*color, power);
38   color++;
39   *color = lighten (*color, power);
40   color++;
41   *color = lighten (*color, power);
42   color++;
43   *color = lighten (*color, power);
44 }
45
46
47
48 static void
49 genline (int id, float param, GMUnitPointer * l, int rx, int ry)
50 {
51   int i;
52
53   switch (id) {
54     case GML_HLINE:
55       for (i = 0; i < 512; i++) {
56         l[i].x = ((float) i * rx) / 512.0f;
57         l[i].y = param;
58         l[i].angle = M_PI / 2.0f;
59       }
60       return;
61     case GML_VLINE:
62       for (i = 0; i < 512; i++) {
63         l[i].y = ((float) i * ry) / 512.0f;
64         l[i].x = param;
65         l[i].angle = 0.0f;
66       }
67       return;
68     case GML_CIRCLE:
69       for (i = 0; i < 512; i++) {
70         float cosa, sina;
71
72         l[i].angle = 2.0f * M_PI * (float) i / 512.0f;
73         cosa = param * cos (l[i].angle);
74         sina = param * sin (l[i].angle);
75         l[i].x = ((float) rx / 2.0f) + cosa;
76         l[i].y = (float) ry / 2.0f + sina;
77       }
78       return;
79   }
80 }
81
82 static guint32
83 getcouleur (int mode)
84 {
85   switch (mode) {
86     case GML_RED:
87       return (230 << (ROUGE * 8)) | (120 << (VERT * 8)) | (18 << (BLEU * 8));
88     case GML_ORANGE_J:
89       return (120 << (VERT * 8)) | (252 << (ROUGE * 8)) | (18 << (BLEU * 8));
90     case GML_ORANGE_V:
91       return (160 << (VERT * 8)) | (236 << (ROUGE * 8)) | (40 << (BLEU * 8));
92     case GML_BLEUBLANC:
93       return (40 << (BLEU * 8)) | (220 << (ROUGE * 8)) | (140 << (VERT * 8));
94     case GML_VERT:
95       return (200 << (VERT * 8)) | (80 << (ROUGE * 8)) | (18 << (BLEU * 8));
96     case GML_BLEU:
97       return (250 << (BLEU * 8)) | (30 << (VERT * 8)) | (80 << (ROUGE * 8));
98     case GML_BLACK:
99       return (16 << (BLEU * 8)) | (16 << (VERT * 8)) | (16 << (ROUGE * 8));
100   }
101   return 0;
102 }
103
104 void
105 goom_lines_set_res (GMLine * gml, int rx, int ry)
106 {
107   if (gml != NULL) {
108     gml->screenX = rx;
109     gml->screenY = ry;
110
111     genline (gml->IDdest, gml->param, gml->points2, rx, ry);
112   }
113 }
114
115
116 static void
117 goom_lines_move (GMLine * l)
118 {
119   int i;
120   unsigned char *c1, *c2;
121
122   for (i = 0; i < 512; i++) {
123     l->points[i].x = (l->points2[i].x + 39.0f * l->points[i].x) / 40.0f;
124     l->points[i].y = (l->points2[i].y + 39.0f * l->points[i].y) / 40.0f;
125     l->points[i].angle =
126         (l->points2[i].angle + 39.0f * l->points[i].angle) / 40.0f;
127   }
128
129   c1 = (unsigned char *) &l->color;
130   c2 = (unsigned char *) &l->color2;
131   for (i = 0; i < 4; i++) {
132     int cc1, cc2;
133
134     cc1 = *c1;
135     cc2 = *c2;
136     *c1 = (unsigned char) ((cc1 * 63 + cc2) >> 6);
137     ++c1;
138     ++c2;
139   }
140
141   l->power += l->powinc;
142   if (l->power < 1.1f) {
143     l->power = 1.1f;
144     l->powinc = (float) (goom_irand (l->goomInfo->gRandom, 20) + 10) / 300.0f;
145   }
146   if (l->power > 17.5f) {
147     l->power = 17.5f;
148     l->powinc = -(float) (goom_irand (l->goomInfo->gRandom, 20) + 10) / 300.0f;
149   }
150
151   l->amplitude = (99.0f * l->amplitude + l->amplitudeF) / 100.0f;
152 }
153
154 void
155 goom_lines_switch_to (GMLine * gml, int IDdest,
156     float param, float amplitude, int col)
157 {
158   genline (IDdest, param, gml->points2, gml->screenX, gml->screenY);
159   gml->IDdest = IDdest;
160   gml->param = param;
161   gml->amplitudeF = amplitude;
162   gml->color2 = getcouleur (col);
163 }
164
165 GMLine *
166 goom_lines_init (PluginInfo * goomInfo, int rx, int ry,
167     int IDsrc, float paramS, int coulS, int IDdest, float paramD, int coulD)
168 {
169   GMLine *l = (GMLine *) malloc (sizeof (GMLine));
170
171   l->goomInfo = goomInfo;
172
173   l->points = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer));
174   l->points2 = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer));
175   l->nbPoints = 512;
176
177   l->IDdest = IDdest;
178   l->param = paramD;
179
180   l->amplitude = l->amplitudeF = 1.0f;
181
182   genline (IDsrc, paramS, l->points, rx, ry);
183   genline (IDdest, paramD, l->points2, rx, ry);
184
185   l->color = getcouleur (coulS);
186   l->color2 = getcouleur (coulD);
187
188   l->screenX = rx;
189   l->screenY = ry;
190
191   l->power = 0.0f;
192   l->powinc = 0.01f;
193
194   goom_lines_switch_to (l, IDdest, paramD, 1.0f, coulD);
195
196   return l;
197 }
198
199 void
200 goom_lines_free (GMLine ** l)
201 {
202   free ((*l)->points);
203   free (*l);
204   l = NULL;
205 }
206
207 void
208 goom_lines_draw (PluginInfo * plug, GMLine * line, gint16 data[512], Pixel * p)
209 {
210   if (line != NULL) {
211     int i, x1, y1;
212     guint32 color = line->color;
213     GMUnitPointer *pt = &(line->points[0]);
214
215     float cosa = cos (pt->angle) / 1000.0f;
216     float sina = sin (pt->angle) / 1000.0f;
217
218     lightencolor (&color, line->power);
219
220     x1 = (int) (pt->x + cosa * line->amplitude * data[0]);
221     y1 = (int) (pt->y + sina * line->amplitude * data[0]);
222
223     for (i = 1; i < 512; i++) {
224       int x2, y2;
225       GMUnitPointer *pt = &(line->points[i]);
226
227       float cosa = cos (pt->angle) / 1000.0f;
228       float sina = sin (pt->angle) / 1000.0f;
229
230       x2 = (int) (pt->x + cosa * line->amplitude * data[i]);
231       y2 = (int) (pt->y + sina * line->amplitude * data[i]);
232
233       plug->methods.draw_line (p, x1, y1, x2, y2, color, line->screenX,
234           line->screenY);
235
236       x1 = x2;
237       y1 = y2;
238     }
239     goom_lines_move (line);
240   }
241 }