summaryrefslogtreecommitdiff
path: root/subprojects/gst-plugins-good/gst/goom
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/gst-plugins-good/gst/goom')
-rw-r--r--subprojects/gst-plugins-good/gst/goom/README13
-rw-r--r--subprojects/gst-plugins-good/gst/goom/config_param.c142
-rw-r--r--subprojects/gst-plugins-good/gst/goom/convolve_fx.c368
-rw-r--r--subprojects/gst-plugins-good/gst/goom/drawmethods.c222
-rw-r--r--subprojects/gst-plugins-good/gst/goom/drawmethods.h27
-rw-r--r--subprojects/gst-plugins-good/gst/goom/filters.c861
-rw-r--r--subprojects/gst-plugins-good/gst/goom/filters_mmx.s216
-rw-r--r--subprojects/gst-plugins-good/gst/goom/flying_stars_fx.c361
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom.h42
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_config.h45
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_config_param.h134
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_core.c856
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_filters.h70
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_fx.h30
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_graphic.h92
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_plugin_info.h181
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_tools.c50
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_tools.h53
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_typedefs.h29
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goom_visual_fx.h35
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goomsl_lex.l94
-rw-r--r--subprojects/gst-plugins-good/gst/goom/goomsl_yacc.y1438
-rw-r--r--subprojects/gst-plugins-good/gst/goom/graphic.c28
-rw-r--r--subprojects/gst-plugins-good/gst/goom/gstgoom.c218
-rw-r--r--subprojects/gst-plugins-good/gst/goom/gstgoom.h68
-rw-r--r--subprojects/gst-plugins-good/gst/goom/ifs.c774
-rw-r--r--subprojects/gst-plugins-good/gst/goom/ifs.h54
-rw-r--r--subprojects/gst-plugins-good/gst/goom/lines.c257
-rw-r--r--subprojects/gst-plugins-good/gst/goom/lines.h94
-rw-r--r--subprojects/gst-plugins-good/gst/goom/mathtools.c106
-rw-r--r--subprojects/gst-plugins-good/gst/goom/mathtools.h58
-rw-r--r--subprojects/gst-plugins-good/gst/goom/meson.build31
-rw-r--r--subprojects/gst-plugins-good/gst/goom/mmx.c291
-rw-r--r--subprojects/gst-plugins-good/gst/goom/mmx.h741
-rw-r--r--subprojects/gst-plugins-good/gst/goom/motif_goom1.h1044
-rw-r--r--subprojects/gst-plugins-good/gst/goom/motif_goom2.h1044
-rw-r--r--subprojects/gst-plugins-good/gst/goom/plugin_info.c262
-rw-r--r--subprojects/gst-plugins-good/gst/goom/ppc_drawings.h28
-rw-r--r--subprojects/gst-plugins-good/gst/goom/ppc_drawings.s394
-rw-r--r--subprojects/gst-plugins-good/gst/goom/ppc_zoom_ultimate.h25
-rw-r--r--subprojects/gst-plugins-good/gst/goom/ppc_zoom_ultimate.s336
-rw-r--r--subprojects/gst-plugins-good/gst/goom/sound_tester.c161
-rw-r--r--subprojects/gst-plugins-good/gst/goom/sound_tester.h29
-rw-r--r--subprojects/gst-plugins-good/gst/goom/surf3d.c152
-rw-r--r--subprojects/gst-plugins-good/gst/goom/surf3d.h57
-rw-r--r--subprojects/gst-plugins-good/gst/goom/surf3d.s484
-rw-r--r--subprojects/gst-plugins-good/gst/goom/tentacle3d.c358
-rw-r--r--subprojects/gst-plugins-good/gst/goom/tentacle3d.h26
-rw-r--r--subprojects/gst-plugins-good/gst/goom/v3d.c38
-rw-r--r--subprojects/gst-plugins-good/gst/goom/v3d.h83
-rw-r--r--subprojects/gst-plugins-good/gst/goom/xmmx.c402
-rw-r--r--subprojects/gst-plugins-good/gst/goom/xmmx.h537
52 files changed, 13539 insertions, 0 deletions
diff --git a/subprojects/gst-plugins-good/gst/goom/README b/subprojects/gst-plugins-good/gst/goom/README
new file mode 100644
index 0000000000..08af2baae8
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/README
@@ -0,0 +1,13 @@
+The Goom plugin is based on the Goom visualization code from
+the Goom homepage found at:
+http://ios.free.fr/?page=projet&quoi=1
+
+Like the original library so is the Goom plugin available under the LGPL license
+
+This is based on goom2k4 with changes to plugin_info.c and mmx.h to use Orc for CPU
+detection and GStreamer-specific ifdef's for architecture detection.
+
+These files are not in use right now:
+filters_mmx.s
+goomsl*
+surf3d.s
diff --git a/subprojects/gst-plugins-good/gst/goom/config_param.c b/subprojects/gst-plugins-good/gst/goom/config_param.c
new file mode 100644
index 0000000000..3a1277f62a
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/config_param.c
@@ -0,0 +1,142 @@
+/* Goom Project
+ * Copyright (C) <2003> Jean-Christophe Hoelt <jeko@free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "goom_config_param.h"
+#include <string.h>
+
+static void
+empty_fct (PluginParam * dummy)
+{
+}
+
+void
+goom_secure_param (PluginParam * p)
+{
+ p->changed = empty_fct;
+ p->change_listener = empty_fct;
+ p->user_data = 0;
+ p->name = p->desc = 0;
+ p->rw = 1;
+}
+
+void
+goom_secure_f_param (PluginParam * p, const char *name)
+{
+ secure_param (p);
+
+ p->name = name;
+ p->type = PARAM_FLOATVAL;
+ FVAL (*p) = 0.5f;
+ FMIN (*p) = 0.0f;
+ FMAX (*p) = 1.0f;
+ FSTEP (*p) = 0.01f;
+}
+
+void
+goom_secure_f_feedback (PluginParam * p, const char *name)
+{
+ secure_f_param (p, name);
+
+ p->rw = 0;
+}
+
+void
+goom_secure_s_param (PluginParam * p, const char *name)
+{
+ secure_param (p);
+
+ p->name = name;
+ p->type = PARAM_STRVAL;
+ SVAL (*p) = 0;
+}
+
+void
+goom_secure_b_param (PluginParam * p, const char *name, int value)
+{
+ secure_param (p);
+
+ p->name = name;
+ p->type = PARAM_BOOLVAL;
+ BVAL (*p) = value;
+}
+
+void
+goom_secure_i_param (PluginParam * p, const char *name)
+{
+ secure_param (p);
+
+ p->name = name;
+ p->type = PARAM_INTVAL;
+ IVAL (*p) = 50;
+ IMIN (*p) = 0;
+ IMAX (*p) = 100;
+ ISTEP (*p) = 1;
+}
+
+void
+goom_secure_i_feedback (PluginParam * p, const char *name)
+{
+ secure_i_param (p, name);
+
+ p->rw = 0;
+}
+
+void
+goom_plugin_parameters (PluginParameters * p, const char *name, int nb)
+{
+ p->name = name;
+ p->desc = "";
+ p->nbParams = nb;
+ p->params = malloc (nb * sizeof (PluginParam *));
+}
+
+void
+goom_plugin_parameters_free (PluginParameters * p)
+{
+ free (p->params);
+}
+
+/*---------------------------------------------------------------------------*/
+
+void
+goom_set_str_param_value (PluginParam * p, const char *str)
+{
+ int len = strlen (str);
+
+ if (SVAL (*p))
+ SVAL (*p) = (char *) realloc (SVAL (*p), len + 1);
+ else
+ SVAL (*p) = (char *) malloc (len + 1);
+ memcpy (SVAL (*p), str, len + 1);
+}
+
+void
+goom_set_list_param_value (PluginParam * p, const char *str)
+{
+ int len = strlen (str);
+
+#ifdef VERBOSE
+ printf ("%s: %d\n", str, len);
+#endif
+ if (LVAL (*p))
+ LVAL (*p) = (char *) realloc (LVAL (*p), len + 1);
+ else
+ LVAL (*p) = (char *) malloc (len + 1);
+ memcpy (LVAL (*p), str, len + 1);
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/convolve_fx.c b/subprojects/gst-plugins-good/gst/goom/convolve_fx.c
new file mode 100644
index 0000000000..980e113a5b
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/convolve_fx.c
@@ -0,0 +1,368 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "goom_fx.h"
+#include "goom_plugin_info.h"
+#include "goom_config.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+//#define CONV_MOTIF_W 32
+//#define CONV_MOTIF_WMASK 0x1f
+
+/* Define if you like the wacky GOOM logo: */
+#undef DRAW_MOTIF
+
+#define CONV_MOTIF_W 128
+#define CONV_MOTIF_WMASK 0x7f
+
+typedef char Motif[CONV_MOTIF_W][CONV_MOTIF_W];
+
+#include "motif_goom1.h"
+#include "motif_goom2.h"
+
+#define NB_THETA 512
+
+typedef struct _CONV_DATA
+{
+ PluginParam light;
+ PluginParam factor_adj_p;
+ PluginParam factor_p;
+ PluginParameters params;
+
+ /* rotozoom */
+ int theta;
+ float ftheta;
+ int h_sin[NB_THETA];
+ int h_cos[NB_THETA];
+ int h_height;
+ float visibility;
+ Motif conv_motif;
+ int inverse_motif;
+
+} ConvData;
+
+/* init rotozoom tables */
+static void
+compute_tables (VisualFX * _this, PluginInfo * info)
+{
+ ConvData *data = (ConvData *) _this->fx_data;
+ double screen_coef;
+ int i;
+ double h;
+ double radian;
+
+ if (data->h_height == info->screen.height)
+ return;
+
+ screen_coef = 2.0 * 300.0 / (double) info->screen.height;
+ data->h_height = info->screen.height;
+
+ for (i = 0; i < NB_THETA; i++) {
+ radian = 2 * i * G_PI / NB_THETA;
+ h = (0.2 + cos (radian) / 15.0 * sin (radian * 2.0 + 12.123)) * screen_coef;
+ data->h_cos[i] = 0x10000 * (-h * cos (radian) * cos (radian));
+ data->h_sin[i] = 0x10000 * (h * sin (radian + 1.57) * sin (radian));
+ }
+}
+
+static void
+set_motif (ConvData * data, Motif motif)
+{
+ int i, j;
+
+ for (i = 0; i < CONV_MOTIF_W; ++i)
+ for (j = 0; j < CONV_MOTIF_W; ++j)
+ data->conv_motif[i][j] =
+ motif[CONV_MOTIF_W - i - 1][CONV_MOTIF_W - j - 1];
+}
+
+static void
+convolve_init (VisualFX * _this, PluginInfo * info)
+{
+ ConvData *data;
+
+ data = (ConvData *) malloc (sizeof (ConvData));
+ _this->fx_data = (void *) data;
+
+ secure_f_param (&data->light, "Screen Brightness");
+ data->light.param.fval.max = 300.0f;
+ data->light.param.fval.step = 1.0f;
+ data->light.param.fval.value = 100.0f;
+
+ secure_f_param (&data->factor_adj_p, "Flash Intensity");
+ data->factor_adj_p.param.fval.max = 200.0f;
+ data->factor_adj_p.param.fval.step = 1.0f;
+ data->factor_adj_p.param.fval.value = 70.0f;
+
+ secure_f_feedback (&data->factor_p, "Factor");
+
+ plugin_parameters (&data->params, "Bright Flash", 5);
+ data->params.params[0] = &data->light;
+ data->params.params[1] = &data->factor_adj_p;
+ data->params.params[2] = 0;
+ data->params.params[3] = &data->factor_p;
+ data->params.params[4] = 0;
+
+ data->h_height = 0;
+
+ /* init rotozoom tables */
+ compute_tables (_this, info);
+ data->theta = 0;
+ data->ftheta = 0.0;
+ data->visibility = 1.0;
+ set_motif (data, CONV_MOTIF2);
+ data->inverse_motif = 0;
+
+ _this->params = &data->params;
+}
+
+static void
+convolve_free (VisualFX * _this)
+{
+ ConvData *data = (ConvData *) _this->fx_data;
+
+ goom_plugin_parameters_free (&data->params);
+
+ free (_this->fx_data);
+}
+
+#ifdef DRAW_MOTIF
+static void
+create_output_with_brightness (VisualFX * _this, Pixel * src, Pixel * dest,
+ PluginInfo * info, int iff)
+{
+ ConvData *data = (ConvData *) _this->fx_data;
+
+ int x, y;
+ int i = 0; //info->screen.height * info->screen.width - 1;
+
+ const int c = data->h_cos[data->theta];
+ const int s = data->h_sin[data->theta];
+
+ const int xi = -(info->screen.width / 2) * c;
+ const int yi = (info->screen.width / 2) * s;
+
+ const int xj = -(info->screen.height / 2) * s;
+ const int yj = -(info->screen.height / 2) * c;
+
+ int xprime = xj;
+ int yprime = yj;
+
+ int ifftab[16];
+
+ if (data->inverse_motif) {
+ int i;
+
+ for (i = 0; i < 16; ++i)
+ ifftab[i] = (double) iff *(1.0 + data->visibility * (15.0 - i) / 15.0);
+ } else {
+ int i;
+
+ for (i = 0; i < 16; ++i)
+ ifftab[i] = (double) iff / (1.0 + data->visibility * (15.0 - i) / 15.0);
+ }
+
+ for (y = info->screen.height; y--;) {
+ int xtex, ytex;
+
+ xtex = xprime + xi + CONV_MOTIF_W * 0x10000 / 2;
+ xprime += s;
+
+ ytex = yprime + yi + CONV_MOTIF_W * 0x10000 / 2;
+ yprime += c;
+
+#ifdef HAVE_MMX
+ __asm__ __volatile__ ("\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */
+ "\n\t movd %[xtex], %%mm2" "\n\t movd %[ytex], %%mm3" "\n\t punpckldq %%mm3, %%mm2" /* mm2 = [ ytex | xtex ] */
+ "\n\t movd %[c], %%mm4" "\n\t movd %[s], %%mm6" "\n\t pxor %%mm5, %%mm5" "\n\t psubd %%mm6, %%mm5" "\n\t punpckldq %%mm5, %%mm4" /* mm4 = [ -s | c ] */
+ "\n\t movd %[motif], %%mm6" /* mm6 = motif */
+ ::[xtex] "g" (xtex),[ytex] "g" (ytex)
+ ,[c] "g" (c),[s] "g" (s)
+ ,[motif] "g" (&data->conv_motif[0][0]));
+
+ for (x = info->screen.width; x--;) {
+ __asm__ __volatile__ ("\n\t movd %[src], %%mm0" /* mm0 = src */
+ "\n\t paddd %%mm4, %%mm2" /* [ ytex | xtex ] += [ -s | s ] */
+ "\n\t movd %%esi, %%mm5" /* save esi into mm5 */
+ "\n\t movq %%mm2, %%mm3" "\n\t psrld $16, %%mm3" /* mm3 = [ (ytex>>16) | (xtex>>16) ] */
+ "\n\t movd %%mm3, %%eax" /* eax = xtex' */
+ "\n\t psrlq $25, %%mm3" "\n\t movd %%mm3, %%ecx" /* ecx = ytex' << 7 */
+ "\n\t andl $127, %%eax" "\n\t andl $16256, %%ecx" "\n\t addl %%ecx, %%eax" "\n\t movd %%mm6, %%esi" /* esi = motif */
+ "\n\t xorl %%ecx, %%ecx" "\n\t movb (%%eax,%%esi), %%cl" "\n\t movl %[ifftab], %%eax" "\n\t movd %%mm5, %%esi" /* restore esi from mm5 */
+ "\n\t movd (%%eax,%%ecx,4), %%mm1" /* mm1 = [0|0|0|iff2] */
+ "\n\t punpcklwd %%mm1, %%mm1"
+ "\n\t punpcklbw %%mm7, %%mm0"
+ "\n\t punpckldq %%mm1, %%mm1"
+ "\n\t psrlw $1, %%mm0"
+ "\n\t psrlw $2, %%mm1"
+ "\n\t pmullw %%mm1, %%mm0"
+ "\n\t psrlw $5, %%mm0"
+ "\n\t packuswb %%mm7, %%mm0"
+ "\n\t movd %%mm0, %[dest]":[dest] "=g" (dest[i].val)
+ :[src] "g" (src[i].val)
+ ,[ifftab] "g" (&ifftab[0])
+ :"eax", "ecx");
+
+ i++;
+ }
+#else
+ for (x = info->screen.width; x--;) {
+
+ int iff2;
+ unsigned int f0, f1, f2, f3;
+
+ xtex += c;
+ ytex -= s;
+
+ iff2 =
+ ifftab[(int) data->conv_motif[(ytex >> 16) & CONV_MOTIF_WMASK][(xtex
+ >> 16) & CONV_MOTIF_WMASK]];
+
+#define sat(a) ((a)>0xFF?0xFF:(a))
+ f0 = src[i].val;
+ f1 = ((f0 >> R_OFFSET) & 0xFF) * iff2 >> 8;
+ f2 = ((f0 >> G_OFFSET) & 0xFF) * iff2 >> 8;
+ f3 = ((f0 >> B_OFFSET) & 0xFF) * iff2 >> 8;
+ dest[i].val =
+ (sat (f1) << R_OFFSET) | (sat (f2) << G_OFFSET) | (sat (f3) <<
+ B_OFFSET);
+/*
+ f0 = (src[i].cop[0] * iff2) >> 8;
+ f1 = (src[i].cop[1] * iff2) >> 8;
+ f2 = (src[i].cop[2] * iff2) >> 8;
+ f3 = (src[i].cop[3] * iff2) >> 8;
+
+ dest[i].cop[0] = (f0 & 0xffffff00) ? 0xff : (unsigned char)f0;
+ dest[i].cop[1] = (f1 & 0xffffff00) ? 0xff : (unsigned char)f1;
+ dest[i].cop[2] = (f2 & 0xffffff00) ? 0xff : (unsigned char)f2;
+ dest[i].cop[3] = (f3 & 0xffffff00) ? 0xff : (unsigned char)f3;
+*/
+ i++;
+ }
+#endif
+ }
+#ifdef HAVE_MMX
+ __asm__ __volatile__ ("\n\t emms");
+#endif
+
+ compute_tables (_this, info);
+}
+#endif
+
+/*#include <stdint.h>
+
+static uint64_t GetTick()
+{
+ uint64_t x;
+ asm volatile ("RDTSC" : "=A" (x));
+ return x;
+}*/
+
+
+static void
+convolve_apply (VisualFX * _this, Pixel * src, Pixel * dest, PluginInfo * info)
+{
+
+ ConvData *data = (ConvData *) _this->fx_data;
+#ifdef DRAW_MOTIF
+ float ff;
+ int iff;
+
+ ff = (FVAL (data->factor_p) * FVAL (data->factor_adj_p) +
+ FVAL (data->light)) / 100.0f;
+ iff = (unsigned int) (ff * 256);
+#endif
+
+ {
+ double fcycle = (double) info->cycle;
+ double rotate_param, rotate_coef;
+ float INCREASE_RATE = 1.5;
+ float DECAY_RATE = 0.955;
+
+ if (FVAL (info->sound.last_goom_p) > 0.8)
+ FVAL (data->factor_p) += FVAL (info->sound.goom_power_p) * INCREASE_RATE;
+ FVAL (data->factor_p) *= DECAY_RATE;
+
+ rotate_param = FVAL (info->sound.last_goom_p);
+ if (rotate_param < 0.0)
+ rotate_param = 0.0;
+ rotate_param += FVAL (info->sound.goom_power_p);
+
+ rotate_coef = 4.0 + FVAL (info->sound.goom_power_p) * 6.0;
+ data->ftheta = (data->ftheta + rotate_coef * sin (rotate_param * 6.3));
+ data->theta = ((unsigned int) data->ftheta) % NB_THETA;
+ data->visibility =
+ (cos (fcycle * 0.001 + 1.5) * sin (fcycle * 0.008) +
+ cos (fcycle * 0.011 + 5.0) - 0.8 + info->sound.speedvar) * 1.5;
+ if (data->visibility < 0.0)
+ data->visibility = 0.0;
+ data->factor_p.change_listener (&data->factor_p);
+ }
+
+ if (data->visibility < 0.01) {
+ switch (goom_irand (info->gRandom, 300)) {
+ case 1:
+ set_motif (data, CONV_MOTIF1);
+ data->inverse_motif = 1;
+ break;
+ case 2:
+ set_motif (data, CONV_MOTIF2);
+ data->inverse_motif = 0;
+ break;
+ }
+ }
+#ifdef DRAW_MOTIF
+ if ((ff > 0.98f) && (ff < 1.02f))
+ memcpy (dest, src, info->screen.size * sizeof (Pixel));
+ else
+ create_output_with_brightness (_this, src, dest, info, iff);
+#else
+ memcpy (dest, src, info->screen.size * sizeof (Pixel));
+#endif
+
+/*
+// Benching suite...
+ {
+ uint64_t before, after;
+ double timed;
+ static double stimed = 10000.0;
+ before = GetTick();
+ data->visibility = 1.0;
+ create_output_with_brightness(_this,src,dest,info,iff);
+ after = GetTick();
+ timed = (double)((after-before) / info->screen.size);
+ if (timed < stimed) {
+ stimed = timed;
+ printf ("CLK = %3.0f CPP\n", stimed);
+ }
+ }
+*/
+}
+
+void
+convolve_create (VisualFX * vfx)
+{
+ vfx->init = convolve_init;
+ vfx->free = convolve_free;
+ vfx->apply = convolve_apply;
+ vfx->fx_data = NULL;
+ vfx->params = NULL;
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/drawmethods.c b/subprojects/gst-plugins-good/gst/goom/drawmethods.c
new file mode 100644
index 0000000000..97f0cf1396
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/drawmethods.c
@@ -0,0 +1,222 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "drawmethods.h"
+
+#define DRAWMETHOD_PLUS(_out,_backbuf,_col) \
+{\
+ int tra=0,i=0;\
+ unsigned char *bra = (unsigned char*)&(_backbuf);\
+ unsigned char *dra = (unsigned char*)&(_out);\
+ unsigned char *cra = (unsigned char*)&(_col);\
+ for (;i<4;i++) {\
+ tra = *cra;\
+ tra += *bra;\
+ if (tra>255) tra=255;\
+ *dra = tra;\
+ ++dra;++cra;++bra;\
+ }\
+}
+
+#define DRAWMETHOD DRAWMETHOD_PLUS(*p,*p,col)
+
+void
+draw_line (Pixel * data, int x1, int y1, int x2, int y2, int col, int screenx,
+ int screeny)
+{
+ int x, y, dx, dy, yy, xx;
+ Pixel *p;
+
+ if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny)
+ || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx))
+ return;
+
+ /* clip to top edge
+ if ((y1 < 0) && (y2 < 0))
+ return;
+
+ if (y1 < 0) {
+ x1 += (y1 * (x1 - x2)) / (y2 - y1);
+ y1 = 0;
+ }
+ if (y2 < 0) {
+ x2 += (y2 * (x1 - x2)) / (y2 - y1);
+ y2 = 0;
+ }
+
+ clip to bottom edge
+ if ((y1 >= screeny) && (y2 >= screeny))
+ return;
+ if (y1 >= screeny) {
+ x1 -= ((screeny - y1) * (x1 - x2)) / (y2 - y1);
+ y1 = screeny - 1;
+ }
+ if (y2 >= screeny) {
+ x2 -= ((screeny - y2) * (x1 - x2)) / (y2 - y1);
+ y2 = screeny - 1;
+ }
+ clip to left edge
+ if ((x1 < 0) && (x2 < 0))
+ return;
+ if (x1 < 0) {
+ y1 += (x1 * (y1 - y2)) / (x2 - x1);
+ x1 = 0;
+ }
+ if (x2 < 0) {
+ y2 += (x2 * (y1 - y2)) / (x2 - x1);
+ x2 = 0;
+ }
+ clip to right edge
+ if ((x1 >= screenx) && (x2 >= screenx))
+ return;
+ if (x1 >= screenx) {
+ y1 -= ((screenx - x1) * (y1 - y2)) / (x2 - x1);
+ x1 = screenx - 1;
+ }
+ if (x2 >= screenx) {
+ y2 -= ((screenx - x2) * (y1 - y2)) / (x2 - x1);
+ x2 = screenx - 1;
+ }
+ */
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (x1 > x2) {
+ int tmp;
+
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ dx = x2 - x1;
+ dy = y2 - y1;
+ }
+
+ /* vertical line */
+ if (dx == 0) {
+ if (y1 < y2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (y = y1; y <= y2; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ } else {
+ p = &(data[(screenx * y2) + x1]);
+ for (y = y2; y <= y1; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ }
+ return;
+ }
+ /* horizontal line */
+ if (dy == 0) {
+ if (x1 < x2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (x = x1; x <= x2; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ return;
+ } else {
+ p = &(data[(screenx * y1) + x2]);
+ for (x = x2; x <= x1; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ return;
+ }
+ }
+ /* 1 */
+ /* \ */
+ /* \ */
+ /* 2 */
+ if (y2 > y1) {
+ /* steep */
+ if (dy > dx) {
+ dx = ((dx << 16) / dy);
+ x = x1 << 16;
+ for (y = y1; y <= y2; y++) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p++;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ return;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ }
+ }
+ /* 2 */
+ /* / */
+ /* / */
+ /* 1 */
+ else {
+ /* steep */
+ if (-dy > dx) {
+ dx = ((dx << 16) / -dy);
+ x = (x1 + 1) << 16;
+ for (y = y1; y >= y2; y--) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p--;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ return;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ return;
+ }
+ }
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/drawmethods.h b/subprojects/gst-plugins-good/gst/goom/drawmethods.h
new file mode 100644
index 0000000000..3f86274241
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/drawmethods.h
@@ -0,0 +1,27 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _DRAWMETHODS_H
+#define _DRAWMETHODS_H
+
+#include "goom_config.h"
+#include "goom_graphic.h"
+
+void draw_line (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny);
+
+#endif /* _DRAWMETHODS_H */
diff --git a/subprojects/gst-plugins-good/gst/goom/filters.c b/subprojects/gst-plugins-good/gst/goom/filters.c
new file mode 100644
index 0000000000..fc930747f7
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/filters.c
@@ -0,0 +1,861 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+// --- CHUI EN TRAIN DE SUPPRIMER LES EXTERN RESOLX ET C_RESOLY ---
+
+/* filter.c version 0.7
+* contient les filtres applicable a un buffer
+* creation : 01/10/2000
+* -ajout de sinFilter()
+* -ajout de zoomFilter()
+* -copie de zoomFilter() en zoomFilterRGB(), gerant les 3 couleurs
+* -optimisation de sinFilter (utilisant une table de sin)
+* -asm
+* -optimisation de la procedure de generation du buffer de transformation
+* la vitesse est maintenant comprise dans [0..128] au lieu de [0..100]
+*/
+
+/* #define _DEBUG_PIXEL */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#include "goom_filters.h"
+#include "goom_graphic.h"
+#include "goom_tools.h"
+#include "goom_plugin_info.h"
+#include "goom_fx.h"
+#include "v3d.h"
+
+/* TODO : MOVE THIS AWAY !!! */
+/* jeko: j'ai essayer de le virer, mais si on veut les laisser inline c'est un peu lourdo... */
+static inline void
+setPixelRGB (PluginInfo * goomInfo, Pixel * buffer, Uint x, Uint y, Color c)
+{
+ Pixel i;
+
+ i.channels.b = c.b;
+ i.channels.g = c.v;
+ i.channels.r = c.r;
+ *(buffer + (x + y * goomInfo->screen.width)) = i;
+}
+
+static inline void
+setPixelRGB_ (Pixel * buffer, Uint x, Color c)
+{
+ buffer[x].channels.r = c.r;
+ buffer[x].channels.g = c.v;
+ buffer[x].channels.b = c.b;
+}
+
+static inline void
+getPixelRGB_ (Pixel * buffer, Uint x, Color * c)
+{
+ Pixel i = *(buffer + x);
+
+ c->b = i.channels.b;
+ c->v = i.channels.g;
+ c->r = i.channels.r;
+}
+
+/* END TODO */
+
+
+/* DEPRECATED */
+// retourne x>>s , en testant le signe de x
+//#define ShiftRight(_x,_s) (((_x)<0) ? -(-(_x)>>(_s)) : ((_x)>>(_s)))
+//#define EFFECT_DISTORS 4
+//#define EFFECT_DISTORS_SL 2
+//#define INTERLACE_ADD 9
+//#define INTERLACE_AND 0xf
+/* END DEPRECATED */
+
+#define BUFFPOINTNB 16
+#define BUFFPOINTNBF 16.0f
+#define BUFFPOINTMASK 0xffff
+
+#define sqrtperte 16
+/* faire : a % sqrtperte <=> a & pertemask */
+#define PERTEMASK 0xf
+/* faire : a / sqrtperte <=> a >> PERTEDEC */
+#define PERTEDEC 4
+
+/* pure c version of the zoom filter */
+static void c_zoom (Pixel * expix1, Pixel * expix2, unsigned int prevX,
+ unsigned int prevY, signed int *brutS, signed int *brutD, int buffratio,
+ int precalCoef[BUFFPOINTNB][BUFFPOINTNB]);
+
+/* simple wrapper to give it the same proto than the others */
+void
+zoom_filter_c (int sizeX, int sizeY, Pixel * src, Pixel * dest, int *brutS,
+ int *brutD, int buffratio, int precalCoef[16][16])
+{
+ c_zoom (src, dest, sizeX, sizeY, brutS, brutD, buffratio, precalCoef);
+}
+
+static void generatePrecalCoef (int precalCoef[BUFFPOINTNB][BUFFPOINTNB]);
+
+
+typedef struct _ZOOM_FILTER_FX_WRAPPER_DATA
+{
+
+ PluginParam enabled_bp;
+ PluginParameters params;
+
+ unsigned int *coeffs, *freecoeffs;
+
+ signed int *brutS, *freebrutS; /* source */
+ signed int *brutD, *freebrutD; /* dest */
+ signed int *brutT, *freebrutT; /* temp (en cours de generation) */
+
+ guint32 zoom_width;
+
+ unsigned int prevX, prevY;
+
+ float general_speed;
+ int reverse; /* reverse the speed */
+ char theMode;
+ int waveEffect;
+ int hypercosEffect;
+ int vPlaneEffect;
+ int hPlaneEffect;
+ char noisify;
+ int middleX, middleY;
+
+ int mustInitBuffers;
+ int interlace_start;
+
+ /* modif by jeko : fixedpoint : buffration = (16:16) (donc 0<=buffration<=2^16) */
+ int buffratio;
+ int *firedec;
+
+ /* modif d'optim by Jeko : precalcul des 4 coefs resultant des 2 pos */
+ int precalCoef[BUFFPOINTNB][BUFFPOINTNB];
+
+ /* calculatePXandPY statics */
+ int wave;
+ int wavesp;
+
+} ZoomFilterFXWrapperData;
+
+
+
+
+static inline void
+zoomVector (v2g * vecteur, ZoomFilterFXWrapperData * data, float X, float Y)
+{
+ float vx, vy;
+ float sq_dist = X * X + Y * Y;
+
+ /* sx = (X < 0.0f) ? -1.0f : 1.0f;
+ sy = (Y < 0.0f) ? -1.0f : 1.0f;
+ */
+ float coefVitesse = (1.0f + data->general_speed) / 50.0f;
+
+ // Effects
+
+ /* Centralized FX */
+
+ switch (data->theMode) {
+ case CRYSTAL_BALL_MODE:
+ coefVitesse -= (sq_dist - 0.3f) / 15.0f;
+ break;
+ case AMULETTE_MODE:
+ coefVitesse += sq_dist * 3.5f;
+ break;
+ case WAVE_MODE:
+ coefVitesse += sin (sq_dist * 20.0f) / 100.0f;
+ break;
+ case SCRUNCH_MODE:
+ coefVitesse += sq_dist / 10.0f;
+ break;
+ //case HYPERCOS1_MODE:
+ break;
+ //case HYPERCOS2_MODE:
+ break;
+ //case YONLY_MODE:
+ break;
+ case SPEEDWAY_MODE:
+ coefVitesse *= 4.0f * Y;
+ break;
+ default:
+ break;
+ }
+
+ if (coefVitesse < -2.01f)
+ coefVitesse = -2.01f;
+ if (coefVitesse > 2.01f)
+ coefVitesse = 2.01f;
+
+ vx = coefVitesse * X;
+ vy = coefVitesse * Y;
+
+ /* Amulette 2 */
+ // vx = X * tan(dist);
+ // vy = Y * tan(dist);
+
+ /* Rotate */
+ //vx = (X+Y)*0.1;
+ //vy = (Y-X)*0.1;
+
+
+ // Effects adds-on
+
+ /* Noise */
+ if (data->noisify) {
+ vx += (((float) rand ()) / ((float) RAND_MAX) - 0.5f) / 50.0f;
+ vy += (((float) rand ()) / ((float) RAND_MAX) - 0.5f) / 50.0f;
+ }
+
+ /* Hypercos */
+ if (data->hypercosEffect) {
+ vx += sin (Y * 10.0f) / 120.0f;
+ vy += sin (X * 10.0f) / 120.0f;
+ }
+
+ /* H Plane */
+ if (data->hPlaneEffect)
+ vx += Y * 0.0025f * data->hPlaneEffect;
+
+ /* V Plane */
+ if (data->vPlaneEffect)
+ vy += X * 0.0025f * data->vPlaneEffect;
+
+ /* TODO : Water Mode */
+ // if (data->waveEffect)
+
+ vecteur->x = vx;
+ vecteur->y = vy;
+}
+
+
+/*
+ * Makes a stripe of a transform buffer (brutT)
+ *
+ * The transform is (in order) :
+ * Translation (-data->middleX, -data->middleY)
+ * Homothetie (Center : 0,0 Coeff : 2/data->prevX)
+ */
+static void
+makeZoomBufferStripe (ZoomFilterFXWrapperData * data, int INTERLACE_INCR)
+{
+ // Position of the pixel to compute in pixmap coordinates
+ Uint x, y;
+
+ // Where (verticaly) to stop generating the buffer stripe
+ int maxEnd;
+
+ // Ratio from pixmap to normalized coordinates
+ float ratio = 2.0f / ((float) data->prevX);
+
+ // Ratio from normalized to virtual pixmap coordinates
+ float inv_ratio = BUFFPOINTNBF / ratio;
+ float min = ratio / BUFFPOINTNBF;
+
+ // Y position of the pixel to compute in normalized coordinates
+ float Y = ((float) (data->interlace_start - data->middleY)) * ratio;
+
+ maxEnd = data->prevY;
+ if (maxEnd > (data->interlace_start + INTERLACE_INCR))
+ maxEnd = (data->interlace_start + INTERLACE_INCR);
+
+ for (y = data->interlace_start;
+ (y < data->prevY) && ((signed int) y < maxEnd); y++) {
+ Uint premul_y_prevX = y * data->prevX * 2;
+ float X = -((float) data->middleX) * ratio;
+
+ for (x = 0; x < data->prevX; x++) {
+ v2g vector;
+
+ zoomVector (&vector, data, X, Y);
+
+ /* Finish and avoid null displacement */
+ if (fabs (vector.x) < min)
+ vector.x = (vector.x < 0.0f) ? -min : min;
+ if (fabs (vector.y) < min)
+ vector.y = (vector.y < 0.0f) ? -min : min;
+
+ data->brutT[premul_y_prevX] =
+ ((int) ((X - vector.x) * inv_ratio) +
+ ((int) (data->middleX * BUFFPOINTNB)));
+ data->brutT[premul_y_prevX + 1] =
+ ((int) ((Y - vector.y) * inv_ratio) +
+ ((int) (data->middleY * BUFFPOINTNB)));
+ premul_y_prevX += 2;
+ X += ratio;
+ }
+ Y += ratio;
+ }
+ data->interlace_start += INTERLACE_INCR;
+ if (y >= data->prevY - 1)
+ data->interlace_start = -1;
+}
+
+
+/*
+ * calculer px et py en fonction de x,y,middleX,middleY et theMode
+ * px et py indique la nouvelle position (en sqrtperte ieme de pixel)
+ * (valeur * 16)
+
+ inline void calculatePXandPY (PluginInfo *goomInfo, ZoomFilterFXWrapperData *data, int x, int y, int *px, int *py)
+ {
+ if (data->theMode == WATER_MODE) {
+ int yy;
+
+ yy = y + goom_irand(goomInfo->gRandom, 4) - goom_irand(goomInfo->gRandom, 4) + data->wave / 10;
+ if (yy < 0)
+ yy = 0;
+ if (yy >= (signed int)goomInfo->screen.height)
+ yy = goomInfo->screen.height - 1;
+
+ *px = (x << 4) + data->firedec[yy] + (data->wave / 10);
+ *py = (y << 4) + 132 - ((data->vitesse < 131) ? data->vitesse : 130);
+
+ data->wavesp += goom_irand(goomInfo->gRandom, 3) - goom_irand(goomInfo->gRandom, 3);
+ if (data->wave < -10)
+ data->wavesp += 2;
+ if (data->wave > 10)
+ data->wavesp -= 2;
+ data->wave += (data->wavesp / 10) + goom_irand(goomInfo->gRandom, 3) - goom_irand(goomInfo->gRandom, 3);
+ if (data->wavesp > 100)
+ data->wavesp = (data->wavesp * 9) / 10;
+ }
+ else {
+ int dist = 0, vx9, vy9;
+ int vx, vy;
+ int ppx, ppy;
+ int fvitesse = data->vitesse << 4;
+
+ if (data->noisify) {
+ x += goom_irand(goomInfo->gRandom, data->noisify) - goom_irand(goomInfo->gRandom, data->noisify);
+ y += goom_irand(goomInfo->gRandom, data->noisify) - goom_irand(goomInfo->gRandom, data->noisify);
+ }
+ vx = (x - data->middleX) << 9;
+ vy = (y - data->middleY) << 9;
+
+ if (data->hPlaneEffect)
+ vx += data->hPlaneEffect * (y - data->middleY);
+
+ if (data->vPlaneEffect)
+ vy += data->vPlaneEffect * (x - data->middleX);
+
+ if (data->waveEffect) {
+ fvitesse *=
+ 1024 +
+ ShiftRight (goomInfo->sintable
+ [(unsigned short) (dist * 0xffff + EFFECT_DISTORS)], 6);
+ fvitesse /= 1024;
+ }
+
+ if (data->hypercosEffect) {
+ vx += ShiftRight (goomInfo->sintable[(-vy + dist) & 0xffff], 1);
+ vy += ShiftRight (goomInfo->sintable[(vx + dist) & 0xffff], 1);
+ }
+
+ vx9 = ShiftRight (vx, 9);
+ vy9 = ShiftRight (vy, 9);
+ dist = vx9 * vx9 + vy9 * vy9;
+
+ switch (data->theMode) {
+ case WAVE_MODE:
+ fvitesse *=
+ 1024 +
+ ShiftRight (goomInfo->sintable
+ [(unsigned short) (dist * 0xffff * EFFECT_DISTORS)], 6);
+ fvitesse>>=10;
+ break;
+ case CRYSTAL_BALL_MODE:
+ fvitesse += (dist >> (10-EFFECT_DISTORS_SL));
+ break;
+ case AMULETTE_MODE:
+ fvitesse -= (dist >> (4 - EFFECT_DISTORS_SL));
+ break;
+ case SCRUNCH_MODE:
+ fvitesse -= (dist >> (10 - EFFECT_DISTORS_SL));
+ break;
+ case HYPERCOS1_MODE:
+ vx = vx + ShiftRight (goomInfo->sintable[(-vy + dist) & 0xffff], 1);
+ vy = vy + ShiftRight (goomInfo->sintable[(vx + dist) & 0xffff], 1);
+ break;
+ case HYPERCOS2_MODE:
+ vx =
+ vx + ShiftRight (goomInfo->sintable[(-ShiftRight (vy, 1) + dist) & 0xffff], 0);
+ vy =
+ vy + ShiftRight (goomInfo->sintable[(ShiftRight (vx, 1) + dist) & 0xffff], 0);
+ fvitesse = 128 << 4;
+ break;
+ case YONLY_MODE:
+ fvitesse *= 1024 + ShiftRight (goomInfo->sintable[vy & 0xffff], 6);
+ fvitesse >>= 10;
+ break;
+ case SPEEDWAY_MODE:
+ fvitesse -= (ShiftRight(vy,10-EFFECT_DISTORS_SL));
+ break;
+ }
+
+ if (fvitesse < -3024)
+ fvitesse = -3024;
+
+ if (vx < 0) // pb avec decalage sur nb negatif
+ ppx = -(-(vx * fvitesse) >> 16);
+ // 16 = 9 + 7 (7 = nb chiffre virgule de vitesse * (v = 128 => immobile)
+ // * * * * * 9 = nb chiffre virgule de vx)
+ else
+ ppx = ((vx * fvitesse) >> 16);
+
+ if (vy < 0)
+ ppy = -(-(vy * fvitesse) >> 16);
+ else
+ ppy = ((vy * fvitesse) >> 16);
+
+ *px = (data->middleX << 4) + ppx;
+ *py = (data->middleY << 4) + ppy;
+ }
+ }
+ */
+
+
+
+static void
+c_zoom (Pixel * expix1, Pixel * expix2, unsigned int prevX, unsigned int prevY,
+ signed int *brutS, signed int *brutD, int buffratio, int precalCoef[16][16])
+{
+ int myPos, myPos2;
+ Color couleur;
+
+ unsigned int ax = (prevX - 1) << PERTEDEC, ay = (prevY - 1) << PERTEDEC;
+
+ int bufsize = prevX * prevY * 2;
+ int bufwidth = prevX;
+
+ expix1[0].val = expix1[prevX - 1].val = expix1[prevX * prevY - 1].val =
+ expix1[prevX * prevY - prevX].val = 0;
+
+ for (myPos = 0; myPos < bufsize; myPos += 2) {
+ Color col1, col2, col3, col4;
+ int c1, c2, c3, c4, px, py;
+ int pos;
+ int coeffs;
+
+ int brutSmypos = brutS[myPos];
+
+ myPos2 = myPos + 1;
+
+ px = brutSmypos + (((brutD[myPos] -
+ brutSmypos) * buffratio) >> BUFFPOINTNB);
+ brutSmypos = brutS[myPos2];
+ py = brutSmypos + (((brutD[myPos2] -
+ brutSmypos) * buffratio) >> BUFFPOINTNB);
+
+ if ((py >= ay) || (px >= ax)) {
+ pos = coeffs = 0;
+ } else {
+ pos = ((px >> PERTEDEC) + prevX * (py >> PERTEDEC));
+ /* coef en modulo 15 */
+ coeffs = precalCoef[px & PERTEMASK][py & PERTEMASK];
+ }
+ getPixelRGB_ (expix1, pos, &col1);
+ getPixelRGB_ (expix1, pos + 1, &col2);
+ getPixelRGB_ (expix1, pos + bufwidth, &col3);
+ getPixelRGB_ (expix1, pos + bufwidth + 1, &col4);
+
+ c1 = coeffs;
+ c2 = (c1 >> 8) & 0xFF;
+ c3 = (c1 >> 16) & 0xFF;
+ c4 = (c1 >> 24) & 0xFF;
+ c1 = c1 & 0xff;
+
+ couleur.r = col1.r * c1 + col2.r * c2 + col3.r * c3 + col4.r * c4;
+ if (couleur.r > 5)
+ couleur.r -= 5;
+ couleur.r >>= 8;
+
+ couleur.v = col1.v * c1 + col2.v * c2 + col3.v * c3 + col4.v * c4;
+ if (couleur.v > 5)
+ couleur.v -= 5;
+ couleur.v >>= 8;
+
+ couleur.b = col1.b * c1 + col2.b * c2 + col3.b * c3 + col4.b * c4;
+ if (couleur.b > 5)
+ couleur.b -= 5;
+ couleur.b >>= 8;
+
+ setPixelRGB_ (expix2, myPos >> 1, couleur);
+ }
+}
+
+/* generate the water fx horizontal direction buffer */
+static void
+generateTheWaterFXHorizontalDirectionBuffer (PluginInfo * goomInfo,
+ ZoomFilterFXWrapperData * data)
+{
+
+ int loopv;
+ int decc = goom_irand (goomInfo->gRandom, 8) - 4;
+ int spdc = goom_irand (goomInfo->gRandom, 8) - 4;
+ int accel = goom_irand (goomInfo->gRandom, 8) - 4;
+
+ for (loopv = data->prevY; loopv != 0;) {
+
+ loopv--;
+ data->firedec[loopv] = decc;
+ decc += spdc / 10;
+ spdc +=
+ goom_irand (goomInfo->gRandom, 3) - goom_irand (goomInfo->gRandom, 3);
+
+ if (decc > 4)
+ spdc -= 1;
+ if (decc < -4)
+ spdc += 1;
+
+ if (spdc > 30)
+ spdc = spdc - goom_irand (goomInfo->gRandom, 3) + accel / 10;
+ if (spdc < -30)
+ spdc = spdc + goom_irand (goomInfo->gRandom, 3) + accel / 10;
+
+ if (decc > 8 && spdc > 1)
+ spdc -= goom_irand (goomInfo->gRandom, 3) - 2;
+
+ if (decc < -8 && spdc < -1)
+ spdc += goom_irand (goomInfo->gRandom, 3) + 2;
+
+ if (decc > 8 || decc < -8)
+ decc = decc * 8 / 9;
+
+ accel +=
+ goom_irand (goomInfo->gRandom, 2) - goom_irand (goomInfo->gRandom, 2);
+ if (accel > 20)
+ accel -= 2;
+ if (accel < -20)
+ accel += 2;
+ }
+}
+
+
+
+/*
+ * Main work for the dynamic displacement map.
+ *
+ * Reads data from pix1, write to pix2.
+ *
+ * Useful datas for this FX are stored in ZoomFilterData.
+ * If you think that this is a strange function name, let me say that a long time ago,
+ * there has been a slow version and a gray-level only one. Then came these function,
+ * fast and workin in RGB colorspace ! nice but it only was applying a zoom to the image.
+ * So that is why you have this name, for the nostalgy of the first days of goom
+ * when it was just a tiny program writen in Turbo Pascal on my i486...
+ */
+void
+zoomFilterFastRGB (PluginInfo * goomInfo, Pixel * pix1, Pixel * pix2,
+ ZoomFilterData * zf, Uint resx, Uint resy, int switchIncr, float switchMult)
+{
+ Uint x, y;
+
+ ZoomFilterFXWrapperData *data =
+ (ZoomFilterFXWrapperData *) goomInfo->zoomFilter_fx.fx_data;
+
+ if (!BVAL (data->enabled_bp))
+ return;
+
+ /* changement de taille */
+ if ((data->prevX != resx) || (data->prevY != resy)) {
+ data->prevX = resx;
+ data->prevY = resy;
+
+ if (data->brutS)
+ free (data->freebrutS);
+ data->brutS = 0;
+ if (data->brutD)
+ free (data->freebrutD);
+ data->brutD = 0;
+ if (data->brutT)
+ free (data->freebrutT);
+ data->brutT = 0;
+
+ data->middleX = resx / 2;
+ data->middleY = resy / 2;
+ data->mustInitBuffers = 1;
+ if (data->firedec)
+ free (data->firedec);
+ data->firedec = 0;
+ }
+
+ if (data->interlace_start != -2)
+ zf = NULL;
+
+ /* changement de config */
+ if (zf) {
+ data->reverse = zf->reverse;
+ data->general_speed = (float) (zf->vitesse - 128) / 128.0f;
+ if (data->reverse)
+ data->general_speed = -data->general_speed;
+ data->middleX = zf->middleX;
+ data->middleY = zf->middleY;
+ data->theMode = zf->mode;
+ data->hPlaneEffect = zf->hPlaneEffect;
+ data->vPlaneEffect = zf->vPlaneEffect;
+ data->waveEffect = zf->waveEffect;
+ data->hypercosEffect = zf->hypercosEffect;
+ data->noisify = zf->noisify;
+ data->interlace_start = 0;
+ }
+
+
+ if (data->mustInitBuffers) {
+
+ data->mustInitBuffers = 0;
+ data->freebrutS =
+ (signed int *) calloc (resx * resy * 2 + 128, sizeof (unsigned int));
+ data->brutS =
+ (gint32 *) ((1 + ((uintptr_t) (data->freebrutS)) / 128) * 128);
+
+ data->freebrutD =
+ (signed int *) calloc (resx * resy * 2 + 128, sizeof (unsigned int));
+ data->brutD =
+ (gint32 *) ((1 + ((uintptr_t) (data->freebrutD)) / 128) * 128);
+
+ data->freebrutT =
+ (signed int *) calloc (resx * resy * 2 + 128, sizeof (unsigned int));
+ data->brutT =
+ (gint32 *) ((1 + ((uintptr_t) (data->freebrutT)) / 128) * 128);
+
+ data->buffratio = 0;
+
+ data->firedec = (int *) malloc (data->prevY * sizeof (int));
+ generateTheWaterFXHorizontalDirectionBuffer (goomInfo, data);
+
+ data->interlace_start = 0;
+ makeZoomBufferStripe (data, resy);
+
+ /* Copy the data from temp to dest and source */
+ memcpy (data->brutS, data->brutT, resx * resy * 2 * sizeof (int));
+ memcpy (data->brutD, data->brutT, resx * resy * 2 * sizeof (int));
+ }
+
+ /* generation du buffer de trans */
+ if (data->interlace_start == -1) {
+
+ /* sauvegarde de l'etat actuel dans la nouvelle source
+ * TODO: write that in MMX (has been done in previous version, but did not follow some new fonctionnalities) */
+ y = data->prevX * data->prevY * 2;
+ for (x = 0; x < y; x += 2) {
+ int brutSmypos = data->brutS[x];
+ int x2 = x + 1;
+
+ data->brutS[x] =
+ brutSmypos + (((data->brutD[x] -
+ brutSmypos) * data->buffratio) >> BUFFPOINTNB);
+ brutSmypos = data->brutS[x2];
+ data->brutS[x2] =
+ brutSmypos + (((data->brutD[x2] -
+ brutSmypos) * data->buffratio) >> BUFFPOINTNB);
+ }
+ data->buffratio = 0;
+ }
+
+ if (data->interlace_start == -1) {
+ signed int *tmp;
+
+ tmp = data->brutD;
+ data->brutD = data->brutT;
+ data->brutT = tmp;
+ tmp = data->freebrutD;
+ data->freebrutD = data->freebrutT;
+ data->freebrutT = tmp;
+ data->interlace_start = -2;
+ }
+
+ if (data->interlace_start >= 0) {
+ /* creation de la nouvelle destination */
+ makeZoomBufferStripe (data, resy / 16);
+ }
+
+ if (switchIncr != 0) {
+ data->buffratio += switchIncr;
+ if (data->buffratio > BUFFPOINTMASK)
+ data->buffratio = BUFFPOINTMASK;
+ }
+
+ if (switchMult != 1.0f) {
+ data->buffratio = (int) ((float) BUFFPOINTMASK * (1.0f - switchMult) +
+ (float) data->buffratio * switchMult);
+ }
+
+ data->zoom_width = data->prevX;
+
+ goomInfo->methods.zoom_filter (data->prevX, data->prevY, pix1, pix2,
+ data->brutS, data->brutD, data->buffratio, data->precalCoef);
+}
+
+static void
+generatePrecalCoef (int precalCoef[16][16])
+{
+ int coefh, coefv;
+
+ for (coefh = 0; coefh < 16; coefh++) {
+ for (coefv = 0; coefv < 16; coefv++) {
+
+ int i;
+ int diffcoeffh;
+ int diffcoeffv;
+
+ diffcoeffh = sqrtperte - coefh;
+ diffcoeffv = sqrtperte - coefv;
+
+ if (!(coefh || coefv)) {
+ i = 255;
+ } else {
+ Uint i1, i2, i3, i4;
+
+ i1 = diffcoeffh * diffcoeffv;
+ i2 = coefh * diffcoeffv;
+ i3 = diffcoeffh * coefv;
+ i4 = coefh * coefv;
+
+ // TODO: faire mieux...
+ if (i1)
+ i1--;
+ if (i2)
+ i2--;
+ if (i3)
+ i3--;
+ if (i4)
+ i4--;
+
+ i = (i1) | (i2 << 8) | (i3 << 16) | (i4 << 24);
+ }
+ precalCoef[coefh][coefv] = i;
+ }
+ }
+}
+
+/* VisualFX Wrapper */
+
+static void
+zoomFilterVisualFXWrapper_init (struct _VISUAL_FX *_this, PluginInfo * info)
+{
+ ZoomFilterFXWrapperData *data =
+ (ZoomFilterFXWrapperData *) malloc (sizeof (ZoomFilterFXWrapperData));
+
+ data->coeffs = 0;
+ data->freecoeffs = 0;
+ data->brutS = 0;
+ data->freebrutS = 0;
+ data->brutD = 0;
+ data->freebrutD = 0;
+ data->brutT = 0;
+ data->freebrutT = 0;
+ data->prevX = 0;
+ data->prevY = 0;
+
+ data->mustInitBuffers = 1;
+ data->interlace_start = -2;
+
+ data->general_speed = 0.0f;
+ data->reverse = 0;
+ data->theMode = AMULETTE_MODE;
+ data->waveEffect = 0;
+ data->hypercosEffect = 0;
+ data->vPlaneEffect = 0;
+ data->hPlaneEffect = 0;
+ data->noisify = 2;
+
+ /* modif by jeko : fixedpoint : buffration = (16:16) (donc 0<=buffration<=2^16) */
+ data->buffratio = 0;
+ data->firedec = 0;
+
+ data->wave = data->wavesp = 0;
+
+ secure_b_param (&data->enabled_bp, "Enabled", 1);
+
+ plugin_parameters (&data->params, "Zoom Filter", 1);
+ data->params.params[0] = &data->enabled_bp;
+
+ _this->params = &data->params;
+ _this->fx_data = (void *) data;
+
+ /* modif d'optim by Jeko : precalcul des 4 coefs resultant des 2 pos */
+ generatePrecalCoef (data->precalCoef);
+}
+
+static void
+zoomFilterVisualFXWrapper_free (struct _VISUAL_FX *_this)
+{
+ ZoomFilterFXWrapperData *data = (ZoomFilterFXWrapperData *) _this->fx_data;
+
+ if (data->freebrutT)
+ free (data->freebrutT);
+ if (data->freebrutS)
+ free (data->freebrutS);
+ if (data->freebrutD)
+ free (data->freebrutD);
+ if (data->firedec)
+ free (data->firedec);
+
+ goom_plugin_parameters_free (_this->params);
+
+ free (_this->fx_data);
+}
+
+static void
+zoomFilterVisualFXWrapper_apply (struct _VISUAL_FX *_this, Pixel * src,
+ Pixel * dest, PluginInfo * info)
+{
+}
+
+void
+zoomFilterVisualFXWrapper_create (VisualFX * fx)
+{
+ fx->init = zoomFilterVisualFXWrapper_init;
+ fx->free = zoomFilterVisualFXWrapper_free;
+ fx->apply = zoomFilterVisualFXWrapper_apply;
+ fx->params = NULL;
+ fx->fx_data = NULL;
+}
+
+
+/* TODO : MOVE THIS AWAY */
+
+void
+pointFilter (PluginInfo * goomInfo, Pixel * pix1, Color c, float t1, float t2,
+ float t3, float t4, Uint cycle)
+{
+ Uint x = (Uint) ((int) (goomInfo->screen.width / 2)
+ + (int) (t1 * cos ((float) cycle / t3)));
+ Uint y = (Uint) ((int) (goomInfo->screen.height / 2)
+ + (int) (t2 * sin ((float) cycle / t4)));
+
+ if ((x > 1) && (y > 1) && (x < goomInfo->screen.width - 2)
+ && (y < goomInfo->screen.height - 2)) {
+ setPixelRGB (goomInfo, pix1, x + 1, y, c);
+ setPixelRGB (goomInfo, pix1, x, y + 1, c);
+ setPixelRGB (goomInfo, pix1, x + 1, y + 1, WHITE);
+ setPixelRGB (goomInfo, pix1, x + 2, y + 1, c);
+ setPixelRGB (goomInfo, pix1, x + 1, y + 2, c);
+ }
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/filters_mmx.s b/subprojects/gst-plugins-good/gst/goom/filters_mmx.s
new file mode 100644
index 0000000000..9320d05ec7
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/filters_mmx.s
@@ -0,0 +1,216 @@
+; Goom Project
+; Copyright (C) <2001> Jean-Christophe Hoelt <jeko@free.fr>
+;
+; This library is free software; you can redistribute it and/or
+; modify it under the terms of the GNU Library General Public
+; License as published by the Free Software Foundation; either
+; version 2 of the License, or (at your option) any later version.
+;
+; This library 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
+; Library General Public License for more details.
+;
+; You should have received a copy of the GNU Library General Public
+; License along with this library; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+; Boston, MA 02110-1301, USA.
+;
+;//
+;// history
+;// 07/01/2001 : Changing FEMMS to EMMS : slower... but run on intel machines
+;// 03/01/2001 : WIDTH and HEIGHT are now variable
+;// 28/12/2000 : adding comments to the code, suppress some useless lines
+;// 27/12/2000 : reducing memory access... improving performance by 20%
+;// coefficients are now on 1 byte
+;// 22/12/2000 : Changing data structure
+;// 16/12/2000 : AT&T version
+;// 14/12/2000 : unrolling loop
+;// 12/12/2000 : 64 bits memory access
+
+
+.data
+
+chaine:
+ .string "pos = %d\n\0"
+ .long 0x0
+
+thezero:
+ .long 0x00000000
+ .long 0x00000000
+
+.text
+
+.globl mmx_zoom ;// name of the function to call by C program
+/* .extern coeffs ;// the transformation buffer */
+.extern expix1,expix2 ;// the source and destination buffer
+.extern mmx_zoom_size, zoom_width ;// size of the buffers
+
+.extern brutS,brutD,buffratio,precalCoef,prevX,prevY
+
+#define PERTEMASK 15
+/* faire : a / sqrtperte <=> a >> PERTEDEC*/
+#define PERTEDEC 4
+
+.align 16
+mmx_zoom:
+
+ pushl %ebp
+ movl %esp,%ebp
+ subl $12,%esp
+
+ movl prevX,%eax
+ decl %eax
+ sarl $4,%eax
+ movl %eax,-4(%ebp)
+
+ movl prevY,%eax
+ decl %eax
+ sarl $4,%eax
+ movl %eax,-8(%ebp)
+
+;// initialisation du mm7 � zero
+ movq (thezero), %mm7
+
+movl mmx_zoom_size, %ecx
+decl %ecx
+
+.while:
+ ;// esi <- nouvelle position
+ movl brutS, %eax
+ leal (%eax, %ecx, 8),%eax
+
+ movl (%eax),%edx /* = brutS.px (brutSmypos) */
+ movl 4(%eax),%eax /* = brutS.py */
+
+ movl brutD,%ebx
+ leal (%ebx, %ecx, 8),%ebx
+ movl (%ebx),%esi
+ subl %edx, %esi
+ imull buffratio,%esi
+ sarl $16,%esi
+ addl %edx,%esi /* esi = px */
+
+ /* eax contient deja brutS.py = le nouveau brutSmypos*/
+ /* ebx pointe sur brutD[myPos] */
+ movl 4(%ebx),%edi
+ subl %eax,%edi
+ imull buffratio,%edi
+ sarl $16,%edi
+ addl %eax,%edi /* edi = py */
+
+/* pushl %eax
+ pushl %ebx*/
+/* popl %ebx
+ popl %eax*/
+
+ movl %esi,%eax
+ andl $15,%eax /* eax = coefh */
+ movl %edi,%ebx
+ andl $15,%ebx /* ebx = coefv */
+
+ leal 0(,%ebx,4),%ebx
+ sall $6,%eax
+ addl %ebx,%eax
+ movl $precalCoef,%ebx
+/* movd (%eax,%ebx),%mm6*/ /* mm6 = coeffs */
+
+ cmpl -8(%ebp),%edi
+ jge .then1
+ cmpl -4(%ebp),%esi
+ jge .then1
+
+ sarl $4,%esi
+ sarl $4,%edi
+ imull zoom_width,%edi
+ leal (%esi,%edi),%esi
+ jmp .finsi1
+
+.then1:
+ movl $0,%esi
+.finsi1:
+
+ /** apres ce calcul, %esi = pos, %mm6 = coeffs **/
+/* pushl %esi
+ pushl $chaine
+ call printf
+ addl $8,%esp*/
+
+ movl expix1,%eax
+
+ ;// recuperation des deux premiers pixels dans mm0 et mm1
+/* movq (%eax,%esi,4), %mm0 /* b1-v1-r1-a1-b2-v2-r2-a2 */
+ movq %mm0, %mm1 /* b1-v1-r1-a1-b2-v2-r2-a2 */
+
+ ;// depackage du premier pixel
+ punpcklbw %mm7, %mm0 /* 00-b2-00-v2-00-r2-00-a2 */
+
+ movq %mm6, %mm5 /* ??-??-??-??-c4-c3-c2-c1 */
+ ;// depackage du 2ieme pixel
+ punpckhbw %mm7, %mm1 /* 00-b1-00-v1-00-r1-00-a1 */
+
+ ;// extraction des coefficients...
+ punpcklbw %mm5, %mm6 /* c4-c4-c3-c3-c2-c2-c1-c1 */
+ movq %mm6, %mm4 /* c4-c4-c3-c3-c2-c2-c1-c1 */
+ movq %mm6, %mm5 /* c4-c4-c3-c3-c2-c2-c1-c1 */
+
+ punpcklbw %mm5, %mm6 /* c2-c2-c2-c2-c1-c1-c1-c1 */
+ punpckhbw %mm5, %mm4 /* c4-c4-c4-c4-c3-c3-c3-c3 */
+
+ movq %mm6, %mm3 /* c2-c2-c2-c2-c1-c1-c1-c1 */
+ punpcklbw %mm7, %mm6 /* 00-c1-00-c1-00-c1-00-c1 */
+ punpckhbw %mm7, %mm3 /* 00-c2-00-c2-00-c2-00-c2 */
+
+ ;// multiplication des pixels par les coefficients
+ pmullw %mm6, %mm0 /* c1*b2-c1*v2-c1*r2-c1*a2 */
+ pmullw %mm3, %mm1 /* c2*b1-c2*v1-c2*r1-c2*a1 */
+ paddw %mm1, %mm0
+
+ ;// ...extraction des 2 derniers coefficients
+ movq %mm4, %mm5 /* c4-c4-c4-c4-c3-c3-c3-c3 */
+ punpcklbw %mm7, %mm4 /* 00-c3-00-c3-00-c3-00-c3 */
+ punpckhbw %mm7, %mm5 /* 00-c4-00-c4-00-c4-00-c4 */
+
+ /* ajouter la longueur de ligne a esi */
+ addl prevX,%esi
+
+ ;// recuperation des 2 derniers pixels
+/* movq (%eax,%esi,4), %mm1*/
+ movq %mm1, %mm2
+
+ ;// depackage des pixels
+ punpcklbw %mm7, %mm1
+ punpckhbw %mm7, %mm2
+
+ ;// multiplication pas les coeffs
+ pmullw %mm4, %mm1
+ pmullw %mm5, %mm2
+
+ ;// ajout des valeurs obtenues � la valeur finale
+ paddw %mm1, %mm0
+ paddw %mm2, %mm0
+
+ ;// division par 256 = 16+16+16+16, puis repackage du pixel final
+ psrlw $8, %mm0
+ packuswb %mm7, %mm0
+
+ ;// passage au suivant
+
+ ;// enregistrement du resultat
+ movl expix2,%eax
+/* movd %mm0,(%eax,%ecx,4)*/
+
+ decl %ecx
+ ;// test de fin du tantque
+ cmpl $0, %ecx ;// 400x300
+
+ jz .fin_while
+ jmp .while
+
+.fin_while:
+ emms
+
+ movl %ebp,%esp
+ popl %ebp
+
+ ret ;//The End
diff --git a/subprojects/gst-plugins-good/gst/goom/flying_stars_fx.c b/subprojects/gst-plugins-good/gst/goom/flying_stars_fx.c
new file mode 100644
index 0000000000..4f97be9c38
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/flying_stars_fx.c
@@ -0,0 +1,361 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "goom_fx.h"
+#include "goom_plugin_info.h"
+#include "goom_tools.h"
+
+#include "mathtools.h"
+
+/* TODO:-- FAIRE PROPREMENT... BOAH... */
+#define NCOL 15
+
+/*static const int colval[] = {
+0xfdf6f5,
+0xfae4e4,
+0xf7d1d1,
+0xf3b6b5,
+0xefa2a2,
+0xec9190,
+0xea8282,
+0xe87575,
+0xe46060,
+0xe14b4c,
+0xde3b3b,
+0xdc2d2f,
+0xd92726,
+0xd81619,
+0xd50c09,
+0
+};
+*/
+static const int colval[] = {
+ 0x1416181a,
+ 0x1419181a,
+ 0x141f181a,
+ 0x1426181a,
+ 0x142a181a,
+ 0x142f181a,
+ 0x1436181a,
+ 0x142f1819,
+ 0x14261615,
+ 0x13201411,
+ 0x111a100a,
+ 0x0c180508,
+ 0x08100304,
+ 0x00050101,
+ 0x0
+};
+
+
+/* The different modes of the visual FX.
+ * Put this values on fx_mode */
+#define FIREWORKS_FX 0
+#define RAIN_FX 1
+#define FOUNTAIN_FX 2
+#define LAST_FX 3
+
+typedef struct _FS_STAR
+{
+ float x, y;
+ float vx, vy;
+ float ax, ay;
+ float age, vage;
+} Star;
+
+typedef struct _FS_DATA
+{
+
+ int fx_mode;
+ int nbStars;
+
+ int maxStars;
+ Star *stars;
+
+ float min_age;
+ float max_age;
+
+ PluginParam min_age_p;
+ PluginParam max_age_p;
+ PluginParam nbStars_p;
+ PluginParam nbStars_limit_p;
+ PluginParam fx_mode_p;
+
+ PluginParameters params;
+} FSData;
+
+static void
+fs_init (VisualFX * _this, PluginInfo * info)
+{
+
+ FSData *data;
+
+ data = (FSData *) malloc (sizeof (FSData));
+
+ data->fx_mode = FIREWORKS_FX;
+ data->maxStars = 4096;
+ data->stars = (Star *) malloc (data->maxStars * sizeof (Star));
+ data->nbStars = 0;
+
+ secure_i_param (&data->max_age_p, "Fireworks Smallest Bombs");
+ IVAL (data->max_age_p) = 80;
+ IMIN (data->max_age_p) = 0;
+ IMAX (data->max_age_p) = 100;
+ ISTEP (data->max_age_p) = 1;
+
+ secure_i_param (&data->min_age_p, "Fireworks Largest Bombs");
+ IVAL (data->min_age_p) = 99;
+ IMIN (data->min_age_p) = 0;
+ IMAX (data->min_age_p) = 100;
+ ISTEP (data->min_age_p) = 1;
+
+ secure_i_param (&data->nbStars_limit_p, "Max Number of Particules");
+ IVAL (data->nbStars_limit_p) = 512;
+ IMIN (data->nbStars_limit_p) = 0;
+ IMAX (data->nbStars_limit_p) = data->maxStars;
+ ISTEP (data->nbStars_limit_p) = 64;
+
+ secure_i_param (&data->fx_mode_p, "FX Mode");
+ IVAL (data->fx_mode_p) = data->fx_mode;
+ IMIN (data->fx_mode_p) = 1;
+ IMAX (data->fx_mode_p) = 3;
+ ISTEP (data->fx_mode_p) = 1;
+
+ secure_f_feedback (&data->nbStars_p, "Number of Particules (% of Max)");
+
+ plugin_parameters (&data->params, "Particule System", 7);
+ data->params.params[0] = &data->fx_mode_p;
+ data->params.params[1] = &data->nbStars_limit_p;
+ data->params.params[2] = 0;
+ data->params.params[3] = &data->min_age_p;
+ data->params.params[4] = &data->max_age_p;
+ data->params.params[5] = 0;
+ data->params.params[6] = &data->nbStars_p;
+
+ _this->params = &data->params;
+ _this->fx_data = (void *) data;
+}
+
+static void
+fs_free (VisualFX * _this)
+{
+ FSData *data = (FSData *) _this->fx_data;
+
+ goom_plugin_parameters_free (&data->params);
+
+ free (data->stars);
+ free (_this->fx_data);
+}
+
+
+/*
+ * Cree une nouvelle 'bombe', c'est a dire une particule appartenant a une fusee d'artifice.
+ */
+static void
+addABomb (FSData * fs, int mx, int my, float radius, float vage, float gravity,
+ PluginInfo * info)
+{
+
+ int i = fs->nbStars;
+ float ro;
+ int theta;
+
+ if (fs->nbStars >= fs->maxStars)
+ return;
+ fs->nbStars++;
+
+ fs->stars[i].x = mx;
+ fs->stars[i].y = my;
+
+ ro = radius * (float) goom_irand (info->gRandom, 100) / 100.0f;
+ ro *= (float) goom_irand (info->gRandom, 100) / 100.0f + 1.0f;
+ theta = goom_irand (info->gRandom, 256);
+
+ fs->stars[i].vx = ro * cos256[theta];
+ fs->stars[i].vy = -0.2f + ro * sin256[theta];
+
+ fs->stars[i].ax = 0;
+ fs->stars[i].ay = gravity;
+
+ fs->stars[i].age = 0;
+ if (vage < fs->min_age)
+ vage = fs->min_age;
+ fs->stars[i].vage = vage;
+}
+
+
+/*
+ * Met a jour la position et vitesse d'une particule.
+ */
+static void
+updateStar (Star * s)
+{
+ s->x += s->vx;
+ s->y += s->vy;
+ s->vx += s->ax;
+ s->vy += s->ay;
+ s->age += s->vage;
+}
+
+
+/*
+ * Ajoute de nouvelles particules au moment d'un evenement sonore.
+ */
+static void
+fs_sound_event_occured (VisualFX * _this, PluginInfo * info)
+{
+
+ FSData *data = (FSData *) _this->fx_data;
+ int i;
+
+ int max = (int) ((1.0f + info->sound.goomPower) * goom_irand (info->gRandom,
+ 150)) + 100;
+ float radius =
+ (1.0f + info->sound.goomPower) * (float) (goom_irand (info->gRandom,
+ 150) + 50) / 300;
+ int mx;
+ int my;
+ float vage, gravity = 0.02f;
+
+ switch (data->fx_mode) {
+ case FIREWORKS_FX:
+ {
+ double dx, dy;
+
+ do {
+ mx = goom_irand (info->gRandom, info->screen.width);
+ my = goom_irand (info->gRandom, info->screen.height);
+ dx = (mx - info->screen.width / 2);
+ dy = (my - info->screen.height / 2);
+ } while (dx * dx + dy * dy <
+ (info->screen.height / 2) * (info->screen.height / 2));
+ vage = data->max_age * (1.0f - info->sound.goomPower);
+ }
+ break;
+ case RAIN_FX:
+ mx = goom_irand (info->gRandom, info->screen.width);
+ if (mx > info->screen.width / 2)
+ mx = info->screen.width;
+ else
+ mx = 0;
+ my = -(info->screen.height / 3) - goom_irand (info->gRandom,
+ info->screen.width / 3);
+ radius *= 1.5;
+ vage = 0.002f;
+ break;
+ case FOUNTAIN_FX:
+ my = info->screen.height + 2;
+ vage = 0.001f;
+ radius += 1.0f;
+ mx = info->screen.width / 2;
+ gravity = 0.04f;
+ break;
+ default:
+ return;
+ /* my = i R A N D (info->screen.height); vage = 0.01f; */
+ }
+
+ radius *= info->screen.height / 200.0f; /* why 200 ? because the FX was developped on 320x200 */
+ max *= info->screen.height / 200.0f;
+
+ if (info->sound.timeSinceLastBigGoom < 1) {
+ radius *= 1.5;
+ max *= 2;
+ }
+ for (i = 0; i < max; ++i)
+ addABomb (data, mx, my, radius, vage, gravity, info);
+}
+
+
+/*
+ * Main methode of the FX.
+ */
+static void
+fs_apply (VisualFX * _this, Pixel * src, Pixel * dest, PluginInfo * info)
+{
+
+ int i;
+ int col;
+ FSData *data = (FSData *) _this->fx_data;
+
+ /* Get the new parameters values */
+ data->min_age = 1.0f - (float) IVAL (data->min_age_p) / 100.0f;
+ data->max_age = 1.0f - (float) IVAL (data->max_age_p) / 100.0f;
+ FVAL (data->nbStars_p) = (float) data->nbStars / (float) data->maxStars;
+ data->nbStars_p.change_listener (&data->nbStars_p);
+ data->maxStars = IVAL (data->nbStars_limit_p);
+ data->fx_mode = IVAL (data->fx_mode_p);
+
+ /* look for events */
+ if (info->sound.timeSinceLastGoom < 1) {
+ fs_sound_event_occured (_this, info);
+ if (goom_irand (info->gRandom, 20) == 1) {
+ IVAL (data->fx_mode_p) = goom_irand (info->gRandom, (LAST_FX * 3));
+ data->fx_mode_p.change_listener (&data->fx_mode_p);
+ }
+ }
+
+ /* update particules */
+ for (i = 0; i < data->nbStars; ++i) {
+ updateStar (&data->stars[i]);
+
+ /* dead particule */
+ if (data->stars[i].age >= NCOL)
+ continue;
+
+ /* choose the color of the particule */
+ col = colval[(int) data->stars[i].age];
+
+ /* draws the particule */
+ info->methods.draw_line (dest, (int) data->stars[i].x,
+ (int) data->stars[i].y,
+ (int) (data->stars[i].x - data->stars[i].vx * 6),
+ (int) (data->stars[i].y - data->stars[i].vy * 6), col,
+ (int) info->screen.width, (int) info->screen.height);
+ info->methods.draw_line (dest, (int) data->stars[i].x,
+ (int) data->stars[i].y,
+ (int) (data->stars[i].x - data->stars[i].vx * 2),
+ (int) (data->stars[i].y - data->stars[i].vy * 2), col,
+ (int) info->screen.width, (int) info->screen.height);
+ }
+
+ /* look for dead particules */
+ for (i = 0; i < data->nbStars;) {
+
+ if ((data->stars[i].x > info->screen.width + 64)
+ || ((data->stars[i].vy >= 0)
+ && (data->stars[i].y - 16 * data->stars[i].vy >
+ info->screen.height))
+ || (data->stars[i].x < -64)
+ || (data->stars[i].age >= NCOL)) {
+ data->stars[i] = data->stars[data->nbStars - 1];
+ data->nbStars--;
+ } else
+ ++i;
+ }
+}
+
+void
+flying_star_create (VisualFX * vfx)
+{
+ vfx->init = fs_init;
+ vfx->free = fs_free;
+ vfx->apply = fs_apply;
+ vfx->fx_data = NULL;
+ vfx->params = NULL;
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/goom.h b/subprojects/gst-plugins-good/gst/goom/goom.h
new file mode 100644
index 0000000000..02a0936e7d
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom.h
@@ -0,0 +1,42 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GOOMCORE_H
+#define _GOOMCORE_H
+
+#include "goom_config.h"
+#include "goom_plugin_info.h"
+
+#define NB_FX 10
+
+PluginInfo *goom_init (guint32 resx, guint32 resy);
+void goom_set_resolution (PluginInfo *goomInfo, guint32 resx, guint32 resy);
+
+/*
+ * forceMode == 0 : do nothing
+ * forceMode == -1 : lock the FX
+ * forceMode == 1..NB_FX : force a switch to FX n# forceMode
+ */
+guint32 *goom_update (PluginInfo *goomInfo, gint16 data[2][512], int forceMode, float fps);
+
+/* returns 0 if the buffer wasn't accepted */
+int goom_set_screenbuffer(PluginInfo *goomInfo, void *buffer);
+
+void goom_close (PluginInfo *goomInfo);
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_config.h b/subprojects/gst-plugins-good/gst/goom/goom_config.h
new file mode 100644
index 0000000000..39b95a0f75
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_config.h
@@ -0,0 +1,45 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include <glib.h>
+
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+#define COLOR_ARGB
+#else
+#define COLOR_BGRA
+#endif
+
+#if 1
+/* ndef COLOR_BGRA */
+/* position des composantes */
+ #define BLEU 0
+ #define VERT 1
+ #define ROUGE 2
+ #define ALPHA 3
+#else
+ #define ROUGE 1
+ #define BLEU 3
+ #define VERT 2
+ #define ALPHA 0
+#endif
+
+#if defined (BUILD_MMX) && defined (HAVE_GCC_ASM)
+
+#define HAVE_MMX
+#endif
+
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_config_param.h b/subprojects/gst-plugins-good/gst/goom/goom_config_param.h
new file mode 100644
index 0000000000..ba08da95c5
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_config_param.h
@@ -0,0 +1,134 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _CONFIG_PARAM_H
+#define _CONFIG_PARAM_H
+
+#include <stdlib.h>
+
+/*
+ * File created on 2003-05-24 by Jeko.
+ * (c)2003, JC Hoelt for iOS-software.
+ *
+ * LGPL Licence.
+ */
+
+typedef enum {
+ PARAM_INTVAL,
+ PARAM_FLOATVAL,
+ PARAM_BOOLVAL,
+ PARAM_STRVAL,
+ PARAM_LISTVAL,
+} ParamType;
+
+struct IntVal {
+ int value;
+ int min;
+ int max;
+ int step;
+};
+struct FloatVal {
+ float value;
+ float min;
+ float max;
+ float step;
+};
+struct StrVal {
+ char *value;
+};
+struct ListVal {
+ char *value;
+ int nbChoices;
+ char **choices;
+};
+struct BoolVal {
+ int value;
+};
+
+
+typedef struct _PARAM {
+ const char *name;
+ const char *desc;
+ char rw;
+ ParamType type;
+ union {
+ struct IntVal ival;
+ struct FloatVal fval;
+ struct StrVal sval;
+ struct ListVal slist;
+ struct BoolVal bval;
+ } param;
+
+ /* used by the core to inform the GUI of a change */
+ void (*change_listener)(struct _PARAM *_this);
+
+ /* used by the GUI to inform the core of a change */
+ void (*changed)(struct _PARAM *_this);
+
+ void *user_data; /* can be used by the GUI */
+} PluginParam;
+
+#define IVAL(p) ((p).param.ival.value)
+#define SVAL(p) ((p).param.sval.value)
+#define FVAL(p) ((p).param.fval.value)
+#define BVAL(p) ((p).param.bval.value)
+#define LVAL(p) ((p).param.slist.value)
+
+#define FMIN(p) ((p).param.fval.min)
+#define FMAX(p) ((p).param.fval.max)
+#define FSTEP(p) ((p).param.fval.step)
+
+#define IMIN(p) ((p).param.ival.min)
+#define IMAX(p) ((p).param.ival.max)
+#define ISTEP(p) ((p).param.ival.step)
+
+void goom_secure_param(PluginParam *p);
+
+void goom_secure_f_param(PluginParam *p, const char *name);
+void goom_secure_i_param(PluginParam *p, const char *name);
+void goom_secure_b_param(PluginParam *p, const char *name, int value);
+void goom_secure_s_param(PluginParam *p, const char *name);
+
+void goom_secure_f_feedback(PluginParam *p, const char *name);
+void goom_secure_i_feedback(PluginParam *p, const char *name);
+
+void goom_set_str_param_value(PluginParam *p, const char *str);
+void goom_set_list_param_value(PluginParam *p, const char *str);
+
+typedef struct _PARAMETERS {
+ const char *name;
+ const char *desc;
+ int nbParams;
+ PluginParam **params;
+} PluginParameters;
+
+void goom_plugin_parameters(PluginParameters *p, const char *name, int nb);
+void goom_plugin_parameters_free(PluginParameters *p);
+
+#define secure_param goom_secure_param
+#define secure_f_param goom_secure_f_param
+#define secure_i_param goom_secure_i_param
+#define secure_b_param goom_secure_b_param
+#define secure_s_param goom_secure_s_param
+#define secure_f_feedback goom_secure_f_feedback
+#define secure_i_feedback goom_secure_i_feedback
+#define set_list_param_value goom_set_list_param_value
+#define set_str_param_value goom_set_str_param_value
+#define plugin_parameters goom_plugin_parameters
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_core.c b/subprojects/gst-plugins-good/gst/goom/goom_core.c
new file mode 100644
index 0000000000..5b1d4f76c8
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_core.c
@@ -0,0 +1,856 @@
+/* Goom Project
+ * Copyright (C) <2003> Jean-Christophe Hoelt <jeko@free.fr>
+ *
+ * goom_core.c:Contains the core of goom's work.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#include "goom.h"
+#include "goom_tools.h"
+#include "goom_filters.h"
+#include "lines.h"
+#include "ifs.h"
+#include "tentacle3d.h"
+
+#include "sound_tester.h"
+#include "goom_plugin_info.h"
+#include "goom_fx.h"
+
+/* #define VERBOSE */
+
+#define STOP_SPEED 128
+/* TODO: put that as variable in PluginInfo */
+#define TIME_BTW_CHG 300
+
+static void choose_a_goom_line (PluginInfo * goomInfo, float *param1,
+ float *param2, int *couleur, int *mode, float *amplitude, int far);
+
+static void
+init_buffers (PluginInfo * goomInfo, int buffsize)
+{
+ goomInfo->pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
+ memset (goomInfo->pixel, 0, buffsize * sizeof (guint32) + 128);
+ goomInfo->back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
+ memset (goomInfo->back, 0, buffsize * sizeof (guint32) + 128);
+ goomInfo->conv = (Pixel *) malloc (buffsize * sizeof (guint32) + 128);
+ memset (goomInfo->conv, 0, buffsize * sizeof (guint32) + 128);
+
+ goomInfo->outputBuf = goomInfo->conv;
+
+ goomInfo->p1 = (Pixel *) ((1 + ((uintptr_t) (goomInfo->pixel)) / 128) * 128);
+ goomInfo->p2 = (Pixel *) ((1 + ((uintptr_t) (goomInfo->back)) / 128) * 128);
+}
+
+/**************************
+* INIT *
+**************************/
+PluginInfo *
+goom_init (guint32 resx, guint32 resy)
+{
+ PluginInfo *goomInfo = (PluginInfo *) malloc (sizeof (PluginInfo));
+
+#ifdef VERBOSE
+ printf ("GOOM: init (%d, %d);\n", resx, resy);
+#endif
+
+ plugin_info_init (goomInfo, 4);
+
+ goomInfo->screen.width = resx;
+ goomInfo->screen.height = resy;
+ goomInfo->screen.size = resx * resy;
+
+ init_buffers (goomInfo, goomInfo->screen.size);
+ goomInfo->gRandom = goom_random_init ((uintptr_t) goomInfo->pixel);
+
+ goomInfo->cycle = 0;
+
+ flying_star_create (&goomInfo->star_fx);
+ goomInfo->star_fx.init (&goomInfo->star_fx, goomInfo);
+
+ zoomFilterVisualFXWrapper_create (&goomInfo->zoomFilter_fx);
+ goomInfo->zoomFilter_fx.init (&goomInfo->zoomFilter_fx, goomInfo);
+
+ tentacle_fx_create (&goomInfo->tentacles_fx);
+ goomInfo->tentacles_fx.init (&goomInfo->tentacles_fx, goomInfo);
+
+ convolve_create (&goomInfo->convolve_fx);
+ goomInfo->convolve_fx.init (&goomInfo->convolve_fx, goomInfo);
+
+ plugin_info_add_visual (goomInfo, 0, &goomInfo->zoomFilter_fx);
+ plugin_info_add_visual (goomInfo, 1, &goomInfo->tentacles_fx);
+ plugin_info_add_visual (goomInfo, 2, &goomInfo->star_fx);
+ plugin_info_add_visual (goomInfo, 3, &goomInfo->convolve_fx);
+
+ ifs_visualfx_create (&goomInfo->ifs_fx);
+ goomInfo->ifs_fx.init (&goomInfo->ifs_fx, goomInfo);
+
+ goomInfo->gmline1 = goom_lines_init (goomInfo, resx, goomInfo->screen.height,
+ GML_HLINE, goomInfo->screen.height, GML_BLACK,
+ GML_CIRCLE, 0.4f * (float) goomInfo->screen.height, GML_VERT);
+ goomInfo->gmline2 = goom_lines_init (goomInfo, resx, goomInfo->screen.height,
+ GML_HLINE, 0, GML_BLACK,
+ GML_CIRCLE, 0.2f * (float) goomInfo->screen.height, GML_RED);
+
+ /* goom_set_main_script(goomInfo, goomInfo->main_script_str); */
+
+ return goomInfo;
+}
+
+
+
+void
+goom_set_resolution (PluginInfo * goomInfo, guint32 resx, guint32 resy)
+{
+ free (goomInfo->pixel);
+ free (goomInfo->back);
+ free (goomInfo->conv);
+
+ goomInfo->screen.width = resx;
+ goomInfo->screen.height = resy;
+ goomInfo->screen.size = resx * resy;
+
+ init_buffers (goomInfo, goomInfo->screen.size);
+
+ /* init_ifs (goomInfo, resx, goomInfo->screen.height); */
+ goomInfo->ifs_fx.free (&goomInfo->ifs_fx);
+ goomInfo->ifs_fx.init (&goomInfo->ifs_fx, goomInfo);
+
+ goom_lines_set_res (goomInfo->gmline1, resx, goomInfo->screen.height);
+ goom_lines_set_res (goomInfo->gmline2, resx, goomInfo->screen.height);
+}
+
+int
+goom_set_screenbuffer (PluginInfo * goomInfo, void *buffer)
+{
+ goomInfo->outputBuf = (Pixel *) buffer;
+ return 1;
+}
+
+/********************************************
+* UPDATE *
+********************************************
+
+* WARNING: this is a 600 lines function ! (21-11-2003)
+*/
+guint32 *
+goom_update (PluginInfo * goomInfo, gint16 data[2][512], int forceMode,
+ float fps)
+{
+ Pixel *return_val;
+ guint32 pointWidth;
+ guint32 pointHeight;
+ int i;
+ float largfactor; /* elargissement de l'intervalle d'�volution des points */
+ Pixel *tmp;
+
+ ZoomFilterData *pzfd;
+
+ /* test if the config has changed, update it if so */
+ pointWidth = (goomInfo->screen.width * 2) / 5;
+ pointHeight = ((goomInfo->screen.height) * 2) / 5;
+
+ /* ! etude du signal ... */
+ evaluate_sound (data, &(goomInfo->sound));
+
+ /* goom_execute_main_script(goomInfo); */
+
+ /* ! calcul du deplacement des petits points ... */
+ largfactor =
+ goomInfo->sound.speedvar / 150.0f + goomInfo->sound.volume / 1.5f;
+
+ if (largfactor > 1.5f)
+ largfactor = 1.5f;
+
+ goomInfo->update.decay_ifs--;
+ if (goomInfo->update.decay_ifs > 0)
+ goomInfo->update.ifs_incr += 2;
+ if (goomInfo->update.decay_ifs == 0)
+ goomInfo->update.ifs_incr = 0;
+
+ if (goomInfo->update.recay_ifs) {
+ goomInfo->update.ifs_incr -= 2;
+ goomInfo->update.recay_ifs--;
+ if ((goomInfo->update.recay_ifs == 0) && (goomInfo->update.ifs_incr <= 0))
+ goomInfo->update.ifs_incr = 1;
+ }
+
+ if (goomInfo->update.ifs_incr > 0)
+ goomInfo->ifs_fx.apply (&goomInfo->ifs_fx, goomInfo->p2, goomInfo->p1,
+ goomInfo);
+
+ if (goomInfo->curGState->drawPoints) {
+ for (i = 1; i * 15 <= goomInfo->sound.speedvar * 80.0f + 15; i++) {
+ goomInfo->update.loopvar += goomInfo->sound.speedvar * 50 + 1;
+
+ pointFilter (goomInfo, goomInfo->p1,
+ YELLOW,
+ ((pointWidth - 6.0f) * largfactor + 5.0f),
+ ((pointHeight - 6.0f) * largfactor + 5.0f),
+ i * 152.0f, 128.0f, goomInfo->update.loopvar + i * 2032);
+ pointFilter (goomInfo, goomInfo->p1, ORANGE,
+ ((pointWidth / 2) * largfactor) / i + 10.0f * i,
+ ((pointHeight / 2) * largfactor) / i + 10.0f * i,
+ 96.0f, i * 80.0f, goomInfo->update.loopvar / i);
+ pointFilter (goomInfo, goomInfo->p1, VIOLET,
+ ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
+ ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
+ i + 122.0f, 134.0f, goomInfo->update.loopvar / i);
+ pointFilter (goomInfo, goomInfo->p1, BLACK,
+ ((pointHeight / 3) * largfactor + 20.0f),
+ ((pointHeight / 3) * largfactor + 20.0f),
+ 58.0f, i * 66.0f, goomInfo->update.loopvar / i);
+ pointFilter (goomInfo, goomInfo->p1, WHITE,
+ (pointHeight * largfactor + 10.0f * i) / i,
+ (pointHeight * largfactor + 10.0f * i) / i,
+ 66.0f, 74.0f, goomInfo->update.loopvar + i * 500);
+ }
+ }
+
+ /* par d�faut pas de changement de zoom */
+ pzfd = NULL;
+
+ /*
+ * Test forceMode
+ */
+#ifdef VERBOSE
+ if (forceMode != 0) {
+ printf ("forcemode = %d\n", forceMode);
+ }
+#endif
+
+
+ /* diminuer de 1 le temps de lockage */
+ /* note pour ceux qui n'ont pas suivis : le lockvar permet d'empecher un */
+ /* changement d'etat du plugin juste apres un autre changement d'etat. oki */
+ if (--goomInfo->update.lockvar < 0)
+ goomInfo->update.lockvar = 0;
+
+ /* on verifie qu'il ne se pas un truc interressant avec le son. */
+ if ((goomInfo->sound.timeSinceLastGoom == 0)
+ || (forceMode > 0)
+ || (goomInfo->update.cyclesSinceLastChange > TIME_BTW_CHG)) {
+
+ /* changement eventuel de mode */
+ if (goom_irand (goomInfo->gRandom, 16) == 0)
+ switch (goom_irand (goomInfo->gRandom, 34)) {
+ case 0:
+ case 10:
+ goomInfo->update.zoomFilterData.hypercosEffect =
+ goom_irand (goomInfo->gRandom, 2);
+ case 13:
+ case 20:
+ case 21:
+ goomInfo->update.zoomFilterData.mode = WAVE_MODE;
+ goomInfo->update.zoomFilterData.reverse = 0;
+ goomInfo->update.zoomFilterData.waveEffect =
+ (goom_irand (goomInfo->gRandom, 3) == 0);
+ if (goom_irand (goomInfo->gRandom, 2))
+ goomInfo->update.zoomFilterData.vitesse =
+ (goomInfo->update.zoomFilterData.vitesse + 127) >> 1;
+ break;
+ case 1:
+ case 11:
+ goomInfo->update.zoomFilterData.mode = CRYSTAL_BALL_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ break;
+ case 2:
+ case 12:
+ goomInfo->update.zoomFilterData.mode = AMULETTE_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ break;
+ case 3:
+ goomInfo->update.zoomFilterData.mode = WATER_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ break;
+ case 4:
+ case 14:
+ goomInfo->update.zoomFilterData.mode = SCRUNCH_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ break;
+ case 5:
+ case 15:
+ case 22:
+ goomInfo->update.zoomFilterData.mode = HYPERCOS1_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect =
+ (goom_irand (goomInfo->gRandom, 3) == 0);
+ break;
+ case 6:
+ case 16:
+ goomInfo->update.zoomFilterData.mode = HYPERCOS2_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ break;
+ case 7:
+ case 17:
+ goomInfo->update.zoomFilterData.mode = CRYSTAL_BALL_MODE;
+ goomInfo->update.zoomFilterData.waveEffect =
+ (goom_irand (goomInfo->gRandom, 4) == 0);
+ goomInfo->update.zoomFilterData.hypercosEffect =
+ goom_irand (goomInfo->gRandom, 2);
+ break;
+ case 8:
+ case 18:
+ case 19:
+ goomInfo->update.zoomFilterData.mode = SCRUNCH_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 1;
+ goomInfo->update.zoomFilterData.hypercosEffect = 1;
+ break;
+ case 29:
+ case 30:
+ goomInfo->update.zoomFilterData.mode = YONLY_MODE;
+ break;
+ case 31:
+ case 32:
+ case 33:
+ goomInfo->update.zoomFilterData.mode = SPEEDWAY_MODE;
+ break;
+ default:
+ goomInfo->update.zoomFilterData.mode = NORMAL_MODE;
+ goomInfo->update.zoomFilterData.waveEffect = 0;
+ goomInfo->update.zoomFilterData.hypercosEffect = 0;
+ }
+ }
+
+ /* tout ceci ne sera fait qu'en cas de non-blocage */
+ if (goomInfo->update.lockvar == 0) {
+ /* reperage de goom (acceleration forte de l'acceleration du volume) */
+ /* -> coup de boost de la vitesse si besoin.. */
+ if (goomInfo->sound.timeSinceLastGoom == 0) {
+
+ int i;
+
+ goomInfo->update.goomvar++;
+
+ /* SELECTION OF THE GOOM STATE */
+ if ((!goomInfo->update.stateSelectionBlocker)
+ && (goom_irand (goomInfo->gRandom, 3))) {
+ goomInfo->update.stateSelectionRnd =
+ goom_irand (goomInfo->gRandom, goomInfo->statesRangeMax);
+ goomInfo->update.stateSelectionBlocker = 3;
+ } else if (goomInfo->update.stateSelectionBlocker)
+ goomInfo->update.stateSelectionBlocker--;
+
+ for (i = 0; i < goomInfo->statesNumber; i++)
+ if ((goomInfo->update.stateSelectionRnd >= goomInfo->states[i].rangemin)
+ && (goomInfo->update.stateSelectionRnd <=
+ goomInfo->states[i].rangemax))
+ goomInfo->curGState = &(goomInfo->states[i]);
+
+ if ((goomInfo->curGState->drawIFS) && (goomInfo->update.ifs_incr <= 0)) {
+ goomInfo->update.recay_ifs = 5;
+ goomInfo->update.ifs_incr = 11;
+ }
+
+ if ((!goomInfo->curGState->drawIFS) && (goomInfo->update.ifs_incr > 0)
+ && (goomInfo->update.decay_ifs <= 0))
+ goomInfo->update.decay_ifs = 100;
+
+ if (!goomInfo->curGState->drawScope)
+ goomInfo->update.stop_lines = 0xf000 & 5;
+
+ if (!goomInfo->curGState->drawScope) {
+ goomInfo->update.stop_lines = 0;
+ goomInfo->update.lineMode = goomInfo->update.drawLinesDuration;
+ }
+
+ /* if (goomInfo->update.goomvar % 1 == 0) */
+ {
+ guint32 vtmp;
+ guint32 newvit;
+
+ goomInfo->update.lockvar = 50;
+ newvit =
+ STOP_SPEED + 1 -
+ ((float) 3.5f * log10 (goomInfo->sound.speedvar * 60 + 1));
+ /* retablir le zoom avant.. */
+ if ((goomInfo->update.zoomFilterData.reverse)
+ && (!(goomInfo->cycle % 13)) && (rand () % 5 == 0)) {
+ goomInfo->update.zoomFilterData.reverse = 0;
+ goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 2;
+ goomInfo->update.lockvar = 75;
+ }
+ if (goom_irand (goomInfo->gRandom, 10) == 0) {
+ goomInfo->update.zoomFilterData.reverse = 1;
+ goomInfo->update.lockvar = 100;
+ }
+
+ if (goom_irand (goomInfo->gRandom, 10) == 0)
+ goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 1;
+ if (goom_irand (goomInfo->gRandom, 12) == 0)
+ goomInfo->update.zoomFilterData.vitesse = STOP_SPEED + 1;
+
+ /* changement de milieu.. */
+ switch (goom_irand (goomInfo->gRandom, 25)) {
+ case 0:
+ case 3:
+ case 6:
+ goomInfo->update.zoomFilterData.middleY =
+ goomInfo->screen.height - 1;
+ goomInfo->update.zoomFilterData.middleX =
+ goomInfo->screen.width / 2;
+ break;
+ case 1:
+ case 4:
+ goomInfo->update.zoomFilterData.middleX =
+ goomInfo->screen.width - 1;
+ break;
+ case 2:
+ case 5:
+ goomInfo->update.zoomFilterData.middleX = 1;
+ break;
+ default:
+ goomInfo->update.zoomFilterData.middleY =
+ goomInfo->screen.height / 2;
+ goomInfo->update.zoomFilterData.middleX =
+ goomInfo->screen.width / 2;
+ }
+
+ if ((goomInfo->update.zoomFilterData.mode == WATER_MODE)
+ || (goomInfo->update.zoomFilterData.mode == YONLY_MODE)
+ || (goomInfo->update.zoomFilterData.mode == AMULETTE_MODE)) {
+ goomInfo->update.zoomFilterData.middleX = goomInfo->screen.width / 2;
+ goomInfo->update.zoomFilterData.middleY = goomInfo->screen.height / 2;
+ }
+
+ switch (vtmp = (goom_irand (goomInfo->gRandom, 15))) {
+ case 0:
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ goom_irand (goomInfo->gRandom, 3)
+ - goom_irand (goomInfo->gRandom, 3);
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ goom_irand (goomInfo->gRandom, 3)
+ - goom_irand (goomInfo->gRandom, 3);
+ break;
+ case 3:
+ goomInfo->update.zoomFilterData.vPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ goom_irand (goomInfo->gRandom, 8)
+ - goom_irand (goomInfo->gRandom, 8);
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ goom_irand (goomInfo->gRandom, 5)
+ - goom_irand (goomInfo->gRandom, 5);
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ -goomInfo->update.zoomFilterData.vPlaneEffect;
+ break;
+ case 8:
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ 5 + goom_irand (goomInfo->gRandom, 8);
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ -goomInfo->update.zoomFilterData.hPlaneEffect;
+ break;
+ case 9:
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ 5 + goom_irand (goomInfo->gRandom, 8);
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ -goomInfo->update.zoomFilterData.hPlaneEffect;
+ break;
+ case 13:
+ goomInfo->update.zoomFilterData.hPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ goom_irand (goomInfo->gRandom, 10)
+ - goom_irand (goomInfo->gRandom, 10);
+ break;
+ case 14:
+ goomInfo->update.zoomFilterData.hPlaneEffect =
+ goom_irand (goomInfo->gRandom, 10)
+ - goom_irand (goomInfo->gRandom, 10);
+ goomInfo->update.zoomFilterData.vPlaneEffect =
+ goom_irand (goomInfo->gRandom, 10)
+ - goom_irand (goomInfo->gRandom, 10);
+ break;
+ default:
+ if (vtmp < 10) {
+ goomInfo->update.zoomFilterData.vPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.hPlaneEffect = 0;
+ }
+ }
+
+ if (goom_irand (goomInfo->gRandom, 5) != 0)
+ goomInfo->update.zoomFilterData.noisify = 0;
+ else {
+ goomInfo->update.zoomFilterData.noisify =
+ goom_irand (goomInfo->gRandom, 2) + 1;
+ goomInfo->update.lockvar *= 2;
+ }
+
+ if (goomInfo->update.zoomFilterData.mode == AMULETTE_MODE) {
+ goomInfo->update.zoomFilterData.vPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.hPlaneEffect = 0;
+ goomInfo->update.zoomFilterData.noisify = 0;
+ }
+
+ if ((goomInfo->update.zoomFilterData.middleX == 1)
+ || (goomInfo->update.zoomFilterData.middleX ==
+ (signed int) goomInfo->screen.width - 1)) {
+ goomInfo->update.zoomFilterData.vPlaneEffect = 0;
+ if (goom_irand (goomInfo->gRandom, 2))
+ goomInfo->update.zoomFilterData.hPlaneEffect = 0;
+ }
+
+ if ((signed int) newvit < goomInfo->update.zoomFilterData.vitesse) { /* on accelere */
+ pzfd = &goomInfo->update.zoomFilterData;
+ if (((newvit < STOP_SPEED - 7) &&
+ (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 6) &&
+ (goomInfo->cycle % 3 == 0))
+ || (goom_irand (goomInfo->gRandom, 40) == 0)) {
+ goomInfo->update.zoomFilterData.vitesse =
+ STOP_SPEED - goom_irand (goomInfo->gRandom, 2)
+ + goom_irand (goomInfo->gRandom, 2);
+ goomInfo->update.zoomFilterData.reverse =
+ !goomInfo->update.zoomFilterData.reverse;
+ } else {
+ goomInfo->update.zoomFilterData.vitesse =
+ (newvit + goomInfo->update.zoomFilterData.vitesse * 7) / 8;
+ }
+ goomInfo->update.lockvar += 50;
+ }
+ }
+
+ if (goomInfo->update.lockvar > 150) {
+ goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount;
+ goomInfo->update.switchMult = 1.0f;
+ }
+ }
+ /* mode mega-lent */
+ if (goom_irand (goomInfo->gRandom, 700) == 0) {
+ /*
+ * printf ("coup du sort...\n") ;
+ */
+ pzfd = &goomInfo->update.zoomFilterData;
+ goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 1;
+ goomInfo->update.zoomFilterData.pertedec = 8;
+ goomInfo->update.zoomFilterData.sqrtperte = 16;
+ goomInfo->update.goomvar = 1;
+ goomInfo->update.lockvar += 50;
+ goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount;
+ goomInfo->update.switchMult = 1.0f;
+ }
+ }
+
+ /*
+ * gros frein si la musique est calme
+ */
+ if ((goomInfo->sound.speedvar < 0.01f)
+ && (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 4)
+ && (goomInfo->cycle % 16 == 0)) {
+ pzfd = &goomInfo->update.zoomFilterData;
+ goomInfo->update.zoomFilterData.vitesse += 3;
+ goomInfo->update.zoomFilterData.pertedec = 8;
+ goomInfo->update.zoomFilterData.sqrtperte = 16;
+ goomInfo->update.goomvar = 0;
+ }
+
+ /*
+ * baisser regulierement la vitesse...
+ */
+ if ((goomInfo->cycle % 73 == 0)
+ && (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 5)) {
+ pzfd = &goomInfo->update.zoomFilterData;
+ goomInfo->update.zoomFilterData.vitesse++;
+ }
+
+ /*
+ * arreter de decr�menter au bout d'un certain temps
+ */
+ if ((goomInfo->cycle % 101 == 0)
+ && (goomInfo->update.zoomFilterData.pertedec == 7)) {
+ pzfd = &goomInfo->update.zoomFilterData;
+ goomInfo->update.zoomFilterData.pertedec = 8;
+ goomInfo->update.zoomFilterData.sqrtperte = 16;
+ }
+
+ /*
+ * Permet de forcer un effet.
+ */
+ if ((forceMode > 0) && (forceMode <= NB_FX)) {
+ pzfd = &goomInfo->update.zoomFilterData;
+ pzfd->mode = forceMode - 1;
+ }
+
+ if (forceMode == -1) {
+ pzfd = NULL;
+ }
+
+ /*
+ * Changement d'effet de zoom !
+ */
+ if (pzfd != NULL) {
+ int dif;
+
+ goomInfo->update.cyclesSinceLastChange = 0;
+
+ goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount;
+
+ dif =
+ goomInfo->update.zoomFilterData.vitesse -
+ goomInfo->update.previousZoomSpeed;
+ if (dif < 0)
+ dif = -dif;
+
+ if (dif > 2) {
+ goomInfo->update.switchIncr *= (dif + 2) / 2;
+ }
+ goomInfo->update.previousZoomSpeed =
+ goomInfo->update.zoomFilterData.vitesse;
+ goomInfo->update.switchMult = 1.0f;
+
+ if (((goomInfo->sound.timeSinceLastGoom == 0)
+ && (goomInfo->sound.totalgoom < 2)) || (forceMode > 0)) {
+ goomInfo->update.switchIncr = 0;
+ goomInfo->update.switchMult = goomInfo->update.switchMultAmount;
+ }
+ } else {
+ if (goomInfo->update.cyclesSinceLastChange > TIME_BTW_CHG) {
+ pzfd = &goomInfo->update.zoomFilterData;
+ goomInfo->update.cyclesSinceLastChange = 0;
+ } else
+ goomInfo->update.cyclesSinceLastChange++;
+ }
+
+#ifdef VERBOSE
+ if (pzfd) {
+ printf ("GOOM: pzfd->mode = %d\n", pzfd->mode);
+ }
+#endif
+
+ /* Zoom here ! */
+ zoomFilterFastRGB (goomInfo, goomInfo->p1, goomInfo->p2, pzfd,
+ goomInfo->screen.width, goomInfo->screen.height,
+ goomInfo->update.switchIncr, goomInfo->update.switchMult);
+
+ /*
+ * Affichage tentacule
+ */
+
+ goomInfo->tentacles_fx.apply (&goomInfo->tentacles_fx, goomInfo->p1,
+ goomInfo->p2, goomInfo);
+ goomInfo->star_fx.apply (&goomInfo->star_fx, goomInfo->p2, goomInfo->p1,
+ goomInfo);
+
+ /*
+ * Gestion du Scope
+ */
+
+ /*
+ * arret demande
+ */
+ if ((goomInfo->update.stop_lines & 0xf000)
+ || (!goomInfo->curGState->drawScope)) {
+ float param1 = 0, param2 = 0, amplitude;
+ int couleur;
+ int mode;
+
+ choose_a_goom_line (goomInfo, &param1, &param2, &couleur, &mode, &amplitude,
+ 1);
+ couleur = GML_BLACK;
+
+ goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude, couleur);
+ goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude, couleur);
+ goomInfo->update.stop_lines &= 0x0fff;
+ }
+
+ /*
+ * arret aleatore.. changement de mode de ligne..
+ */
+ if (goomInfo->update.lineMode != goomInfo->update.drawLinesDuration) {
+ goomInfo->update.lineMode--;
+ if (goomInfo->update.lineMode == -1)
+ goomInfo->update.lineMode = 0;
+ } else if ((goomInfo->cycle % 80 == 0)
+ && (goom_irand (goomInfo->gRandom, 5) == 0) && goomInfo->update.lineMode)
+ goomInfo->update.lineMode--;
+
+ if ((goomInfo->cycle % 120 == 0)
+ && (goom_irand (goomInfo->gRandom, 4) == 0)
+ && (goomInfo->curGState->drawScope)) {
+ if (goomInfo->update.lineMode == 0)
+ goomInfo->update.lineMode = goomInfo->update.drawLinesDuration;
+ else if (goomInfo->update.lineMode == goomInfo->update.drawLinesDuration) {
+ float param1, param2, amplitude;
+ int couleur1, couleur2;
+ int mode;
+
+ goomInfo->update.lineMode--;
+ choose_a_goom_line (goomInfo, &param1, &param2, &couleur1,
+ &mode, &amplitude, goomInfo->update.stop_lines);
+
+ couleur2 = 5 - couleur1;
+ if (goomInfo->update.stop_lines) {
+ goomInfo->update.stop_lines--;
+ if (goom_irand (goomInfo->gRandom, 2))
+ couleur2 = couleur1 = GML_BLACK;
+ }
+
+ goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude,
+ couleur1);
+ goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude,
+ couleur2);
+ }
+ }
+
+ /*
+ * si on est dans un goom : afficher les lignes...
+ */
+ if ((goomInfo->update.lineMode != 0)
+ || (goomInfo->sound.timeSinceLastGoom < 5)) {
+ goomInfo->gmline2->power = goomInfo->gmline1->power;
+
+ goom_lines_draw (goomInfo, goomInfo->gmline1, data[0], goomInfo->p2);
+ goom_lines_draw (goomInfo, goomInfo->gmline2, data[1], goomInfo->p2);
+
+ if (((goomInfo->cycle % 121) == 9)
+ && (goom_irand (goomInfo->gRandom, 3) == 1)
+ && ((goomInfo->update.lineMode == 0)
+ || (goomInfo->update.lineMode ==
+ goomInfo->update.drawLinesDuration))) {
+ float param1, param2, amplitude;
+ int couleur1, couleur2;
+ int mode;
+
+ choose_a_goom_line (goomInfo, &param1, &param2, &couleur1,
+ &mode, &amplitude, goomInfo->update.stop_lines);
+ couleur2 = 5 - couleur1;
+
+ if (goomInfo->update.stop_lines) {
+ goomInfo->update.stop_lines--;
+ if (goom_irand (goomInfo->gRandom, 2))
+ couleur2 = couleur1 = GML_BLACK;
+ }
+ goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude,
+ couleur1);
+ goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude,
+ couleur2);
+ }
+ }
+
+ return_val = goomInfo->p1;
+ tmp = goomInfo->p1;
+ goomInfo->p1 = goomInfo->p2;
+ goomInfo->p2 = tmp;
+
+ /* affichage et swappage des buffers.. */
+ goomInfo->cycle++;
+
+ goomInfo->convolve_fx.apply (&goomInfo->convolve_fx, return_val,
+ goomInfo->outputBuf, goomInfo);
+
+ return (guint32 *) goomInfo->outputBuf;
+}
+
+/****************************************
+* CLOSE *
+****************************************/
+void
+goom_close (PluginInfo * goomInfo)
+{
+ if (goomInfo->pixel != NULL)
+ free (goomInfo->pixel);
+ if (goomInfo->back != NULL)
+ free (goomInfo->back);
+ if (goomInfo->conv != NULL)
+ free (goomInfo->conv);
+
+ goomInfo->pixel = goomInfo->back = NULL;
+ goomInfo->conv = NULL;
+ goom_random_free (goomInfo->gRandom);
+ goom_lines_free (&goomInfo->gmline1);
+ goom_lines_free (&goomInfo->gmline2);
+
+ /* release_ifs (); */
+ goomInfo->ifs_fx.free (&goomInfo->ifs_fx);
+ goomInfo->convolve_fx.free (&goomInfo->convolve_fx);
+ goomInfo->star_fx.free (&goomInfo->star_fx);
+ goomInfo->tentacles_fx.free (&goomInfo->tentacles_fx);
+ goomInfo->zoomFilter_fx.free (&goomInfo->zoomFilter_fx);
+
+ plugin_info_free (goomInfo);
+ free (goomInfo);
+}
+
+
+/* *** */
+void
+choose_a_goom_line (PluginInfo * goomInfo, float *param1, float *param2,
+ int *couleur, int *mode, float *amplitude, int far)
+{
+ *mode = goom_irand (goomInfo->gRandom, 3);
+ *amplitude = 1.0f;
+ switch (*mode) {
+ case GML_CIRCLE:
+ if (far) {
+ *param1 = *param2 = 0.47f;
+ *amplitude = 0.8f;
+ break;
+ }
+ if (goom_irand (goomInfo->gRandom, 3) == 0) {
+ *param1 = *param2 = 0;
+ *amplitude = 3.0f;
+ } else if (goom_irand (goomInfo->gRandom, 2)) {
+ *param1 = 0.40f * goomInfo->screen.height;
+ *param2 = 0.22f * goomInfo->screen.height;
+ } else {
+ *param1 = *param2 = goomInfo->screen.height * 0.35;
+ }
+ break;
+ case GML_HLINE:
+ if (goom_irand (goomInfo->gRandom, 4) || far) {
+ *param1 = goomInfo->screen.height / 7;
+ *param2 = 6.0f * goomInfo->screen.height / 7.0f;
+ } else {
+ *param1 = *param2 = goomInfo->screen.height / 2.0f;
+ *amplitude = 2.0f;
+ }
+ break;
+ case GML_VLINE:
+ if (goom_irand (goomInfo->gRandom, 3) || far) {
+ *param1 = goomInfo->screen.width / 7.0f;
+ *param2 = 6.0f * goomInfo->screen.width / 7.0f;
+ } else {
+ *param1 = *param2 = goomInfo->screen.width / 2.0f;
+ *amplitude = 1.5f;
+ }
+ break;
+ default:
+ *param1 = *param2 = 0;
+ break;
+ }
+
+ *couleur = goom_irand (goomInfo->gRandom, 6);
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_filters.h b/subprojects/gst-plugins-good/gst/goom/goom_filters.h
new file mode 100644
index 0000000000..e4cfaeb0ce
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_filters.h
@@ -0,0 +1,70 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef FILTERS_H
+#define FILTERS_H
+
+#include "goom_config.h"
+#include "goom_typedefs.h"
+#include "goom_visual_fx.h"
+#include "goom_graphic.h"
+
+void zoomFilterVisualFXWrapper_create(VisualFX *fx);
+
+struct _ZOOM_FILTER_DATA
+{
+ int vitesse; /* 128 = vitesse nule... * * 256 = en arriere
+ * hyper vite.. * * 0 = en avant hype vite. */
+ unsigned char pertedec;
+ unsigned char sqrtperte;
+ int middleX, middleY; /* milieu de l'effet */
+ char reverse; /* inverse la vitesse */
+ char mode; /* type d'effet � appliquer (cf les #define) */
+ /* @since June 2001 */
+ int hPlaneEffect; /* deviation horitontale */
+ int vPlaneEffect; /* deviation verticale */
+ /* @since April 2002 */
+ int waveEffect; /* applique une "surcouche" de wave effect */
+ int hypercosEffect; /* applique une "surcouche de hypercos effect */
+
+ char noisify; /* ajoute un bruit a la transformation */
+};
+
+#define NORMAL_MODE 0
+#define WAVE_MODE 1
+#define CRYSTAL_BALL_MODE 2
+#define SCRUNCH_MODE 3
+#define AMULETTE_MODE 4
+#define WATER_MODE 5
+#define HYPERCOS1_MODE 6
+#define HYPERCOS2_MODE 7
+#define YONLY_MODE 8
+#define SPEEDWAY_MODE 9
+
+void pointFilter (PluginInfo *goomInfo, Pixel * pix1, Color c,
+ float t1, float t2, float t3, float t4, guint32 cycle);
+
+/* filtre de zoom :
+ * le contenu de pix1 est copie dans pix2.
+ * zf : si non NULL, configure l'effet.
+ * resx,resy : taille des buffers.
+ */
+void zoomFilterFastRGB (PluginInfo *goomInfo, Pixel * pix1, Pixel * pix2, ZoomFilterData * zf, guint32 resx,
+ guint32 resy, int switchIncr, float switchMult);
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_fx.h b/subprojects/gst-plugins-good/gst/goom/goom_fx.h
new file mode 100644
index 0000000000..7c82d6cfe2
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_fx.h
@@ -0,0 +1,30 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GOOM_FX_H
+#define _GOOM_FX_H
+
+#include "goom_visual_fx.h"
+#include "goom_plugin_info.h"
+
+void convolve_create (VisualFX *vfx);
+void flying_star_create (VisualFX *vfx);
+
+void zoom_filter_c(int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_graphic.h b/subprojects/gst-plugins-good/gst/goom/goom_graphic.h
new file mode 100644
index 0000000000..54dde3765d
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_graphic.h
@@ -0,0 +1,92 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef GRAPHIC_H
+#define GRAPHIC_H
+
+typedef unsigned int Uint;
+
+typedef struct
+{
+ unsigned short r, v, b;
+}
+Color;
+
+extern const Color BLACK;
+extern const Color WHITE;
+extern const Color RED;
+extern const Color BLUE;
+extern const Color GREEN;
+extern const Color YELLOW;
+extern const Color ORANGE;
+extern const Color VIOLET;
+
+
+#ifdef COLOR_BGRA
+
+#define B_CHANNEL 0xFF000000
+#define G_CHANNEL 0x00FF0000
+#define R_CHANNEL 0x0000FF00
+#define A_CHANNEL 0x000000FF
+#define B_OFFSET 24
+#define G_OFFSET 16
+#define R_OFFSET 8
+#define A_OFFSET 0
+
+typedef union _PIXEL {
+ struct {
+ unsigned char b;
+ unsigned char g;
+ unsigned char r;
+ unsigned char a;
+ } channels;
+ unsigned int val;
+ unsigned char cop[4];
+} Pixel;
+
+#else
+
+#define A_CHANNEL 0xFF000000
+#define R_CHANNEL 0x00FF0000
+#define G_CHANNEL 0x0000FF00
+#define B_CHANNEL 0x000000FF
+#define A_OFFSET 24
+#define R_OFFSET 16
+#define G_OFFSET 8
+#define B_OFFSET 0
+
+typedef union _PIXEL {
+ struct {
+ unsigned char a;
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ } channels;
+ unsigned int val;
+ unsigned char cop[4];
+} Pixel;
+
+#endif /* COLOR_BGRA */
+
+/*
+inline void setPixelRGB (Pixel * buffer, Uint x, Uint y, Color c);
+inline void getPixelRGB (Pixel * buffer, Uint x, Uint y, Color * c);
+*/
+
+
+#endif /* GRAPHIC_H */
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_plugin_info.h b/subprojects/gst-plugins-good/gst/goom/goom_plugin_info.h
new file mode 100644
index 0000000000..907d780c23
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_plugin_info.h
@@ -0,0 +1,181 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _PLUGIN_INFO_H
+#define _PLUGIN_INFO_H
+
+#include "goom_typedefs.h"
+
+#include "goom_config.h"
+
+#include "goom_graphic.h"
+#include "goom_config_param.h"
+#include "goom_visual_fx.h"
+#include "goom_filters.h"
+#include "goom_tools.h"
+
+typedef struct {
+ char drawIFS;
+ char drawPoints;
+ char drawTentacle;
+
+ char drawScope;
+ int farScope;
+
+ int rangemin;
+ int rangemax;
+} GoomState;
+
+#define STATES_MAX_NB 128
+
+/*
+ * Gives informations about the sound.
+ */
+struct _SOUND_INFO {
+
+ /* nota : a Goom is just a sound event... */
+
+ int timeSinceLastGoom; /* >= 0 */
+ float goomPower; /* power of the last Goom [0..1] */
+
+ int timeSinceLastBigGoom; /* >= 0 */
+
+ float volume; /* [0..1] */
+ short samples[2][512];
+
+ /* other "internal" datas for the sound_tester */
+ float goom_limit; /* auto-updated limit of goom_detection */
+ float bigGoomLimit;
+ float accelvar; /* acceleration of the sound - [0..1] */
+ float speedvar; /* speed of the sound - [0..100] */
+ int allTimesMax;
+ int totalgoom; /* number of goom since last reset
+ * (a reset every 64 cycles) */
+
+ float prov_max; /* accel max since last reset */
+
+ int cycle;
+
+ /* private */
+ PluginParam volume_p;
+ PluginParam speed_p;
+ PluginParam accel_p;
+ PluginParam goom_limit_p;
+ PluginParam goom_power_p;
+ PluginParam last_goom_p;
+ PluginParam last_biggoom_p;
+ PluginParam biggoom_speed_limit_p;
+ PluginParam biggoom_factor_p;
+
+ PluginParameters params; /* contains the previously defined parameters. */
+};
+
+
+/*
+ * Allows FXs to know the current state of the plugin.
+ */
+struct _PLUGIN_INFO {
+
+ /* public datas */
+
+ int nbParams;
+ PluginParameters *params;
+
+ /* private datas */
+
+ struct _SIZE_TYPE {
+ int width;
+ int height;
+ int size; /* == screen.height * screen.width. */
+ } screen;
+
+ SoundInfo sound;
+
+ int nbVisuals;
+ VisualFX **visuals; /* pointers on all the visual fx */
+
+ /* The known FX */
+ VisualFX convolve_fx;
+ VisualFX star_fx;
+ VisualFX zoomFilter_fx;
+ VisualFX tentacles_fx;
+ VisualFX ifs_fx;
+
+ /* image buffers */
+ guint32 *pixel;
+ guint32 *back;
+ Pixel *p1, *p2;
+ Pixel *conv;
+ Pixel *outputBuf;
+
+ /* state of goom */
+ guint32 cycle;
+ GoomState states[STATES_MAX_NB];
+ int statesNumber;
+ int statesRangeMax;
+
+ GoomState *curGState;
+
+ /* effet de ligne.. */
+ GMLine *gmline1;
+ GMLine *gmline2;
+
+ /* sinus table */
+ int sintable[0x10000];
+
+ /* INTERNALS */
+
+ /* goom_update internals.
+ * I took all static variables from goom_update and put them here.. for the moment.
+ */
+ struct {
+ int lockvar; /* pour empecher de nouveaux changements */
+ int goomvar; /* boucle des gooms */
+ int loopvar; /* mouvement des points */
+ int stop_lines;
+ int ifs_incr; /* dessiner l'ifs (0 = non: > = increment) */
+ int decay_ifs; /* disparition de l'ifs */
+ int recay_ifs; /* dedisparition de l'ifs */
+ int cyclesSinceLastChange; /* nombre de Cycle Depuis Dernier Changement */
+ int drawLinesDuration; /* duree de la transition entre afficher les lignes ou pas */
+ int lineMode; /* l'effet lineaire a dessiner */
+ float switchMultAmount; /* SWITCHMULT (29.0f/30.0f) */
+ int switchIncrAmount; /* 0x7f */
+ float switchMult; /* 1.0f */
+ int switchIncr; /* = SWITCHINCR; */
+ int stateSelectionRnd;
+ int stateSelectionBlocker;
+ int previousZoomSpeed;
+ ZoomFilterData zoomFilterData;
+ } update;
+
+ struct {
+ void (*draw_line) (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny);
+ void (*zoom_filter) (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+ } methods;
+
+ GoomRandom *gRandom;
+};
+
+void plugin_info_init(PluginInfo *p, int nbVisual);
+void plugin_info_free(PluginInfo *p);
+
+/* i = [0..p->nbVisual-1] */
+void plugin_info_add_visual(PluginInfo *p, int i, VisualFX *visual);
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_tools.c b/subprojects/gst-plugins-good/gst/goom/goom_tools.c
new file mode 100644
index 0000000000..01758fd987
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_tools.c
@@ -0,0 +1,50 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "goom_tools.h"
+#include <stdlib.h>
+
+GoomRandom *
+goom_random_init (int i)
+{
+ GoomRandom *grandom = (GoomRandom *) malloc (sizeof (GoomRandom));
+
+ srand (i);
+ grandom->pos = 1;
+ goom_random_update_array (grandom, GOOM_NB_RAND);
+ return grandom;
+}
+
+void
+goom_random_free (GoomRandom * grandom)
+{
+ free (grandom);
+}
+
+void
+goom_random_update_array (GoomRandom * grandom, int numberOfValuesToChange)
+{
+ while (numberOfValuesToChange > 0) {
+#if RAND_MAX < 0x10000
+ grandom->array[grandom->pos++] = ((rand () << 16) + rand ()) / 127;
+#else
+ grandom->array[grandom->pos++] = rand () / 127;
+#endif
+ numberOfValuesToChange--;
+ }
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_tools.h b/subprojects/gst-plugins-good/gst/goom/goom_tools.h
new file mode 100644
index 0000000000..db5c407fe0
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_tools.h
@@ -0,0 +1,53 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GOOMTOOLS_H
+#define _GOOMTOOLS_H
+
+#include "goom_config.h"
+
+/*
+ * Random number generator wrapper for faster random number.
+ */
+
+#define GOOM_NB_RAND 0x10000
+
+typedef struct _GOOM_RANDOM {
+ int array[GOOM_NB_RAND];
+ unsigned short pos;
+} GoomRandom;
+
+GoomRandom *goom_random_init(int i);
+void goom_random_free(GoomRandom *grandom);
+
+inline static int goom_random(GoomRandom *grandom) {
+
+ grandom->pos++; /* works because pos is an unsigned short */
+ return grandom->array[grandom->pos];
+}
+
+inline static int goom_irand(GoomRandom *grandom, int i) {
+
+ grandom->pos++;
+ return grandom->array[grandom->pos] % i;
+}
+
+/* called to change the specified number of value in the array, so that the array does not remain the same*/
+void goom_random_update_array(GoomRandom *grandom, int numberOfValuesToChange);
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_typedefs.h b/subprojects/gst-plugins-good/gst/goom/goom_typedefs.h
new file mode 100644
index 0000000000..d3a33a999b
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_typedefs.h
@@ -0,0 +1,29 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GOOM_TYPEDEFS_H
+#define _GOOM_TYPEDEFS_H
+
+typedef struct _PLUGIN_INFO PluginInfo;
+typedef struct _SOUND_INFO SoundInfo;
+typedef struct _GMLINE GMLine;
+typedef struct _GMUNITPOINTER GMUnitPointer;
+typedef struct _ZOOM_FILTER_DATA ZoomFilterData;
+typedef struct _VISUAL_FX VisualFX;
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/goom_visual_fx.h b/subprojects/gst-plugins-good/gst/goom/goom_visual_fx.h
new file mode 100644
index 0000000000..0bb5a49c29
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goom_visual_fx.h
@@ -0,0 +1,35 @@
+/* Goom Project
+ * Copyright (C) <2003> Jean-Christophe Hoelt <jeko@free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _VISUAL_FX_H
+#define _VISUAL_FX_H
+
+#include "goom_config_param.h"
+#include "goom_graphic.h"
+#include "goom_typedefs.h"
+
+struct _VISUAL_FX {
+ void (*init) (struct _VISUAL_FX *_this, PluginInfo *info);
+ void (*free) (struct _VISUAL_FX *_this);
+ void (*apply) (struct _VISUAL_FX *_this, Pixel *src, Pixel *dest, PluginInfo *info);
+ void *fx_data;
+
+ PluginParameters *params;
+};
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/goomsl_lex.l b/subprojects/gst-plugins-good/gst/goom/goomsl_lex.l
new file mode 100644
index 0000000000..7a7de29069
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goomsl_lex.l
@@ -0,0 +1,94 @@
+%{
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "goomsl.h"
+#include "goomsl_private.h"
+#include "goomsl_yacc.h"
+void yyerror(char *);
+void yyparse(void);
+
+GoomSL *currentGoomSL;
+static int string_size;
+static char string[1024];
+%}
+
+DIGIT [0-9]
+XDIGIT [0-9a-f]
+ID [a-zA-Z_@&][a-zA-Z0-9_\.]*
+
+%S C_COMMENT
+%S LINE_COMMENT
+%S STRING
+
+%%
+
+<LINE_COMMENT,C_COMMENT,INITIAL>^[ \t]*\n { ++currentGoomSL->num_lines; /* Ignore empty lines */ }
+<LINE_COMMENT,C_COMMENT,INITIAL>^[ \t]*"//"[^\n]*\n { ++currentGoomSL->num_lines; /* Ignore empty lines */ }
+
+<LINE_COMMENT>\n { ++currentGoomSL->num_lines; yylval.charValue=*yytext; BEGIN INITIAL; return '\n'; }
+<INITIAL>\n { ++currentGoomSL->num_lines; yylval.charValue=*yytext; return '\n'; }
+
+<C_COMMENT>"*/" { BEGIN INITIAL; }
+<C_COMMENT>\n { ++currentGoomSL->num_lines; }
+<C_COMMENT,LINE_COMMENT>. { /* eat up comment */ }
+
+<INITIAL>"#RST_LINE#" { currentGoomSL->num_lines = 0; }
+<INITIAL>"#FILE ".*"#" { currentGoomSL->num_lines = 0; /* printf("%s\n", yytext); */ }
+<INITIAL>"#"[^\n]* { /* ignore preprocessor lines */ }
+
+<INITIAL>"/*" { BEGIN C_COMMENT; }
+<INITIAL>"//" { BEGIN LINE_COMMENT; }
+<INITIAL>\" { BEGIN STRING; string_size=0; }
+
+<STRING>"\\n" { string[string_size++] = '\n'; }
+<STRING>"\\\"" { string[string_size++] = '\"'; }
+<STRING>\" { /* fin de la chaine: on cree le pointeur qui va bien */
+ unsigned int tmp;
+ BEGIN INITIAL;
+ string[string_size]=0;
+ tmp = gsl_malloc(currentGoomSL, string_size+1);
+ strcpy((char*)currentGoomSL->ptrArray[tmp],string);
+ sprintf(yylval.strValue, "0x%08x", tmp);
+ return LTYPE_PTR;
+ }
+<STRING>. { string[string_size++] = *yytext; }
+
+<INITIAL>"float" { return FLOAT_TK; }
+<INITIAL>"int" { return INT_TK; }
+<INITIAL>"boolean" { return INT_TK; }
+<INITIAL>"ptr" { return PTR_TK; }
+<INITIAL>"string" { return PTR_TK; }
+<INITIAL>"declare" { return DECLARE; }
+<INITIAL>"external" { return EXTERNAL; }
+<INITIAL>"struct" { return STRUCT; }
+<INITIAL>"not" { return NOT; }
+<INITIAL>"while" { return WHILE; }
+<INITIAL>"do" { return DO; }
+<INITIAL>"for" { return FOR; }
+<INITIAL>"in" { return IN; }
+<INITIAL>"true" { strncpy(yylval.strValue, "1", 2047); return LTYPE_INTEGER; }
+<INITIAL>"false" { strncpy(yylval.strValue, "0", 2047); return LTYPE_INTEGER; }
+<INITIAL>{ID} { strncpy(yylval.strValue, yytext, 2047); return LTYPE_VAR; }
+<INITIAL>{DIGIT}+ { strncpy(yylval.strValue, yytext, 2047); return LTYPE_INTEGER; }
+<INITIAL>\'.\' { sprintf(yylval.strValue, "%d", (int)yytext[1]); return LTYPE_INTEGER; }
+<INITIAL>"0x"{XDIGIT}+ { strncpy(yylval.strValue, yytext, 2047); return LTYPE_INTEGER; }
+<INITIAL>{DIGIT}+"."{DIGIT}* { strncpy(yylval.strValue, yytext, 2047); return LTYPE_FLOAT; }
+<INITIAL>{DIGIT}+"%" { sprintf(yylval.strValue, "%3.2f", atof(yytext)/100.0f); return LTYPE_FLOAT; }
+<INITIAL>"+=" { return PLUS_EQ; }
+<INITIAL>"*=" { return MUL_EQ; }
+<INITIAL>"-=" { return SUB_EQ; }
+<INITIAL>"/=" { return DIV_EQ; }
+<INITIAL>"<=" { return LOW_EQ; }
+<INITIAL>">=" { return SUP_EQ; }
+<INITIAL>"!=" { return NOT_EQ; }
+<INITIAL>"<>" { return NOT_EQ; }
+<INITIAL>[ \t]+ /* eat up whitespace */
+<INITIAL>. { yylval.charValue = *yytext; return *yytext; }
+
+%%
+
+
+int yywrap(void) { return 1; yyunput(0,0); }
+
diff --git a/subprojects/gst-plugins-good/gst/goom/goomsl_yacc.y b/subprojects/gst-plugins-good/gst/goom/goomsl_yacc.y
new file mode 100644
index 0000000000..078933c278
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/goomsl_yacc.y
@@ -0,0 +1,1438 @@
+/**
+ * copyright 2004, Jean-Christophe Hoelt <jeko@ios-software.com>
+ *
+ * This program is released under the terms of the GNU Lesser General Public Licence.
+ */
+%{
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <glib.h>
+ #include "goomsl.h"
+ #include "goomsl_private.h"
+
+#define STRUCT_ALIGNMENT 16
+/* #define VERBOSE */
+
+ int yylex(void);
+ void yyerror(char *);
+ extern GoomSL *currentGoomSL;
+
+ static NodeType *nodeNew(const char *str, int type, int line_number);
+ static NodeType *nodeClone(NodeType *node);
+ static void nodeFreeInternals(NodeType *node);
+ static void nodeFree(NodeType *node);
+
+ static void commit_node(NodeType *node, int releaseIfTemp);
+ static void precommit_node(NodeType *node);
+
+ static NodeType *new_constInt(const char *str, int line_number);
+ static NodeType *new_constFloat(const char *str, int line_number);
+ static NodeType *new_constPtr(const char *str, int line_number);
+ static NodeType *new_var(const char *str, int line_number);
+ static NodeType *new_nop(const char *str);
+ static NodeType *new_op(const char *str, int type, int nbOp);
+
+ static int allocateLabel();
+ static int allocateTemp();
+ static void releaseTemp(int n);
+ static void releaseAllTemps();
+
+ static int is_tmp_expr(NodeType *node) {
+ if (node->str) {
+ return (!strncmp(node->str,"_i_tmp_",7))
+ || (!strncmp(node->str,"_f_tmp_",7))
+ || (!strncmp(node->str,"_p_tmp",7));
+ }
+ return 0;
+ }
+ /* pre: is_tmp_expr(node); */
+ static int get_tmp_id(NodeType *node) { return atoi((node->str)+5); }
+
+ static int is_commutative_expr(int itype)
+ { /* {{{ */
+ return (itype == INSTR_ADD)
+ || (itype == INSTR_MUL)
+ || (itype == INSTR_ISEQUAL);
+ } /* }}} */
+
+ static void GSL_PUT_LABEL(char *name, int line_number)
+ { /* {{{ */
+#ifdef VERBOSE
+ printf("label %s\n", name);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, line_number);
+ gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
+ } /* }}} */
+ static void GSL_PUT_JUMP(char *name, int line_number)
+ { /* {{{ */
+#ifdef VERBOSE
+ printf("jump %s\n", name);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "jump", INSTR_JUMP, 1, line_number);
+ gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
+ } /* }}} */
+
+ static void GSL_PUT_JXXX(char *name, char *iname, int instr_id, int line_number)
+ { /* {{{ */
+#ifdef VERBOSE
+ printf("%s %s\n", iname, name);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, iname, instr_id, 1, line_number);
+ gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
+ } /* }}} */
+ static void GSL_PUT_JZERO(char *name,int line_number)
+ { /* {{{ */
+ GSL_PUT_JXXX(name,"jzero.i",INSTR_JZERO,line_number);
+ } /* }}} */
+ static void GSL_PUT_JNZERO(char *name, int line_number)
+ { /* {{{ */
+ GSL_PUT_JXXX(name,"jnzero.i",INSTR_JNZERO,line_number);
+ } /* }}} */
+
+ /* Structures Management */
+
+#define ALIGN_ADDR(_addr,_align) {\
+ if (_align>1) {\
+ int _dec = (_addr%_align);\
+ if (_dec != 0) _addr += _align - _dec;\
+ }}
+
+ /* */
+ void gsl_prepare_struct(GSL_Struct *s, int s_align, int i_align, int f_align)
+ {
+ int i;
+ int consumed = 0;
+ int iblk=0, fblk=0;
+
+ s->iBlock[0].size = 0;
+ s->iBlock[0].data = 0;
+ s->fBlock[0].size = 0;
+ s->fBlock[0].data = 0;
+
+ /* Prepare sub-struct and calculate space needed for their storage */
+ for (i = 0; i < s->nbFields; ++i)
+ {
+ if (s->fields[i]->type < FIRST_RESERVED)
+ {
+ int j=0;
+ GSL_Struct *substruct = currentGoomSL->gsl_struct[s->fields[i]->type];
+ consumed += sizeof(int); /* stocke le prefix */
+ ALIGN_ADDR(consumed, s_align);
+ s->fields[i]->offsetInStruct = consumed;
+ gsl_prepare_struct(substruct, s_align, i_align, f_align);
+ for(j=0;substruct->iBlock[j].size>0;++j) {
+ s->iBlock[iblk].data = consumed + substruct->iBlock[j].data;
+ s->iBlock[iblk].size = substruct->iBlock[j].size;
+ iblk++;
+ }
+ for(j=0;substruct->fBlock[j].size>0;++j) {
+ s->fBlock[fblk].data = consumed + substruct->fBlock[j].data;
+ s->fBlock[fblk].size = substruct->fBlock[j].size;
+ fblk++;
+ }
+ consumed += substruct->size;
+ }
+ }
+
+ /* Then prepare integers */
+ ALIGN_ADDR(consumed, i_align);
+ for (i = 0; i < s->nbFields; ++i)
+ {
+ if (s->fields[i]->type == INSTR_INT)
+ {
+ if (s->iBlock[iblk].size == 0) {
+ s->iBlock[iblk].size = 1;
+ s->iBlock[iblk].data = consumed;
+ } else {
+ s->iBlock[iblk].size += 1;
+ }
+ s->fields[i]->offsetInStruct = consumed;
+ consumed += sizeof(int);
+ }
+ }
+
+ iblk++;
+ s->iBlock[iblk].size = 0;
+ s->iBlock[iblk].data = 0;
+
+ /* Then prepare floats */
+ ALIGN_ADDR(consumed, f_align);
+ for (i = 0; i < s->nbFields; ++i)
+ {
+ if (s->fields[i]->type == INSTR_FLOAT)
+ {
+ if (s->fBlock[fblk].size == 0) {
+ s->fBlock[fblk].size = 1;
+ s->fBlock[fblk].data = consumed;
+ } else {
+ s->fBlock[fblk].size += 1;
+ }
+ s->fields[i]->offsetInStruct = consumed;
+ consumed += sizeof(int);
+ }
+ }
+
+ fblk++;
+ s->fBlock[fblk].size = 0;
+ s->fBlock[fblk].data = 0;
+
+ /* Finally prepare pointers */
+ ALIGN_ADDR(consumed, i_align);
+ for (i = 0; i < s->nbFields; ++i)
+ {
+ if (s->fields[i]->type == INSTR_PTR)
+ {
+ s->fields[i]->offsetInStruct = consumed;
+ consumed += sizeof(int);
+ }
+ }
+ s->size = consumed;
+ }
+
+ /* Returns the ID of a struct from its name */
+ int gsl_get_struct_id(const char *name) /* {{{ */
+ {
+ HashValue *ret = goom_hash_get(currentGoomSL->structIDS, name);
+ if (ret != NULL) return ret->i;
+ return -1;
+ } /* }}} */
+
+ /* Adds the definition of a struct */
+ void gsl_add_struct(const char *name, GSL_Struct *gsl_struct) /* {{{ */
+ {
+ /* Prepare the struct: ie calculate internal storage format */
+ gsl_prepare_struct(gsl_struct, STRUCT_ALIGNMENT, STRUCT_ALIGNMENT, STRUCT_ALIGNMENT);
+
+ /* If the struct does not already exists */
+ if (gsl_get_struct_id(name) < 0)
+ {
+ /* adds it */
+ int id = currentGoomSL->nbStructID++;
+ goom_hash_put_int(currentGoomSL->structIDS, name, id);
+ if (currentGoomSL->gsl_struct_size <= id) {
+ currentGoomSL->gsl_struct_size *= 2;
+ currentGoomSL->gsl_struct = (GSL_Struct**)realloc(currentGoomSL->gsl_struct,
+ sizeof(GSL_Struct*) * currentGoomSL->gsl_struct_size);
+ }
+ currentGoomSL->gsl_struct[id] = gsl_struct;
+ }
+ } /* }}} */
+
+ /* Creates a field for a struct */
+ GSL_StructField *gsl_new_struct_field(const char *name, int type)
+ {
+ GSL_StructField *field = (GSL_StructField*)malloc(sizeof(GSL_StructField));
+ strcpy(field->name, name);
+ field->type = type;
+ return field;
+ }
+
+ /* Create as field for a struct which will be a struct itself */
+ GSL_StructField *gsl_new_struct_field_struct(const char *name, const char *type)
+ {
+ GSL_StructField *field = gsl_new_struct_field(name, gsl_get_struct_id(type));
+ if (field->type < 0) {
+ g_assert_not_reached ();
+#if 0
+ fprintf(stderr, "ERROR: Line %d, Unknown structure: '%s'\n",
+ currentGoomSL->num_lines, type);
+ exit(1);
+#endif
+ }
+ return field;
+ }
+
+ /* Creates a Struct */
+ GSL_Struct *gsl_new_struct(GSL_StructField *field)
+ {
+ GSL_Struct *s = (GSL_Struct*)malloc(sizeof(GSL_Struct));
+ s->nbFields = 1;
+ s->fields[0] = field;
+ return s;
+ }
+
+ /* Adds a field to a struct */
+ void gsl_add_struct_field(GSL_Struct *s, GSL_StructField *field)
+ {
+ s->fields[s->nbFields++] = field;
+ }
+
+ int gsl_type_of_var(GoomHash *ns, const char *name)
+ {
+ char type_of[256];
+ HashValue *hv;
+ sprintf(type_of, "__type_of_%s", name);
+ hv = goom_hash_get(ns, type_of);
+ if (hv != NULL)
+ return hv->i;
+ fprintf(stderr, "ERROR: Unknown variable type: '%s'\n", name);
+ return -1;
+ }
+
+ static void gsl_declare_var(GoomHash *ns, const char *name, int type, void *space)
+ {
+ char type_of[256];
+ if (name[0] == '@') { ns = currentGoomSL->vars; }
+
+ if (space == NULL) {
+ switch (type) {
+ case INSTR_INT:
+ case INSTR_FLOAT:
+ case INSTR_PTR:
+ space = goom_heap_malloc_with_alignment(currentGoomSL->data_heap,
+ sizeof(int), sizeof(int));
+ break;
+#if 0
+ case -1:
+ fprintf(stderr, "What the fuck!\n");
+ exit(1);
+#endif
+ default: /* On a un struct_id */
+ space = goom_heap_malloc_with_alignment_prefixed(currentGoomSL->data_heap,
+ currentGoomSL->gsl_struct[type]->size, STRUCT_ALIGNMENT, sizeof(int));
+ }
+ }
+ goom_hash_put_ptr(ns, name, (void*)space);
+ sprintf(type_of, "__type_of_%s", name);
+ goom_hash_put_int(ns, type_of, type);
+
+ /* Ensuite le hack: on ajoute les champs en tant que variables. */
+ if (type < FIRST_RESERVED)
+ {
+ int i;
+ GSL_Struct *gsl_struct = currentGoomSL->gsl_struct[type];
+ ((int*)space)[-1] = type; /* stockage du type dans le prefixe de structure */
+ for (i = 0; i < gsl_struct->nbFields; ++i)
+ {
+ char full_name[256];
+ char *cspace = (char*)space + gsl_struct->fields[i]->offsetInStruct;
+ sprintf(full_name, "%s.%s", name, gsl_struct->fields[i]->name);
+ gsl_declare_var(ns, full_name, gsl_struct->fields[i]->type, cspace);
+ }
+ }
+ }
+
+ /* Declare a variable which will be a struct */
+ static void gsl_struct_decl(GoomHash *namespace, const char *struct_name, const char *name)
+ {
+ int struct_id = gsl_get_struct_id(struct_name);
+ gsl_declare_var(namespace, name, struct_id, NULL);
+ }
+
+ static void gsl_float_decl_global(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->vars, name, INSTR_FLOAT, NULL);
+ }
+ static void gsl_int_decl_global(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->vars, name, INSTR_INT, NULL);
+ }
+ static void gsl_ptr_decl_global(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->vars, name, INSTR_PTR, NULL);
+ }
+ static void gsl_struct_decl_global_from_id(const char *name, int id)
+ {
+ gsl_declare_var(currentGoomSL->vars, name, id, NULL);
+ }
+
+ /* FLOAT */
+ static void gsl_float_decl_local(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_FLOAT, NULL);
+ }
+ /* INT */
+ static void gsl_int_decl_local(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_INT, NULL);
+ }
+ /* PTR */
+ static void gsl_ptr_decl_local(const char *name)
+ {
+ gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_PTR, NULL);
+ }
+ /* STRUCT */
+ static void gsl_struct_decl_local(const char *struct_name, const char *name)
+ {
+ gsl_struct_decl(currentGoomSL->namespaces[currentGoomSL->currentNS],struct_name,name);
+ }
+
+
+ static void commit_test2(NodeType *set,const char *type, int instr);
+ static NodeType *new_call(const char *name, NodeType *affect_list);
+
+ /* SETTER */
+ static NodeType *new_set(NodeType *lvalue, NodeType *expression)
+ { /* {{{ */
+ NodeType *set = new_op("set", OPR_SET, 2);
+ set->unode.opr.op[0] = lvalue;
+ set->unode.opr.op[1] = expression;
+ return set;
+ } /* }}} */
+ static void commit_set(NodeType *set)
+ { /* {{{ */
+ commit_test2(set,"set",INSTR_SET);
+ } /* }}} */
+
+ /* PLUS_EQ */
+ static NodeType *new_plus_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
+ {
+ NodeType *set = new_op("plus_eq", OPR_PLUS_EQ, 2);
+ set->unode.opr.op[0] = lvalue;
+ set->unode.opr.op[1] = expression;
+ return set;
+ }
+ static void commit_plus_eq(NodeType *set)
+ {
+ precommit_node(set->unode.opr.op[1]);
+#ifdef VERBOSE
+ printf("add %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "add", INSTR_ADD, 2, set->line_number);
+ commit_node(set->unode.opr.op[0],0);
+ commit_node(set->unode.opr.op[1],1);
+ } /* }}} */
+
+ /* SUB_EQ */
+ static NodeType *new_sub_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
+ {
+ NodeType *set = new_op("sub_eq", OPR_SUB_EQ, 2);
+ set->unode.opr.op[0] = lvalue;
+ set->unode.opr.op[1] = expression;
+ return set;
+ }
+ static void commit_sub_eq(NodeType *set)
+ {
+ precommit_node(set->unode.opr.op[1]);
+#ifdef VERBOSE
+ printf("sub %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "sub", INSTR_SUB, 2, set->line_number);
+ commit_node(set->unode.opr.op[0],0);
+ commit_node(set->unode.opr.op[1],1);
+ } /* }}} */
+
+ /* MUL_EQ */
+ static NodeType *new_mul_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
+ {
+ NodeType *set = new_op("mul_eq", OPR_MUL_EQ, 2);
+ set->unode.opr.op[0] = lvalue;
+ set->unode.opr.op[1] = expression;
+ return set;
+ }
+ static void commit_mul_eq(NodeType *set)
+ {
+ precommit_node(set->unode.opr.op[1]);
+#ifdef VERBOSE
+ printf("mul %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "mul", INSTR_MUL, 2, set->line_number);
+ commit_node(set->unode.opr.op[0],0);
+ commit_node(set->unode.opr.op[1],1);
+ } /* }}} */
+
+ /* DIV_EQ */
+ static NodeType *new_div_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
+ {
+ NodeType *set = new_op("div_eq", OPR_DIV_EQ, 2);
+ set->unode.opr.op[0] = lvalue;
+ set->unode.opr.op[1] = expression;
+ return set;
+ }
+ static void commit_div_eq(NodeType *set)
+ {
+ precommit_node(set->unode.opr.op[1]);
+#ifdef VERBOSE
+ printf("div %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "div", INSTR_DIV, 2, set->line_number);
+ commit_node(set->unode.opr.op[0],0);
+ commit_node(set->unode.opr.op[1],1);
+ } /* }}} */
+
+ /* commodity method for add, mult, ... */
+
+ static void precommit_expr(NodeType *expr, const char *type, int instr_id)
+ { /* {{{ */
+ NodeType *tmp, *tmpcpy;
+ int toAdd;
+
+ /* compute "left" and "right" */
+ switch (expr->unode.opr.nbOp) {
+ case 2:
+ precommit_node(expr->unode.opr.op[1]);
+ case 1:
+ precommit_node(expr->unode.opr.op[0]);
+ }
+
+ if (is_tmp_expr(expr->unode.opr.op[0])) {
+ tmp = expr->unode.opr.op[0];
+ toAdd = 1;
+ }
+ else if (is_commutative_expr(instr_id) && (expr->unode.opr.nbOp==2) && is_tmp_expr(expr->unode.opr.op[1])) {
+ tmp = expr->unode.opr.op[1];
+ toAdd = 0;
+ }
+ else {
+ char stmp[256];
+ /* declare a temporary variable to store the result */
+ if (expr->unode.opr.op[0]->type == CONST_INT_NODE) {
+ sprintf(stmp,"_i_tmp_%i",allocateTemp());
+ gsl_int_decl_global(stmp);
+ }
+ else if (expr->unode.opr.op[0]->type == CONST_FLOAT_NODE) {
+ sprintf(stmp,"_f_tmp%i",allocateTemp());
+ gsl_float_decl_global(stmp);
+ }
+ else if (expr->unode.opr.op[0]->type == CONST_PTR_NODE) {
+ sprintf(stmp,"_p_tmp%i",allocateTemp());
+ gsl_ptr_decl_global(stmp);
+ }
+ else {
+ int type = gsl_type_of_var(expr->unode.opr.op[0]->vnamespace, expr->unode.opr.op[0]->str);
+ if (type == INSTR_FLOAT) {
+ sprintf(stmp,"_f_tmp_%i",allocateTemp());
+ gsl_float_decl_global(stmp);
+ }
+ else if (type == INSTR_PTR) {
+ sprintf(stmp,"_p_tmp_%i",allocateTemp());
+ gsl_ptr_decl_global(stmp);
+ }
+ else if (type == INSTR_INT) {
+ sprintf(stmp,"_i_tmp_%i",allocateTemp());
+ gsl_int_decl_global(stmp);
+ }
+ else if (type == -1) {
+ g_assert_not_reached ();
+#if 0
+ fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
+ expr->line_number, expr->unode.opr.op[0]->str);
+ exit(1);
+#endif
+ }
+ else { /* type is a struct_id */
+ sprintf(stmp,"_s_tmp_%i",allocateTemp());
+ gsl_struct_decl_global_from_id(stmp,type);
+ }
+ }
+ tmp = new_var(stmp,expr->line_number);
+
+ /* set the tmp to the value of "op1" */
+ tmpcpy = nodeClone(tmp);
+ commit_node(new_set(tmp,expr->unode.opr.op[0]),0);
+ toAdd = 1;
+
+ tmp = tmpcpy;
+ }
+
+ /* add op2 to tmp */
+#ifdef VERBOSE
+ if (expr->unode.opr.nbOp == 2)
+ printf("%s %s %s\n", type, tmp->str, expr->unode.opr.op[toAdd]->str);
+ else
+ printf("%s %s\n", type, tmp->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr_id, expr->unode.opr.nbOp, expr->line_number);
+ tmpcpy = nodeClone(tmp);
+ commit_node(tmp,0);
+ if (expr->unode.opr.nbOp == 2) {
+ commit_node(expr->unode.opr.op[toAdd],1);
+ }
+
+ /* redefine the ADD node now as the computed variable */
+ nodeFreeInternals(expr);
+ *expr = *tmpcpy;
+ free(tmpcpy);
+ } /* }}} */
+
+ static NodeType *new_expr1(const char *name, int id, NodeType *expr1)
+ { /* {{{ */
+ NodeType *add = new_op(name, id, 1);
+ add->unode.opr.op[0] = expr1;
+ return add;
+ } /* }}} */
+
+ static NodeType *new_expr2(const char *name, int id, NodeType *expr1, NodeType *expr2)
+ { /* {{{ */
+ NodeType *add = new_op(name, id, 2);
+ add->unode.opr.op[0] = expr1;
+ add->unode.opr.op[1] = expr2;
+ return add;
+ } /* }}} */
+
+ /* ADD */
+ static NodeType *new_add(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("add", OPR_ADD, expr1, expr2);
+ }
+ static void precommit_add(NodeType *add) {
+ precommit_expr(add,"add",INSTR_ADD);
+ } /* }}} */
+
+ /* SUB */
+ static NodeType *new_sub(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("sub", OPR_SUB, expr1, expr2);
+ }
+ static void precommit_sub(NodeType *sub) {
+ precommit_expr(sub,"sub",INSTR_SUB);
+ } /* }}} */
+
+ /* NEG */
+ static NodeType *new_neg(NodeType *expr) { /* {{{ */
+ NodeType *zeroConst = NULL;
+ if (expr->type == CONST_INT_NODE)
+ zeroConst = new_constInt("0", currentGoomSL->num_lines);
+ else if (expr->type == CONST_FLOAT_NODE)
+ zeroConst = new_constFloat("0.0", currentGoomSL->num_lines);
+ else if (expr->type == CONST_PTR_NODE) {
+ g_assert_not_reached ();
+#if 0
+ fprintf(stderr, "ERROR: Line %d, Could not negate const pointer.\n",
+ currentGoomSL->num_lines);
+ exit(1);
+#endif
+ }
+ else {
+ int type = gsl_type_of_var(expr->vnamespace, expr->str);
+ if (type == INSTR_FLOAT)
+ zeroConst = new_constFloat("0.0", currentGoomSL->num_lines);
+ else if (type == INSTR_PTR) {
+ g_assert_not_reached ();
+#if 0
+ fprintf(stderr, "ERROR: Line %d, Could not negate pointer.\n",
+ currentGoomSL->num_lines);
+ exit(1);
+#endif
+ }
+ else if (type == INSTR_INT)
+ zeroConst = new_constInt("0", currentGoomSL->num_lines);
+ else if (type == -1) {
+ g_assert_not_reached ();
+#if 0
+ fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
+ expr->line_number, expr->unode.opr.op[0]->str);
+ exit(1);
+#endif
+ }
+ else { /* type is a struct_id */
+ g_assert_not_reached ();
+#if 0
+ fprintf(stderr, "ERROR: Line %d, Could not negate struct '%s'\n",
+ expr->line_number, expr->str);
+ exit(1);
+#endif
+ }
+ }
+ return new_expr2("sub", OPR_SUB, zeroConst, expr);
+ }
+ /* }}} */
+
+ /* MUL */
+ static NodeType *new_mul(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("mul", OPR_MUL, expr1, expr2);
+ }
+ static void precommit_mul(NodeType *mul) {
+ precommit_expr(mul,"mul",INSTR_MUL);
+ } /* }}} */
+
+ /* DIV */
+ static NodeType *new_div(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("div", OPR_DIV, expr1, expr2);
+ }
+ static void precommit_div(NodeType *mul) {
+ precommit_expr(mul,"div",INSTR_DIV);
+ } /* }}} */
+
+ /* CALL EXPRESSION */
+ static NodeType *new_call_expr(const char *name, NodeType *affect_list) { /* {{{ */
+ NodeType *call = new_call(name,affect_list);
+ NodeType *node = new_expr1(name, OPR_CALL_EXPR, call);
+ node->vnamespace = gsl_find_namespace(name);
+ if (node->vnamespace == NULL)
+ /* fprintf(stderr, "ERROR: Line %d, No return type for: '%s'\n", currentGoomSL->num_lines, name); */
+ return node;
+ }
+ static void precommit_call_expr(NodeType *call) {
+ char stmp[256];
+ NodeType *tmp,*tmpcpy;
+ int type = gsl_type_of_var(call->vnamespace, call->str);
+ if (type == INSTR_FLOAT) {
+ sprintf(stmp,"_f_tmp_%i",allocateTemp());
+ gsl_float_decl_global(stmp);
+ }
+ else if (type == INSTR_PTR) {
+ sprintf(stmp,"_p_tmp_%i",allocateTemp());
+ gsl_ptr_decl_global(stmp);
+ }
+ else if (type == INSTR_INT) {
+ sprintf(stmp,"_i_tmp_%i",allocateTemp());
+ gsl_int_decl_global(stmp);
+ }
+ else if (type == -1) {
+ g_assert_not_reached ();
+#if 0
+ fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
+ call->line_number, call->str);
+ exit(1);
+#endif
+ }
+ else { /* type is a struct_id */
+ sprintf(stmp,"_s_tmp_%i",allocateTemp());
+ gsl_struct_decl_global_from_id(stmp,type);
+ }
+ tmp = new_var(stmp,call->line_number);
+ commit_node(call->unode.opr.op[0],0);
+ tmpcpy = nodeClone(tmp);
+ commit_node(new_set(tmp,new_var(call->str,call->line_number)),0);
+
+ nodeFreeInternals(call);
+ *call = *tmpcpy;
+ free(tmpcpy);
+ } /* }}} */
+
+ static void commit_test2(NodeType *set,const char *type, int instr)
+ { /* {{{ */
+ NodeType *tmp;
+ char stmp[256];
+ precommit_node(set->unode.opr.op[0]);
+ precommit_node(set->unode.opr.op[1]);
+ tmp = set->unode.opr.op[0];
+
+ stmp[0] = 0;
+ if (set->unode.opr.op[0]->type == CONST_INT_NODE) {
+ sprintf(stmp,"_i_tmp_%i",allocateTemp());
+ gsl_int_decl_global(stmp);
+ }
+ else if (set->unode.opr.op[0]->type == CONST_FLOAT_NODE) {
+ sprintf(stmp,"_f_tmp%i",allocateTemp());
+ gsl_float_decl_global(stmp);
+ }
+ else if (set->unode.opr.op[0]->type == CONST_PTR_NODE) {
+ sprintf(stmp,"_p_tmp%i",allocateTemp());
+ gsl_ptr_decl_global(stmp);
+ }
+ if (stmp[0]) {
+ NodeType *tmpcpy;
+ tmp = new_var(stmp, set->line_number);
+ tmpcpy = nodeClone(tmp);
+ commit_node(new_set(tmp,set->unode.opr.op[0]),0);
+ tmp = tmpcpy;
+ }
+
+#ifdef VERBOSE
+ printf("%s %s %s\n", type, tmp->str, set->unode.opr.op[1]->str);
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr, 2, set->line_number);
+ commit_node(tmp,instr!=INSTR_SET);
+ commit_node(set->unode.opr.op[1],1);
+ } /* }}} */
+
+ /* NOT */
+ static NodeType *new_not(NodeType *expr1) { /* {{{ */
+ return new_expr1("not", OPR_NOT, expr1);
+ }
+ static void commit_not(NodeType *set)
+ {
+ commit_node(set->unode.opr.op[0],0);
+#ifdef VERBOSE
+ printf("not\n");
+#endif
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "not", INSTR_NOT, 1, set->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
+ } /* }}} */
+
+ /* EQU */
+ static NodeType *new_equ(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("isequal", OPR_EQU, expr1, expr2);
+ }
+ static void commit_equ(NodeType *mul) {
+ commit_test2(mul,"isequal",INSTR_ISEQUAL);
+ } /* }}} */
+
+ /* INF */
+ static NodeType *new_low(NodeType *expr1, NodeType *expr2) { /* {{{ */
+ return new_expr2("islower", OPR_LOW, expr1, expr2);
+ }
+ static void commit_low(NodeType *mul) {
+ commit_test2(mul,"islower",INSTR_ISLOWER);
+ } /* }}} */
+
+ /* WHILE */
+ static NodeType *new_while(NodeType *expression, NodeType *instr) { /* {{{ */
+ NodeType *node = new_op("while", OPR_WHILE, 2);
+ node->unode.opr.op[0] = expression;
+ node->unode.opr.op[1] = instr;
+ return node;
+ }
+
+ static void commit_while(NodeType *node)
+ {
+ int lbl = allocateLabel();
+ char start_while[1024], test_while[1024];
+ sprintf(start_while, "|start_while_%d|", lbl);
+ sprintf(test_while, "|test_while_%d|", lbl);
+
+ GSL_PUT_JUMP(test_while,node->line_number);
+ GSL_PUT_LABEL(start_while,node->line_number);
+
+ /* code */
+ commit_node(node->unode.opr.op[1],0);
+
+ GSL_PUT_LABEL(test_while,node->line_number);
+ commit_node(node->unode.opr.op[0],0);
+ GSL_PUT_JNZERO(start_while,node->line_number);
+ } /* }}} */
+
+ /* FOR EACH */
+ static NodeType *new_static_foreach(NodeType *var, NodeType *var_list, NodeType *instr) { /* {{{ */
+ NodeType *node = new_op("for", OPR_FOREACH, 3);
+ node->unode.opr.op[0] = var;
+ node->unode.opr.op[1] = var_list;
+ node->unode.opr.op[2] = instr;
+ node->line_number = currentGoomSL->num_lines;
+ return node;
+ }
+ static void commit_foreach(NodeType *node)
+ {
+ NodeType *cur = node->unode.opr.op[1];
+ char tmp_func[256], tmp_loop[256];
+ int lbl = allocateLabel();
+ sprintf(tmp_func, "|foreach_func_%d|", lbl);
+ sprintf(tmp_loop, "|foreach_loop_%d|", lbl);
+
+ GSL_PUT_JUMP(tmp_loop, node->line_number);
+ GSL_PUT_LABEL(tmp_func, node->line_number);
+
+ precommit_node(node->unode.opr.op[2]);
+ commit_node(node->unode.opr.op[2], 0);
+
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
+#ifdef VERBOSE
+ printf("ret\n");
+#endif
+
+ GSL_PUT_LABEL(tmp_loop, node->line_number);
+
+ while (cur != NULL)
+ {
+ NodeType *x, *var;
+
+ /* 1: x=var */
+ x = nodeClone(node->unode.opr.op[0]);
+ var = nodeClone(cur->unode.opr.op[0]);
+ commit_node(new_set(x, var),0);
+
+ /* 2: instr */
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, tmp_func, TYPE_LABEL);
+#ifdef VERBOSE
+ printf("call %s\n", tmp_func);
+#endif
+
+ /* 3: var=x */
+ x = nodeClone(node->unode.opr.op[0]);
+ var = cur->unode.opr.op[0];
+ commit_node(new_set(var, x),0);
+ cur = cur->unode.opr.op[1];
+ }
+ nodeFree(node->unode.opr.op[0]);
+ } /* }}} */
+
+ /* IF */
+ static NodeType *new_if(NodeType *expression, NodeType *instr) { /* {{{ */
+ NodeType *node = new_op("if", OPR_IF, 2);
+ node->unode.opr.op[0] = expression;
+ node->unode.opr.op[1] = instr;
+ return node;
+ }
+ static void commit_if(NodeType *node) {
+
+ char slab[1024];
+ sprintf(slab, "|eif%d|", allocateLabel());
+ commit_node(node->unode.opr.op[0],0);
+ GSL_PUT_JZERO(slab,node->line_number);
+ /* code */
+ commit_node(node->unode.opr.op[1],0);
+ GSL_PUT_LABEL(slab,node->line_number);
+ } /* }}} */
+
+ /* BLOCK */
+ static NodeType *new_block(NodeType *lastNode) { /* {{{ */
+ NodeType *blk = new_op("block", OPR_BLOCK, 2);
+ blk->unode.opr.op[0] = new_nop("start_of_block");
+ blk->unode.opr.op[1] = lastNode;
+ return blk;
+ }
+ static void commit_block(NodeType *node) {
+ commit_node(node->unode.opr.op[0]->unode.opr.next,0);
+ } /* }}} */
+
+ /* FUNCTION INTRO */
+ static NodeType *new_function_intro(const char *name) { /* {{{ */
+ char stmp[256];
+ if (strlen(name) < 200) {
+ sprintf(stmp, "|__func_%s|", name);
+ }
+ return new_op(stmp, OPR_FUNC_INTRO, 0);
+ }
+ static void commit_function_intro(NodeType *node) {
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL);
+#ifdef VERBOSE
+ printf("label %s\n", node->str);
+#endif
+ } /* }}} */
+
+ /* FUNCTION OUTRO */
+ static NodeType *new_function_outro() { /* {{{ */
+ return new_op("ret", OPR_FUNC_OUTRO, 0);
+ }
+ static void commit_function_outro(NodeType *node) {
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
+ releaseAllTemps();
+#ifdef VERBOSE
+ printf("ret\n");
+#endif
+ } /* }}} */
+
+ /* AFFECTATION LIST */
+ static NodeType *new_affec_list(NodeType *set, NodeType *next) /* {{{ */
+ {
+ NodeType *node = new_op("affect_list", OPR_AFFECT_LIST, 2);
+ node->unode.opr.op[0] = set;
+ node->unode.opr.op[1] = next;
+ return node;
+ }
+ static NodeType *new_affect_list_after(NodeType *affect_list)
+ {
+ NodeType *ret = NULL;
+ NodeType *cur = affect_list;
+ while(cur != NULL) {
+ NodeType *set = cur->unode.opr.op[0];
+ NodeType *next = cur->unode.opr.op[1];
+ NodeType *lvalue = set->unode.opr.op[0];
+ NodeType *expression = set->unode.opr.op[1];
+ if ((lvalue->str[0] == '&') && (expression->type == VAR_NODE)) {
+ NodeType *nset = new_set(nodeClone(expression), nodeClone(lvalue));
+ ret = new_affec_list(nset, ret);
+ }
+ cur = next;
+ }
+ return ret;
+ }
+ static void commit_affect_list(NodeType *node)
+ {
+ NodeType *cur = node;
+ while(cur != NULL) {
+ NodeType *set = cur->unode.opr.op[0];
+ precommit_node(set->unode.opr.op[0]);
+ precommit_node(set->unode.opr.op[1]);
+ cur = cur->unode.opr.op[1];
+ }
+ cur = node;
+ while(cur != NULL) {
+ NodeType *set = cur->unode.opr.op[0];
+ commit_node(set,0);
+ cur = cur->unode.opr.op[1];
+ }
+ } /* }}} */
+
+ /* VAR LIST */
+ static NodeType *new_var_list(NodeType *var, NodeType *next) /* {{{ */
+ {
+ NodeType *node = new_op("var_list", OPR_VAR_LIST, 2);
+ node->unode.opr.op[0] = var;
+ node->unode.opr.op[1] = next;
+ return node;
+ }
+ static void commit_var_list(NodeType *node)
+ {
+ } /* }}} */
+
+ /* FUNCTION CALL */
+ static NodeType *new_call(const char *name, NodeType *affect_list) { /* {{{ */
+ HashValue *fval;
+ fval = goom_hash_get(currentGoomSL->functions, name);
+ if (!fval) {
+ gsl_declare_task(name);
+ fval = goom_hash_get(currentGoomSL->functions, name);
+ }
+ if (!fval) {
+ g_assert_not_reached ();
+#if 0
+ fprintf(stderr, "ERROR: Line %d, Could not find function %s\n", currentGoomSL->num_lines, name);
+ exit(1);
+ return NULL;
+#endif
+ }
+ else {
+ ExternalFunctionStruct *gef = (ExternalFunctionStruct*)fval->ptr;
+ if (gef->is_extern) {
+ NodeType *node = new_op(name, OPR_EXT_CALL, 1);
+ node->unode.opr.op[0] = affect_list;
+ return node;
+ }
+ else {
+ NodeType *node;
+ char stmp[256];
+ if (strlen(name) < 200) {
+ sprintf(stmp, "|__func_%s|", name);
+ }
+ node = new_op(stmp, OPR_CALL, 1);
+ node->unode.opr.op[0] = affect_list;
+ return node;
+ }
+ }
+ }
+ static void commit_ext_call(NodeType *node) {
+ NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]);
+ commit_node(node->unode.opr.op[0],0);
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "extcall", INSTR_EXT_CALL, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR);
+#ifdef VERBOSE
+ printf("extcall %s\n", node->str);
+#endif
+ commit_node(alafter,0);
+ }
+ static void commit_call(NodeType *node) {
+ NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]);
+ commit_node(node->unode.opr.op[0],0);
+ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number);
+ gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL);
+#ifdef VERBOSE
+ printf("call %s\n", node->str);
+#endif
+ commit_node(alafter,0);
+ } /* }}} */
+
+ /** **/
+
+ static NodeType *rootNode = 0; /* TODO: reinitialiser a chaque compilation. */
+ static NodeType *lastNode = 0;
+ static NodeType *gsl_append(NodeType *curNode) {
+ if (curNode == 0) return 0; /* {{{ */
+ if (lastNode)
+ lastNode->unode.opr.next = curNode;
+ lastNode = curNode;
+ while(lastNode->unode.opr.next) lastNode = lastNode->unode.opr.next;
+ if (rootNode == 0)
+ rootNode = curNode;
+ return curNode;
+ } /* }}} */
+
+#if 1
+ int allocateTemp() {
+ return allocateLabel();
+ }
+ void releaseAllTemps() {}
+ void releaseTemp(int n) {}
+#else
+ static int nbTemp = 0;
+ static int *tempArray = 0;
+ static int tempArraySize = 0;
+ int allocateTemp() { /* TODO: allocateITemp, allocateFTemp */
+ int i = 0; /* {{{ */
+ if (tempArray == 0) {
+ tempArraySize = 256;
+ tempArray = (int*)malloc(tempArraySize * sizeof(int));
+ }
+ while (1) {
+ int j;
+ for (j=0;j<nbTemp;++j) {
+ if (tempArray[j] == i) break;
+ }
+ if (j == nbTemp) {
+ if (nbTemp == tempArraySize) {
+ tempArraySize *= 2;
+ tempArray = (int*)realloc(tempArray,tempArraySize * sizeof(int));
+ }
+ tempArray[nbTemp++] = i;
+ return i;
+ }
+ i++;
+ }
+ } /* }}} */
+ void releaseAllTemps() {
+ nbTemp = 0; /* {{{ */
+ } /* }}} */
+ void releaseTemp(int n) {
+ int j; /* {{{ */
+ for (j=0;j<nbTemp;++j) {
+ if (tempArray[j] == n) {
+ tempArray[j] = tempArray[--nbTemp];
+ break;
+ }
+ }
+ } /* }}} */
+#endif
+
+ static int lastLabel = 0;
+ int allocateLabel() {
+ return ++lastLabel; /* {{{ */
+ } /* }}} */
+
+ void gsl_commit_compilation()
+ { /* {{{ */
+ commit_node(rootNode,0);
+ rootNode = 0;
+ lastNode = 0;
+ } /* }}} */
+
+ void precommit_node(NodeType *node)
+ { /* {{{ */
+ /* do here stuff for expression.. for exemple */
+ if (node->type == OPR_NODE)
+ switch(node->unode.opr.type) {
+ case OPR_ADD: precommit_add(node); break;
+ case OPR_SUB: precommit_sub(node); break;
+ case OPR_MUL: precommit_mul(node); break;
+ case OPR_DIV: precommit_div(node); break;
+ case OPR_CALL_EXPR: precommit_call_expr(node); break;
+ }
+ } /* }}} */
+
+ void commit_node(NodeType *node, int releaseIfTmp)
+ { /* {{{ */
+ if (node == 0) return;
+
+ switch(node->type) {
+ case OPR_NODE:
+ switch(node->unode.opr.type) {
+ case OPR_SET: commit_set(node); break;
+ case OPR_PLUS_EQ: commit_plus_eq(node); break;
+ case OPR_SUB_EQ: commit_sub_eq(node); break;
+ case OPR_MUL_EQ: commit_mul_eq(node); break;
+ case OPR_DIV_EQ: commit_div_eq(node); break;
+ case OPR_IF: commit_if(node); break;
+ case OPR_WHILE: commit_while(node); break;
+ case OPR_BLOCK: commit_block(node); break;
+ case OPR_FUNC_INTRO: commit_function_intro(node); break;
+ case OPR_FUNC_OUTRO: commit_function_outro(node); break;
+ case OPR_CALL: commit_call(node); break;
+ case OPR_EXT_CALL: commit_ext_call(node); break;
+ case OPR_EQU: commit_equ(node); break;
+ case OPR_LOW: commit_low(node); break;
+ case OPR_NOT: commit_not(node); break;
+ case OPR_AFFECT_LIST: commit_affect_list(node); break;
+ case OPR_FOREACH: commit_foreach(node); break;
+ case OPR_VAR_LIST: commit_var_list(node); break;
+#ifdef VERBOSE
+ case EMPTY_NODE: printf("NOP\n"); break;
+#endif
+ }
+
+ commit_node(node->unode.opr.next,0); /* recursive for the moment, maybe better to do something iterative? */
+ break;
+
+ case VAR_NODE: gsl_instr_set_namespace(currentGoomSL->instr, node->vnamespace);
+ gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR); break;
+ case CONST_INT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_INTEGER); break;
+ case CONST_FLOAT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_FLOAT); break;
+ case CONST_PTR_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_PTR); break;
+ }
+ if (releaseIfTmp && is_tmp_expr(node))
+ releaseTemp(get_tmp_id(node));
+
+ nodeFree(node);
+ } /* }}} */
+
+ NodeType *nodeNew(const char *str, int type, int line_number) {
+ NodeType *node = (NodeType*)malloc(sizeof(NodeType)); /* {{{ */
+ node->type = type;
+ node->str = (char*)malloc(strlen(str)+1);
+ node->vnamespace = NULL;
+ node->line_number = line_number;
+ strcpy(node->str, str);
+ return node;
+ } /* }}} */
+ static NodeType *nodeClone(NodeType *node) {
+ NodeType *ret = nodeNew(node->str, node->type, node->line_number); /* {{{ */
+ ret->vnamespace = node->vnamespace;
+ ret->unode = node->unode;
+ return ret;
+ } /* }}} */
+
+ void nodeFreeInternals(NodeType *node) {
+ free(node->str); /* {{{ */
+ } /* }}} */
+
+ void nodeFree(NodeType *node) {
+ nodeFreeInternals(node); /* {{{ */
+ free(node);
+ } /* }}} */
+
+ NodeType *new_constInt(const char *str, int line_number) {
+ NodeType *node = nodeNew(str, CONST_INT_NODE, line_number); /* {{{ */
+ node->unode.constInt.val = atoi(str);
+ return node;
+ } /* }}} */
+
+ NodeType *new_constPtr(const char *str, int line_number) {
+ NodeType *node = nodeNew(str, CONST_PTR_NODE, line_number); /* {{{ */
+ node->unode.constPtr.id = strtol(str,NULL,0);
+ return node;
+ } /* }}} */
+
+ NodeType *new_constFloat(const char *str, int line_number) {
+ NodeType *node = nodeNew(str, CONST_FLOAT_NODE, line_number); /* {{{ */
+ node->unode.constFloat.val = atof(str);
+ return node;
+ } /* }}} */
+
+ NodeType *new_var(const char *str, int line_number) {
+ NodeType *node = nodeNew(str, VAR_NODE, line_number); /* {{{ */
+ node->vnamespace = gsl_find_namespace(str);
+ if (node->vnamespace == 0) {
+ g_assert_not_reached ();
+#if 0
+ fprintf(stderr, "ERROR: Line %d, Variable not found: '%s'\n", line_number, str);
+ exit(1);
+#endif
+ }
+ return node;
+ } /* }}} */
+
+ NodeType *new_nop(const char *str) {
+ NodeType *node = new_op(str, EMPTY_NODE, 0); /* {{{ */
+ return node;
+ } /* }}} */
+
+ NodeType *new_op(const char *str, int type, int nbOp) {
+ int i; /* {{{ */
+ NodeType *node = nodeNew(str, OPR_NODE, currentGoomSL->num_lines);
+ node->unode.opr.next = 0;
+ node->unode.opr.type = type;
+ node->unode.opr.nbOp = nbOp;
+ for (i=0;i<nbOp;++i) node->unode.opr.op[i] = 0;
+ return node;
+ } /* }}} */
+
+
+ void gsl_declare_global_variable(int type, char *name) {
+ switch(type){
+ case -1: break;
+ case FLOAT_TK:gsl_float_decl_global(name);break;
+ case INT_TK: gsl_int_decl_global(name);break;
+ case PTR_TK: gsl_ptr_decl_global(name);break;
+ default:
+ {
+ int id = type - 1000;
+ gsl_struct_decl_global_from_id(name,id);
+ }
+ }
+ }
+
+%}
+
+%union {
+ int intValue;
+ float floatValue;
+ char charValue;
+ char strValue[2048];
+ NodeType *nPtr;
+ GoomHash *namespace;
+ GSL_Struct *gsl_struct;
+ GSL_StructField *gsl_struct_field;
+ };
+
+%token <strValue> LTYPE_INTEGER
+%token <strValue> LTYPE_FLOAT
+%token <strValue> LTYPE_VAR
+%token <strValue> LTYPE_PTR
+
+%token PTR_TK INT_TK FLOAT_TK DECLARE EXTERNAL WHILE DO NOT PLUS_EQ SUB_EQ DIV_EQ MUL_EQ SUP_EQ LOW_EQ NOT_EQ STRUCT FOR IN
+
+%type <intValue> return_type
+%type <nPtr> expression constValue instruction test func_call func_call_expression
+%type <nPtr> start_block affectation_list affectation_in_list affectation declaration
+%type <nPtr> var_list_content var_list
+%type <strValue> task_name ext_task_name
+%type <namespace> leave_namespace
+%type <gsl_struct> struct_members
+%type <gsl_struct_field> struct_member
+%left '\n'
+%left PLUS_EQ SUB_EQ MUL_EQ DIV_EQ
+%left NOT
+%left '=' '<' '>'
+%left '+' '-'
+%left '/' '*'
+
+%%
+
+/* -------------- Global architechture of a GSL program ------------*/
+
+gsl: gsl_code function_outro gsl_def_functions ;
+
+gsl_code: gsl_code instruction { gsl_append($2); }
+ | gsl_code EXTERNAL '<' ext_task_name '>' return_type '\n' leave_namespace { gsl_declare_global_variable($6,$4); }
+ | gsl_code EXTERNAL '<' ext_task_name ':' arglist '>' return_type '\n' leave_namespace { gsl_declare_global_variable($8,$4); }
+ | gsl_code DECLARE '<' task_name '>' return_type '\n' leave_namespace { gsl_declare_global_variable($6,$4); }
+ | gsl_code DECLARE '<' task_name ':' arglist '>' return_type '\n' leave_namespace { gsl_declare_global_variable($8,$4); }
+ | gsl_code struct_declaration
+ | gsl_code '\n'
+ |
+ ;
+
+/* ------------- Declaration of a structure ------------ */
+
+struct_declaration: STRUCT '<' LTYPE_VAR ':' struct_members '>' '\n' { gsl_add_struct($3, $5); }
+ ;
+
+struct_members: opt_nl struct_member { $$ = gsl_new_struct($2); }
+ | struct_members ',' opt_nl struct_member { $$ = $1; gsl_add_struct_field($1, $4); }
+ ;
+
+struct_member: INT_TK LTYPE_VAR { $$ = gsl_new_struct_field($2, INSTR_INT); }
+ | FLOAT_TK LTYPE_VAR { $$ = gsl_new_struct_field($2, INSTR_FLOAT); }
+ | PTR_TK LTYPE_VAR { $$ = gsl_new_struct_field($2, INSTR_PTR); }
+ | LTYPE_VAR LTYPE_VAR { $$ = gsl_new_struct_field_struct($2, $1); }
+ ;
+
+/* ------------- Fonction declarations -------------- */
+
+ext_task_name: LTYPE_VAR { gsl_declare_external_task($1); gsl_enternamespace($1); strcpy($$,$1); }
+ ;
+task_name: LTYPE_VAR { gsl_declare_task($1); gsl_enternamespace($1); strcpy($$,$1); strcpy($$,$1); }
+ ;
+
+return_type: { $$=-1; }
+ | ':' INT_TK { $$=INT_TK; }
+ | ':' FLOAT_TK { $$=FLOAT_TK; }
+ | ':' PTR_TK { $$=PTR_TK; }
+ | ':' LTYPE_VAR { $$= 1000 + gsl_get_struct_id($2); }
+ ;
+
+arglist: empty_declaration
+ | empty_declaration ',' arglist
+ ;
+
+/* ------------- Fonction definition -------------- */
+
+gsl_def_functions: gsl_def_functions function
+ |
+ ;
+
+function: function_intro gsl_code function_outro { gsl_leavenamespace(); }
+
+function_intro: '<' task_name '>' return_type '\n' { gsl_append(new_function_intro($2));
+ gsl_declare_global_variable($4,$2); }
+ | '<' task_name ':' arglist '>' return_type '\n' { gsl_append(new_function_intro($2));
+ gsl_declare_global_variable($6,$2); }
+ ;
+function_outro: { gsl_append(new_function_outro()); } ;
+
+leave_namespace: { $$ = gsl_leavenamespace(); };
+
+/* ------------ Variable declaration ---------------- */
+
+declaration: FLOAT_TK LTYPE_VAR '=' expression { gsl_float_decl_local($2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
+ | INT_TK LTYPE_VAR '=' expression { gsl_int_decl_local($2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
+ | PTR_TK LTYPE_VAR '=' expression { gsl_ptr_decl_local($2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
+ | LTYPE_VAR LTYPE_VAR '=' expression { gsl_struct_decl_local($1,$2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
+ | empty_declaration { $$ = 0; }
+ ;
+
+empty_declaration: FLOAT_TK LTYPE_VAR { gsl_float_decl_local($2); }
+ | INT_TK LTYPE_VAR { gsl_int_decl_local($2); }
+ | PTR_TK LTYPE_VAR { gsl_ptr_decl_local($2); }
+ | LTYPE_VAR LTYPE_VAR { gsl_struct_decl_local($1,$2); }
+ ;
+
+/* -------------- Instructions and Expressions ------------------ */
+
+instruction: affectation '\n' { $$ = $1; }
+ | declaration '\n' { $$ = $1; }
+ | '(' test ')' '?' opt_nl instruction { $$ = new_if($2,$6); }
+ | WHILE test opt_nl DO opt_nl instruction { $$ = new_while($2,$6); }
+ | '{' '\n' start_block gsl_code '}' '\n' { lastNode = $3->unode.opr.op[1]; $$=$3; }
+ | func_call { $$ = $1; }
+ | LTYPE_VAR PLUS_EQ expression { $$ = new_plus_eq(new_var($1,currentGoomSL->num_lines),$3); }
+ | LTYPE_VAR SUB_EQ expression { $$ = new_sub_eq(new_var($1,currentGoomSL->num_lines),$3); }
+ | LTYPE_VAR MUL_EQ expression { $$ = new_mul_eq(new_var($1,currentGoomSL->num_lines),$3); }
+ | LTYPE_VAR DIV_EQ expression { $$ = new_div_eq(new_var($1,currentGoomSL->num_lines),$3); }
+ | FOR LTYPE_VAR IN var_list DO instruction { $$ = new_static_foreach(new_var($2, currentGoomSL->num_lines), $4, $6); }
+ ;
+
+var_list: '(' var_list_content ')' { $$ = $2; }
+ ;
+var_list_content: LTYPE_VAR { $$ = new_var_list(new_var($1,currentGoomSL->num_lines), NULL); }
+ | LTYPE_VAR var_list_content { $$ = new_var_list(new_var($1,currentGoomSL->num_lines), $2); }
+ ;
+
+affectation: LTYPE_VAR '=' expression { $$ = new_set(new_var($1,currentGoomSL->num_lines),$3); } ;
+
+start_block: { $$ = new_block(lastNode); lastNode = $$->unode.opr.op[0]; }
+ ;
+
+expression: LTYPE_VAR { $$ = new_var($1,currentGoomSL->num_lines); }
+ | constValue { $$ = $1; }
+ | expression '*' expression { $$ = new_mul($1,$3); }
+ | expression '/' expression { $$ = new_div($1,$3); }
+ | expression '+' expression { $$ = new_add($1,$3); }
+ | expression '-' expression { $$ = new_sub($1,$3); }
+ | '-' expression { $$ = new_neg($2); }
+ | '(' expression ')' { $$ = $2; }
+ | func_call_expression { $$ = $1; }
+ ;
+
+test: expression '=' expression { $$ = new_equ($1,$3); }
+ | expression '<' expression { $$ = new_low($1,$3); }
+ | expression '>' expression { $$ = new_low($3,$1); }
+ | expression SUP_EQ expression { $$ = new_not(new_low($1,$3)); }
+ | expression LOW_EQ expression { $$ = new_not(new_low($3,$1)); }
+ | expression NOT_EQ expression { $$ = new_not(new_equ($1,$3)); }
+ | NOT test { $$ = new_not($2); }
+ ;
+
+constValue: LTYPE_FLOAT { $$ = new_constFloat($1,currentGoomSL->num_lines); }
+ | LTYPE_INTEGER { $$ = new_constInt($1,currentGoomSL->num_lines); }
+ | LTYPE_PTR { $$ = new_constPtr($1,currentGoomSL->num_lines); }
+ ;
+
+/* ---------------- Function Calls ------------------ */
+
+func_call: task_name '\n' leave_namespace { $$ = new_call($1,NULL); }
+ | task_name ':' affectation_list '\n' leave_namespace { $$ = new_call($1,$3); }
+ | '[' task_name ']' '\n' leave_namespace { $$ = new_call($2,NULL); }
+ | '[' task_name ':' affectation_list ']' '\n' leave_namespace { $$ = new_call($2,$4); }
+ ;
+
+func_call_expression:
+ '[' task_name leave_namespace ']' { $$ = new_call_expr($2,NULL); }
+ | '[' task_name ':' affectation_list ']' leave_namespace { $$ = new_call_expr($2,$4); }
+ ;
+
+affectation_list: affectation_in_list affectation_list { $$ = new_affec_list($1,$2); }
+ | affectation_in_list { $$ = new_affec_list($1,NULL); }
+
+affectation_in_list: LTYPE_VAR '=' leave_namespace expression {
+ gsl_reenternamespace($3);
+ $$ = new_set(new_var($1,currentGoomSL->num_lines),$4);
+ }
+ | ':' leave_namespace expression {
+ gsl_reenternamespace($2);
+ $$ = new_set(new_var("&this", currentGoomSL->num_lines),$3);
+ }
+ ;
+
+
+/* ------------ Misc ---------- */
+
+opt_nl: '\n' | ;
+
+
+%%
+
+
+void yyerror(char *str)
+{ /* {{{ */
+ g_assert_not_reached ();
+#if 0
+ fprintf(stderr, "ERROR: Line %d, %s\n", currentGoomSL->num_lines, str);
+ currentGoomSL->compilationOK = 0;
+ exit(1);
+#endif
+} /* }}} */
+
diff --git a/subprojects/gst-plugins-good/gst/goom/graphic.c b/subprojects/gst-plugins-good/gst/goom/graphic.c
new file mode 100644
index 0000000000..9f3044829d
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/graphic.c
@@ -0,0 +1,28 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "goom_graphic.h"
+
+const Color BLACK = { 0, 0, 0 };
+const Color WHITE = { 0xff, 0xff, 0xff };
+const Color RED = { 0xff, 0x05, 0x05 };
+const Color GREEN = { 0x05, 0xff, 0x05 };
+const Color BLUE = { 0x05, 0x05, 0xff };
+const Color YELLOW = { 0xff, 0xff, 0x33 };
+const Color ORANGE = { 0xff, 0xcc, 0x05 };
+const Color VIOLET = { 0x55, 0x05, 0xff };
diff --git a/subprojects/gst-plugins-good/gst/goom/gstgoom.c b/subprojects/gst-plugins-good/gst/goom/gstgoom.c
new file mode 100644
index 0000000000..e40bfa7a97
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/gstgoom.c
@@ -0,0 +1,218 @@
+/* gstgoom.c: implementation of goom drawing element
+ * Copyright (C) <2001> Richard Boulton <richard@tartarus.org>
+ * (C) <2006> Wim Taymans <wim at fluendo dot com>
+ * (C) <2011> Wim Taymans <wim.taymans at gmail dot com>
+ * (C) <2015> Luis de Bethencourt <luis@debethencourt.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:element-goom
+ * @title: goom
+ * @see_also: synaesthesia
+ *
+ * Goom is an audio visualisation element. It creates warping structures
+ * based on the incoming audio signal.
+ *
+ * ## Example launch line
+ * |[
+ * gst-launch-1.0 -v audiotestsrc ! goom ! videoconvert ! xvimagesink
+ * ]|
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include "gstgoom.h"
+#include "goom.h"
+
+#if HAVE_ORC
+#include <orc/orc.h>
+#endif
+
+GST_DEBUG_CATEGORY (goom_debug);
+#define GST_CAT_DEFAULT goom_debug
+
+#define DEFAULT_WIDTH 320
+#define DEFAULT_HEIGHT 240
+
+/* signals and args */
+enum
+{
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum
+{
+ ARG_0
+ /* FILL ME */
+};
+
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+#define RGB_ORDER "xRGB"
+#else
+#define RGB_ORDER "BGRx"
+#endif
+
+static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (RGB_ORDER))
+ );
+
+static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", /* the name of the pads */
+ GST_PAD_SINK, /* type of the pad */
+ GST_PAD_ALWAYS, /* ALWAYS/SOMETIMES */
+ GST_STATIC_CAPS ("audio/x-raw, "
+ "format = (string) " GST_AUDIO_NE (S16) ", "
+ "rate = (int) [ 8000, 96000 ], "
+ "channels = (int) 1, "
+ "layout = (string) interleaved; "
+ "audio/x-raw, "
+ "format = (string) " GST_AUDIO_NE (S16) ", "
+ "rate = (int) [ 8000, 96000 ], "
+ "channels = (int) 2, "
+ "channel-mask = (bitmask) 0x3, " "layout = (string) interleaved")
+ );
+
+
+static void gst_goom_finalize (GObject * object);
+
+static gboolean gst_goom_setup (GstAudioVisualizer * base);
+static gboolean gst_goom_render (GstAudioVisualizer * base, GstBuffer * audio,
+ GstVideoFrame * video);
+static gboolean goom_element_init (GstPlugin * plugin);
+
+G_DEFINE_TYPE (GstGoom, gst_goom, GST_TYPE_AUDIO_VISUALIZER);
+GST_ELEMENT_REGISTER_DEFINE_CUSTOM (goom, goom_element_init);
+
+static void
+gst_goom_class_init (GstGoomClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+ GstAudioVisualizerClass *visualizer_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+ visualizer_class = (GstAudioVisualizerClass *) klass;
+
+ gobject_class->finalize = gst_goom_finalize;
+
+ gst_element_class_set_static_metadata (gstelement_class, "GOOM: what a GOOM!",
+ "Visualization",
+ "Takes frames of data and outputs video frames using the GOOM filter",
+ "Wim Taymans <wim@fluendo.com>");
+ gst_element_class_add_static_pad_template (gstelement_class, &sink_template);
+ gst_element_class_add_static_pad_template (gstelement_class, &src_template);
+
+ visualizer_class->setup = GST_DEBUG_FUNCPTR (gst_goom_setup);
+ visualizer_class->render = GST_DEBUG_FUNCPTR (gst_goom_render);
+}
+
+static void
+gst_goom_init (GstGoom * goom)
+{
+ goom->width = DEFAULT_WIDTH;
+ goom->height = DEFAULT_HEIGHT;
+ goom->channels = 0;
+
+ goom->plugin = goom_init (goom->width, goom->height);
+}
+
+static void
+gst_goom_finalize (GObject * object)
+{
+ GstGoom *goom = GST_GOOM (object);
+
+ goom_close (goom->plugin);
+ goom->plugin = NULL;
+
+ G_OBJECT_CLASS (gst_goom_parent_class)->finalize (object);
+}
+
+static gboolean
+gst_goom_setup (GstAudioVisualizer * base)
+{
+ GstGoom *goom = GST_GOOM (base);
+
+ goom->width = GST_VIDEO_INFO_WIDTH (&base->vinfo);
+ goom->height = GST_VIDEO_INFO_HEIGHT (&base->vinfo);
+ goom_set_resolution (goom->plugin, goom->width, goom->height);
+
+ return TRUE;
+}
+
+static gboolean
+gst_goom_render (GstAudioVisualizer * base, GstBuffer * audio,
+ GstVideoFrame * video)
+{
+ GstGoom *goom = GST_GOOM (base);
+ GstMapInfo amap;
+ gint16 datain[2][GOOM_SAMPLES];
+ gint16 *adata;
+ gint i;
+
+ /* get next GOOM_SAMPLES, we have at least this amount of samples */
+ gst_buffer_map (audio, &amap, GST_MAP_READ);
+ adata = (gint16 *) amap.data;
+
+ if (goom->channels == 2) {
+ for (i = 0; i < GOOM_SAMPLES; i++) {
+ datain[0][i] = *adata++;
+ datain[1][i] = *adata++;
+ }
+ } else {
+ for (i = 0; i < GOOM_SAMPLES; i++) {
+ datain[0][i] = *adata;
+ datain[1][i] = *adata++;
+ }
+ }
+
+ video->data[0] = goom_update (goom->plugin, datain, 0, 0);
+ gst_buffer_unmap (audio, &amap);
+
+ return TRUE;
+}
+
+static gboolean
+goom_element_init (GstPlugin * plugin)
+{
+ GST_DEBUG_CATEGORY_INIT (goom_debug, "goom", 0, "goom visualisation element");
+
+#if HAVE_ORC
+ orc_init ();
+#endif
+
+ return gst_element_register (plugin, "goom", GST_RANK_NONE, GST_TYPE_GOOM);
+}
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ return GST_ELEMENT_REGISTER (goom, plugin);
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ goom,
+ "GOOM visualization filter",
+ plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/subprojects/gst-plugins-good/gst/goom/gstgoom.h b/subprojects/gst-plugins-good/gst/goom/gstgoom.h
new file mode 100644
index 0000000000..d19246096b
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/gstgoom.h
@@ -0,0 +1,68 @@
+/* gstgoom.c: implementation of goom drawing element
+ * Copyright (C) <2001> Richard Boulton <richard@tartarus.org>
+ * Copyright (C) <2015> Luis de Bethencourt <luis@debethencourt.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_GOOM_H__
+#define __GST_GOOM_H__
+
+#include <gst/pbutils/gstaudiovisualizer.h>
+
+#include "goom.h"
+
+G_BEGIN_DECLS
+
+#define GOOM_SAMPLES 512
+
+#define GST_TYPE_GOOM (gst_goom_get_type())
+#define GST_GOOM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GOOM,GstGoom))
+#define GST_GOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GOOM,GstGoomClass))
+#define GST_IS_GOOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GOOM))
+#define GST_IS_GOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GOOM))
+
+typedef struct _GstGoom GstGoom;
+typedef struct _GstGoomClass GstGoomClass;
+
+struct _GstGoom
+{
+ GstAudioVisualizer parent;
+
+ /* input tracking */
+ gint channels;
+
+ /* video state */
+ gint width;
+ gint height;
+
+ /* goom stuff */
+ PluginInfo *plugin;
+};
+
+struct _GstGoomClass
+{
+ GstAudioVisualizerClass parent_class;
+};
+
+GType gst_goom_get_type (void);
+
+GST_ELEMENT_REGISTER_DECLARE (goom);
+
+G_END_DECLS
+
+#endif /* __GST_GOOM_H__ */
+
diff --git a/subprojects/gst-plugins-good/gst/goom/ifs.c b/subprojects/gst-plugins-good/gst/goom/ifs.c
new file mode 100644
index 0000000000..5af721fb6e
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/ifs.c
@@ -0,0 +1,774 @@
+/*-
+ * Copyright (c) 1997 by Massimino Pascal <Pascal.Massimon@ens.fr>
+ *
+ * ifs.c: modified iterated functions system for goom.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind. The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof. In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * If this mode is weird and you have an old MetroX server, it is buggy.
+ * There is a free SuSE-enhanced MetroX X server that is fine.
+ *
+ * When shown ifs, Diana Rose (4 years old) said, "It looks like dancing."
+ *
+ * Revision History:
+ * 13-Dec-2003: Added some goom specific stuffs (to make ifs a VisualFX).
+ * 11-Apr-2002: jeko@ios-software.com: Make ifs.c system-indendant. (ifs.h added)
+ * 01-Nov-2000: Allocation checks
+ * 10-May-1997: jwz@jwz.org: turned into a standalone program.
+ * Made it render into an offscreen bitmap and then copy
+ * that onto the screen, to reduce flicker.
+ */
+
+/* #ifdef STANDALONE */
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "goom_config.h"
+
+#ifdef HAVE_MMX
+#include "mmx.h"
+#endif
+
+#include "goom_graphic.h"
+#include "ifs.h"
+#include "goom_tools.h"
+
+typedef struct _ifsPoint
+{
+ gint32 x, y;
+}
+IFSPoint;
+
+
+#define MODE_ifs
+
+#define PROGCLASS "IFS"
+
+#define HACK_INIT init_ifs
+#define HACK_DRAW draw_ifs
+
+#define ifs_opts xlockmore_opts
+
+#define DEFAULTS "*delay: 20000 \n" \
+"*ncolors: 100 \n"
+
+#define SMOOTH_COLORS
+
+#define LRAND() ((long) (goom_random(goomInfo->gRandom) & 0x7fffffff))
+#define NRAND(n) ((int) (LRAND() % (n)))
+
+#if RAND_MAX < 0x10000
+#define MAXRAND (((float)(RAND_MAX<16)+((float)RAND_MAX)+1.0f)/127.0f)
+#else
+#define MAXRAND (2147483648.0/127.0) /* unsigned 1<<31 / 127.0 (cf goom_tools) as a float */
+#endif
+
+/*****************************************************/
+
+typedef float DBL;
+typedef int F_PT;
+
+/* typedef float F_PT; */
+
+/*****************************************************/
+
+#define FIX 12
+#define UNIT ( 1<<FIX )
+#define MAX_SIMI 6
+
+#define MAX_DEPTH_2 10
+#define MAX_DEPTH_3 6
+#define MAX_DEPTH_4 4
+#define MAX_DEPTH_5 2
+
+/* PREVIOUS VALUE
+#define MAX_SIMI 6
+
+ * settings for a PC 120Mhz... *
+#define MAX_DEPTH_2 10
+#define MAX_DEPTH_3 6
+#define MAX_DEPTH_4 4
+#define MAX_DEPTH_5 3
+*/
+
+#define DBL_To_F_PT(x) (F_PT)( (DBL)(UNIT)*(x) )
+
+typedef struct Similitude_Struct SIMI;
+typedef struct Fractal_Struct FRACTAL;
+
+struct Similitude_Struct
+{
+
+ DBL c_x, c_y;
+ DBL r, r2, A, A2;
+ F_PT Ct, St, Ct2, St2;
+ F_PT Cx, Cy;
+ F_PT R, R2;
+};
+
+
+struct Fractal_Struct
+{
+
+ int Nb_Simi;
+ SIMI Components[5 * MAX_SIMI];
+ int Depth, Col;
+ int Count, Speed;
+ int Width, Height, Lx, Ly;
+ DBL r_mean, dr_mean, dr2_mean;
+ int Cur_Pt, Max_Pt;
+
+ IFSPoint *Buffer1, *Buffer2;
+};
+
+typedef struct _IFS_DATA
+{
+ FRACTAL *Root;
+ FRACTAL *Cur_F;
+
+ /* Used by the Trace recursive method */
+ IFSPoint *Buf;
+ int Cur_Pt;
+ int initalized;
+} IfsData;
+
+
+/*****************************************************/
+
+static DBL
+Gauss_Rand (PluginInfo * goomInfo, DBL c, DBL A, DBL S)
+{
+ DBL y;
+
+ y = (DBL) LRAND () / MAXRAND;
+ y = A * (1.0 - exp (-y * y * S)) / (1.0 - exp (-S));
+ if (NRAND (2))
+ return (c + y);
+ return (c - y);
+}
+
+static DBL
+Half_Gauss_Rand (PluginInfo * goomInfo, DBL c, DBL A, DBL S)
+{
+ DBL y;
+
+ y = (DBL) LRAND () / MAXRAND;
+ y = A * (1.0 - exp (-y * y * S)) / (1.0 - exp (-S));
+ return (c + y);
+}
+
+static void
+Random_Simis (PluginInfo * goomInfo, FRACTAL * F, SIMI * Cur, int i)
+{
+ while (i--) {
+ Cur->c_x = Gauss_Rand (goomInfo, 0.0, .8, 4.0);
+ Cur->c_y = Gauss_Rand (goomInfo, 0.0, .8, 4.0);
+ Cur->r = Gauss_Rand (goomInfo, F->r_mean, F->dr_mean, 3.0);
+ Cur->r2 = Half_Gauss_Rand (goomInfo, 0.0, F->dr2_mean, 2.0);
+ Cur->A = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (G_PI / 180.0);
+ Cur->A2 = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (G_PI / 180.0);
+ Cur++;
+ }
+}
+
+static void
+free_ifs_buffers (FRACTAL * Fractal)
+{
+ if (Fractal->Buffer1 != NULL) {
+ (void) free ((void *) Fractal->Buffer1);
+ Fractal->Buffer1 = (IFSPoint *) NULL;
+ }
+ if (Fractal->Buffer2 != NULL) {
+ (void) free ((void *) Fractal->Buffer2);
+ Fractal->Buffer2 = (IFSPoint *) NULL;
+ }
+}
+
+
+static void
+free_ifs (FRACTAL * Fractal)
+{
+ free_ifs_buffers (Fractal);
+}
+
+/***************************************************************/
+
+static void
+init_ifs (PluginInfo * goomInfo, IfsData * data)
+{
+ int i;
+ FRACTAL *Fractal;
+ int width = goomInfo->screen.width;
+ int height = goomInfo->screen.height;
+
+ if (data->Root == NULL) {
+ data->Root = (FRACTAL *) malloc (sizeof (FRACTAL));
+ if (data->Root == NULL)
+ return;
+ data->Root->Buffer1 = (IFSPoint *) NULL;
+ data->Root->Buffer2 = (IFSPoint *) NULL;
+ }
+ Fractal = data->Root;
+
+ free_ifs_buffers (Fractal);
+
+ i = (NRAND (4)) + 2; /* Number of centers */
+ switch (i) {
+ case 3:
+ Fractal->Depth = MAX_DEPTH_3;
+ Fractal->r_mean = .6;
+ Fractal->dr_mean = .4;
+ Fractal->dr2_mean = .3;
+ break;
+
+ case 4:
+ Fractal->Depth = MAX_DEPTH_4;
+ Fractal->r_mean = .5;
+ Fractal->dr_mean = .4;
+ Fractal->dr2_mean = .3;
+ break;
+
+ case 5:
+ Fractal->Depth = MAX_DEPTH_5;
+ Fractal->r_mean = .5;
+ Fractal->dr_mean = .4;
+ Fractal->dr2_mean = .3;
+ break;
+
+ default:
+ case 2:
+ Fractal->Depth = MAX_DEPTH_2;
+ Fractal->r_mean = .7;
+ Fractal->dr_mean = .3;
+ Fractal->dr2_mean = .4;
+ break;
+ }
+ Fractal->Nb_Simi = i;
+ Fractal->Max_Pt = Fractal->Nb_Simi - 1;
+ for (i = 0; i <= Fractal->Depth + 2; ++i)
+ Fractal->Max_Pt *= Fractal->Nb_Simi;
+
+ if ((Fractal->Buffer1 = (IFSPoint *) calloc (Fractal->Max_Pt,
+ sizeof (IFSPoint))) == NULL) {
+ free_ifs (Fractal);
+ return;
+ }
+ if ((Fractal->Buffer2 = (IFSPoint *) calloc (Fractal->Max_Pt,
+ sizeof (IFSPoint))) == NULL) {
+ free_ifs (Fractal);
+ return;
+ }
+
+ Fractal->Speed = 6;
+ Fractal->Width = width; /* modif by JeKo */
+ Fractal->Height = height; /* modif by JeKo */
+ Fractal->Cur_Pt = 0;
+ Fractal->Count = 0;
+ Fractal->Lx = (Fractal->Width - 1) / 2;
+ Fractal->Ly = (Fractal->Height - 1) / 2;
+ Fractal->Col = rand () % (width * height); /* modif by JeKo */
+
+ Random_Simis (goomInfo, Fractal, Fractal->Components, 5 * MAX_SIMI);
+}
+
+
+/***************************************************************/
+
+static inline void
+Transform (SIMI * Simi, F_PT xo, F_PT yo, F_PT * x, F_PT * y)
+{
+ F_PT xx, yy;
+
+ xo = xo - Simi->Cx;
+ xo = (xo * Simi->R) >> FIX; /* / UNIT; */
+ yo = yo - Simi->Cy;
+ yo = (yo * Simi->R) >> FIX; /* / UNIT; */
+
+ xx = xo - Simi->Cx;
+ xx = (xx * Simi->R2) >> FIX; /* / UNIT; */
+ yy = -yo - Simi->Cy;
+ yy = (yy * Simi->R2) >> FIX; /* / UNIT; */
+
+ *x = ((xo * Simi->Ct - yo * Simi->St + xx * Simi->Ct2 - yy * Simi->St2)
+ >> FIX /* / UNIT */ ) + Simi->Cx;
+ *y = ((xo * Simi->St + yo * Simi->Ct + xx * Simi->St2 + yy * Simi->Ct2)
+ >> FIX /* / UNIT */ ) + Simi->Cy;
+}
+
+/***************************************************************/
+
+static void
+Trace (FRACTAL * F, F_PT xo, F_PT yo, IfsData * data)
+{
+ F_PT x, y, i;
+ SIMI *Cur;
+
+ Cur = data->Cur_F->Components;
+ for (i = data->Cur_F->Nb_Simi; i; --i, Cur++) {
+ Transform (Cur, xo, yo, &x, &y);
+
+ data->Buf->x = F->Lx + ((x * F->Lx) >> (FIX + 1) /* /(UNIT*2) */ );
+ data->Buf->y = F->Ly - ((y * F->Ly) >> (FIX + 1) /* /(UNIT*2) */ );
+ data->Buf++;
+
+ data->Cur_Pt++;
+
+ if (F->Depth && ((x - xo) >> 4) && ((y - yo) >> 4)) {
+ F->Depth--;
+ Trace (F, x, y, data);
+ F->Depth++;
+ }
+ }
+}
+
+static void
+Draw_Fractal (IfsData * data)
+{
+ FRACTAL *F = data->Root;
+ int i, j;
+ F_PT x, y, xo, yo;
+ SIMI *Cur, *Simi;
+
+ for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) {
+ Cur->Cx = DBL_To_F_PT (Cur->c_x);
+ Cur->Cy = DBL_To_F_PT (Cur->c_y);
+
+ Cur->Ct = DBL_To_F_PT (cos (Cur->A));
+ Cur->St = DBL_To_F_PT (sin (Cur->A));
+ Cur->Ct2 = DBL_To_F_PT (cos (Cur->A2));
+ Cur->St2 = DBL_To_F_PT (sin (Cur->A2));
+
+ Cur->R = DBL_To_F_PT (Cur->r);
+ Cur->R2 = DBL_To_F_PT (Cur->r2);
+ }
+
+
+ data->Cur_Pt = 0;
+ data->Cur_F = F;
+ data->Buf = F->Buffer2;
+ for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) {
+ xo = Cur->Cx;
+ yo = Cur->Cy;
+ for (Simi = F->Components, j = F->Nb_Simi; j; --j, Simi++) {
+ if (Simi == Cur)
+ continue;
+ Transform (Simi, xo, yo, &x, &y);
+ Trace (F, x, y, data);
+ }
+ }
+
+ /* Erase previous */
+
+ F->Cur_Pt = data->Cur_Pt;
+ data->Buf = F->Buffer1;
+ F->Buffer1 = F->Buffer2;
+ F->Buffer2 = data->Buf;
+}
+
+
+static IFSPoint *
+draw_ifs (PluginInfo * goomInfo, int *nbpt, IfsData * data)
+{
+ int i;
+ DBL u, uu, v, vv, u0, u1, u2, u3;
+ SIMI *S, *S1, *S2, *S3, *S4;
+ FRACTAL *F;
+
+ if (data->Root == NULL)
+ return NULL;
+ F = data->Root;
+ if (F->Buffer1 == NULL)
+ return NULL;
+
+ u = (DBL) (F->Count) * (DBL) (F->Speed) / 1000.0;
+ uu = u * u;
+ v = 1.0 - u;
+ vv = v * v;
+ u0 = vv * v;
+ u1 = 3.0 * vv * u;
+ u2 = 3.0 * v * uu;
+ u3 = u * uu;
+
+ S = F->Components;
+ S1 = S + F->Nb_Simi;
+ S2 = S1 + F->Nb_Simi;
+ S3 = S2 + F->Nb_Simi;
+ S4 = S3 + F->Nb_Simi;
+
+ for (i = F->Nb_Simi; i; --i, S++, S1++, S2++, S3++, S4++) {
+ S->c_x = u0 * S1->c_x + u1 * S2->c_x + u2 * S3->c_x + u3 * S4->c_x;
+ S->c_y = u0 * S1->c_y + u1 * S2->c_y + u2 * S3->c_y + u3 * S4->c_y;
+ S->r = u0 * S1->r + u1 * S2->r + u2 * S3->r + u3 * S4->r;
+ S->r2 = u0 * S1->r2 + u1 * S2->r2 + u2 * S3->r2 + u3 * S4->r2;
+ S->A = u0 * S1->A + u1 * S2->A + u2 * S3->A + u3 * S4->A;
+ S->A2 = u0 * S1->A2 + u1 * S2->A2 + u2 * S3->A2 + u3 * S4->A2;
+ }
+
+ Draw_Fractal (data);
+
+ if (F->Count >= 1000 / F->Speed) {
+ S = F->Components;
+ S1 = S + F->Nb_Simi;
+ S2 = S1 + F->Nb_Simi;
+ S3 = S2 + F->Nb_Simi;
+ S4 = S3 + F->Nb_Simi;
+
+ for (i = F->Nb_Simi; i; --i, S++, S1++, S2++, S3++, S4++) {
+ S2->c_x = 2.0 * S4->c_x - S3->c_x;
+ S2->c_y = 2.0 * S4->c_y - S3->c_y;
+ S2->r = 2.0 * S4->r - S3->r;
+ S2->r2 = 2.0 * S4->r2 - S3->r2;
+ S2->A = 2.0 * S4->A - S3->A;
+ S2->A2 = 2.0 * S4->A2 - S3->A2;
+
+ *S1 = *S4;
+ }
+ Random_Simis (goomInfo, F, F->Components + 3 * F->Nb_Simi, F->Nb_Simi);
+
+ Random_Simis (goomInfo, F, F->Components + 4 * F->Nb_Simi, F->Nb_Simi);
+
+ F->Count = 0;
+ } else
+ F->Count++;
+
+ F->Col++;
+
+ (*nbpt) = data->Cur_Pt;
+ return F->Buffer2;
+}
+
+
+/***************************************************************/
+
+static void
+release_ifs (IfsData * data)
+{
+ if (data->Root != NULL) {
+ free_ifs (data->Root);
+ (void) free ((void *) data->Root);
+ data->Root = (FRACTAL *) NULL;
+ }
+}
+
+#define RAND() goom_random(goomInfo->gRandom)
+
+static void
+ifs_update (PluginInfo * goomInfo, Pixel * data, Pixel * back, int increment,
+ IfsData * fx_data)
+{
+ static unsigned int couleur = 0xc0c0c0c0;
+ static int v[4] = { 2, 4, 3, 2 };
+ static int col[4] = { 2, 4, 3, 2 };
+
+#define MOD_MER 0
+#define MOD_FEU 1
+#define MOD_MERVER 2
+ static int mode = MOD_MERVER;
+ static int justChanged = 0;
+ static int cycle = 0;
+ int cycle10;
+
+ int nbpt = 0;
+ IFSPoint *points;
+ int i;
+
+ unsigned int couleursl = couleur;
+ int width = goomInfo->screen.width;
+ int height = goomInfo->screen.height;
+
+ cycle++;
+ if (cycle >= 80)
+ cycle = 0;
+
+ if (cycle < 40)
+ cycle10 = cycle / 10;
+ else
+ cycle10 = 7 - cycle / 10;
+
+ {
+ unsigned char *tmp = (unsigned char *) &couleursl;
+
+ for (i = 0; i < 4; i++) {
+ *tmp = (*tmp) >> cycle10;
+ tmp++;
+ }
+ }
+
+ points = draw_ifs (goomInfo, &nbpt, fx_data);
+ nbpt--;
+
+#ifdef HAVE_MMX
+ movd_m2r (couleursl, mm1);
+ punpckldq_r2r (mm1, mm1);
+ for (i = 0; i < nbpt; i += increment) {
+ int x = points[i].x;
+ int y = points[i].y;
+
+ if ((x < width) && (y < height) && (x > 0) && (y > 0)) {
+ int pos = x + (y * width);
+
+ movd_m2r (back[pos], mm0);
+ paddusb_r2r (mm1, mm0);
+ movd_r2m (mm0, data[pos]);
+ }
+ }
+ emms (); /*__asm__ __volatile__ ("emms");*/
+#else
+ for (i = 0; i < nbpt; i += increment) {
+ int x = (int) points[i].x & 0x7fffffff;
+ int y = (int) points[i].y & 0x7fffffff;
+
+ if ((x < width) && (y < height)) {
+ int pos = x + (int) (y * width);
+ int tra = 0, i = 0;
+ unsigned char *bra = (unsigned char *) &back[pos];
+ unsigned char *dra = (unsigned char *) &data[pos];
+ unsigned char *cra = (unsigned char *) &couleursl;
+
+ for (; i < 4; i++) {
+ tra = *cra;
+ tra += *bra;
+ if (tra > 255)
+ tra = 255;
+ *dra = tra;
+ ++dra;
+ ++cra;
+ ++bra;
+ }
+ }
+ }
+#endif /*MMX*/
+ justChanged--;
+
+ col[ALPHA] = couleur >> (ALPHA * 8) & 0xff;
+ col[BLEU] = couleur >> (BLEU * 8) & 0xff;
+ col[VERT] = couleur >> (VERT * 8) & 0xff;
+ col[ROUGE] = couleur >> (ROUGE * 8) & 0xff;
+
+ if (mode == MOD_MER) {
+ col[BLEU] += v[BLEU];
+ if (col[BLEU] > 255) {
+ col[BLEU] = 255;
+ v[BLEU] = -(RAND () % 4) - 1;
+ }
+ if (col[BLEU] < 32) {
+ col[BLEU] = 32;
+ v[BLEU] = (RAND () % 4) + 1;
+ }
+
+ col[VERT] += v[VERT];
+ if (col[VERT] > 200) {
+ col[VERT] = 200;
+ v[VERT] = -(RAND () % 3) - 2;
+ }
+ if (col[VERT] > col[BLEU]) {
+ col[VERT] = col[BLEU];
+ v[VERT] = v[BLEU];
+ }
+ if (col[VERT] < 32) {
+ col[VERT] = 32;
+ v[VERT] = (RAND () % 3) + 2;
+ }
+
+ col[ROUGE] += v[ROUGE];
+ if (col[ROUGE] > 64) {
+ col[ROUGE] = 64;
+ v[ROUGE] = -(RAND () % 4) - 1;
+ }
+ if (col[ROUGE] < 0) {
+ col[ROUGE] = 0;
+ v[ROUGE] = (RAND () % 4) + 1;
+ }
+
+ col[ALPHA] += v[ALPHA];
+ if (col[ALPHA] > 0) {
+ col[ALPHA] = 0;
+ v[ALPHA] = -(RAND () % 4) - 1;
+ }
+ if (col[ALPHA] < 0) {
+ col[ALPHA] = 0;
+ v[ALPHA] = (RAND () % 4) + 1;
+ }
+
+ if (((col[VERT] > 32) && (col[ROUGE] < col[VERT] + 40)
+ && (col[VERT] < col[ROUGE] + 20) && (col[BLEU] < 64)
+ && (RAND () % 20 == 0)) && (justChanged < 0)) {
+ mode = (RAND () % 3) ? MOD_FEU : MOD_MERVER;
+ justChanged = 250;
+ }
+ } else if (mode == MOD_MERVER) {
+ col[BLEU] += v[BLEU];
+ if (col[BLEU] > 128) {
+ col[BLEU] = 128;
+ v[BLEU] = -(RAND () % 4) - 1;
+ }
+ if (col[BLEU] < 16) {
+ col[BLEU] = 16;
+ v[BLEU] = (RAND () % 4) + 1;
+ }
+
+ col[VERT] += v[VERT];
+ if (col[VERT] > 200) {
+ col[VERT] = 200;
+ v[VERT] = -(RAND () % 3) - 2;
+ }
+ if (col[VERT] > col[ALPHA]) {
+ col[VERT] = col[ALPHA];
+ v[VERT] = v[ALPHA];
+ }
+ if (col[VERT] < 32) {
+ col[VERT] = 32;
+ v[VERT] = (RAND () % 3) + 2;
+ }
+
+ col[ROUGE] += v[ROUGE];
+ if (col[ROUGE] > 128) {
+ col[ROUGE] = 128;
+ v[ROUGE] = -(RAND () % 4) - 1;
+ }
+ if (col[ROUGE] < 0) {
+ col[ROUGE] = 0;
+ v[ROUGE] = (RAND () % 4) + 1;
+ }
+
+ col[ALPHA] += v[ALPHA];
+ if (col[ALPHA] > 255) {
+ col[ALPHA] = 255;
+ v[ALPHA] = -(RAND () % 4) - 1;
+ }
+ if (col[ALPHA] < 0) {
+ col[ALPHA] = 0;
+ v[ALPHA] = (RAND () % 4) + 1;
+ }
+
+ if (((col[VERT] > 32) && (col[ROUGE] < col[VERT] + 40)
+ && (col[VERT] < col[ROUGE] + 20) && (col[BLEU] < 64)
+ && (RAND () % 20 == 0)) && (justChanged < 0)) {
+ mode = (RAND () % 3) ? MOD_FEU : MOD_MER;
+ justChanged = 250;
+ }
+ } else if (mode == MOD_FEU) {
+
+ col[BLEU] += v[BLEU];
+ if (col[BLEU] > 64) {
+ col[BLEU] = 64;
+ v[BLEU] = -(RAND () % 4) - 1;
+ }
+ if (col[BLEU] < 0) {
+ col[BLEU] = 0;
+ v[BLEU] = (RAND () % 4) + 1;
+ }
+
+ col[VERT] += v[VERT];
+ if (col[VERT] > 200) {
+ col[VERT] = 200;
+ v[VERT] = -(RAND () % 3) - 2;
+ }
+ if (col[VERT] > col[ROUGE] + 20) {
+ col[VERT] = col[ROUGE] + 20;
+ v[VERT] = -(RAND () % 3) - 2;
+ v[ROUGE] = (RAND () % 4) + 1;
+ v[BLEU] = (RAND () % 4) + 1;
+ }
+ if (col[VERT] < 0) {
+ col[VERT] = 0;
+ v[VERT] = (RAND () % 3) + 2;
+ }
+
+ col[ROUGE] += v[ROUGE];
+ if (col[ROUGE] > 255) {
+ col[ROUGE] = 255;
+ v[ROUGE] = -(RAND () % 4) - 1;
+ }
+ if (col[ROUGE] > col[VERT] + 40) {
+ col[ROUGE] = col[VERT] + 40;
+ v[ROUGE] = -(RAND () % 4) - 1;
+ }
+ if (col[ROUGE] < 0) {
+ col[ROUGE] = 0;
+ v[ROUGE] = (RAND () % 4) + 1;
+ }
+
+ col[ALPHA] += v[ALPHA];
+ if (col[ALPHA] > 0) {
+ col[ALPHA] = 0;
+ v[ALPHA] = -(RAND () % 4) - 1;
+ }
+ if (col[ALPHA] < 0) {
+ col[ALPHA] = 0;
+ v[ALPHA] = (RAND () % 4) + 1;
+ }
+
+ if (((col[ROUGE] < 64) && (col[VERT] > 32) && (col[VERT] < col[BLEU])
+ && (col[BLEU] > 32)
+ && (RAND () % 20 == 0)) && (justChanged < 0)) {
+ mode = (RAND () % 2) ? MOD_MER : MOD_MERVER;
+ justChanged = 250;
+ }
+ }
+
+ couleur = (col[ALPHA] << (ALPHA * 8))
+ | (col[BLEU] << (BLEU * 8))
+ | (col[VERT] << (VERT * 8))
+ | (col[ROUGE] << (ROUGE * 8));
+}
+
+/* VISUAL_FX WRAPPER FOR IFS */
+
+static void
+ifs_vfx_apply (VisualFX * _this, Pixel * src, Pixel * dest,
+ PluginInfo * goomInfo)
+{
+
+ IfsData *data = (IfsData *) _this->fx_data;
+
+ if (!data->initalized) {
+ data->initalized = 1;
+ init_ifs (goomInfo, data);
+ }
+ ifs_update (goomInfo, dest, src, goomInfo->update.ifs_incr, data);
+ /*TODO: trouver meilleur soluce pour increment (mettre le code de gestion de l'ifs dans ce fichier: ifs_vfx_apply) */
+}
+
+static void
+ifs_vfx_init (VisualFX * _this, PluginInfo * info)
+{
+
+ IfsData *data = (IfsData *) malloc (sizeof (IfsData));
+
+ data->Root = (FRACTAL *) NULL;
+ data->initalized = 0;
+ _this->fx_data = data;
+}
+
+static void
+ifs_vfx_free (VisualFX * _this)
+{
+ IfsData *data = (IfsData *) _this->fx_data;
+
+ release_ifs (data);
+ free (data);
+}
+
+void
+ifs_visualfx_create (VisualFX * vfx)
+{
+
+ vfx->init = ifs_vfx_init;
+ vfx->free = ifs_vfx_free;
+ vfx->apply = ifs_vfx_apply;
+ vfx->fx_data = NULL;
+ vfx->params = NULL;
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/ifs.h b/subprojects/gst-plugins-good/gst/goom/ifs.h
new file mode 100644
index 0000000000..400377349d
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/ifs.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1997 by Massimino Pascal <Pascal.Massimon@ens.fr>
+ *
+ * ifs.h: modified iterated functions system for goom.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind. The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof. In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * If this mode is weird and you have an old MetroX server, it is buggy.
+ * There is a free SuSE-enhanced MetroX X server that is fine.
+ *
+ * When shown ifs, Diana Rose (4 years old) said, "It looks like dancing."
+ *
+ * Revision History:
+ * 13-Dec-2003: Added some goom specific stuffs (to make ifs a VisualFX).
+ * 11-Apr-2002: jeko@ios-software.com: Make ifs.c system-indendant. (ifs.h added)
+ * 01-Nov-2000: Allocation checks
+ * 10-May-1997: jwz@jwz.org: turned into a standalone program.
+ * Made it render into an offscreen bitmap and then copy
+ * that onto the screen, to reduce flicker.
+ */
+
+#ifndef IFS_H
+#define IFS_H
+
+#include "goom_config.h"
+#include "goom_graphic.h"
+#include "goom_plugin_info.h"
+#include "goom_visual_fx.h"
+
+void ifs_visualfx_create(VisualFX *vfx);
+
+/* init ifs for a (width)x(height) output. * /
+void init_ifs (PluginInfo *goomInfo, int width, int height);
+
+/ * draw an ifs on the buffer (which size is width * height)
+ increment means that we draw 1/increment of the ifs's points * /
+void ifs_update (PluginInfo *goomInfo, Pixel * buffer, Pixel * back, int width, int height, int increment);
+
+/ * free all ifs's data. * /
+void release_ifs (void);
+*/
+
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/lines.c b/subprojects/gst-plugins-good/gst/goom/lines.c
new file mode 100644
index 0000000000..a7c1eda914
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/lines.c
@@ -0,0 +1,257 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "lines.h"
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "goom_tools.h"
+#include "drawmethods.h"
+#include "goom_plugin_info.h"
+
+static inline unsigned char
+lighten (unsigned char value, float power)
+{
+ int val = value;
+ float t = (float) val * log10 (power) / 2.0;
+
+ if (t > 0) {
+ val = (int) t; /* (32.0f * log (t)); */
+ if (val > 255)
+ val = 255;
+ if (val < 0)
+ val = 0;
+ return val;
+ } else {
+ return 0;
+ }
+}
+
+static void
+lightencolor (guint32 * col, float power)
+{
+ unsigned char *color;
+
+ color = (unsigned char *) col;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+}
+
+
+
+static void
+genline (int id, float param, GMUnitPointer * l, int rx, int ry)
+{
+ int i;
+
+ switch (id) {
+ case GML_HLINE:
+ for (i = 0; i < 512; i++) {
+ l[i].x = ((float) i * rx) / 512.0f;
+ l[i].y = param;
+ l[i].angle = G_PI / 2.0f;
+ }
+ return;
+ case GML_VLINE:
+ for (i = 0; i < 512; i++) {
+ l[i].y = ((float) i * ry) / 512.0f;
+ l[i].x = param;
+ l[i].angle = 0.0f;
+ }
+ return;
+ case GML_CIRCLE:
+ for (i = 0; i < 512; i++) {
+ float cosa, sina;
+
+ l[i].angle = 2.0f * G_PI * (float) i / 512.0f;
+ cosa = param * cos (l[i].angle);
+ sina = param * sin (l[i].angle);
+ l[i].x = ((float) rx / 2.0f) + cosa;
+ l[i].y = (float) ry / 2.0f + sina;
+ }
+ return;
+ }
+}
+
+static guint32
+getcouleur (int mode)
+{
+ switch (mode) {
+ case GML_RED:
+ return (230 << (ROUGE * 8)) | (120 << (VERT * 8)) | (18 << (BLEU * 8));
+ case GML_ORANGE_J:
+ return (120 << (VERT * 8)) | (252 << (ROUGE * 8)) | (18 << (BLEU * 8));
+ case GML_ORANGE_V:
+ return (160 << (VERT * 8)) | (236 << (ROUGE * 8)) | (40 << (BLEU * 8));
+ case GML_BLEUBLANC:
+ return (40 << (BLEU * 8)) | (220 << (ROUGE * 8)) | (140 << (VERT * 8));
+ case GML_VERT:
+ return (200 << (VERT * 8)) | (80 << (ROUGE * 8)) | (18 << (BLEU * 8));
+ case GML_BLEU:
+ return (250 << (BLEU * 8)) | (30 << (VERT * 8)) | (80 << (ROUGE * 8));
+ case GML_BLACK:
+ return (16 << (BLEU * 8)) | (16 << (VERT * 8)) | (16 << (ROUGE * 8));
+ }
+ return 0;
+}
+
+void
+goom_lines_set_res (GMLine * gml, int rx, int ry)
+{
+ if (gml != NULL) {
+ gml->screenX = rx;
+ gml->screenY = ry;
+
+ genline (gml->IDdest, gml->param, gml->points2, rx, ry);
+ }
+}
+
+
+static void
+goom_lines_move (GMLine * l)
+{
+ int i;
+ unsigned char *c1, *c2;
+
+ for (i = 0; i < 512; i++) {
+ l->points[i].x = (l->points2[i].x + 39.0f * l->points[i].x) / 40.0f;
+ l->points[i].y = (l->points2[i].y + 39.0f * l->points[i].y) / 40.0f;
+ l->points[i].angle =
+ (l->points2[i].angle + 39.0f * l->points[i].angle) / 40.0f;
+ }
+
+ c1 = (unsigned char *) &l->color;
+ c2 = (unsigned char *) &l->color2;
+ for (i = 0; i < 4; i++) {
+ int cc1, cc2;
+
+ cc1 = *c1;
+ cc2 = *c2;
+ *c1 = (unsigned char) ((cc1 * 63 + cc2) >> 6);
+ ++c1;
+ ++c2;
+ }
+
+ l->power += l->powinc;
+ if (l->power < 1.1f) {
+ l->power = 1.1f;
+ l->powinc = (float) (goom_irand (l->goomInfo->gRandom, 20) + 10) / 300.0f;
+ }
+ if (l->power > 17.5f) {
+ l->power = 17.5f;
+ l->powinc = -(float) (goom_irand (l->goomInfo->gRandom, 20) + 10) / 300.0f;
+ }
+
+ l->amplitude = (99.0f * l->amplitude + l->amplitudeF) / 100.0f;
+}
+
+void
+goom_lines_switch_to (GMLine * gml, int IDdest,
+ float param, float amplitude, int col)
+{
+ genline (IDdest, param, gml->points2, gml->screenX, gml->screenY);
+ gml->IDdest = IDdest;
+ gml->param = param;
+ gml->amplitudeF = amplitude;
+ gml->color2 = getcouleur (col);
+}
+
+GMLine *
+goom_lines_init (PluginInfo * goomInfo, int rx, int ry,
+ int IDsrc, float paramS, int coulS, int IDdest, float paramD, int coulD)
+{
+ GMLine *l = (GMLine *) malloc (sizeof (GMLine));
+
+ l->goomInfo = goomInfo;
+
+ l->points = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer));
+ l->points2 = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer));
+ l->nbPoints = 512;
+
+ l->IDdest = IDdest;
+ l->param = paramD;
+
+ l->amplitude = l->amplitudeF = 1.0f;
+
+ genline (IDsrc, paramS, l->points, rx, ry);
+ genline (IDdest, paramD, l->points2, rx, ry);
+
+ l->color = getcouleur (coulS);
+ l->color2 = getcouleur (coulD);
+
+ l->screenX = rx;
+ l->screenY = ry;
+
+ l->power = 0.0f;
+ l->powinc = 0.01f;
+
+ goom_lines_switch_to (l, IDdest, paramD, 1.0f, coulD);
+
+ return l;
+}
+
+void
+goom_lines_free (GMLine ** l)
+{
+ free ((*l)->points2);
+ free ((*l)->points);
+ free (*l);
+ l = NULL;
+}
+
+void
+goom_lines_draw (PluginInfo * plug, GMLine * line, gint16 data[512], Pixel * p)
+{
+ if (line != NULL) {
+ int i, x1, y1;
+ guint32 color = line->color;
+ GMUnitPointer *pt = &(line->points[0]);
+
+ float cosa = cos (pt->angle) / 1000.0f;
+ float sina = sin (pt->angle) / 1000.0f;
+
+ lightencolor (&color, line->power);
+
+ x1 = (int) (pt->x + cosa * line->amplitude * data[0]);
+ y1 = (int) (pt->y + sina * line->amplitude * data[0]);
+
+ for (i = 1; i < 512; i++) {
+ int x2, y2;
+ GMUnitPointer *pt = &(line->points[i]);
+
+ float cosa = cos (pt->angle) / 1000.0f;
+ float sina = sin (pt->angle) / 1000.0f;
+
+ x2 = (int) (pt->x + cosa * line->amplitude * data[i]);
+ y2 = (int) (pt->y + sina * line->amplitude * data[i]);
+
+ plug->methods.draw_line (p, x1, y1, x2, y2, color, line->screenX,
+ line->screenY);
+
+ x1 = x2;
+ y1 = y2;
+ }
+ goom_lines_move (line);
+ }
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/lines.h b/subprojects/gst-plugins-good/gst/goom/lines.h
new file mode 100644
index 0000000000..4cd50d8779
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/lines.h
@@ -0,0 +1,94 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _LINES_H
+#define _LINES_H
+
+#include "goom_typedefs.h"
+#include "goom_graphic.h"
+#include "goom_config.h"
+
+struct _GMUNITPOINTER
+{
+ float x;
+ float y;
+ float angle;
+};
+
+/* tableau de points */
+struct _GMLINE
+{
+
+ GMUnitPointer *points;
+ GMUnitPointer *points2;
+ int IDdest;
+ float param;
+ float amplitudeF;
+ float amplitude;
+
+ int nbPoints;
+ guint32 color; /* pour l'instant je stocke la couleur a terme, on stockera le mode couleur et l'on animera */
+ guint32 color2;
+
+ int screenX;
+ int screenY;
+
+ float power;
+ float powinc;
+
+ PluginInfo *goomInfo;
+};
+
+/* les ID possibles */
+
+#define GML_CIRCLE 0
+/* (param = radius) */
+
+#define GML_HLINE 1
+/* (param = y) */
+
+#define GML_VLINE 2
+/* (param = x) */
+
+/* les modes couleur possible (si tu mets un autre c'est noir) */
+
+#define GML_BLEUBLANC 0
+#define GML_RED 1
+#define GML_ORANGE_V 2
+#define GML_ORANGE_J 3
+#define GML_VERT 4
+#define GML_BLEU 5
+#define GML_BLACK 6
+
+/* construit un effet de line (une ligne horitontale pour commencer) */
+GMLine *goom_lines_init (PluginInfo *goomInfo, int rx, int ry,
+ int IDsrc, float paramS, int modeCoulSrc,
+ int IDdest, float paramD, int modeCoulDest);
+
+void goom_lines_switch_to (GMLine * gml, int IDdest, float param,
+ float amplitude,
+ int modeCoul);
+
+void goom_lines_set_res (GMLine * gml, int rx, int ry);
+
+void goom_lines_free (GMLine ** gml);
+
+void goom_lines_draw (PluginInfo *plugInfo, GMLine * gml, gint16 data[512], Pixel *p);
+
+#endif /* _LINES_H */
diff --git a/subprojects/gst-plugins-good/gst/goom/mathtools.c b/subprojects/gst-plugins-good/gst/goom/mathtools.c
new file mode 100644
index 0000000000..dd190bf607
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/mathtools.c
@@ -0,0 +1,106 @@
+/* Goom Project
+ * Copyright (C) <2003> Jean-Christophe Hoelt <jeko@free.fr>
+ *
+ * goom_core.c:Contains the core of goom's work.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "mathtools.h"
+
+float sin256[256] = {
+ 0, 0.0245412, 0.0490677, 0.0735646, 0.0980171, 0.122411, 0.14673, 0.170962,
+ 0.19509, 0.219101, 0.24298, 0.266713, 0.290285, 0.313682, 0.33689,
+ 0.359895, 0.382683, 0.405241, 0.427555, 0.449611, 0.471397, 0.492898,
+ 0.514103, 0.534998, 0.55557, 0.575808, 0.595699, 0.615232, 0.634393,
+ 0.653173, 0.671559, 0.689541, 0.707107, 0.724247, 0.740951, 0.757209,
+ 0.77301, 0.788346, 0.803208, 0.817585, 0.83147, 0.844854, 0.857729,
+ 0.870087, 0.881921, 0.893224, 0.903989, 0.91421, 0.92388, 0.932993,
+ 0.941544, 0.949528, 0.95694, 0.963776, 0.970031, 0.975702, 0.980785,
+ 0.985278, 0.989177, 0.99248, 0.995185, 0.99729, 0.998795, 0.999699, 1,
+ 0.999699, 0.998795, 0.99729, 0.995185, 0.99248, 0.989177, 0.985278,
+ 0.980785, 0.975702, 0.970031, 0.963776, 0.95694, 0.949528, 0.941544,
+ 0.932993, 0.92388, 0.91421, 0.903989, 0.893224, 0.881921, 0.870087,
+ 0.857729, 0.844854, 0.83147, 0.817585, 0.803208, 0.788346, 0.77301,
+ 0.757209, 0.740951, 0.724247, 0.707107, 0.689541, 0.671559, 0.653173,
+ 0.634393, 0.615232, 0.595699, 0.575808, 0.55557, 0.534998, 0.514103,
+ 0.492898, 0.471397, 0.449611, 0.427555, 0.405241, 0.382683, 0.359895,
+ 0.33689, 0.313682, 0.290285, 0.266713, 0.24298, 0.219101, 0.19509,
+ 0.170962, 0.14673, 0.122411, 0.0980171, 0.0735646, 0.0490677, 0.0245412,
+ 1.22465e-16, -0.0245412, -0.0490677, -0.0735646, -0.0980171, -0.122411,
+ -0.14673, -0.170962, -0.19509, -0.219101, -0.24298, -0.266713, -0.290285,
+ -0.313682, -0.33689, -0.359895, -0.382683, -0.405241, -0.427555,
+ -0.449611, -0.471397, -0.492898, -0.514103, -0.534998, -0.55557,
+ -0.575808, -0.595699, -0.615232, -0.634393, -0.653173, -0.671559,
+ -0.689541, -0.707107, -0.724247, -0.740951, -0.757209, -0.77301,
+ -0.788346, -0.803208, -0.817585, -0.83147, -0.844854, -0.857729,
+ -0.870087, -0.881921, -0.893224, -0.903989, -0.91421, -0.92388, -0.932993,
+ -0.941544, -0.949528, -0.95694, -0.963776, -0.970031, -0.975702,
+ -0.980785, -0.985278, -0.989177, -0.99248, -0.995185, -0.99729, -0.998795,
+ -0.999699, -1, -0.999699, -0.998795, -0.99729, -0.995185, -0.99248,
+ -0.989177, -0.985278, -0.980785, -0.975702, -0.970031, -0.963776,
+ -0.95694, -0.949528, -0.941544, -0.932993, -0.92388, -0.91421, -0.903989,
+ -0.893224, -0.881921, -0.870087, -0.857729, -0.844854, -0.83147,
+ -0.817585, -0.803208, -0.788346, -0.77301, -0.757209, -0.740951,
+ -0.724247, -0.707107, -0.689541, -0.671559, -0.653173, -0.634393,
+ -0.615232, -0.595699, -0.575808, -0.55557, -0.534998, -0.514103,
+ -0.492898, -0.471397, -0.449611, -0.427555, -0.405241, -0.382683,
+ -0.359895, -0.33689, -0.313682, -0.290285, -0.266713, -0.24298, -0.219101,
+ -0.19509, -0.170962, -0.14673, -0.122411, -0.0980171, -0.0735646,
+ -0.0490677, -0.0245412
+};
+
+float cos256[256] = {
+ 0, 0.999699, 0.998795, 0.99729, 0.995185, 0.99248, 0.989177, 0.985278,
+ 0.980785, 0.975702, 0.970031, 0.963776, 0.95694, 0.949528, 0.941544,
+ 0.932993, 0.92388, 0.91421, 0.903989, 0.893224, 0.881921, 0.870087,
+ 0.857729, 0.844854, 0.83147, 0.817585, 0.803208, 0.788346, 0.77301,
+ 0.757209, 0.740951, 0.724247, 0.707107, 0.689541, 0.671559, 0.653173,
+ 0.634393, 0.615232, 0.595699, 0.575808, 0.55557, 0.534998, 0.514103,
+ 0.492898, 0.471397, 0.449611, 0.427555, 0.405241, 0.382683, 0.359895,
+ 0.33689, 0.313682, 0.290285, 0.266713, 0.24298, 0.219101, 0.19509,
+ 0.170962, 0.14673, 0.122411, 0.0980171, 0.0735646, 0.0490677, 0.0245412,
+ 6.12323e-17, -0.0245412, -0.0490677, -0.0735646, -0.0980171, -0.122411,
+ -0.14673, -0.170962, -0.19509, -0.219101, -0.24298, -0.266713, -0.290285,
+ -0.313682, -0.33689, -0.359895, -0.382683, -0.405241, -0.427555,
+ -0.449611, -0.471397, -0.492898, -0.514103, -0.534998, -0.55557,
+ -0.575808, -0.595699, -0.615232, -0.634393, -0.653173, -0.671559,
+ -0.689541, -0.707107, -0.724247, -0.740951, -0.757209, -0.77301,
+ -0.788346, -0.803208, -0.817585, -0.83147, -0.844854, -0.857729,
+ -0.870087, -0.881921, -0.893224, -0.903989, -0.91421, -0.92388, -0.932993,
+ -0.941544, -0.949528, -0.95694, -0.963776, -0.970031, -0.975702,
+ -0.980785, -0.985278, -0.989177, -0.99248, -0.995185, -0.99729, -0.998795,
+ -0.999699, -1, -0.999699, -0.998795, -0.99729, -0.995185, -0.99248,
+ -0.989177, -0.985278, -0.980785, -0.975702, -0.970031, -0.963776,
+ -0.95694, -0.949528, -0.941544, -0.932993, -0.92388, -0.91421, -0.903989,
+ -0.893224, -0.881921, -0.870087, -0.857729, -0.844854, -0.83147,
+ -0.817585, -0.803208, -0.788346, -0.77301, -0.757209, -0.740951,
+ -0.724247, -0.707107, -0.689541, -0.671559, -0.653173, -0.634393,
+ -0.615232, -0.595699, -0.575808, -0.55557, -0.534998, -0.514103,
+ -0.492898, -0.471397, -0.449611, -0.427555, -0.405241, -0.382683,
+ -0.359895, -0.33689, -0.313682, -0.290285, -0.266713, -0.24298, -0.219101,
+ -0.19509, -0.170962, -0.14673, -0.122411, -0.0980171, -0.0735646,
+ -0.0490677, -0.0245412, -1.83697e-16, 0.0245412, 0.0490677, 0.0735646,
+ 0.0980171, 0.122411, 0.14673, 0.170962, 0.19509, 0.219101, 0.24298,
+ 0.266713, 0.290285, 0.313682, 0.33689, 0.359895, 0.382683, 0.405241,
+ 0.427555, 0.449611, 0.471397, 0.492898, 0.514103, 0.534998, 0.55557,
+ 0.575808, 0.595699, 0.615232, 0.634393, 0.653173, 0.671559, 0.689541,
+ 0.707107, 0.724247, 0.740951, 0.757209, 0.77301, 0.788346, 0.803208,
+ 0.817585, 0.83147, 0.844854, 0.857729, 0.870087, 0.881921, 0.893224,
+ 0.903989, 0.91421, 0.92388, 0.932993, 0.941544, 0.949528, 0.95694,
+ 0.963776, 0.970031, 0.975702, 0.980785, 0.985278, 0.989177, 0.99248,
+ 0.995185, 0.99729, 0.998795, 0.999699
+};
diff --git a/subprojects/gst-plugins-good/gst/goom/mathtools.h b/subprojects/gst-plugins-good/gst/goom/mathtools.h
new file mode 100644
index 0000000000..5340dab743
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/mathtools.h
@@ -0,0 +1,58 @@
+/* Goom Project
+ * Copyright (C) <2003> Jean-Christophe Hoelt <jeko@free.fr>
+ *
+ * goom_core.c:Contains the core of goom's work.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+ #ifndef MATHTOOLS_H
+#define MATHTOOLS_H
+
+#include <glib.h>
+
+#define _double2fixmagic (68719476736.0*1.5)
+/* 2^36 * 1.5, (52-_shiftamt=36) uses limited precisicion to floor */
+#define _shiftamt 16
+/* 16.16 fixed point representation */
+
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+#define iexp_ 0
+#define iman_ 1
+#else
+#define iexp_ 1
+#define iman_ 0
+#endif /* BigEndian_ */
+
+/* TODO: this optimization is very efficient: put it again when all works
+#ifdef HAVE_MMX
+#define F2I(dbl,i) {double d = dbl + _double2fixmagic; i = ((int*)&d)[iman_] >> _shiftamt;}
+#else*/
+#define F2I(dbl,i) i=(int)dbl;
+/*#endif*/
+
+#if 0
+#define SINCOS(f,s,c) \
+ __asm__ __volatile__ ("fsincos" : "=t" (c), "=u" (s) : "0" (f))
+#else
+#define SINCOS(f,s,c) {s=sin(f);c=cos(f);}
+#endif
+
+extern float sin256[256];
+extern float cos256[256];
+
+#endif
+
diff --git a/subprojects/gst-plugins-good/gst/goom/meson.build b/subprojects/gst-plugins-good/gst/goom/meson.build
new file mode 100644
index 0000000000..b094e51bc3
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/meson.build
@@ -0,0 +1,31 @@
+goom_sources = [
+ 'gstgoom.c',
+ 'drawmethods.c',
+ 'sound_tester.c',
+ 'mathtools.c',
+ 'lines.c',
+ 'ifs.c',
+ 'surf3d.c',
+ 'tentacle3d.c',
+ 'v3d.c',
+ 'convolve_fx.c',
+ 'flying_stars_fx.c',
+ 'plugin_info.c',
+ 'goom_tools.c',
+ 'config_param.c',
+ 'filters.c',
+ 'goom_core.c',
+ 'graphic.c',
+]
+
+
+gstgoom = library('gstgoom',
+ goom_sources,
+ c_args : gst_plugins_good_args,
+ include_directories : [configinc],
+ dependencies : [gst_dep, gstpbutils_dep, gstbase_dep, orc_dep, libm],
+ install : true,
+ install_dir : plugins_install_dir,
+)
+pkgconfig.generate(gstgoom, install_dir : plugins_pkgconfig_install_dir)
+plugins += [gstgoom]
diff --git a/subprojects/gst-plugins-good/gst/goom/mmx.c b/subprojects/gst-plugins-good/gst/goom/mmx.c
new file mode 100644
index 0000000000..bc2a6c46bd
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/mmx.c
@@ -0,0 +1,291 @@
+/* mmx.c
+
+ MultiMedia eXtensions GCC interface library for IA32.
+
+ To use this library, simply include this header file
+ and compile with GCC. You MUST have inlining enabled
+ in order for mmx_ok() to work; this can be done by
+ simply using -O on the GCC command line.
+
+ Compiling with -DMMX_TRACE will cause detailed trace
+ output to be sent to stderr for each mmx operation.
+ This adds lots of code, and obviously slows execution to
+ a crawl, but can be very useful for debugging.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ 1997-99 by H. Dietz and R. Fisher
+
+ Notes:
+ It appears that the latest gas has the pand problem fixed, therefore
+ I'll undefine BROKEN_PAND by default.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "goom_config.h"
+
+#ifdef HAVE_MMX
+
+#define BUFFPOINTNB 16
+#define BUFFPOINTMASK 0xffff
+#define BUFFINCR 0xff
+
+#include "mmx.h"
+#include "goom_graphic.h"
+
+#define sqrtperte 16
+// faire : a % sqrtperte <=> a & pertemask
+#define PERTEMASK 0xf
+// faire : a / sqrtperte <=> a >> PERTEDEC
+#define PERTEDEC 4
+
+int
+mmx_supported (void)
+{
+ return (mm_support () & 0x1);
+}
+
+void
+zoom_filter_mmx (int prevX, int prevY,
+ Pixel * expix1, Pixel * expix2,
+ int *brutS, int *brutD, int buffratio, int precalCoef[16][16])
+{
+ unsigned int ax = (prevX - 1) << PERTEDEC, ay = (prevY - 1) << PERTEDEC;
+
+ int bufsize = prevX * prevY;
+ int loop;
+
+ __asm__ __volatile__ ("pxor %mm7,%mm7");
+
+ for (loop = 0; loop < bufsize; loop++) {
+ /* int couleur; */
+ int px, py;
+ int pos;
+ int coeffs;
+
+ int myPos = loop << 1, myPos2 = myPos + 1;
+ int brutSmypos = brutS[myPos];
+
+ px = brutSmypos + (((brutD[myPos] -
+ brutSmypos) * buffratio) >> BUFFPOINTNB);
+ brutSmypos = brutS[myPos2];
+ py = brutSmypos + (((brutD[myPos2] -
+ brutSmypos) * buffratio) >> BUFFPOINTNB);
+
+ if ((py >= ay) || (px >= ax)) {
+ pos = coeffs = 0;
+ } else {
+ pos = ((px >> PERTEDEC) + prevX * (py >> PERTEDEC));
+ // coef en modulo 15
+ coeffs = precalCoef[px & PERTEMASK][py & PERTEMASK];
+ }
+
+ __asm__ __volatile__ ("movd %2, %%mm6 \n\t"
+ /* recuperation des deux premiers pixels dans mm0 et mm1 */
+ "movq (%3,%1,4), %%mm0 \n\t" /* b1-v1-r1-a1-b2-v2-r2-a2 */
+ "movq %%mm0, %%mm1 \n\t" /* b1-v1-r1-a1-b2-v2-r2-a2 */
+ /* depackage du premier pixel */
+ "punpcklbw %%mm7, %%mm0 \n\t" /* 00-b2-00-v2-00-r2-00-a2 */
+ "movq %%mm6, %%mm5 \n\t" /* ??-??-??-??-c4-c3-c2-c1 */
+ /* depackage du 2ieme pixel */
+ "punpckhbw %%mm7, %%mm1 \n\t" /* 00-b1-00-v1-00-r1-00-a1 */
+ /* extraction des coefficients... */
+ "punpcklbw %%mm5, %%mm6 \n\t" /* c4-c4-c3-c3-c2-c2-c1-c1 */
+ "movq %%mm6, %%mm4 \n\t" /* c4-c4-c3-c3-c2-c2-c1-c1 */
+ "movq %%mm6, %%mm5 \n\t" /* c4-c4-c3-c3-c2-c2-c1-c1 */
+ "punpcklbw %%mm5, %%mm6 \n\t" /* c2-c2-c2-c2-c1-c1-c1-c1 */
+ "punpckhbw %%mm5, %%mm4 \n\t" /* c4-c4-c4-c4-c3-c3-c3-c3 */
+ "movq %%mm6, %%mm3 \n\t" /* c2-c2-c2-c2-c1-c1-c1-c1 */
+ "punpcklbw %%mm7, %%mm6 \n\t" /* 00-c1-00-c1-00-c1-00-c1 */
+ "punpckhbw %%mm7, %%mm3 \n\t" /* 00-c2-00-c2-00-c2-00-c2 */
+ /* multiplication des pixels par les coefficients */
+ "pmullw %%mm6, %%mm0 \n\t" /* c1*b2-c1*v2-c1*r2-c1*a2 */
+ "pmullw %%mm3, %%mm1 \n\t" /* c2*b1-c2*v1-c2*r1-c2*a1 */
+ "paddw %%mm1, %%mm0 \n\t"
+ /* ...extraction des 2 derniers coefficients */
+ "movq %%mm4, %%mm5 \n\t" /* c4-c4-c4-c4-c3-c3-c3-c3 */
+ "punpcklbw %%mm7, %%mm4 \n\t" /* 00-c3-00-c3-00-c3-00-c3 */
+ "punpckhbw %%mm7, %%mm5 \n\t" /* 00-c4-00-c4-00-c4-00-c4 */
+ /* ajouter la longueur de ligne a esi */
+ "addl 8(%%ebp),%1 \n\t"
+ /* recuperation des 2 derniers pixels */
+ "movq (%3,%1,4), %%mm1 \n\t" "movq %%mm1, %%mm2 \n\t"
+ /* depackage des pixels */
+ "punpcklbw %%mm7, %%mm1 \n\t" "punpckhbw %%mm7, %%mm2 \n\t"
+ /* multiplication pas les coeffs */
+ "pmullw %%mm4, %%mm1 \n\t" "pmullw %%mm5, %%mm2 \n\t"
+ /* ajout des valeurs obtenues ? la valeur finale */
+ "paddw %%mm1, %%mm0 \n\t" "paddw %%mm2, %%mm0 \n\t"
+ /* division par 256 = 16+16+16+16, puis repackage du pixel final */
+ "psrlw $8, %%mm0 \n\t"
+ "packuswb %%mm7, %%mm0 \n\t" "movd %%mm0,%0 \n\t":"=g" (expix2[loop])
+ :"r" (pos), "r" (coeffs), "r" (expix1)
+
+ );
+
+ emms ();
+ }
+}
+
+#define DRAWMETHOD_PLUS_MMX(_out,_backbuf,_col) \
+{ \
+ movd_m2r(_backbuf, mm0); \
+ paddusb_m2r(_col, mm0); \
+ movd_r2m(mm0, _out); \
+}
+
+#define DRAWMETHOD DRAWMETHOD_PLUS_MMX(*p,*p,col)
+
+void
+draw_line_mmx (Pixel * data, int x1, int y1, int x2, int y2, int col,
+ int screenx, int screeny)
+{
+ int x, y, dx, dy, yy, xx;
+ Pixel *p;
+
+ if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny)
+ || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx))
+ goto end_of_line;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (x1 >= x2) {
+ int tmp;
+
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ dx = x2 - x1;
+ dy = y2 - y1;
+ }
+
+ /* vertical line */
+ if (dx == 0) {
+ if (y1 < y2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (y = y1; y <= y2; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ } else {
+ p = &(data[(screenx * y2) + x1]);
+ for (y = y2; y <= y1; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ }
+ goto end_of_line;
+ }
+ /* horizontal line */
+ if (dy == 0) {
+ if (x1 < x2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (x = x1; x <= x2; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ goto end_of_line;
+ } else {
+ p = &(data[(screenx * y1) + x2]);
+ for (x = x2; x <= x1; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ goto end_of_line;
+ }
+ }
+ /* 1 */
+ /* \ */
+ /* \ */
+ /* 2 */
+ if (y2 > y1) {
+ /* steep */
+ if (dy > dx) {
+ dx = ((dx << 16) / dy);
+ x = x1 << 16;
+ for (y = y1; y <= y2; y++) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p++;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ goto end_of_line;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ }
+ }
+ /* 2 */
+ /* / */
+ /* / */
+ /* 1 */
+ else {
+ /* steep */
+ if (-dy > dx) {
+ dx = ((dx << 16) / -dy);
+ x = (x1 + 1) << 16;
+ for (y = y1; y >= y2; y--) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p--;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ goto end_of_line;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ goto end_of_line;
+ }
+ }
+end_of_line:
+ emms ();
+ /* __asm__ __volatile__ ("emms"); */
+}
+#else
+int
+mmx_supported (void)
+{
+ return (0);
+}
+#endif /* HAVE_MMX */
diff --git a/subprojects/gst-plugins-good/gst/goom/mmx.h b/subprojects/gst-plugins-good/gst/goom/mmx.h
new file mode 100644
index 0000000000..2649e109ea
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/mmx.h
@@ -0,0 +1,741 @@
+/* mmx.h
+
+ MultiMedia eXtensions GCC interface library for IA32.
+
+ To use this library, simply include this header file
+ and compile with GCC. You MUST have inlining enabled
+ in order for mmx_ok() to work; this can be done by
+ simply using -O on the GCC command line.
+
+ Compiling with -DMMX_TRACE will cause detailed trace
+ output to be sent to stderr for each mmx operation.
+ This adds lots of code, and obviously slows execution to
+ a crawl, but can be very useful for debugging.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ 1997-99 by H. Dietz and R. Fisher
+
+ Notes:
+ It appears that the latest gas has the pand problem fixed, therefore
+ I'll undefine BROKEN_PAND by default.
+*/
+
+#ifndef _MMX_H
+#define _MMX_H
+
+#include "goom_graphic.h"
+
+/* Warning: at this writing, the version of GAS packaged
+ with most Linux distributions does not handle the
+ parallel AND operation mnemonic correctly. If the
+ symbol BROKEN_PAND is defined, a slower alternative
+ coding will be used. If execution of mmxtest results
+ in an illegal instruction fault, define this symbol.
+*/
+#undef BROKEN_PAND
+
+
+/* The type of an value that fits in an MMX register
+ (note that long long constant values MUST be suffixed
+ by LL and unsigned long long values by ULL, lest
+ they be truncated by the compiler)
+*/
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} __attribute__ ((aligned (8))) mmx_t; /* On an 8-byte (64-bit) boundary */
+
+
+
+/* Function to test if multimedia instructions are supported...
+*/
+static int
+mm_support(void)
+{
+ /* Returns 1 if MMX instructions are supported,
+ 3 if Cyrix MMX and Extended MMX instructions are supported
+ 5 if AMD MMX and 3DNow! instructions are supported
+ 13 if AMD Extended MMX, &3dNow supported
+ 0 if hardware does not support any of these
+ */
+ register int rval = 0;
+
+ __asm__ __volatile__ (
+ /* See if CPUID instruction is supported ... */
+ /* ... Get copies of EFLAGS into eax and ecx */
+ "pushl %%ebx\n\t"
+ "pushf\n\t"
+ "popl %%eax\n\t"
+ "movl %%eax, %%ecx\n\t"
+
+ /* ... Toggle the ID bit in one copy and store */
+ /* to the EFLAGS reg */
+ "xorl $0x200000, %%eax\n\t"
+ "push %%eax\n\t"
+ "popf\n\t"
+
+ /* ... Get the (hopefully modified) EFLAGS */
+ "pushf\n\t"
+ "popl %%eax\n\t"
+
+ /* ... Compare and test result */
+ "xorl %%eax, %%ecx\n\t"
+ "testl $0x200000, %%ecx\n\t"
+ "jz NotSupported1\n\t" /* CPUID not supported */
+
+
+ /* Get standard CPUID information, and
+ go to a specific vendor section */
+ "movl $0, %%eax\n\t"
+ "cpuid\n\t"
+
+ /* Check for Intel */
+ "cmpl $0x756e6547, %%ebx\n\t"
+ "jne TryAMD\n\t"
+ "cmpl $0x49656e69, %%edx\n\t"
+ "jne TryAMD\n\t"
+ "cmpl $0x6c65746e, %%ecx\n"
+ "jne TryAMD\n\t"
+ "jmp Intel\n\t"
+
+ /* Check for AMD */
+ "\nTryAMD:\n\t"
+ "cmpl $0x68747541, %%ebx\n\t"
+ "jne TryCyrix\n\t"
+ "cmpl $0x69746e65, %%edx\n\t"
+ "jne TryCyrix\n\t"
+ "cmpl $0x444d4163, %%ecx\n"
+ "jne TryCyrix\n\t"
+ "jmp AMD\n\t"
+
+ /* Check for Cyrix */
+ "\nTryCyrix:\n\t"
+ "cmpl $0x69727943, %%ebx\n\t"
+ "jne NotSupported2\n\t"
+ "cmpl $0x736e4978, %%edx\n\t"
+ "jne NotSupported3\n\t"
+ "cmpl $0x64616574, %%ecx\n\t"
+ "jne NotSupported4\n\t"
+ /* Drop through to Cyrix... */
+
+
+ /* Cyrix Section */
+ /* See if extended CPUID level 80000001 is supported */
+ /* The value of CPUID/80000001 for the 6x86MX is undefined
+ according to the Cyrix CPU Detection Guide (Preliminary
+ Rev. 1.01 table 1), so we'll check the value of eax for
+ CPUID/0 to see if standard CPUID level 2 is supported.
+ According to the table, the only CPU which supports level
+ 2 is also the only one which supports extended CPUID levels.
+ */
+ "cmpl $0x2, %%eax\n\t"
+ "jne MMXtest\n\t" /* Use standard CPUID instead */
+
+ /* Extended CPUID supported (in theory), so get extended
+ features */
+ "movl $0x80000001, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%eax\n\t" /* Test for MMX */
+ "jz NotSupported5\n\t" /* MMX not supported */
+ "testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */
+ "jnz EMMXSupported\n\t"
+ "movl $1, %0\n\n\t" /* MMX Supported */
+ "jmp Return\n\n"
+ "EMMXSupported:\n\t"
+ "movl $3, %0\n\n\t" /* EMMX and MMX Supported */
+ "jmp Return\n\t"
+
+
+ /* AMD Section */
+ "AMD:\n\t"
+
+ /* See if extended CPUID is supported */
+ "movl $0x80000000, %%eax\n\t"
+ "cpuid\n\t"
+ "cmpl $0x80000000, %%eax\n\t"
+ "jl MMXtest\n\t" /* Use standard CPUID instead */
+
+ /* Extended CPUID supported, so get extended features */
+ "movl $0x80000001, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%edx\n\t" /* Test for MMX */
+ "jz NotSupported6\n\t" /* MMX not supported */
+ "testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */
+ "jnz ThreeDNowSupported\n\t"
+ "movl $1, %0\n\n\t" /* MMX Supported */
+ "jmp Return\n\n"
+ "ThreeDNowSupported:\n\t"
+ "testl $0x40000000, %%edx\n\t" /* Test AMD Extended MMX */
+ "jnz AMDXMMXSupported\n\t"
+ "movl $5, %0\n\n\t" /* 3DNow! and MMX Supported */
+ "jmp Return\n\t"
+ "AMDXMMXSupported:\n\t"
+ "movl $13, %0\n\n\t" /* XMMX, 3DNow! and MMX Supported */
+ "jmp Return\n\t"
+
+
+ /* Intel Section */
+ "Intel:\n\t"
+
+ /* Check for MMX */
+ "MMXtest:\n\t"
+ "movl $1, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%edx\n\t" /* Test for MMX */
+ "jz NotSupported7\n\t" /* MMX Not supported */
+ "movl $1, %0\n\n\t" /* MMX Supported */
+ "jmp Return\n\t"
+
+ /* Nothing supported */
+ "\nNotSupported1:\n\t"
+ "#movl $101, %0\n\n\t"
+ "\nNotSupported2:\n\t"
+ "#movl $102, %0\n\n\t"
+ "\nNotSupported3:\n\t"
+ "#movl $103, %0\n\n\t"
+ "\nNotSupported4:\n\t"
+ "#movl $104, %0\n\n\t"
+ "\nNotSupported5:\n\t"
+ "#movl $105, %0\n\n\t"
+ "\nNotSupported6:\n\t"
+ "#movl $106, %0\n\n\t"
+ "\nNotSupported7:\n\t"
+ "#movl $107, %0\n\n\t"
+ "movl $0, %0\n\n\t"
+
+ "Return:\n\t"
+ "popl %%ebx\n\t"
+ : "=X" (rval)
+ : /* no input */
+ : "eax", "ecx", "edx"
+ );
+
+ /* Return */
+ return(rval);
+}
+
+/* Function to test if mmx instructions are supported...
+*/
+static inline int
+mmx_ok(void)
+{
+ /* Returns 1 if MMX instructions are supported, 0 otherwise */
+ return ( mm_support() & 0x1 );
+}
+
+int mmx_supported (void);
+int xmmx_supported (void);
+
+
+/* MMX optimized implementations */
+void draw_line_mmx (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny);
+void draw_line_xmmx (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny);
+void zoom_filter_mmx (int prevX, int prevY, Pixel *expix1, Pixel *expix2,
+ int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+void zoom_filter_xmmx (int prevX, int prevY, Pixel *expix1, Pixel *expix2,
+ int *lbruS, int *lbruD, int buffratio, int precalCoef[16][16]);
+
+
+/* Helper functions for the instruction macros that follow...
+ (note that memory-to-register, m2r, instructions are nearly
+ as efficient as register-to-register, r2r, instructions;
+ however, memory-to-memory instructions are really simulated
+ as a convenience, and are only 1/3 as efficient)
+*/
+#ifdef MMX_TRACE
+
+/* Include the stuff for printing a trace to stderr...
+*/
+
+#include <stdio.h>
+
+#define mmx_i2r(op, imm, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace.uq = (imm); \
+ printf(#op "_i2r(" #imm "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_m2r(op, mem, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mem); \
+ printf(#op "_m2r(" #mem "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "m" (mem)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_r2m(op, reg, mem) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#op "_r2m(" #reg "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ mmx_trace = (mem); \
+ printf(#mem "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=m" (mem) \
+ : /* nothing */ ); \
+ mmx_trace = (mem); \
+ printf(#mem "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_r2r(op, regs, regd) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #regs ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#op "_r2r(" #regs "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#regd "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#regd "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_m2m(op, mems, memd) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mems); \
+ printf(#op "_m2m(" #mems "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ mmx_trace = (memd); \
+ printf(#memd "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=m" (memd) \
+ : "m" (mems)); \
+ mmx_trace = (memd); \
+ printf(#memd "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#else
+
+/* These macros are a lot simpler without the tracing...
+*/
+
+#define mmx_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "m" (mem))
+
+#define mmx_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=m" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define mmx_m2m(op, mems, memd) \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=m" (memd) \
+ : "m" (mems))
+
+#endif
+
+
+/* 1x64 MOVe Quadword
+ (this is both a load and a store...
+ in fact, it is the only way to store)
+*/
+#define movq_m2r(var, reg) mmx_m2r(movq, var, reg)
+#define movq_r2m(reg, var) mmx_r2m(movq, reg, var)
+#define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd)
+#define movq(vars, vard) \
+ __asm__ __volatile__ ("movq %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (vard) \
+ : "X" (vars))
+
+
+/* 1x32 MOVe Doubleword
+ (like movq, this is both load and store...
+ but is most useful for moving things between
+ mmx registers and ordinary registers)
+*/
+#define movd_m2r(var, reg) mmx_m2r(movd, var, reg)
+#define movd_r2m(reg, var) mmx_r2m(movd, reg, var)
+#define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd)
+#define movd(vars, vard) \
+ __asm__ __volatile__ ("movd %1, %%mm0\n\t" \
+ "movd %%mm0, %0" \
+ : "=X" (vard) \
+ : "X" (vars))
+
+
+/* 2x32, 4x16, and 8x8 Parallel ADDs
+*/
+#define paddd_m2r(var, reg) mmx_m2r(paddd, var, reg)
+#define paddd_r2r(regs, regd) mmx_r2r(paddd, regs, regd)
+#define paddd(vars, vard) mmx_m2m(paddd, vars, vard)
+
+#define paddw_m2r(var, reg) mmx_m2r(paddw, var, reg)
+#define paddw_r2r(regs, regd) mmx_r2r(paddw, regs, regd)
+#define paddw(vars, vard) mmx_m2m(paddw, vars, vard)
+
+#define paddb_m2r(var, reg) mmx_m2r(paddb, var, reg)
+#define paddb_r2r(regs, regd) mmx_r2r(paddb, regs, regd)
+#define paddb(vars, vard) mmx_m2m(paddb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel ADDs using Saturation arithmetic
+*/
+#define paddsw_m2r(var, reg) mmx_m2r(paddsw, var, reg)
+#define paddsw_r2r(regs, regd) mmx_r2r(paddsw, regs, regd)
+#define paddsw(vars, vard) mmx_m2m(paddsw, vars, vard)
+
+#define paddsb_m2r(var, reg) mmx_m2r(paddsb, var, reg)
+#define paddsb_r2r(regs, regd) mmx_r2r(paddsb, regs, regd)
+#define paddsb(vars, vard) mmx_m2m(paddsb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel ADDs using Unsigned Saturation arithmetic
+*/
+#define paddusw_m2r(var, reg) mmx_m2r(paddusw, var, reg)
+#define paddusw_r2r(regs, regd) mmx_r2r(paddusw, regs, regd)
+#define paddusw(vars, vard) mmx_m2m(paddusw, vars, vard)
+
+#define paddusb_m2r(var, reg) mmx_m2r(paddusb, var, reg)
+#define paddusb_r2r(regs, regd) mmx_r2r(paddusb, regs, regd)
+#define paddusb(vars, vard) mmx_m2m(paddusb, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel SUBs
+*/
+#define psubd_m2r(var, reg) mmx_m2r(psubd, var, reg)
+#define psubd_r2r(regs, regd) mmx_r2r(psubd, regs, regd)
+#define psubd(vars, vard) mmx_m2m(psubd, vars, vard)
+
+#define psubw_m2r(var, reg) mmx_m2r(psubw, var, reg)
+#define psubw_r2r(regs, regd) mmx_r2r(psubw, regs, regd)
+#define psubw(vars, vard) mmx_m2m(psubw, vars, vard)
+
+#define psubb_m2r(var, reg) mmx_m2r(psubb, var, reg)
+#define psubb_r2r(regs, regd) mmx_r2r(psubb, regs, regd)
+#define psubb(vars, vard) mmx_m2m(psubb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel SUBs using Saturation arithmetic
+*/
+#define psubsw_m2r(var, reg) mmx_m2r(psubsw, var, reg)
+#define psubsw_r2r(regs, regd) mmx_r2r(psubsw, regs, regd)
+#define psubsw(vars, vard) mmx_m2m(psubsw, vars, vard)
+
+#define psubsb_m2r(var, reg) mmx_m2r(psubsb, var, reg)
+#define psubsb_r2r(regs, regd) mmx_r2r(psubsb, regs, regd)
+#define psubsb(vars, vard) mmx_m2m(psubsb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel SUBs using Unsigned Saturation arithmetic
+*/
+#define psubusw_m2r(var, reg) mmx_m2r(psubusw, var, reg)
+#define psubusw_r2r(regs, regd) mmx_r2r(psubusw, regs, regd)
+#define psubusw(vars, vard) mmx_m2m(psubusw, vars, vard)
+
+#define psubusb_m2r(var, reg) mmx_m2r(psubusb, var, reg)
+#define psubusb_r2r(regs, regd) mmx_r2r(psubusb, regs, regd)
+#define psubusb(vars, vard) mmx_m2m(psubusb, vars, vard)
+
+
+/* 4x16 Parallel MULs giving Low 4x16 portions of results
+*/
+#define pmullw_m2r(var, reg) mmx_m2r(pmullw, var, reg)
+#define pmullw_r2r(regs, regd) mmx_r2r(pmullw, regs, regd)
+#define pmullw(vars, vard) mmx_m2m(pmullw, vars, vard)
+
+
+/* 4x16 Parallel MULs giving High 4x16 portions of results
+*/
+#define pmulhw_m2r(var, reg) mmx_m2r(pmulhw, var, reg)
+#define pmulhw_r2r(regs, regd) mmx_r2r(pmulhw, regs, regd)
+#define pmulhw(vars, vard) mmx_m2m(pmulhw, vars, vard)
+
+
+/* 4x16->2x32 Parallel Mul-ADD
+ (muls like pmullw, then adds adjacent 16-bit fields
+ in the multiply result to make the final 2x32 result)
+*/
+#define pmaddwd_m2r(var, reg) mmx_m2r(pmaddwd, var, reg)
+#define pmaddwd_r2r(regs, regd) mmx_r2r(pmaddwd, regs, regd)
+#define pmaddwd(vars, vard) mmx_m2m(pmaddwd, vars, vard)
+
+
+/* 1x64 bitwise AND
+*/
+#ifdef BROKEN_PAND
+#define pand_m2r(var, reg) \
+ { \
+ mmx_m2r(pandn, (mmx_t) -1LL, reg); \
+ mmx_m2r(pandn, var, reg); \
+ }
+#define pand_r2r(regs, regd) \
+ { \
+ mmx_m2r(pandn, (mmx_t) -1LL, regd); \
+ mmx_r2r(pandn, regs, regd) \
+ }
+#define pand(vars, vard) \
+ { \
+ movq_m2r(vard, mm0); \
+ mmx_m2r(pandn, (mmx_t) -1LL, mm0); \
+ mmx_m2r(pandn, vars, mm0); \
+ movq_r2m(mm0, vard); \
+ }
+#else
+#define pand_m2r(var, reg) mmx_m2r(pand, var, reg)
+#define pand_r2r(regs, regd) mmx_r2r(pand, regs, regd)
+#define pand(vars, vard) mmx_m2m(pand, vars, vard)
+#endif
+
+
+/* 1x64 bitwise AND with Not the destination
+*/
+#define pandn_m2r(var, reg) mmx_m2r(pandn, var, reg)
+#define pandn_r2r(regs, regd) mmx_r2r(pandn, regs, regd)
+#define pandn(vars, vard) mmx_m2m(pandn, vars, vard)
+
+
+/* 1x64 bitwise OR
+*/
+#define por_m2r(var, reg) mmx_m2r(por, var, reg)
+#define por_r2r(regs, regd) mmx_r2r(por, regs, regd)
+#define por(vars, vard) mmx_m2m(por, vars, vard)
+
+
+/* 1x64 bitwise eXclusive OR
+*/
+#define pxor_m2r(var, reg) mmx_m2r(pxor, var, reg)
+#define pxor_r2r(regs, regd) mmx_r2r(pxor, regs, regd)
+#define pxor(vars, vard) mmx_m2m(pxor, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel CoMPare for EQuality
+ (resulting fields are either 0 or -1)
+*/
+#define pcmpeqd_m2r(var, reg) mmx_m2r(pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs, regd) mmx_r2r(pcmpeqd, regs, regd)
+#define pcmpeqd(vars, vard) mmx_m2m(pcmpeqd, vars, vard)
+
+#define pcmpeqw_m2r(var, reg) mmx_m2r(pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs, regd) mmx_r2r(pcmpeqw, regs, regd)
+#define pcmpeqw(vars, vard) mmx_m2m(pcmpeqw, vars, vard)
+
+#define pcmpeqb_m2r(var, reg) mmx_m2r(pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs, regd) mmx_r2r(pcmpeqb, regs, regd)
+#define pcmpeqb(vars, vard) mmx_m2m(pcmpeqb, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel CoMPare for Greater Than
+ (resulting fields are either 0 or -1)
+*/
+#define pcmpgtd_m2r(var, reg) mmx_m2r(pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs, regd) mmx_r2r(pcmpgtd, regs, regd)
+#define pcmpgtd(vars, vard) mmx_m2m(pcmpgtd, vars, vard)
+
+#define pcmpgtw_m2r(var, reg) mmx_m2r(pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs, regd) mmx_r2r(pcmpgtw, regs, regd)
+#define pcmpgtw(vars, vard) mmx_m2m(pcmpgtw, vars, vard)
+
+#define pcmpgtb_m2r(var, reg) mmx_m2r(pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs, regd) mmx_r2r(pcmpgtb, regs, regd)
+#define pcmpgtb(vars, vard) mmx_m2m(pcmpgtb, vars, vard)
+
+
+/* 1x64, 2x32, and 4x16 Parallel Shift Left Logical
+*/
+#define psllq_i2r(imm, reg) mmx_i2r(psllq, imm, reg)
+#define psllq_m2r(var, reg) mmx_m2r(psllq, var, reg)
+#define psllq_r2r(regs, regd) mmx_r2r(psllq, regs, regd)
+#define psllq(vars, vard) mmx_m2m(psllq, vars, vard)
+
+#define pslld_i2r(imm, reg) mmx_i2r(pslld, imm, reg)
+#define pslld_m2r(var, reg) mmx_m2r(pslld, var, reg)
+#define pslld_r2r(regs, regd) mmx_r2r(pslld, regs, regd)
+#define pslld(vars, vard) mmx_m2m(pslld, vars, vard)
+
+#define psllw_i2r(imm, reg) mmx_i2r(psllw, imm, reg)
+#define psllw_m2r(var, reg) mmx_m2r(psllw, var, reg)
+#define psllw_r2r(regs, regd) mmx_r2r(psllw, regs, regd)
+#define psllw(vars, vard) mmx_m2m(psllw, vars, vard)
+
+
+/* 1x64, 2x32, and 4x16 Parallel Shift Right Logical
+*/
+#define psrlq_i2r(imm, reg) mmx_i2r(psrlq, imm, reg)
+#define psrlq_m2r(var, reg) mmx_m2r(psrlq, var, reg)
+#define psrlq_r2r(regs, regd) mmx_r2r(psrlq, regs, regd)
+#define psrlq(vars, vard) mmx_m2m(psrlq, vars, vard)
+
+#define psrld_i2r(imm, reg) mmx_i2r(psrld, imm, reg)
+#define psrld_m2r(var, reg) mmx_m2r(psrld, var, reg)
+#define psrld_r2r(regs, regd) mmx_r2r(psrld, regs, regd)
+#define psrld(vars, vard) mmx_m2m(psrld, vars, vard)
+
+#define psrlw_i2r(imm, reg) mmx_i2r(psrlw, imm, reg)
+#define psrlw_m2r(var, reg) mmx_m2r(psrlw, var, reg)
+#define psrlw_r2r(regs, regd) mmx_r2r(psrlw, regs, regd)
+#define psrlw(vars, vard) mmx_m2m(psrlw, vars, vard)
+
+
+/* 2x32 and 4x16 Parallel Shift Right Arithmetic
+*/
+#define psrad_i2r(imm, reg) mmx_i2r(psrad, imm, reg)
+#define psrad_m2r(var, reg) mmx_m2r(psrad, var, reg)
+#define psrad_r2r(regs, regd) mmx_r2r(psrad, regs, regd)
+#define psrad(vars, vard) mmx_m2m(psrad, vars, vard)
+
+#define psraw_i2r(imm, reg) mmx_i2r(psraw, imm, reg)
+#define psraw_m2r(var, reg) mmx_m2r(psraw, var, reg)
+#define psraw_r2r(regs, regd) mmx_r2r(psraw, regs, regd)
+#define psraw(vars, vard) mmx_m2m(psraw, vars, vard)
+
+
+/* 2x32->4x16 and 4x16->8x8 PACK and Signed Saturate
+ (packs source and dest fields into dest in that order)
+*/
+#define packssdw_m2r(var, reg) mmx_m2r(packssdw, var, reg)
+#define packssdw_r2r(regs, regd) mmx_r2r(packssdw, regs, regd)
+#define packssdw(vars, vard) mmx_m2m(packssdw, vars, vard)
+
+#define packsswb_m2r(var, reg) mmx_m2r(packsswb, var, reg)
+#define packsswb_r2r(regs, regd) mmx_r2r(packsswb, regs, regd)
+#define packsswb(vars, vard) mmx_m2m(packsswb, vars, vard)
+
+
+/* 4x16->8x8 PACK and Unsigned Saturate
+ (packs source and dest fields into dest in that order)
+*/
+#define packuswb_m2r(var, reg) mmx_m2r(packuswb, var, reg)
+#define packuswb_r2r(regs, regd) mmx_r2r(packuswb, regs, regd)
+#define packuswb(vars, vard) mmx_m2m(packuswb, vars, vard)
+
+
+/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK Low
+ (interleaves low half of dest with low half of source
+ as padding in each result field)
+*/
+#define punpckldq_m2r(var, reg) mmx_m2r(punpckldq, var, reg)
+#define punpckldq_r2r(regs, regd) mmx_r2r(punpckldq, regs, regd)
+#define punpckldq(vars, vard) mmx_m2m(punpckldq, vars, vard)
+
+#define punpcklwd_m2r(var, reg) mmx_m2r(punpcklwd, var, reg)
+#define punpcklwd_r2r(regs, regd) mmx_r2r(punpcklwd, regs, regd)
+#define punpcklwd(vars, vard) mmx_m2m(punpcklwd, vars, vard)
+
+#define punpcklbw_m2r(var, reg) mmx_m2r(punpcklbw, var, reg)
+#define punpcklbw_r2r(regs, regd) mmx_r2r(punpcklbw, regs, regd)
+#define punpcklbw(vars, vard) mmx_m2m(punpcklbw, vars, vard)
+
+
+/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK High
+ (interleaves high half of dest with high half of source
+ as padding in each result field)
+*/
+#define punpckhdq_m2r(var, reg) mmx_m2r(punpckhdq, var, reg)
+#define punpckhdq_r2r(regs, regd) mmx_r2r(punpckhdq, regs, regd)
+#define punpckhdq(vars, vard) mmx_m2m(punpckhdq, vars, vard)
+
+#define punpckhwd_m2r(var, reg) mmx_m2r(punpckhwd, var, reg)
+#define punpckhwd_r2r(regs, regd) mmx_r2r(punpckhwd, regs, regd)
+#define punpckhwd(vars, vard) mmx_m2m(punpckhwd, vars, vard)
+
+#define punpckhbw_m2r(var, reg) mmx_m2r(punpckhbw, var, reg)
+#define punpckhbw_r2r(regs, regd) mmx_r2r(punpckhbw, regs, regd)
+#define punpckhbw(vars, vard) mmx_m2m(punpckhbw, vars, vard)
+
+
+/* Empty MMx State
+ (used to clean-up when going from mmx to float use
+ of the registers that are shared by both; note that
+ there is no float-to-mmx operation needed, because
+ only the float tag word info is corruptible)
+*/
+#ifdef MMX_TRACE
+
+#ifdef __clang__
+#define emms() \
+ { \
+ printf("emms()\n"); \
+ __asm__ __volatile__ ("emms"); \
+ }
+#else
+#define emms() \
+ { \
+ printf("emms()\n"); \
+ __asm__ __volatile__ ("emms" \
+ "st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)"); \
+ }
+#endif
+
+#else
+
+#ifdef __clang__
+#define emms() __asm__ __volatile__ ("emms")
+#else
+#define emms() __asm__ __volatile__ ("emms"::: \
+ "st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)")
+#endif
+
+#endif
+
+#endif
+
diff --git a/subprojects/gst-plugins-good/gst/goom/motif_goom1.h b/subprojects/gst-plugins-good/gst/goom/motif_goom1.h
new file mode 100644
index 0000000000..82f381bdb0
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/motif_goom1.h
@@ -0,0 +1,1044 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+static Motif CONV_MOTIF1 = {
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,14,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,13,9,9,7,2,2,9,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,11,
+ 11,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,12,7,4,0,0,0,2,0,0,3,14,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,12,10,9,9,4,1,0,
+ 1,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,10,3,0,0,0,1,1,3,5,0,0,1,14,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,6,3,1,1,4,9,1,
+ 1,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 10,3,0,0,2,7,13,14,14,14,7,0,0,2,14,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,12,1,9,15,15,15,15,3,
+ 0,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,4,
+ 0,0,2,10,15,15,15,15,15,15,1,0,0,10,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,9,0,2,14,15,15,15,7,
+ 0,9,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,14,6,0,0,
+ 2,9,15,15,15,15,15,15,15,13,0,0,3,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,11,0,0,10,15,15,15,9,
+ 0,9,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,13,3,0,1,5,
+ 5,4,4,4,6,12,15,15,15,13,0,0,7,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,0,0,5,15,15,15,10,
+ 0,7,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,11,1,0,3,3,1,
+ 0,0,0,0,0,0,5,13,15,12,0,0,13,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,13,14,15,
+ 15,15,15,15,15,15,15,15,14,0,0,1,15,15,15,12,
+ 0,3,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,10,1,2,4,0,0,1,
+ 9,12,12,12,9,3,0,2,14,5,0,7,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,14,7,4,4,1,1,12,
+ 15,15,15,15,15,15,15,15,14,1,0,0,12,15,15,15,
+ 1,0,12,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,10,0,3,2,0,0,3,12,
+ 15,15,15,15,15,14,2,1,13,2,0,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,3,0,0,0,0,0,2,
+ 13,15,15,15,15,15,15,15,14,1,0,0,8,15,15,15,
+ 1,0,9,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,12,2,1,0,0,0,9,14,15,
+ 15,15,15,15,15,14,1,1,11,0,3,14,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,7,4,11,12,10,1,0,
+ 3,12,15,15,15,15,15,15,13,1,1,0,4,15,15,15,
+ 2,0,10,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,2,1,0,0,3,12,15,15,15,
+ 15,15,15,15,15,11,0,5,9,1,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,5,1,13,15,15,12,1,
+ 0,1,9,15,15,15,15,15,14,2,5,0,1,14,15,15,
+ 2,0,7,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,14,3,0,0,0,7,14,15,15,15,15,
+ 15,15,15,15,15,9,0,8,7,4,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,7,0,7,8,11,15,13,
+ 2,0,0,3,10,15,15,15,15,5,11,0,0,11,15,15,
+ 6,0,2,14,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,6,0,0,0,8,15,15,15,15,15,15,
+ 15,15,15,15,15,6,0,4,0,6,15,15,15,15,15,15,
+ 14,9,14,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,11,0,3,3,0,8,15,
+ 14,5,0,0,0,4,12,15,15,5,13,2,0,6,15,15,
+ 12,0,0,11,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,10,0,0,0,8,15,15,15,15,15,15,15,
+ 15,15,15,15,10,1,7,6,4,13,15,15,15,15,13,11,
+ 6,0,8,11,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,1,1,11,2,0,5,
+ 14,15,8,0,0,0,0,7,15,5,14,6,0,2,15,15,
+ 15,3,0,5,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,1,0,0,7,15,15,15,15,15,15,15,15,
+ 15,15,15,15,7,9,15,15,15,15,15,15,12,6,2,1,
+ 1,1,8,6,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,4,0,6,12,1,0,
+ 3,13,15,11,2,0,0,0,8,4,14,10,0,0,13,15,
+ 15,7,0,1,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,5,0,0,5,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,13,15,15,15,15,14,8,3,1,2,7,11,
+ 5,4,5,6,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,8,0,1,14,11,0,
+ 0,1,9,15,14,5,0,0,2,4,14,13,0,0,10,15,
+ 15,12,0,0,12,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,10,0,0,1,14,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,13,7,2,0,5,9,15,15,15,
+ 5,3,6,9,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,13,0,0,9,15,12,
+ 2,0,0,4,13,14,4,0,3,2,12,15,1,0,5,15,
+ 15,14,1,0,8,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,2,0,0,9,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,11,6,1,0,2,3,10,15,15,15,15,7,
+ 1,2,4,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,5,0,3,14,15,
+ 9,2,0,0,1,6,12,13,13,1,9,12,0,0,2,14,
+ 15,15,4,0,4,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,10,0,0,2,14,15,15,15,15,15,15,15,15,15,15,
+ 13,9,6,0,1,2,9,10,15,15,15,15,14,7,1,0,
+ 6,2,4,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,11,0,0,9,15,
+ 4,4,11,6,1,0,0,1,1,0,10,4,0,0,0,12,
+ 15,15,9,0,1,14,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,3,0,0,8,15,15,15,15,15,15,15,13,12,4,4,
+ 1,1,3,10,12,15,15,15,15,15,9,2,1,0,1,6,
+ 6,0,10,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,4,0,3,14,
+ 4,3,15,15,14,9,7,9,1,0,0,0,0,1,0,7,
+ 15,15,13,0,0,9,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 13,0,0,1,14,15,15,15,15,15,12,9,1,0,1,4,
+ 7,15,15,15,15,15,15,14,8,2,0,0,0,2,13,9,
+ 0,4,14,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,11,0,0,9,
+ 3,0,8,14,15,15,15,15,10,5,4,4,7,4,0,3,
+ 15,15,15,4,0,3,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 5,0,0,5,15,15,15,15,14,8,7,8,10,12,14,15,
+ 15,15,15,15,15,15,11,1,0,0,0,5,11,15,13,1,
+ 1,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,3,0,4,
+ 4,0,0,2,6,10,15,15,15,15,15,15,15,10,0,0,
+ 12,15,15,9,0,0,12,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 1,0,0,10,15,15,15,15,15,13,14,15,15,15,15,15,
+ 15,15,15,15,14,7,1,0,0,3,12,15,15,15,6,0,
+ 7,15,15,15,12,10,9,10,12,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,9,0,0,
+ 8,3,1,4,1,0,1,12,15,15,15,15,15,14,2,0,
+ 6,15,15,15,2,0,6,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 0,0,1,14,15,15,15,15,14,5,15,15,15,15,15,15,
+ 15,15,15,7,2,0,0,1,8,15,15,15,15,12,0,2,
+ 14,15,12,4,0,0,0,0,0,1,5,10,14,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,14,0,0,
+ 5,4,1,14,15,10,7,13,15,15,15,15,15,15,8,0,
+ 1,14,15,15,7,0,1,14,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 0,0,4,15,15,15,15,15,13,2,13,15,15,15,15,15,
+ 12,7,0,0,0,0,5,12,15,15,15,15,14,3,0,9,
+ 11,1,0,0,1,1,0,1,0,0,0,0,2,12,15,15,
+ 15,15,15,15,15,15,15,14,15,15,15,15,15,15,2,0,
+ 5,2,1,14,15,14,13,15,15,15,15,15,15,15,12,0,
+ 0,10,15,15,13,0,0,9,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,
+ 0,0,4,15,15,15,15,15,12,0,12,15,15,15,12,6,
+ 0,0,0,0,6,14,15,15,15,15,15,15,7,0,0,12,
+ 1,0,0,2,2,1,1,7,12,8,3,0,0,1,13,15,
+ 15,15,15,15,15,8,4,8,12,15,15,15,15,15,8,0,
+ 4,2,0,14,15,11,9,15,15,15,15,15,15,15,15,3,
+ 0,5,15,15,15,5,0,3,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,
+ 0,0,4,15,15,15,15,15,12,0,12,15,13,3,1,0,
+ 0,0,5,12,15,15,15,15,15,15,15,12,0,0,7,7,
+ 0,0,0,0,0,0,0,1,12,15,15,12,3,0,5,15,
+ 15,15,15,14,5,0,0,0,0,2,2,3,7,14,9,8,
+ 14,2,1,14,15,2,12,13,15,15,15,15,15,15,15,9,
+ 0,0,13,15,15,10,0,0,12,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 0,0,5,15,15,15,15,15,12,0,11,10,1,0,0,1,
+ 5,14,15,15,15,15,15,15,15,15,15,6,0,2,7,0,
+ 0,0,0,1,2,7,4,0,3,14,15,15,14,2,0,12,
+ 15,15,15,9,0,1,2,1,0,0,0,0,0,1,3,7,
+ 15,3,0,14,15,4,12,15,15,15,15,15,15,15,15,14,
+ 1,0,8,15,15,14,1,0,8,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 0,0,4,15,15,15,15,15,12,0,2,0,0,1,10,15,
+ 15,15,15,15,15,15,15,15,15,15,12,0,0,6,0,0,
+ 0,1,10,14,15,15,11,1,0,9,15,15,15,8,0,9,
+ 15,15,12,4,8,14,15,8,1,0,0,0,0,0,1,9,
+ 15,2,0,13,15,1,9,15,15,15,15,15,15,15,15,15,
+ 6,0,1,14,15,14,1,0,3,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,
+ 1,0,1,14,15,15,15,15,12,1,3,7,9,13,15,15,
+ 15,15,15,15,15,15,15,15,15,15,3,0,2,3,0,4,
+ 0,8,15,15,15,15,15,13,1,2,14,15,15,10,0,6,
+ 15,14,2,6,15,15,15,1,3,7,3,0,0,0,0,1,
+ 11,1,0,11,12,0,12,15,15,15,15,15,15,15,15,15,
+ 11,0,0,9,15,15,4,0,0,12,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 6,0,0,9,15,15,15,15,15,12,14,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,11,0,0,3,0,8,14,
+ 2,5,15,15,15,15,15,15,5,0,8,15,15,12,0,4,
+ 15,5,2,14,15,15,10,0,13,15,13,2,4,5,5,0,
+ 9,1,0,10,9,1,14,15,15,15,15,15,15,15,15,15,
+ 13,0,0,3,15,15,9,0,0,8,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 12,0,0,3,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,3,0,1,1,5,14,15,
+ 11,0,12,15,15,15,15,15,14,1,1,14,15,12,0,4,
+ 10,0,9,15,15,11,1,8,15,15,8,1,14,15,14,2,
+ 5,0,0,10,6,2,15,15,15,15,15,15,15,15,15,15,
+ 15,3,0,0,12,15,13,0,0,2,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,3,0,0,10,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,10,0,0,1,0,11,15,15,
+ 15,2,6,15,15,15,15,15,15,6,0,9,15,13,0,6,
+ 3,0,13,15,14,2,6,15,15,13,1,8,15,15,15,4,
+ 3,1,0,10,7,2,15,15,15,15,15,15,15,15,15,15,
+ 15,9,0,0,6,15,15,3,0,0,13,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,9,0,0,2,14,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,11,10,2,0,3,0,3,15,15,15,
+ 15,8,1,14,15,15,15,15,15,13,0,2,15,9,1,10,
+ 0,3,15,15,6,2,14,15,14,3,1,14,15,15,15,2,
+ 4,0,0,12,5,3,15,15,15,15,15,15,15,15,15,15,
+ 15,14,1,0,1,14,15,5,0,0,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,4,0,0,6,15,15,15,15,15,15,15,15,14,12,
+ 12,9,5,4,4,3,0,0,0,0,4,0,8,15,15,15,
+ 15,13,1,10,15,15,15,15,15,15,2,0,11,3,5,10,
+ 0,7,15,9,1,11,15,15,8,0,6,15,15,15,10,0,
+ 3,0,0,13,3,6,15,15,15,15,15,15,15,15,15,15,
+ 15,15,6,0,0,12,15,5,0,0,7,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,13,1,0,0,8,14,15,15,13,6,4,4,1,0,
+ 0,0,0,0,0,0,2,0,0,4,3,0,12,15,15,15,
+ 15,15,5,3,15,15,15,15,14,8,0,0,1,1,12,9,
+ 0,9,10,0,6,15,15,15,2,2,14,15,15,13,2,0,
+ 4,0,1,13,0,10,15,15,15,15,15,15,15,15,15,15,
+ 15,15,13,1,0,10,15,10,0,0,5,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,9,0,0,0,3,2,2,1,0,0,0,1,4,
+ 4,5,10,12,12,12,11,0,0,11,4,0,12,15,15,15,
+ 15,15,12,0,7,13,15,15,5,0,0,0,1,6,15,9,
+ 0,3,0,0,1,6,14,10,0,12,15,15,11,2,0,2,
+ 3,0,3,12,1,11,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,3,0,6,8,7,0,0,5,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,9,1,0,0,0,2,6,10,12,12,14,15,
+ 15,15,15,15,11,5,4,0,2,14,4,0,12,15,15,15,
+ 15,15,15,4,0,3,13,6,0,0,0,1,2,14,15,12,
+ 0,0,0,0,0,0,2,2,6,15,14,8,0,0,0,7,
+ 4,0,4,12,0,12,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,0,0,0,0,0,1,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,12,2,0,0,0,1,6,11,15,15,15,
+ 15,15,15,15,2,1,0,0,9,15,6,0,7,15,15,15,
+ 15,15,15,13,2,0,0,0,0,0,0,1,12,15,15,15,
+ 4,0,0,0,0,0,0,6,13,6,1,0,0,4,13,15,
+ 6,0,6,12,0,12,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,14,5,0,0,0,0,0,5,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,5,0,0,0,0,0,2,4,5,
+ 7,3,6,3,0,2,0,2,15,15,11,0,0,9,15,15,
+ 15,15,15,15,11,0,0,0,0,0,2,11,15,15,15,15,
+ 12,1,0,0,1,4,6,10,2,0,0,0,7,14,15,15,
+ 9,0,9,9,0,12,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,13,9,8,9,7,13,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,12,6,1,0,0,0,0,0,
+ 0,0,0,2,8,0,0,9,15,15,14,4,0,0,3,10,
+ 14,15,15,15,15,13,3,0,0,4,14,15,15,15,15,15,
+ 15,11,2,0,0,1,1,0,0,0,1,11,15,15,15,15,
+ 9,0,10,5,3,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,14,12,10,5,4,6,
+ 2,4,10,14,8,0,1,14,15,15,15,14,5,0,0,0,
+ 1,2,4,4,4,3,1,2,9,14,15,15,15,15,15,15,
+ 15,15,15,11,11,13,10,9,9,11,15,15,15,15,15,15,
+ 10,0,8,2,4,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 2,7,15,14,1,0,6,15,15,15,15,15,15,10,6,4,
+ 2,2,4,4,4,3,9,14,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 11,0,3,1,4,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,11,
+ 1,10,15,9,0,0,13,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 11,0,11,11,11,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,2,
+ 5,15,14,2,0,5,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 14,1,13,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,10,1,
+ 13,15,11,0,0,12,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,5,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,8,1,
+ 15,15,5,0,3,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,10,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,12,2,3,
+ 15,14,1,0,7,15,15,15,15,15,13,15,15,15,15,14,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,13,12,12,11,9,4,7,14,15,
+ 14,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,12,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,14,3,0,10,
+ 15,9,0,0,8,7,4,2,2,1,0,3,4,3,4,9,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,14,13,11,7,4,2,0,0,0,0,0,0,1,12,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,14,13,11,7,4,2,2,13,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,12,0,3,11,
+ 7,1,0,0,0,0,0,1,4,9,11,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,14,12,11,9,7,4,
+ 3,1,0,0,0,0,0,0,0,0,0,2,11,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,13,11,8,
+ 4,3,1,0,0,0,0,3,8,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,14,11,3,0,0,0,
+ 0,0,0,2,6,9,12,14,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,13,9,6,3,1,0,0,0,0,0,0,
+ 0,0,0,0,1,4,7,11,12,12,12,14,15,15,15,15,
+ 15,15,15,15,15,15,15,14,12,11,7,4,2,0,0,0,
+ 0,0,0,1,5,10,13,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,12,7,3,1,0,0,0,2,5,
+ 2,0,2,14,15,15,15,15,15,15,15,15,15,14,13,12,
+ 11,9,6,4,2,0,0,0,0,0,0,0,0,1,2,4,
+ 5,9,11,13,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,14,12,11,7,4,3,1,0,0,0,0,0,0,0,1,
+ 4,5,10,14,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,10,5,1,0,0,0,1,0,0,2,13,14,
+ 1,0,8,15,15,14,12,11,9,8,4,3,2,1,0,0,
+ 0,0,0,0,1,3,2,3,5,9,10,12,13,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,13,11,10,6,4,
+ 3,1,0,0,0,0,0,0,0,0,1,4,7,11,13,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,11,4,0,0,0,1,4,9,13,13,1,0,0,1,7,
+ 0,0,7,8,5,2,0,0,0,0,0,0,1,2,3,4,
+ 5,9,10,12,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,14,11,8,4,3,1,0,0,0,0,0,
+ 0,0,0,0,1,4,5,9,12,13,15,15,15,15,15,15,
+ 15,15,14,12,9,8,8,7,4,2,5,4,5,5,12,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,14,10,5,
+ 1,0,1,3,6,11,14,15,15,15,15,13,12,8,3,2,
+ 0,0,1,1,3,3,4,5,8,10,12,13,14,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 11,9,6,4,2,1,0,0,0,0,0,0,0,1,2,4,
+ 6,10,11,13,15,15,15,15,15,15,15,15,13,11,9,7,
+ 4,2,1,0,0,0,0,2,4,7,12,14,14,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,10,5,1,1,3,
+ 8,12,14,15,15,15,15,15,15,15,15,15,15,15,15,9,
+ 3,11,14,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,8,6,9,9,9,9,9,8,5,4,4,3,1,0,
+ 0,0,0,0,1,2,3,2,4,5,9,11,12,14,15,15,
+ 15,15,15,15,15,15,15,14,12,9,5,2,0,0,0,0,
+ 0,1,2,4,7,10,14,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,14,9,4,1,3,9,13,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 11,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,13,3,1,1,1,1,1,1,1,0,0,0,0,2,3,
+ 5,8,10,12,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,12,5,2,0,0,0,1,3,4,7,10,
+ 12,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,13,11,13,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,14,12,12,12,13,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,8,1,0,1,4,7,11,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,7,8,11,14,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15}
+ };
diff --git a/subprojects/gst-plugins-good/gst/goom/motif_goom2.h b/subprojects/gst-plugins-good/gst/goom/motif_goom2.h
new file mode 100644
index 0000000000..2de92afa29
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/motif_goom2.h
@@ -0,0 +1,1044 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+static Motif CONV_MOTIF2 = {
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,12,5,14,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,12,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,10,1,14,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,10,0,12,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,6,0,12,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,7,0,8,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,13,2,0,10,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,6,0,2,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,5,0,0,10,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,9,0,0,12,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,14,9,0,0,1,14,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,8,0,0,8,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,8,3,0,0,0,9,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,11,0,0,2,14,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,9,5,3,4,1,0,0,0,0,7,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,14,4,0,0,4,11,13,13,15,15,14,12,10,8,5,
+ 6,4,1,0,0,0,0,0,0,0,0,0,0,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,12,1,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,9,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 13,9,10,13,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,3,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,2,5,6,0,0,0,0,12,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 5,0,0,0,3,10,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,14,9,2,1,0,0,0,1,4,6,6,1,
+ 0,0,0,8,13,15,15,15,12,1,0,2,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,
+ 2,0,0,0,0,0,4,12,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,3,0,0,10,15,15,15,10,
+ 0,0,4,15,15,15,15,15,15,2,0,6,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,5,
+ 3,11,5,0,0,0,0,0,4,11,14,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,0,13,15,15,15,11,
+ 0,0,7,15,15,15,15,15,15,1,0,9,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,9,0,
+ 13,15,15,12,5,0,0,0,0,0,1,8,14,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,1,14,15,15,15,11,
+ 0,0,7,15,15,15,15,15,14,0,0,9,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,11,1,10,
+ 15,15,15,15,15,11,5,0,0,0,0,0,1,6,13,15,
+ 15,15,15,15,14,8,11,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,6,0,2,15,15,15,15,11,
+ 0,0,6,15,15,15,15,15,13,0,0,11,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,11,1,6,15,
+ 15,15,15,15,15,15,15,14,5,0,0,0,0,0,0,6,
+ 14,15,15,15,6,0,4,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,5,15,15,15,15,11,
+ 0,0,5,15,15,15,15,15,12,0,0,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,13,2,1,13,15,
+ 15,15,15,15,15,15,15,15,15,12,2,0,0,0,0,0,
+ 1,6,11,7,0,0,4,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,7,15,15,15,15,11,
+ 0,0,6,15,15,15,15,15,12,0,0,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,5,0,7,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,11,5,0,0,0,
+ 0,0,0,0,0,1,11,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,10,15,15,15,15,11,
+ 0,0,6,15,15,15,15,15,12,0,0,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,10,0,4,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,13,7,0,
+ 0,0,0,0,0,1,6,12,14,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,10,15,15,15,15,11,
+ 0,0,7,15,15,15,15,15,12,0,0,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,13,1,1,12,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,
+ 5,0,0,0,0,0,0,0,3,10,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,10,15,15,15,15,11,
+ 0,0,7,15,15,15,15,15,11,0,0,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,14,4,0,8,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 13,0,0,0,1,0,0,0,0,1,13,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,10,15,15,15,15,11,
+ 0,0,8,15,15,15,15,15,8,0,2,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,9,0,4,14,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,
+ 4,0,0,5,13,12,6,2,0,2,13,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,7,0,10,15,15,15,15,11,
+ 0,0,7,15,15,15,15,15,4,0,4,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,13,1,1,13,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,11,
+ 0,0,1,13,15,15,15,14,9,13,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,5,0,6,15,15,15,15,11,
+ 0,0,8,15,15,15,15,15,2,0,8,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,5,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,11,15,15,15,15,15,15,15,9,
+ 0,0,10,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,4,0,4,15,15,15,15,11,
+ 0,0,7,15,15,15,15,13,0,0,11,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,10,0,3,14,15,15,15,15,15,15,
+ 15,15,15,15,15,14,3,0,13,15,15,15,15,15,15,14,
+ 9,11,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,4,0,4,15,15,15,15,11,
+ 0,0,8,15,15,15,15,12,0,0,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,14,2,1,12,15,15,15,15,15,15,15,
+ 15,15,15,15,14,3,0,0,9,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,6,0,3,15,15,15,15,13,
+ 1,0,8,15,15,15,15,12,0,0,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,9,0,5,15,15,15,15,15,15,15,15,
+ 15,15,15,14,4,0,0,0,10,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,8,0,2,15,15,15,15,15,
+ 3,0,13,15,15,15,15,12,0,0,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,13,2,1,12,15,15,15,15,15,15,15,15,
+ 15,15,15,7,0,0,0,0,8,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,10,0,1,14,15,15,15,15,
+ 11,5,15,15,15,15,15,12,0,0,11,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,6,0,7,15,15,15,15,15,15,15,15,15,
+ 15,15,8,0,0,0,0,0,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,12,0,0,12,15,15,15,15,
+ 15,14,15,15,15,15,15,10,0,0,12,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,1,2,14,15,15,15,15,15,15,15,15,15,
+ 15,10,0,0,0,6,6,0,0,0,5,12,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,12,
+ 15,15,15,15,15,15,15,15,13,0,0,11,15,15,15,15,
+ 15,15,15,15,15,15,15,9,0,1,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,7,0,8,15,15,15,15,15,15,15,15,15,15,
+ 15,9,0,0,4,15,15,8,0,0,0,1,5,13,15,15,
+ 15,15,15,15,15,15,15,15,15,15,12,8,7,6,5,3,
+ 3,3,4,12,15,15,15,15,15,15,15,15,15,7,0,6,
+ 15,15,15,15,15,15,15,15,14,1,0,10,15,15,15,15,
+ 15,15,15,15,15,15,15,6,0,3,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,13,1,0,13,15,15,15,15,15,15,15,15,15,15,
+ 15,14,7,8,13,15,15,15,11,2,0,0,0,0,5,11,
+ 15,15,15,15,15,15,15,15,13,3,0,0,0,0,0,0,
+ 0,0,0,5,15,15,15,15,15,15,15,15,12,1,0,0,
+ 3,11,15,15,15,15,15,15,13,1,0,10,15,15,15,15,
+ 15,15,15,15,15,15,15,3,0,5,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,9,0,5,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,14,8,1,0,0,0,0,
+ 4,12,15,15,15,15,15,15,4,0,0,0,0,0,0,0,
+ 0,0,0,2,15,15,15,15,15,15,15,14,4,0,0,0,
+ 0,0,9,15,15,15,15,15,14,1,0,10,15,15,15,15,
+ 15,15,15,15,15,15,15,2,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,14,4,0,11,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,14,8,2,0,0,
+ 0,0,4,10,14,15,15,15,4,0,0,0,0,0,0,0,
+ 0,0,0,3,15,15,15,15,15,15,15,6,0,0,0,2,
+ 3,0,0,8,15,15,15,15,14,1,0,10,15,15,15,15,
+ 15,15,15,15,15,15,15,1,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 14,5,0,4,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,14,9,3,
+ 0,0,0,0,2,5,10,15,5,0,1,11,11,12,13,15,
+ 11,0,0,7,15,15,15,15,15,15,8,0,0,0,1,12,
+ 14,6,0,0,7,14,15,15,14,1,0,9,15,15,15,15,
+ 15,15,15,15,15,15,15,2,0,10,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 9,0,1,13,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,
+ 10,2,0,0,0,0,1,14,4,0,1,14,15,15,15,15,
+ 9,0,0,9,15,15,15,15,15,9,0,0,0,0,9,15,
+ 15,15,7,0,0,6,14,15,15,3,0,6,15,15,15,15,
+ 15,15,15,15,15,15,15,1,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,9,
+ 0,0,1,10,14,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,13,1,0,0,0,1,14,3,0,0,14,15,15,15,15,
+ 5,0,0,11,15,15,15,15,13,1,0,0,0,6,15,15,
+ 15,15,15,8,0,0,2,10,15,6,0,3,15,15,15,15,
+ 15,15,15,15,15,15,15,2,0,10,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,1,
+ 0,0,0,0,3,9,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,6,1,0,0,0,8,15,1,0,0,14,15,15,15,15,
+ 4,0,0,13,15,15,15,14,4,0,0,0,3,14,15,15,
+ 15,15,15,15,5,0,0,1,14,9,0,1,14,15,15,15,
+ 15,15,15,15,15,15,15,1,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,1,
+ 0,0,0,0,0,0,4,12,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 9,0,0,0,0,7,15,15,1,0,0,14,15,15,15,14,
+ 2,0,1,14,15,15,15,12,0,0,0,3,13,15,15,15,
+ 15,15,15,9,0,0,0,1,14,12,0,0,12,15,15,15,
+ 15,15,15,15,15,15,14,1,0,10,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,
+ 3,0,0,0,0,0,0,1,8,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,9,
+ 0,0,0,0,7,15,15,15,1,0,0,14,15,15,15,13,
+ 0,0,1,15,15,15,15,12,0,0,0,6,14,15,15,15,
+ 15,15,12,0,0,0,0,3,14,12,0,0,12,15,15,15,
+ 15,15,15,15,15,15,12,0,0,12,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,13,3,0,0,0,0,0,0,1,6,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,0,
+ 0,0,0,3,15,15,15,12,0,0,0,14,15,15,15,11,
+ 0,0,3,15,15,15,15,15,12,7,0,0,4,14,15,15,
+ 15,11,1,0,0,0,4,13,15,12,0,0,12,15,15,15,
+ 15,15,15,15,15,15,10,0,1,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,7,0,0,0,0,0,0,0,3,8,12,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,4,0,
+ 0,0,1,13,15,15,15,6,0,0,0,14,15,15,15,8,
+ 0,0,7,15,15,15,15,15,15,15,8,1,0,2,13,15,
+ 14,2,0,0,0,4,14,15,15,13,1,0,10,15,15,15,
+ 15,15,15,15,15,15,9,0,2,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,11,6,2,0,0,0,0,0,0,0,1,
+ 10,15,15,15,15,15,15,15,15,15,15,15,15,8,0,0,
+ 0,0,10,15,15,15,15,4,0,0,1,15,15,15,15,4,
+ 0,0,8,15,15,15,15,15,15,15,15,10,1,0,1,8,
+ 2,0,0,0,5,15,15,15,15,15,2,0,6,15,15,15,
+ 15,15,15,15,15,15,9,0,1,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,9,1,0,0,0,0,0,0,
+ 0,1,7,13,14,15,15,15,15,15,15,15,9,0,0,0,
+ 0,6,15,15,15,15,15,4,0,0,4,15,15,15,14,1,
+ 0,0,9,15,15,15,15,15,15,15,15,15,12,2,0,0,
+ 0,0,0,4,14,15,15,15,15,15,4,0,4,15,15,15,
+ 15,15,15,15,15,15,7,0,0,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,14,11,6,2,0,0,0,
+ 0,0,0,0,1,9,12,15,15,15,15,14,3,0,0,0,
+ 4,15,15,15,15,15,15,4,0,0,3,6,4,4,2,0,
+ 0,0,13,15,15,15,15,15,15,15,15,15,15,12,1,0,
+ 0,0,3,14,15,15,15,15,15,15,4,0,4,15,15,15,
+ 15,15,15,15,15,15,5,0,0,12,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,8,2,0,
+ 0,0,0,0,0,0,0,1,9,15,15,5,0,0,0,0,
+ 12,15,15,15,15,15,15,4,0,0,0,0,0,0,0,0,
+ 0,3,15,15,15,15,15,15,15,15,15,15,15,14,4,0,
+ 0,1,12,15,15,15,15,15,15,15,6,0,1,14,15,15,
+ 15,15,15,15,15,15,5,0,0,13,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,
+ 7,1,0,0,0,0,0,0,0,5,7,0,0,0,0,10,
+ 15,15,15,15,15,15,15,7,0,0,0,0,0,0,0,0,
+ 1,10,15,15,15,15,15,15,15,15,15,15,15,14,3,0,
+ 3,12,15,15,15,15,15,15,15,15,12,0,0,12,15,15,
+ 15,15,15,15,15,15,5,0,0,1,1,4,11,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,11,6,1,0,0,0,0,0,0,0,0,0,7,15,
+ 15,15,15,15,15,15,15,14,7,4,4,4,5,9,12,13,
+ 14,15,15,15,15,15,15,15,15,15,15,15,15,15,11,9,
+ 14,15,15,14,12,11,11,11,10,9,7,0,0,5,13,15,
+ 15,15,15,15,15,12,1,0,0,0,0,0,0,10,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,14,7,1,0,0,0,0,0,3,14,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,13,2,0,0,0,0,0,0,0,0,0,0,0,8,
+ 15,15,15,15,15,11,0,0,0,0,0,0,0,9,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,13,5,0,0,0,0,12,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,8,0,0,0,0,0,0,0,0,0,0,0,0,5,
+ 15,15,15,15,15,15,10,5,6,7,7,7,9,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,8,3,2,2,2,2,5,14,15,
+ 15,15,15,15,15,15,15,15,15,10,3,0,6,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,13,3,1,0,1,0,1,1,2,4,4,3,9,14,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,12,4,0,1,6,7,7,4,1,3,13,
+ 15,15,15,15,15,15,15,15,15,15,14,10,13,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,11,11,15,15,15,15,
+ 15,15,15,14,14,14,14,14,14,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,14,2,0,4,13,15,15,15,15,10,0,12,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,13,14,12,12,12,12,12,12,12,
+ 12,14,15,15,15,15,15,15,15,15,4,14,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,7,1,5,14,15,15,15,15,15,12,1,11,
+ 15,15,15,13,12,13,15,15,14,11,13,15,15,15,15,15,
+ 15,15,15,11,6,3,1,1,1,0,0,0,0,0,0,0,
+ 0,1,4,7,11,14,15,15,15,14,4,15,13,10,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,14,7,4,5,
+ 12,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,13,1,1,14,15,15,14,10,12,15,11,1,12,
+ 15,15,11,1,0,4,15,15,6,0,2,14,15,15,15,15,
+ 15,15,14,8,6,3,3,2,2,1,0,0,0,0,0,0,
+ 0,0,0,0,0,3,11,15,15,11,8,15,12,6,15,9,
+ 8,15,15,15,15,15,15,15,15,15,15,15,10,4,4,1,
+ 4,15,15,15,15,11,6,2,8,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,4,15,15,15,11,2,10,15,9,1,13,
+ 15,13,1,7,6,2,14,14,1,2,1,14,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,13,12,12,12,12,12,12,
+ 11,11,11,10,9,10,12,15,15,6,7,15,9,4,15,4,
+ 1,14,15,15,15,15,15,15,15,15,15,15,2,11,15,4,
+ 4,15,15,15,15,3,9,4,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,4,15,15,15,5,0,6,6,1,9,15,
+ 15,4,1,13,10,1,13,9,2,7,1,14,14,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,3,5,15,3,5,14,1,
+ 0,12,13,9,14,15,15,15,15,15,15,15,2,2,4,1,
+ 6,15,15,15,14,1,5,6,0,9,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,4,15,15,15,12,4,2,2,10,15,15,
+ 11,0,6,15,12,0,10,7,9,10,1,14,7,14,15,15,
+ 15,15,15,15,15,15,13,12,11,11,10,9,9,10,11,13,
+ 15,15,15,15,15,15,15,15,15,1,9,15,2,7,14,1,
+ 0,10,7,0,8,15,15,15,15,15,15,15,11,4,4,4,
+ 13,15,15,15,15,10,2,2,4,14,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,4,15,15,15,15,15,15,15,15,15,15,
+ 4,2,14,15,15,1,9,5,14,9,1,14,8,14,15,15,
+ 15,15,15,15,15,10,3,0,1,0,0,0,0,0,0,5,
+ 15,15,15,15,15,15,15,15,15,1,9,14,1,8,14,1,
+ 0,11,13,6,11,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,14,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,0,4,15,15,15,15,15,15,15,15,15,11,
+ 0,6,15,15,15,1,5,3,13,10,0,6,8,15,15,15,
+ 15,15,15,15,15,15,13,12,12,11,10,9,9,10,11,13,
+ 15,15,15,15,15,15,15,15,15,1,9,12,1,11,15,4,
+ 1,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 14,10,4,2,12,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,12,1,3,14,15,15,15,15,15,15,15,15,4,
+ 3,14,15,15,15,5,1,8,15,14,5,2,9,15,15,15,
+ 15,15,15,15,15,15,15,15,15,11,9,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,1,9,12,1,12,15,13,
+ 11,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 10,2,9,2,3,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,14,4,0,5,14,15,15,15,15,15,15,11,0,
+ 6,15,15,15,15,15,14,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,8,1,0,3,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,1,9,15,11,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 7,1,12,6,1,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,11,1,0,3,8,9,9,10,11,9,5,4,
+ 13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,12,9,13,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,5,11,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 10,3,4,1,5,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,12,2,0,0,0,0,0,0,1,8,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,14,12,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,13,8,8,10,9,10,11,14,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15},
+ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15}
+ };
diff --git a/subprojects/gst-plugins-good/gst/goom/plugin_info.c b/subprojects/gst-plugins-good/gst/goom/plugin_info.c
new file mode 100644
index 0000000000..96d570c63b
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/plugin_info.c
@@ -0,0 +1,262 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+
+#include "goom_config.h"
+
+#include "goom_plugin_info.h"
+#include "goom_fx.h"
+#include "drawmethods.h"
+#include <math.h>
+#include <stdio.h>
+#ifdef HAVE_ORC
+#include <orc/orc.h>
+#endif
+
+
+#if defined (HAVE_CPU_PPC64) || defined (HAVE_CPU_PPC)
+#include "ppc_zoom_ultimate.h"
+#include "ppc_drawings.h"
+#endif /* HAVE_CPU_PPC64 || HAVE_CPU_PPC */
+
+
+#ifdef HAVE_MMX
+#include "mmx.h"
+#endif /* HAVE_MMX */
+
+#include <string.h>
+
+GST_DEBUG_CATEGORY_EXTERN (goom_debug);
+#define GST_CAT_DEFAULT goom_debug
+
+static void
+setOptimizedMethods (PluginInfo * p)
+{
+#ifdef HAVE_ORC
+ unsigned int cpuFlavour =
+ orc_target_get_default_flags (orc_target_get_by_name ("mmx"));
+#else
+ unsigned int cpuFlavour = 0;
+#endif
+
+ /* set default methods */
+ p->methods.draw_line = draw_line;
+ p->methods.zoom_filter = zoom_filter_c;
+/* p->methods.create_output_with_brightness = create_output_with_brightness;*/
+
+ GST_INFO ("orc cpu flags: 0x%08x", cpuFlavour);
+
+/* FIXME: what about HAVE_CPU_X86_64 ? */
+#ifdef HAVE_CPU_I386
+#ifdef HAVE_MMX
+#ifdef HAVE_ORC
+ GST_INFO ("have an x86");
+ if (cpuFlavour & ORC_TARGET_MMX_MMXEXT) {
+ GST_INFO ("Extended MMX detected. Using the fastest methods!");
+ p->methods.draw_line = draw_line_xmmx;
+ p->methods.zoom_filter = zoom_filter_xmmx;
+ } else if (cpuFlavour & ORC_TARGET_MMX_MMX) {
+ GST_INFO ("MMX detected. Using fast methods!");
+ p->methods.draw_line = draw_line_mmx;
+ p->methods.zoom_filter = zoom_filter_mmx;
+ } else {
+ GST_INFO ("Too bad ! No SIMD optimization available for your CPU.");
+ }
+#endif
+#endif
+#endif /* HAVE_CPU_I386 */
+
+/* disable all PPC stuff until someone finds out what to use here instead of
+ * CPU_OPTION_64_BITS, and until someone fixes the assembly build for ppc */
+#if 0
+#ifdef HAVE_CPU_PPC64
+ if ((cpuFlavour & CPU_OPTION_64_BITS) != 0) {
+/* p->methods.create_output_with_brightness = ppc_brightness_G5; */
+ p->methods.zoom_filter = ppc_zoom_generic;
+ }
+#endif /* HAVE_CPU_PPC64 */
+
+#ifdef HAVE_CPU_PPC
+ if ((cpuFlavour & ORC_TARGET_ALTIVEC_ALTIVEC) != 0) {
+/* p->methods.create_output_with_brightness = ppc_brightness_G4; */
+ p->methods.zoom_filter = ppc_zoom_G4;
+ } else {
+/* p->methods.create_output_with_brightness = ppc_brightness_generic;*/
+ p->methods.zoom_filter = ppc_zoom_generic;
+ }
+#endif /* HAVE_CPU_PPC */
+#endif
+}
+
+void
+plugin_info_init (PluginInfo * pp, int nbVisuals)
+{
+
+ int i;
+
+ memset (pp, 0, sizeof (PluginInfo));
+
+ pp->sound.speedvar = pp->sound.accelvar = pp->sound.totalgoom = 0;
+ pp->sound.prov_max = 0;
+ pp->sound.goom_limit = 1;
+ pp->sound.allTimesMax = 1;
+ pp->sound.timeSinceLastGoom = 1;
+ pp->sound.timeSinceLastBigGoom = 1;
+ pp->sound.cycle = 0;
+
+ secure_f_feedback (&pp->sound.volume_p, "Sound Volume");
+ secure_f_feedback (&pp->sound.accel_p, "Sound Acceleration");
+ secure_f_feedback (&pp->sound.speed_p, "Sound Speed");
+ secure_f_feedback (&pp->sound.goom_limit_p, "Goom Limit");
+ secure_f_feedback (&pp->sound.last_goom_p, "Goom Detection");
+ secure_f_feedback (&pp->sound.last_biggoom_p, "Big Goom Detection");
+ secure_f_feedback (&pp->sound.goom_power_p, "Goom Power");
+
+ secure_i_param (&pp->sound.biggoom_speed_limit_p, "Big Goom Speed Limit");
+ IVAL (pp->sound.biggoom_speed_limit_p) = 10;
+ IMIN (pp->sound.biggoom_speed_limit_p) = 0;
+ IMAX (pp->sound.biggoom_speed_limit_p) = 100;
+ ISTEP (pp->sound.biggoom_speed_limit_p) = 1;
+
+ secure_i_param (&pp->sound.biggoom_factor_p, "Big Goom Factor");
+ IVAL (pp->sound.biggoom_factor_p) = 10;
+ IMIN (pp->sound.biggoom_factor_p) = 0;
+ IMAX (pp->sound.biggoom_factor_p) = 100;
+ ISTEP (pp->sound.biggoom_factor_p) = 1;
+
+ plugin_parameters (&pp->sound.params, "Sound", 11);
+
+ pp->nbParams = 0;
+ pp->params = NULL;
+ pp->nbVisuals = nbVisuals;
+ pp->visuals = (VisualFX **) malloc (sizeof (VisualFX *) * nbVisuals);
+
+ pp->sound.params.params[0] = &pp->sound.biggoom_speed_limit_p;
+ pp->sound.params.params[1] = &pp->sound.biggoom_factor_p;
+ pp->sound.params.params[2] = 0;
+ pp->sound.params.params[3] = &pp->sound.volume_p;
+ pp->sound.params.params[4] = &pp->sound.accel_p;
+ pp->sound.params.params[5] = &pp->sound.speed_p;
+ pp->sound.params.params[6] = 0;
+ pp->sound.params.params[7] = &pp->sound.goom_limit_p;
+ pp->sound.params.params[8] = &pp->sound.goom_power_p;
+ pp->sound.params.params[9] = &pp->sound.last_goom_p;
+ pp->sound.params.params[10] = &pp->sound.last_biggoom_p;
+
+ pp->statesNumber = 8;
+ pp->statesRangeMax = 510;
+ {
+ GoomState states[8] = {
+ {1, 0, 0, 1, 4, 0, 100}
+ ,
+ {1, 0, 0, 0, 1, 101, 140}
+ ,
+ {1, 0, 0, 1, 2, 141, 200}
+ ,
+ {0, 1, 0, 1, 2, 201, 260}
+ ,
+ {0, 1, 0, 1, 0, 261, 330}
+ ,
+ {0, 1, 1, 1, 4, 331, 400}
+ ,
+ {0, 0, 1, 0, 5, 401, 450}
+ ,
+ {0, 0, 1, 1, 1, 451, 510}
+ };
+ for (i = 0; i < 8; ++i)
+ pp->states[i] = states[i];
+ }
+ pp->curGState = &(pp->states[6]);
+
+ /* datas for the update loop */
+ pp->update.lockvar = 0;
+ pp->update.goomvar = 0;
+ pp->update.loopvar = 0;
+ pp->update.stop_lines = 0;
+ pp->update.ifs_incr = 1; /* dessiner l'ifs (0 = non: > = increment) */
+ pp->update.decay_ifs = 0; /* disparition de l'ifs */
+ pp->update.recay_ifs = 0; /* dedisparition de l'ifs */
+ pp->update.cyclesSinceLastChange = 0;
+ pp->update.drawLinesDuration = 80;
+ pp->update.lineMode = pp->update.drawLinesDuration;
+
+ pp->update.switchMultAmount = (29.0f / 30.0f);
+ pp->update.switchIncrAmount = 0x7f;
+ pp->update.switchMult = 1.0f;
+ pp->update.switchIncr = pp->update.switchIncrAmount;
+
+ pp->update.stateSelectionRnd = 0;
+ pp->update.stateSelectionBlocker = 0;
+ pp->update.previousZoomSpeed = 128;
+
+ {
+ ZoomFilterData zfd = {
+ 127, 8, 16,
+ 1, 1, 0, NORMAL_MODE,
+ 0, 0, 0, 0, 0
+ };
+ pp->update.zoomFilterData = zfd;
+ }
+
+ setOptimizedMethods (pp);
+
+ for (i = 0; i < 0xffff; i++) {
+ pp->sintable[i] =
+ (int) (1024 * sin ((double) i * 360 / (sizeof (pp->sintable) /
+ sizeof (pp->sintable[0]) - 1) * 3.141592 / 180) + .5);
+ /* sintable [us] = (int)(1024.0f * sin (us*2*3.31415f/0xffff)) ; */
+ }
+}
+
+void
+plugin_info_add_visual (PluginInfo * p, int i, VisualFX * visual)
+{
+ p->visuals[i] = visual;
+ if (i == p->nbVisuals - 1) {
+ ++i;
+ p->nbParams = 1;
+ while (i--) {
+ if (p->visuals[i]->params)
+ p->nbParams++;
+ }
+ p->params =
+ (PluginParameters *) malloc (sizeof (PluginParameters) * p->nbParams);
+ i = p->nbVisuals;
+ p->nbParams = 1;
+ p->params[0] = p->sound.params;
+ while (i--) {
+ if (p->visuals[i]->params)
+ p->params[p->nbParams++] = *(p->visuals[i]->params);
+ }
+ }
+}
+
+void
+plugin_info_free (PluginInfo * p)
+{
+ goom_plugin_parameters_free (&p->sound.params);
+
+ if (p->params)
+ free (p->params);
+ free (p->visuals);
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/ppc_drawings.h b/subprojects/gst-plugins-good/gst/goom/ppc_drawings.h
new file mode 100644
index 0000000000..d35adf6500
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/ppc_drawings.h
@@ -0,0 +1,28 @@
+/* Goom Project
+ * Copyright (C) <2003> Guillaume Borios, iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* Generic PowerPC Code */
+void ppc_brightness_generic(Pixel *src, Pixel *dest, int size, int coeff);
+
+/* G4 Specific PowerPC Code (Possible use of Altivec and Data Streams) */
+void ppc_brightness_G4(Pixel *src, Pixel *dest, int size, int coeff);
+
+/* G5 Specific PowerPC Code (Possible use of Altivec) */
+void ppc_brightness_G5(Pixel *src, Pixel *dest, int size, int coeff);
+
diff --git a/subprojects/gst-plugins-good/gst/goom/ppc_drawings.s b/subprojects/gst-plugins-good/gst/goom/ppc_drawings.s
new file mode 100644
index 0000000000..943cce7fde
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/ppc_drawings.s
@@ -0,0 +1,394 @@
+; PowerPC optimized drawing methods for Goom
+; © 2003 Guillaume Borios
+; This library is free software; you can redistribute it and/or
+; modify it under the terms of the GNU Library General Public
+; License as published by the Free Software Foundation; either
+; version 2 of the License, or (at your option) any later version.
+;
+; This library 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
+; Library General Public License for more details.
+;
+; You should have received a copy of the GNU Library General Public
+; License along with this library; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+; Boston, MA 02110-1301, USA.
+
+; Change log :
+; 30 May 2003 : File creation
+
+; Section definition : We use a read only code section for the whole file
+.section __TEXT,__text,regular,pure_instructions
+
+
+; --------------------------------------------------------------------------------------
+; Single 32b pixel drawing macros
+; Usage :
+; DRAWMETHOD_XXXX_MACRO *pixelIN, *pixelOUT, COLOR, WR1, WR2, WR3, WR4
+; Only the work registers (WR) can be touched by the macros
+;
+; Available methods :
+; DRAWMETHOD_DFLT_MACRO : Default drawing method (Actually OVRW)
+; DRAWMETHOD_PLUS_MACRO : RVB Saturated per channel addition (SLOWEST)
+; DRAWMETHOD_HALF_MACRO : 50% Transparency color drawing
+; DRAWMETHOD_OVRW_MACRO : Direct COLOR drawing (FASTEST)
+; DRAWMETHOD_B_OR_MACRO : Bitwise OR
+; DRAWMETHOD_BAND_MACRO : Bitwise AND
+; DRAWMETHOD_BXOR_MACRO : Bitwise XOR
+; DRAWMETHOD_BNOT_MACRO : Bitwise NOT
+; --------------------------------------------------------------------------------------
+
+.macro DRAWMETHOD_OVRW_MACRO
+ stw $2,0($1) ;; *$1 <- $2
+.endmacro
+
+.macro DRAWMETHOD_B_OR_MACRO
+ lwz $3,0($0) ;; $3 <- *$0
+ or $3,$3,$2 ;; $3 <- $3 | $2
+ stw $3,0($1) ;; *$1 <- $3
+.endmacro
+
+.macro DRAWMETHOD_BAND_MACRO
+ lwz $3,0($0) ;; $3 <- *$0
+ and $3,$3,$2 ;; $3 <- $3 & $2
+ stw $3,0($1) ;; *$1 <- $3
+.endmacro
+
+.macro DRAWMETHOD_BXOR_MACRO
+ lwz $3,0($0) ;; $3 <- *$0
+ xor $3,$3,$2 ;; $3 <- $3 ^ $2
+ stw $3,0($1) ;; *$1 <- $3
+.endmacro
+
+.macro DRAWMETHOD_BNOT_MACRO
+ lwz $3,0($0) ;; $3 <- *$0
+ nand $3,$3,$3 ;; $3 <- ~$3
+ stw $3,0($1) ;; *$1 <- $3
+.endmacro
+
+.macro DRAWMETHOD_PLUS_MACRO
+ lwz $4,0($0) ;; $4 <- *$0
+ andi. $3,$4,0xFF00 ;; $3 <- $4 & 0x0000FF00
+ andi. $5,$2,0xFF00 ;; $5 <- $2 & 0x0000FF00
+ add $3,$3,$5 ;; $3 <- $3 + $5
+ rlwinm $5,$3,15,0,0 ;; $5 <- 0 | ($3[15] << 15)
+ srawi $5,$5,23 ;; $5 <- $5 >> 23 (algebraic for sign extension)
+ or $3,$3,$5 ;; $3 <- $3 | $5
+ lis $5,0xFF ;; $5 <- 0x00FF00FF
+ addi $5,$5,0xFF
+ and $4,$4,$5 ;; $4 <- $4 & $5
+ and $6,$2,$5 ;; $6 <- $2 & $5
+ add $4,$4,$6 ;; $4 <- $4 + $6
+ rlwinm $6,$4,7,0,0 ;; $6 <- 0 | ($4[7] << 7)
+ srawi $6,$6,15 ;; $6 <- $6 >> 15 (algebraic for sign extension)
+ rlwinm $5,$4,23,0,0 ;; $5 <- 0 | ($4[23] << 23)
+ srawi $5,$5,31 ;; $5 <- $5 >> 31 (algebraic for sign extension)
+ rlwimi $6,$5,0,24,31 ;; $6[24..31] <- $5[24..31]
+ or $4,$4,$6 ;; $4 <- $4 | $6
+ rlwimi $4,$3,0,16,23 ;; $4[16..23] <- $3[16..23]
+ stw $4,0($1) ;; *$1 <- $4
+.endmacro
+
+.macro DRAWMETHOD_HALF_MACRO
+ lwz $4,0($0) ;; $4 <- *$0
+ andi. $3,$4,0xFF00 ;; $3 <- $4 & 0x0000FF00
+ andi. $5,$2,0xFF00 ;; $5 <- $2 & 0x0000FF00
+ add $3,$3,$5 ;; $3 <- $3 + $5
+ lis $5,0xFF ;; $5 <- 0x00FF00FF
+ addi $5,$5,0xFF
+ and $4,$4,$5 ;; $4 <- $4 & $5
+ and $5,$2,$5 ;; $5 <- $2 & $5
+ add $4,$4,$5 ;; $4 <- $4 + $5
+ srwi $4,$4,1 ;; $4 <- $4 >> 1
+ rlwimi $4,$3,31,16,23 ;; $4[16..23] <- $3[15..22]
+ stw $4,0($1) ;; *$1 <- $4
+.endmacro
+
+.macro DRAWMETHOD_DFLT_MACRO
+ DRAWMETHOD_PLUS_MACRO
+.endmacro
+
+; --------------------------------------------------------------------------------------
+
+
+
+; **************************************************************************************
+; void DRAWMETHOD_PLUS_PPC(unsigned int * buf, unsigned int _col);
+; void DRAWMETHOD_PLUS_2_PPC(unsigned * in, unsigned int * out, unsigned int _col);
+; **************************************************************************************
+.globl _DRAWMETHOD_PLUS_2_PPC
+.align 3
+_DRAWMETHOD_PLUS_2_PPC:
+ DRAWMETHOD_PLUS_MACRO r3,r4,r5,r6,r7,r8,r9
+ blr ;; return
+
+.globl _DRAWMETHOD_PLUS_PPC
+.align 3
+_DRAWMETHOD_PLUS_PPC:
+ DRAWMETHOD_PLUS_MACRO r3,r3,r4,r5,r6,r7,r9
+ blr ;; return
+
+
+; **************************************************************************************
+; void DRAWMETHOD_HALF_PPC(unsigned int * buf, unsigned int _col);
+; void DRAWMETHOD_HALF_2_PPC(unsigned * in, unsigned int * out, unsigned int _col);
+; **************************************************************************************
+.globl _DRAWMETHOD_HALF_2_PPC
+.align 3
+_DRAWMETHOD_HALF_2_PPC:
+ DRAWMETHOD_HALF_MACRO r3,r4,r5,r6,r7,r8
+ blr ;; return
+
+.globl _DRAWMETHOD_HALF_PPC
+.align 3
+_DRAWMETHOD_HALF_PPC:
+ DRAWMETHOD_HALF_MACRO r3,r3,r4,r5,r6,r7
+ blr ;; return
+
+
+; **************************************************************************************
+; void DRAW_LINE_PPC(unsigned int *data, int x1, int y1, int x2, int y2, unsigned int col,
+; unsigned int screenx, unsigned int screeny)
+; **************************************************************************************
+.globl _DRAW_LINE_PPC
+.align 3
+_DRAW_LINE_PPC:
+ ;; NOT IMPLEMENTED YET
+ blr ;; return
+
+
+; **************************************************************************************
+; void _ppc_brightness(Pixel * src, Pixel * dest, unsigned int size, unsigned int coeff)
+; **************************************************************************************
+
+
+.const
+.align 4
+vectorZERO:
+ .long 0,0,0,0
+ .long 0x10101000, 0x10101001, 0x10101002, 0x10101003
+ .long 0x10101004, 0x10101005, 0x10101006, 0x10101007
+ .long 0x10101008, 0x10101009, 0x1010100A, 0x1010100B
+ .long 0x1010100C, 0x1010100D, 0x1010100E, 0x1010100F
+
+
+.section __TEXT,__text,regular,pure_instructions
+
+.globl _ppc_brightness_G4
+.align 3
+_ppc_brightness_G4:
+
+
+;; PowerPC Altivec code
+ srwi r5,r5,2
+ mtctr r5
+
+;;vrsave
+ mfspr r11,256
+ lis r12,0xCFFC
+ mtspr 256,r12
+
+ mflr r0
+ bcl 20,31,"L00000000001$pb"
+"L00000000001$pb":
+ mflr r10
+ mtlr r0
+
+ addis r9,r10,ha16(vectorZERO-"L00000000001$pb")
+ addi r9,r9,lo16(vectorZERO-"L00000000001$pb")
+
+ vxor v0,v0,v0 ;; V0 = NULL vector
+
+ addi r9,r9,16
+ lvx v10,0,r9
+ addi r9,r9,16
+ lvx v11,0,r9
+ addi r9,r9,16
+ lvx v12,0,r9
+ addi r9,r9,16
+ lvx v13,0,r9
+
+ addis r9,r10,ha16(vectortmpwork-"L00000000001$pb")
+ addi r9,r9,lo16(vectortmpwork-"L00000000001$pb")
+ stw r6,0(r9)
+ li r6,8
+ stw r6,4(r9)
+ lvx v9,0,r9
+ li r9,128
+ vspltw v8,v9,0
+ vspltw v9,v9,1
+
+;; elt counter
+ li r9,0
+ lis r7,0x0F01
+ b L7
+.align 4
+L7:
+ lvx v1,r9,r3
+
+ vperm v4,v1,v0,v10
+ ;*********************
+ add r10,r9,r3
+ ;*********************
+ vperm v5,v1,v0,v11
+ vperm v6,v1,v0,v12
+ vperm v7,v1,v0,v13
+
+ vmulouh v4,v4,v8
+ ;*********************
+ dst r10,r7,3
+ ;*********************
+ vmulouh v5,v5,v8
+ vmulouh v6,v6,v8
+ vmulouh v7,v7,v8
+ vsrw v4,v4,v9
+ vsrw v5,v5,v9
+ vsrw v6,v6,v9
+ vsrw v7,v7,v9
+
+ vpkuwus v4,v4,v5
+ vpkuwus v6,v6,v7
+ vpkuhus v1,v4,v6
+
+ stvx v1,r9,r4
+ addi r9,r9,16
+
+ bdnz L7
+
+ mtspr 256,r11
+ blr
+
+
+.globl _ppc_brightness_G5
+.align 3
+_ppc_brightness_G5:
+
+;; PowerPC Altivec G5 code
+ srwi r5,r5,2
+ mtctr r5
+
+;;vrsave
+ mfspr r11,256
+ lis r12,0xCFFC
+ mtspr 256,r12
+
+ mflr r0
+ bcl 20,31,"L00000000002$pb"
+"L00000000002$pb":
+ mflr r10
+ mtlr r0
+
+ addis r9,r10,ha16(vectorZERO-"L00000000002$pb")
+ addi r9,r9,lo16(vectorZERO-"L00000000002$pb")
+
+ vxor v0,v0,v0 ;; V0 = NULL vector
+
+ addi r9,r9,16
+ lvx v10,0,r9
+ addi r9,r9,16
+ lvx v11,0,r9
+ addi r9,r9,16
+ lvx v12,0,r9
+ addi r9,r9,16
+ lvx v13,0,r9
+
+ addis r9,r10,ha16(vectortmpwork-"L00000000002$pb")
+ addi r9,r9,lo16(vectortmpwork-"L00000000002$pb")
+ stw r6,0(r9)
+ li r6,8
+ stw r6,4(r9)
+ lvx v9,0,r9
+ li r9,128
+ vspltw v8,v9,0
+ vspltw v9,v9,1
+
+;; elt counter
+ li r9,0
+ lis r7,0x0F01
+ b L6
+.align 4
+L6:
+ lvx v1,r9,r3
+
+ vperm v4,v1,v0,v10
+ ;*********************
+ add r10,r9,r3
+ ;*********************
+ vperm v5,v1,v0,v11
+ vperm v6,v1,v0,v12
+ vperm v7,v1,v0,v13
+
+ vmulouh v4,v4,v8
+ vmulouh v5,v5,v8
+ vmulouh v6,v6,v8
+ vmulouh v7,v7,v8
+ vsrw v4,v4,v9
+ vsrw v5,v5,v9
+ vsrw v6,v6,v9
+ vsrw v7,v7,v9
+
+ vpkuwus v4,v4,v5
+ vpkuwus v6,v6,v7
+ vpkuhus v1,v4,v6
+
+ stvx v1,r9,r4
+ addi r9,r9,16
+
+ bdnz L6
+
+ mtspr 256,r11
+ blr
+
+
+.globl _ppc_brightness_generic
+.align 3
+_ppc_brightness_generic:
+ lis r12,0x00FF
+ ori r12,r12,0x00FF
+ subi r3,r3,4
+ subi r4,r4,4
+ mtctr r5
+ b L1
+.align 4
+L1:
+ lwzu r7,4(r3)
+
+ rlwinm r8,r7,16,24,31
+ rlwinm r9,r7,24,24,31
+ mullw r8,r8,r6
+ rlwinm r10,r7,0,24,31
+ mullw r9,r9,r6
+ srwi r8,r8,8
+ mullw r10,r10,r6
+ srwi r9,r9,8
+
+ rlwinm. r11,r8,0,0,23
+ beq L2
+ li r8,0xFF
+L2:
+ srwi r10,r10,8
+ rlwinm. r11,r9,0,0,23
+ beq L3
+ li r9,0xFF
+L3:
+ rlwinm r7,r8,16,8,15
+ rlwinm. r11,r10,0,0,23
+ beq L4
+ li r10,0xFF
+L4:
+ rlwimi r7,r9,8,16,23
+ rlwimi r7,r10,0,24,31
+
+ stwu r7,4(r4)
+ bdnz L1
+
+ blr
+
+
+
+.static_data
+.align 4
+vectortmpwork:
+ .long 0,0,0,0
+
diff --git a/subprojects/gst-plugins-good/gst/goom/ppc_zoom_ultimate.h b/subprojects/gst-plugins-good/gst/goom/ppc_zoom_ultimate.h
new file mode 100644
index 0000000000..cd2c8a2683
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/ppc_zoom_ultimate.h
@@ -0,0 +1,25 @@
+/* Goom Project
+ * Copyright (C) <2003> Guillaume Borios, iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* Generic PowerPC Code */
+void ppc_zoom_generic (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+
+/* G4 Specific PowerPC Code (Possible use of Altivec and Data Streams) */
+void ppc_zoom_G4 (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+
diff --git a/subprojects/gst-plugins-good/gst/goom/ppc_zoom_ultimate.s b/subprojects/gst-plugins-good/gst/goom/ppc_zoom_ultimate.s
new file mode 100644
index 0000000000..c37ec503e0
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/ppc_zoom_ultimate.s
@@ -0,0 +1,336 @@
+; PowerPC optimized zoom for Goom
+; © 2001-2003 Guillaume Borios
+; This library is free software; you can redistribute it and/or
+; modify it under the terms of the GNU Library General Public
+; License as published by the Free Software Foundation; either
+; version 2 of the License, or (at your option) any later version.
+;
+; This library 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
+; Library General Public License for more details.
+;
+; You should have received a copy of the GNU Library General Public
+; License along with this library; if not, write to the
+; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+; Boston, MA 02110-1301, USA.
+
+; Change log :
+; 21 Dec 2003 : Use of altivec is now determined with a parameter
+
+; Section definition : We use a read only section
+.text
+
+; name of the function to call by C program : ppc_zoom
+; We declare this label as a global to extend its scope outside this file
+.globl _ppc_zoom_generic
+.globl _ppc_zoom_G4
+
+; Description :
+; This routine dynamically computes and applies a zoom filter
+
+; parameters :
+; r3 <=> unsigned int sizeX (in pixels)
+; r4 <=> unsigned int sizeY (in pixels)
+; r5 <=> unsigned int * frompixmap
+; r6 <=> unsigned int * topixmap
+; r7 <=> unsigned int * brutS
+; r8 <=> unsigned int * brutD
+; r9 <=> unsigned int buffratio
+; r10 <=> int [16][16] precalccoeffs
+
+; globals after init
+; r5 <=> frompixmap - 1 byte needed for preincremental fetch (replaces r5)
+; r6 <=> topixmap - 1 byte needed for preincremental fetch (replaces r6)
+; r3 <=> ax = x max in 16th of pixels (replaces old r3)
+; r4 <=> ay = y max in 16th of pixels (replaces old r4)
+; r20 <=> row size in bytes
+; r12 <=> 0xFF00FF (mask for parallel 32 bits pixs computing)
+; r30 <=> brutS - 1 byte needed for preincremental fetch (replaces r7)
+; r31 <=> brutD - 1 byte needed for preincremental fetch (replaces r8)
+
+; ABI notes :
+; r1 is the Stack Pointer (SP) => Do not use
+; r13..r31 are non-volatiles => Do not use
+
+_ppc_zoom_generic:
+
+; Saves the used non volatile registers in the Mach-O stack s Red-Zone
+stmw r18,-56(r1)
+
+; init
+li r18,0 ; Default value if out of range : 0 (Black)
+mr r11,r10
+lis r12,0xFF
+mullw r2,r3,r4 ; Number of pixels to compute
+subi r30,r8,0
+slwi r20,r3,2
+srawi r19,r20,2
+ori r12,r12,0xFF
+subi r3,r3,1
+subi r4,r4,1
+mtspr ctr,r2 ; Init the loop count (one loop per pixel computed)
+subi r31,r7,0
+subi r6,r6,4
+slwi r3,r3,4
+slwi r4,r4,4
+
+;pre init for loop
+lwz r2,0(r31) ; px
+lwz r29,4(r31) ; py
+lwz r8,0(r30) ; px2
+lwz r10,4(r30) ; py2
+
+b L1
+.align 5
+L1:
+
+; computes dynamically the position to fetch
+sub r8,r8,r2
+sub r10,r10,r29
+mullw r8,r8,r9
+addi r31,r31,8
+mullw r10,r10,r9
+addi r30,r30,8
+
+srawi r8,r8,16
+srawi r10,r10,16
+add r2,r2,r8
+add r29,r29,r10
+
+; if px>ax or py>ay goto outofrange
+; computes the attenuation coeffs and the original point address
+rlwinm r10,r2,6,28-6,31-6 ; r10 <- (r2 << 2) & 0x000002D0 (r10=(r2%16)*4*16)
+cmpl cr4,0,r2,r3
+rlwimi r10, r29, 2, 28-2, 31-2 ; r10 <- ((r29 << 2) & 0x0000002D) | (r10 & !0x0000002D) (r10=(r10%16)*4 | r10)
+cmpl cr7,0,r29,r4
+srawi r29,r29,4 ; pos computing
+bge- cr4,L4
+srawi r2,r2,4 ; pos computing
+mullw r29, r29,r19 ; pos computing
+bge- cr7,L4
+
+; Channels notation : 00112233 (AARRVVBB)
+
+add r2,r2,r29 ; pos computing
+lwzx r10,r11,r10 ; Loads coefs
+slwi r2,r2,2 ; pos computing
+add r2,r2,r5 ; pos computing
+rlwinm r21,r10,0,24,31 ; Isolates coef1 (??????11 -> 00000011)
+lwz r25,0(r2) ; Loads col1 -> r25
+lwz r26,4(r2) ; Loads col2 -> r26
+rlwinm r22,r10,24,24,31 ; Isolates coef2 (????22?? -> 00000022)
+rlwinm r23,r10,16,24,31 ; Isolates coef3 (??33???? -> 00000033)
+add r2,r2,r20 ; Adds one line for future load of col3 and col4
+and r8, r25,r12 ; Masks col1 channels 1 & 3 : 0x00XX00XX
+rlwinm r24,r10,8,24,31 ; Isolates coef4 (44?????? -> 00000044)
+andi. r25,r25,0xFF00 ; Masks col1 channel 2 : 0x0000XX00
+mullw r8, r8, r21 ; Applies coef1 on col1 channels 1 & 3
+
+
+; computes final pixel color
+and r10,r26,r12 ; Masks col2 channels 1 & 3 : 0x00XX00XX
+lwz r27,0(r2) ; Loads col3 -> r27
+mullw r10,r10,r22 ; Applies coef2 on col2 channels 1 & 3
+mullw r25,r25,r21 ; Applies coef1 on col1 channel 2
+andi. r29,r26,0xFF00 ; Masks col2 channel 2 : 0x0000XX00
+mullw r29,r29,r22 ; Applies coef2 on col2 channel 2
+lwz r28,4(r2) ; Loads col4 -> r28
+add r8 ,r8 ,r10 ; Adds col1 & col2 channels 1 & 3
+and r10,r27,r12 ; Masks col3 channels 1 & 3 : 0x00XX00XX
+add r25,r25,r29 ; Adds col1 & col2 channel 2
+mullw r10,r10,r23 ; Applies coef3 on col3 channels 1 & 3
+andi. r29,r27,0xFF00 ; Masks col3 channel 2 : 0x0000XX00
+mullw r29,r29,r23 ; Applies coef3 on col3 channel 2
+lwz r2,0(r31) ; px
+add r7 ,r8 ,r10 ; Adds col3 to (col1 + col2) channels 1 & 3
+and r10,r28,r12 ; Masks col4 channels 1 & 3 : 0x00XX00XX
+mullw r10,r10,r24 ; Applies coef4 on col4 channels 1 & 3
+add r25,r25,r29 ; Adds col 3 to (col1 + col2) channel 2
+lwz r8,0(r30) ; px2
+andi. r28,r28,0xFF00 ; Masks col4 channel 2 : 0x0000XX00
+add r7 ,r7 ,r10 ; Adds col4 to (col1 + col2 + col3) channels 1 & 3
+lwz r10,4(r30) ; py2
+mullw r28,r28,r24 ; Applies coef4 on col4 channel 2
+srawi r7, r7, 8 ; (sum of channels 1 & 3) >> 8
+lwz r29,4(r31) ; py
+add r25,r25,r28 ; Adds col 4 to (col1 + col2 + col3) channel 2
+rlwimi r7, r25, 24, 16, 23 ; (((sum of channels 2) >> 8 ) & 0x0000FF00) | ((sum of channels 1 and 3) & 0xFFFF00FF)
+stwu r7,4(r6) ; Stores the computed pixel
+bdnz L1 ; Iterate again if needed
+b L3 ;goto end ; If not, returns from the function
+
+
+; if out of range
+L4:
+stwu r18,4(r6)
+lwz r8,0(r30) ; px2
+lwz r10,4(r30) ; py2
+lwz r2,0(r31) ; px
+lwz r29,4(r31) ; py
+bdnz L1
+
+
+L3:
+
+; Restore saved registers and return
+lmw r18,-56(r1)
+blr
+
+
+
+
+
+
+
+
+_ppc_zoom_G4:
+
+; Saves the used non volatile registers in the Mach-O stack s Red-Zone
+stmw r17,-60(r1)
+
+; init
+li r18,0 ; Default value if out of range : 0 (Black)
+mr r11,r10
+lis r12,0xFF
+mullw r2,r3,r4 ; Number of pixels to compute
+subi r30,r8,0
+slwi r20,r3,2
+srawi r19,r20,2
+ori r12,r12,0xFF
+subi r3,r3,1
+subi r4,r4,1
+mtspr ctr,r2 ; Init the loop count (one loop per pixel computed)
+subi r31,r7,0
+subi r6,r6,4
+slwi r3,r3,4
+slwi r4,r4,4
+
+;pre init for loop
+lwz r2,0(r31) ; px
+lwz r29,4(r31) ; py
+lwz r8,0(r30) ; px2
+lwz r10,4(r30) ; py2
+
+;*********************
+lis r17,0x0F01
+
+b L100
+.align 5
+L100:
+
+addi r6,r6,4
+
+; Optimization to ensure the destination buffer
+; won't be loaded into the data cache
+rlwinm. r0,r6,0,27,31
+bne+ L500
+dcbz 0,r6
+;dcba 0,r6
+L500:
+
+; computes dynamically the position to fetch
+;mullw r8,r8,r29
+;mullw r2,r2,r29
+;add r2,r8,r2
+;srawi r2,r2,17
+
+sub r8,r8,r2
+sub r10,r10,r29
+mullw r8,r8,r9
+addi r31,r31,8
+mullw r10,r10,r9
+addi r30,r30,8
+
+dst r30,r17,0
+
+srawi r8,r8,16
+srawi r10,r10,16
+add r2,r2,r8
+add r29,r29,r10
+
+dst r31,r17,1
+
+; if px>ax or py>ay goto outofrange
+; computes the attenuation coeffs and the original point address
+rlwinm r10,r2,6,28-6,31-6 ; r10 <- (r2 << 2) & 0x000002D0 (r10=(r2%16)*4*16)
+cmpl cr4,0,r2,r3
+rlwimi r10, r29, 2, 28-2, 31-2 ; r10 <- ((r29 << 2) & 0x0000002D) | (r10 & !0x0000002D) (r10=(r29%16)*4 | r10)
+cmpl cr7,0,r29,r4
+srawi r29,r29,4 ; pos computing
+bge- cr4,L400
+srawi r2,r2,4 ; pos computing
+mullw r29, r29,r19 ; pos computing
+bge- cr7,L400
+
+; Channels notation : 00112233 (AARRVVBB)
+
+add r2,r2,r29 ; pos computing
+lwzx r10,r11,r10 ; Loads coefs
+slwi r2,r2,2 ; pos computing
+add r2,r2,r5 ; pos computing
+rlwinm r21,r10,0,24,31 ; Isolates coef1 (??????11 -> 00000011)
+lwz r25,0(r2) ; Loads col1 -> r25
+lwz r26,4(r2) ; Loads col2 -> r26
+rlwinm r22,r10,24,24,31 ; Isolates coef2 (????22?? -> 00000022)
+rlwinm r23,r10,16,24,31 ; Isolates coef3 (??33???? -> 00000033)
+add r2,r2,r20 ; Adds one line for future load of col3 and col4
+and r8, r25,r12 ; Masks col1 channels 1 & 3 : 0x00XX00XX
+rlwinm r24,r10,8,24,31 ; Isolates coef4 (44?????? -> 00000044)
+dst r2,r17,2
+rlwinm r25,r25,0,16,23 ; Masks col1 channel 2 : 0x0000XX00
+;andi. r25,r25,0xFF00 ; Masks col1 channel 2 : 0x0000XX00
+mullw r8, r8, r21 ; Applies coef1 on col1 channels 1 & 3
+
+
+; computes final pixel color
+and r10,r26,r12 ; Masks col2 channels 1 & 3 : 0x00XX00XX
+lwz r27,0(r2) ; Loads col3 -> r27
+mullw r10,r10,r22 ; Applies coef2 on col2 channels 1 & 3
+mullw r25,r25,r21 ; Applies coef1 on col1 channel 2
+rlwinm r29,r26,0,16,23 ; Masks col2 channel 2 : 0x0000XX00
+;andi. r29,r26,0xFF00 ; Masks col2 channel 2 : 0x0000XX00
+mullw r29,r29,r22 ; Applies coef2 on col2 channel 2
+lwz r28,4(r2) ; Loads col4 -> r28
+add r8 ,r8 ,r10 ; Adds col1 & col2 channels 1 & 3
+and r10,r27,r12 ; Masks col3 channels 1 & 3 : 0x00XX00XX
+add r25,r25,r29 ; Adds col1 & col2 channel 2
+mullw r10,r10,r23 ; Applies coef3 on col3 channels 1 & 3
+rlwinm r29,r27,0,16,23 ; Masks col3 channel 2 : 0x0000XX00
+;andi. r29,r27,0xFF00 ; Masks col3 channel 2 : 0x0000XX00
+mullw r29,r29,r23 ; Applies coef3 on col3 channel 2
+lwz r2,0(r31) ; px
+add r7 ,r8 ,r10 ; Adds col3 to (col1 + col2) channels 1 & 3
+and r10,r28,r12 ; Masks col4 channels 1 & 3 : 0x00XX00XX
+mullw r10,r10,r24 ; Applies coef4 on col4 channels 1 & 3
+add r25,r25,r29 ; Adds col 3 to (col1 + col2) channel 2
+lwz r8,0(r30) ; px2
+rlwinm r28,r28,0,16,23 ; Masks col4 channel 2 : 0x0000XX00
+;andi. r28,r28,0xFF00 ; Masks col4 channel 2 : 0x0000XX00
+add r7 ,r7 ,r10 ; Adds col4 to (col1 + col2 + col3) channels 1 & 3
+lwz r10,4(r30) ; py2
+mullw r28,r28,r24 ; Applies coef4 on col4 channel 2
+srawi r7, r7, 8 ; (sum of channels 1 & 3) >> 8
+lwz r29,4(r31) ; py
+add r25,r25,r28 ; Adds col 4 to (col1 + col2 + col3) channel 2
+rlwimi r7, r25, 24, 16, 23 ; (((sum of channels 2) >> 8 ) & 0x0000FF00) | ((sum of channels 1 and 3) & 0xFFFF00FF)
+stw r7,0(r6) ; Stores the computed pixel
+bdnz L100 ; Iterate again if needed
+b L300 ;goto end ; If not, returns from the function
+
+
+; if out of range
+L400:
+stw r18,0(r6)
+lwz r8,0(r30) ; px2
+lwz r10,4(r30) ; py2
+lwz r2,0(r31) ; px
+lwz r29,4(r31) ; py
+bdnz L100
+
+
+L300:
+
+; Restore saved registers and return
+lmw r17,-60(r1)
+blr
diff --git a/subprojects/gst-plugins-good/gst/goom/sound_tester.c b/subprojects/gst-plugins-good/gst/goom/sound_tester.c
new file mode 100644
index 0000000000..d02f0b51ac
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/sound_tester.c
@@ -0,0 +1,161 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "sound_tester.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/* some constants */
+#define BIG_GOOM_DURATION 100
+#define BIG_GOOM_SPEED_LIMIT 0.1f
+
+#define ACCEL_MULT 0.95f
+#define SPEED_MULT 0.99f
+
+
+void
+evaluate_sound (gint16 data[2][512], SoundInfo * info)
+{
+
+ int i;
+ float difaccel;
+ float prevspeed;
+
+ /* find the max */
+ int incvar = 0;
+
+ for (i = 0; i < 512; i += 2) {
+ if (incvar < data[0][i])
+ incvar = data[0][i];
+ }
+
+ if (incvar > info->allTimesMax)
+ info->allTimesMax = incvar;
+
+ /* volume sonore */
+ info->volume = (float) incvar / (float) info->allTimesMax;
+ memcpy (info->samples[0], data[0], 512 * sizeof (short));
+ memcpy (info->samples[1], data[1], 512 * sizeof (short));
+
+ difaccel = info->accelvar;
+ info->accelvar = info->volume; /* accel entre 0 et 1 */
+
+ /* transformations sur la vitesse du son */
+ if (info->speedvar > 1.0f)
+ info->speedvar = 1.0f;
+
+ if (info->speedvar < 0.1f)
+ info->accelvar *= (1.0f - (float) info->speedvar);
+ else if (info->speedvar < 0.3f)
+ info->accelvar *= (0.9f - (float) (info->speedvar - 0.1f) / 2.0f);
+ else
+ info->accelvar *= (0.8f - (float) (info->speedvar - 0.3f) / 4.0f);
+
+ /* adoucissement de l'acceleration */
+ info->accelvar *= ACCEL_MULT;
+ if (info->accelvar < 0)
+ info->accelvar = 0;
+
+ difaccel = info->accelvar - difaccel;
+ if (difaccel < 0)
+ difaccel = -difaccel;
+
+ /* mise a jour de la vitesse */
+ prevspeed = info->speedvar;
+ info->speedvar = (info->speedvar + difaccel * 0.5f) / 2;
+ info->speedvar *= SPEED_MULT;
+ info->speedvar = (info->speedvar + 3.0f * prevspeed) / 4.0f;
+ if (info->speedvar < 0)
+ info->speedvar = 0;
+ if (info->speedvar > 1)
+ info->speedvar = 1;
+
+ /* temps du goom */
+ info->timeSinceLastGoom++;
+ info->timeSinceLastBigGoom++;
+ info->cycle++;
+
+ /* detection des nouveaux gooms */
+ if ((info->speedvar > (float) IVAL (info->biggoom_speed_limit_p) / 100.0f)
+ && (info->accelvar > info->bigGoomLimit)
+ && (info->timeSinceLastBigGoom > BIG_GOOM_DURATION)) {
+ info->timeSinceLastBigGoom = 0;
+ }
+
+ if (info->accelvar > info->goom_limit) {
+ /* TODO: tester && (info->timeSinceLastGoom > 20)) { */
+ info->totalgoom++;
+ info->timeSinceLastGoom = 0;
+ info->goomPower = info->accelvar - info->goom_limit;
+ }
+
+ if (info->accelvar > info->prov_max)
+ info->prov_max = info->accelvar;
+
+ if (info->goom_limit > 1)
+ info->goom_limit = 1;
+
+ /* toute les 2 secondes : v�rifier si le taux de goom est correct
+ * et le modifier sinon.. */
+ if (info->cycle % 64 == 0) {
+ if (info->speedvar < 0.01f)
+ info->goom_limit *= 0.91;
+ if (info->totalgoom > 4) {
+ info->goom_limit += 0.02;
+ }
+ if (info->totalgoom > 7) {
+ info->goom_limit *= 1.03f;
+ info->goom_limit += 0.03;
+ }
+ if (info->totalgoom > 16) {
+ info->goom_limit *= 1.05f;
+ info->goom_limit += 0.04;
+ }
+ if (info->totalgoom == 0) {
+ info->goom_limit = info->prov_max - 0.02;
+ }
+ if ((info->totalgoom == 1) && (info->goom_limit > 0.02))
+ info->goom_limit -= 0.01;
+ info->totalgoom = 0;
+ info->bigGoomLimit =
+ info->goom_limit * (1.0f +
+ (float) IVAL (info->biggoom_factor_p) / 500.0f);
+ info->prov_max = 0;
+ }
+
+ /* mise a jour des parametres pour la GUI */
+ FVAL (info->volume_p) = info->volume;
+ info->volume_p.change_listener (&info->volume_p);
+ FVAL (info->speed_p) = info->speedvar * 4;
+ info->speed_p.change_listener (&info->speed_p);
+ FVAL (info->accel_p) = info->accelvar;
+ info->accel_p.change_listener (&info->accel_p);
+
+ FVAL (info->goom_limit_p) = info->goom_limit;
+ info->goom_limit_p.change_listener (&info->goom_limit_p);
+ FVAL (info->goom_power_p) = info->goomPower;
+ info->goom_power_p.change_listener (&info->goom_power_p);
+ FVAL (info->last_goom_p) = 1.0 - ((float) info->timeSinceLastGoom / 20.0f);
+ info->last_goom_p.change_listener (&info->last_goom_p);
+ FVAL (info->last_biggoom_p) =
+ 1.0 - ((float) info->timeSinceLastBigGoom / 40.0f);
+ info->last_biggoom_p.change_listener (&info->last_biggoom_p);
+
+ /* bigGoomLimit ==goomLimit*9/8+7 ? */
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/sound_tester.h b/subprojects/gst-plugins-good/gst/goom/sound_tester.h
new file mode 100644
index 0000000000..26418c5e24
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/sound_tester.h
@@ -0,0 +1,29 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _SOUND_TESTER_H
+#define _SOUND_TESTER_H
+
+#include "goom_plugin_info.h"
+#include "goom_config.h"
+
+/* change les donnees du SoundInfo */
+void evaluate_sound(gint16 data[2][512], SoundInfo *sndInfo);
+
+#endif
+
diff --git a/subprojects/gst-plugins-good/gst/goom/surf3d.c b/subprojects/gst-plugins-good/gst/goom/surf3d.c
new file mode 100644
index 0000000000..847284b370
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/surf3d.c
@@ -0,0 +1,152 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "surf3d.h"
+#include "goom_plugin_info.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+grid3d *
+grid3d_new (int sizex, int defx, int sizez, int defz, v3d center)
+{
+ int x = defx;
+ int y = defz;
+ grid3d *g = malloc (sizeof (grid3d));
+ surf3d *s = &(g->surf);
+
+ s->nbvertex = x * y;
+ s->vertex = malloc (x * y * sizeof (v3d));
+ s->svertex = malloc (x * y * sizeof (v3d));
+ s->center = center;
+
+ g->defx = defx;
+ g->sizex = sizex;
+ g->defz = defz;
+ g->sizez = sizez;
+ g->mode = 0;
+
+ while (y) {
+ --y;
+ x = defx;
+ while (x) {
+ --x;
+ s->vertex[x + defx * y].x = (float) (x - defx / 2) * sizex / defx;
+ s->vertex[x + defx * y].y = 0;
+ s->vertex[x + defx * y].z = (float) (y - defz / 2) * sizez / defz;
+ }
+ }
+ return g;
+}
+
+void
+grid3d_free (grid3d * g)
+{
+ surf3d *s = &(g->surf);
+
+ free (s->vertex);
+ free (s->svertex);
+
+ free (g);
+}
+
+void
+grid3d_draw (PluginInfo * plug, grid3d * g, int color, int colorlow,
+ int dist, Pixel * buf, Pixel * back, int W, int H)
+{
+
+ int x;
+ v2d v2, v2x;
+
+ v2d *v2_array = malloc (g->surf.nbvertex * sizeof (v2d));
+
+ v3d_to_v2d (g->surf.svertex, g->surf.nbvertex, W, H, dist, v2_array);
+
+ for (x = 0; x < g->defx; x++) {
+ int z;
+
+ v2x = v2_array[x];
+
+ for (z = 1; z < g->defz; z++) {
+ v2 = v2_array[z * g->defx + x];
+ if (((v2.x != -666) || (v2.y != -666))
+ && ((v2x.x != -666) || (v2x.y != -666))) {
+ plug->methods.draw_line (buf, v2x.x, v2x.y, v2.x, v2.y, colorlow, W, H);
+ plug->methods.draw_line (back, v2x.x, v2x.y, v2.x, v2.y, color, W, H);
+ }
+ v2x = v2;
+ }
+ }
+
+ free (v2_array);
+}
+
+void
+surf3d_rotate (surf3d * s, float angle)
+{
+ int i;
+ float cosa;
+ float sina;
+
+ SINCOS (angle, sina, cosa);
+ for (i = 0; i < s->nbvertex; i++) {
+ Y_ROTATE_V3D (s->vertex[i], s->svertex[i], cosa, sina);
+ }
+}
+
+void
+surf3d_translate (surf3d * s)
+{
+ int i;
+
+ for (i = 0; i < s->nbvertex; i++) {
+ TRANSLATE_V3D (s->center, s->svertex[i]);
+ }
+}
+
+void
+grid3d_update (grid3d * g, float angle, float *vals, float dist)
+{
+ int i;
+ float cosa;
+ float sina;
+ surf3d *s = &(g->surf);
+ v3d cam = s->center;
+
+ cam.z += dist;
+
+ SINCOS ((angle / 4.3f), sina, cosa);
+ cam.y += sina * 2.0f;
+ SINCOS (angle, sina, cosa);
+
+ if (g->mode == 0) {
+ if (vals)
+ for (i = 0; i < g->defx; i++)
+ s->vertex[i].y = s->vertex[i].y * 0.2 + vals[i] * 0.8;
+
+ for (i = g->defx; i < s->nbvertex; i++) {
+ s->vertex[i].y *= 0.255f;
+ s->vertex[i].y += (s->vertex[i - g->defx].y * 0.777f);
+ }
+ }
+
+ for (i = 0; i < s->nbvertex; i++) {
+ Y_ROTATE_V3D (s->vertex[i], s->svertex[i], cosa, sina);
+ TRANSLATE_V3D (cam, s->svertex[i]);
+ }
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/surf3d.h b/subprojects/gst-plugins-good/gst/goom/surf3d.h
new file mode 100644
index 0000000000..f8a2180d97
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/surf3d.h
@@ -0,0 +1,57 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _SURF3D_H
+#define _SURF3D_H
+
+#include "v3d.h"
+#include "goom_graphic.h"
+#include "goom_typedefs.h"
+
+typedef struct {
+ v3d *vertex;
+ v3d *svertex;
+ int nbvertex;
+
+ v3d center;
+} surf3d;
+
+typedef struct {
+ surf3d surf;
+
+ int defx;
+ int sizex;
+ int defz;
+ int sizez;
+ int mode;
+} grid3d;
+
+/* hi-level */
+
+/* works on grid3d */
+grid3d *grid3d_new (int sizex, int defx, int sizez, int defz, v3d center);
+void grid3d_free (grid3d *g);
+void grid3d_update (grid3d *s, float angle, float *vals, float dist);
+
+/* low level */
+void surf3d_draw (surf3d *s, int color, int dist, int *buf, int *back, int W,int H);
+void grid3d_draw (PluginInfo *plug, grid3d *g, int color, int colorlow, int dist, Pixel *buf, Pixel *back, int W,int H);
+void surf3d_rotate (surf3d *s, float angle);
+void surf3d_translate (surf3d *s);
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/surf3d.s b/subprojects/gst-plugins-good/gst/goom/surf3d.s
new file mode 100644
index 0000000000..f8c8c5d440
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/surf3d.s
@@ -0,0 +1,484 @@
+ .file "surf3d.c"
+ .version "01.01"
+gcc2_compiled.:
+.text
+ .align 4
+.globl grid3d_new
+ .type grid3d_new,@function
+grid3d_new:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $44,%esp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ movl 20(%ebp),%eax
+ movl 12(%ebp),%esi
+ movl %eax,-8(%ebp)
+ addl $-12,%esp
+ pushl $44
+ call malloc
+ movl %esi,%edx
+ imull -8(%ebp),%edx
+ movl %eax,%edi
+ movl %edx,-12(%ebp)
+ leal (%edx,%edx,2),%ebx
+ movl %edx,8(%edi)
+ addl $-12,%esp
+ sall $2,%ebx
+ pushl %ebx
+ call malloc
+ addl $32,%esp
+ movl %eax,(%edi)
+ addl $-12,%esp
+ pushl %ebx
+ call malloc
+ movl %eax,4(%edi)
+ movl 24(%ebp),%eax
+ movl %eax,12(%edi)
+ movl 28(%ebp),%eax
+ movl %eax,16(%edi)
+ movl 32(%ebp),%eax
+ movl %eax,20(%edi)
+ movl 8(%ebp),%eax
+ movl %eax,28(%edi)
+ movl %esi,24(%edi)
+ movl -8(%ebp),%edx
+ movl 16(%ebp),%eax
+ movl %edx,32(%edi)
+ movl %eax,36(%edi)
+ movl $0,40(%edi)
+ testl %edx,%edx
+ je .L480
+ movl %esi,%eax
+ movl %esi,-28(%ebp)
+ shrl $31,%eax
+ addl %eax,%esi
+ movl -8(%ebp),%eax
+ shrl $31,%eax
+ addl -8(%ebp),%eax
+ movl -12(%ebp),%edx
+ sarl $1,%eax
+ movl %edx,-24(%ebp)
+ negl -28(%ebp)
+ movl %esi,-16(%ebp)
+ movl %eax,-20(%ebp)
+ .p2align 4,,7
+.L481:
+ movl -28(%ebp),%eax
+ addl %eax,-24(%ebp)
+ decl -8(%ebp)
+ movl 12(%ebp),%esi
+ testl %esi,%esi
+ je .L479
+ movl -8(%ebp),%eax
+ subl -20(%ebp),%eax
+ movl %eax,-4(%ebp)
+ fildl -4(%ebp)
+ movl %esi,-4(%ebp)
+ movl -24(%ebp),%edx
+ leal (%edx,%esi),%eax
+ movl -16(%ebp),%ebx
+ fildl 16(%ebp)
+ leal (%eax,%eax,2),%eax
+ sarl $1,%ebx
+ leal 0(,%eax,4),%ecx
+ fmulp %st,%st(1)
+ fildl 20(%ebp)
+ fdivrp %st,%st(1)
+ fildl 8(%ebp)
+ fildl -4(%ebp)
+ jmp .L484
+.L487:
+ fxch %st(2)
+ .p2align 4,,7
+.L484:
+ decl %esi
+ movl %esi,%eax
+ movl (%edi),%edx
+ subl %ebx,%eax
+ movl %eax,-4(%ebp)
+ fildl -4(%ebp)
+ addl $-12,%ecx
+ fmul %st(2),%st
+ fdiv %st(1),%st
+ fstps (%edx,%ecx)
+ fxch %st(2)
+ movl (%edi),%eax
+ movl $0,4(%eax,%ecx)
+ movl (%edi),%eax
+ fsts 8(%eax,%ecx)
+ testl %esi,%esi
+ jne .L487
+ fstp %st(0)
+ fstp %st(0)
+ fstp %st(0)
+.L479:
+ cmpl $0,-8(%ebp)
+ jne .L481
+.L480:
+ leal -56(%ebp),%esp
+ popl %ebx
+ movl %edi,%eax
+ popl %esi
+ popl %edi
+ leave
+ ret
+.Lfe1:
+ .size grid3d_new,.Lfe1-grid3d_new
+.section .rodata
+ .align 8
+.LC48:
+ .long 0x0,0x3fe00000
+ .align 4
+.LC49:
+ .long 0x3f19999a
+ .align 4
+.LC50:
+ .long 0x3ee3d70a
+.text
+ .align 4
+.globl grid3d_update
+ .type grid3d_update,@function
+grid3d_update:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $32,%esp
+ pushl %esi
+ pushl %ebx
+ flds 12(%ebp)
+ movl 8(%ebp),%ebx
+ movl 16(%ebp),%ecx
+ fld %st(0)
+#APP
+ fsin
+#NO_APP
+ fstps -4(%ebp)
+ flds -4(%ebp)
+ fxch %st(1)
+#APP
+ fcos
+#NO_APP
+ fstps -4(%ebp)
+ flds -4(%ebp)
+ cmpl $0,40(%ebx)
+ jne .L519
+ testl %ecx,%ecx
+ je .L520
+ xorl %esi,%esi
+ cmpl 24(%ebx),%esi
+ jge .L520
+ fldl .LC48
+ xorl %edx,%edx
+ .p2align 4,,7
+.L524:
+ movl (%ebx),%eax
+ fld %st(0)
+ fld %st(1)
+ fxch %st(1)
+ fmuls 4(%eax,%edx)
+ fxch %st(1)
+ fmuls (%ecx,%esi,4)
+ faddp %st,%st(1)
+ incl %esi
+ fstps 4(%eax,%edx)
+ addl $12,%edx
+ cmpl 24(%ebx),%esi
+ jl .L524
+ fstp %st(0)
+.L520:
+ movl 24(%ebx),%esi
+ cmpl 8(%ebx),%esi
+ jge .L519
+ leal (%esi,%esi,2),%eax
+ flds .LC49
+ flds .LC50
+ leal 0(,%eax,4),%ecx
+ .p2align 4,,7
+.L529:
+ movl (%ebx),%eax
+ flds 4(%eax,%ecx)
+ fmul %st(2),%st
+ fstps 4(%eax,%ecx)
+ movl %esi,%eax
+ subl 24(%ebx),%eax
+ movl (%ebx),%edx
+ leal (%eax,%eax,2),%eax
+ flds 4(%edx,%eax,4)
+ fmul %st(1),%st
+ fadds 4(%edx,%ecx)
+ incl %esi
+ fstps 4(%edx,%ecx)
+ addl $12,%ecx
+ cmpl 8(%ebx),%esi
+ jl .L529
+ fstp %st(0)
+ fstp %st(0)
+.L519:
+ xorl %esi,%esi
+ cmpl 8(%ebx),%esi
+ jge .L536
+ xorl %ecx,%ecx
+ .p2align 4,,7
+.L534:
+ movl (%ebx),%eax
+ flds (%eax,%ecx)
+ flds 8(%eax,%ecx)
+ fmul %st(2),%st
+ fxch %st(1)
+ fmul %st(3),%st
+ fsubp %st,%st(1)
+ movl 4(%ebx),%edx
+ incl %esi
+ fstps (%edx,%ecx)
+ movl (%ebx),%eax
+ flds (%eax,%ecx)
+ flds 8(%eax,%ecx)
+ fxch %st(1)
+ fmul %st(2),%st
+ fxch %st(1)
+ fmul %st(3),%st
+ faddp %st,%st(1)
+ movl 4(%ebx),%edx
+ fstps 8(%edx,%ecx)
+ movl (%ebx),%eax
+ flds 4(%eax,%ecx)
+ movl 4(%ebx),%edx
+ fstps 4(%edx,%ecx)
+ movl 4(%ebx),%eax
+ flds (%eax,%ecx)
+ fadds 12(%ebx)
+ fstps (%eax,%ecx)
+ movl 4(%ebx),%eax
+ flds 4(%eax,%ecx)
+ fadds 16(%ebx)
+ fstps 4(%eax,%ecx)
+ movl 4(%ebx),%eax
+ flds 8(%eax,%ecx)
+ fadds 20(%ebx)
+ fstps 8(%eax,%ecx)
+ addl $12,%ecx
+ cmpl 8(%ebx),%esi
+ jl .L534
+.L536:
+ fstp %st(0)
+ fstp %st(0)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+.Lfe2:
+ .size grid3d_update,.Lfe2-grid3d_update
+.section .rodata
+ .align 4
+.LC51:
+ .long 0x40000000
+ .align 8
+.LC52:
+ .long 0x0,0x42380000
+.text
+ .align 4
+.globl surf3d_draw
+ .type surf3d_draw,@function
+surf3d_draw:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $60,%esp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ movl $0,-20(%ebp)
+ movl -20(%ebp),%edx
+ movl 8(%ebp),%eax
+ cmpl 8(%eax),%edx
+ jge .L493
+ fldl .LC52
+ flds .LC51
+ xorl %edi,%edi
+ .p2align 4,,7
+.L495:
+ movl 8(%ebp),%eax
+ movl 4(%eax),%eax
+ movl %eax,-36(%ebp)
+ fcoms 8(%eax,%edi)
+ fnstsw %ax
+ andb $69,%ah
+ cmpb $1,%ah
+ jne .L496
+ fildl 16(%ebp)
+ movl -36(%ebp),%edx
+ fld %st(0)
+ fmuls (%edx,%edi)
+ fdivs 8(%edx,%edi)
+ fld %st(3)
+ faddp %st,%st(1)
+ fstpl -32(%ebp)
+ movl -32(%ebp),%eax
+ movl -28(%ebp),%edx
+ movl %eax,-40(%ebp)
+ sarl $16,-40(%ebp)
+ movl -36(%ebp),%edx
+ fmuls 4(%edx,%edi)
+ fdivs 8(%edx,%edi)
+ movl -40(%ebp),%ecx
+ fld %st(2)
+ faddp %st,%st(1)
+ fstpl -32(%ebp)
+ movl -32(%ebp),%eax
+ movl -28(%ebp),%edx
+ movl %eax,-44(%ebp)
+ movl 28(%ebp),%eax
+ sarl $1,%eax
+ addl %eax,%ecx
+ movl 32(%ebp),%eax
+ sarl $16,-44(%ebp)
+ sarl $1,%eax
+ movl %ecx,%ebx
+ subl -44(%ebp),%eax
+ movl %eax,%esi
+ cmpl 28(%ebp),%ebx
+ jge .L496
+ testl %ecx,%ecx
+ jl .L496
+ cmpl 32(%ebp),%esi
+ jge .L496
+ testl %eax,%eax
+ jge .L499
+.L496:
+ xorl %esi,%esi
+ xorl %ebx,%ebx
+.L499:
+ movl 20(%ebp),%eax
+ movl %ebx,%edx
+ leal (%eax,%edx,4),%edx
+ movl 28(%ebp),%eax
+ imull %esi,%eax
+ leal (%edx,%eax,4),%eax
+ testl %ebx,%ebx
+ je .L494
+ testl %esi,%esi
+ je .L494
+#APP
+ movd (%eax), %mm0
+ paddusb 12(%ebp), %mm0
+ movd %mm0, (%eax)
+#NO_APP
+.L494:
+ incl -20(%ebp)
+ addl $12,%edi
+ movl -20(%ebp),%eax
+ movl 8(%ebp),%edx
+ cmpl 8(%edx),%eax
+ jl .L495
+ fstp %st(0)
+ fstp %st(0)
+.L493:
+ popl %ebx
+ popl %esi
+ popl %edi
+ leave
+ ret
+.Lfe3:
+ .size surf3d_draw,.Lfe3-surf3d_draw
+ .align 4
+.globl surf3d_rotate
+ .type surf3d_rotate,@function
+surf3d_rotate:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $32,%esp
+ pushl %esi
+ pushl %ebx
+ flds 12(%ebp)
+ movl 8(%ebp),%ebx
+ fld %st(0)
+#APP
+ fsin
+#NO_APP
+ fstps -4(%ebp)
+ flds -4(%ebp)
+ fxch %st(1)
+#APP
+ fcos
+#NO_APP
+ fstps -4(%ebp)
+ xorl %esi,%esi
+ flds -4(%ebp)
+ cmpl 8(%ebx),%esi
+ jge .L537
+ xorl %ecx,%ecx
+ .p2align 4,,7
+.L508:
+ movl (%ebx),%eax
+ flds (%eax,%ecx)
+ flds 8(%eax,%ecx)
+ fmul %st(2),%st
+ fxch %st(1)
+ fmul %st(3),%st
+ fsubp %st,%st(1)
+ movl 4(%ebx),%edx
+ incl %esi
+ fstps (%edx,%ecx)
+ movl (%ebx),%eax
+ flds (%eax,%ecx)
+ flds 8(%eax,%ecx)
+ fxch %st(1)
+ fmul %st(2),%st
+ fxch %st(1)
+ fmul %st(3),%st
+ faddp %st,%st(1)
+ movl 4(%ebx),%edx
+ fstps 8(%edx,%ecx)
+ movl (%ebx),%eax
+ flds 4(%eax,%ecx)
+ movl 4(%ebx),%edx
+ fstps 4(%edx,%ecx)
+ addl $12,%ecx
+ cmpl 8(%ebx),%esi
+ jl .L508
+.L537:
+ fstp %st(0)
+ fstp %st(0)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+.Lfe4:
+ .size surf3d_rotate,.Lfe4-surf3d_rotate
+ .align 4
+.globl surf3d_translate
+ .type surf3d_translate,@function
+surf3d_translate:
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %ebx
+ movl 8(%ebp),%ecx
+ xorl %ebx,%ebx
+ cmpl 8(%ecx),%ebx
+ jge .L512
+ xorl %edx,%edx
+ .p2align 4,,7
+.L514:
+ movl 4(%ecx),%eax
+ flds (%eax,%edx)
+ fadds 12(%ecx)
+ incl %ebx
+ fstps (%eax,%edx)
+ movl 4(%ecx),%eax
+ flds 4(%eax,%edx)
+ fadds 16(%ecx)
+ fstps 4(%eax,%edx)
+ movl 4(%ecx),%eax
+ flds 8(%eax,%edx)
+ fadds 20(%ecx)
+ fstps 8(%eax,%edx)
+ addl $12,%edx
+ cmpl 8(%ecx),%ebx
+ jl .L514
+.L512:
+ popl %ebx
+ leave
+ ret
+.Lfe5:
+ .size surf3d_translate,.Lfe5-surf3d_translate
+ .ident "GCC: (GNU) 2.95.3 19991030 (prerelease)"
diff --git a/subprojects/gst-plugins-good/gst/goom/tentacle3d.c b/subprojects/gst-plugins-good/gst/goom/tentacle3d.c
new file mode 100644
index 0000000000..f82ffba380
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/tentacle3d.c
@@ -0,0 +1,358 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+
+#include "v3d.h"
+#include "surf3d.h"
+#include "goom_tools.h"
+#include "goom_config.h"
+#include "goom_plugin_info.h"
+#include "tentacle3d.h"
+
+#define D 256.0f
+
+#define nbgrid 6
+#define definitionx 15
+#define definitionz 45
+
+typedef struct _TENTACLE_FX_DATA
+{
+ PluginParam enabled_bp;
+ PluginParameters params;
+
+ float cycle;
+ grid3d *grille[nbgrid];
+ float *vals;
+
+#define NB_TENTACLE_COLORS 4
+ int colors[NB_TENTACLE_COLORS];
+
+ int col;
+ int dstcol;
+ float lig;
+ float ligs;
+
+ /* statics from pretty_move */
+ float distt;
+ float distt2;
+ float rot; /* entre 0 et 2 * G_PI */
+ int happens;
+ int rotation;
+ int lock;
+} TentacleFXData;
+
+static void tentacle_new (TentacleFXData * data);
+static void tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back,
+ int W, int H, short[2][512], float, int drawit, TentacleFXData * data);
+static void tentacle_free (TentacleFXData * data);
+
+/*
+ * VisualFX wrapper for the tentacles
+ */
+
+static void
+tentacle_fx_init (VisualFX * _this, PluginInfo * info)
+{
+
+ TentacleFXData *data = (TentacleFXData *) malloc (sizeof (TentacleFXData));
+
+ secure_b_param (&data->enabled_bp, "Enabled", 1);
+ plugin_parameters (&data->params, "3D Tentacles", 1);
+ data->params.params[0] = &data->enabled_bp;
+
+ data->cycle = 0.0f;
+ data->col =
+ (0x28 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x5f << (BLEU * 8));
+ data->dstcol = 0;
+ data->lig = 1.15f;
+ data->ligs = 0.1f;
+
+ data->distt = 10.0f;
+ data->distt2 = 0.0f;
+ data->rot = 0.0f; /* entre 0 et 2 * G_PI */
+ data->happens = 0;
+
+ data->rotation = 0;
+ data->lock = 0;
+ data->colors[0] =
+ (0x18 << (ROUGE * 8)) | (0x4c << (VERT * 8)) | (0x2f << (BLEU * 8));
+ data->colors[1] =
+ (0x48 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x6f << (BLEU * 8));
+ data->colors[2] =
+ (0x58 << (ROUGE * 8)) | (0x3c << (VERT * 8)) | (0x0f << (BLEU * 8));
+ data->colors[3] =
+ (0x87 << (ROUGE * 8)) | (0x55 << (VERT * 8)) | (0x74 << (BLEU * 8));
+ tentacle_new (data);
+
+ _this->params = &data->params;
+ _this->fx_data = (void *) data;
+}
+
+static void
+tentacle_fx_apply (VisualFX * _this, Pixel * src, Pixel * dest,
+ PluginInfo * goomInfo)
+{
+ TentacleFXData *data = (TentacleFXData *) _this->fx_data;
+
+ if (BVAL (data->enabled_bp)) {
+ tentacle_update (goomInfo, dest, src, goomInfo->screen.width,
+ goomInfo->screen.height, goomInfo->sound.samples,
+ (float) goomInfo->sound.accelvar,
+ goomInfo->curGState->drawTentacle, data);
+ }
+}
+
+static void
+tentacle_fx_free (VisualFX * _this)
+{
+ tentacle_free ((TentacleFXData *) _this->fx_data);
+ free (_this->fx_data);
+}
+
+void
+tentacle_fx_create (VisualFX * fx)
+{
+ fx->init = tentacle_fx_init;
+ fx->apply = tentacle_fx_apply;
+ fx->free = tentacle_fx_free;
+ fx->fx_data = NULL;
+ fx->params = NULL;
+}
+
+/* ----- */
+
+static void
+tentacle_free (TentacleFXData * data)
+{
+ int tmp;
+
+ /* FREE GRID */
+ for (tmp = 0; tmp < nbgrid; tmp++)
+ grid3d_free (data->grille[tmp]);
+ free (data->vals);
+
+ goom_plugin_parameters_free (&data->params);
+}
+
+static void
+tentacle_new (TentacleFXData * data)
+{
+ int tmp;
+
+ v3d center = { 0, -17.0, 0 };
+ data->vals = (float *) malloc ((definitionx + 20) * sizeof (float));
+
+ for (tmp = 0; tmp < nbgrid; tmp++) {
+ int x, z;
+
+ z = 45 + rand () % 30;
+ x = 85 + rand () % 5;
+ center.z = z;
+ data->grille[tmp] =
+ grid3d_new (x, definitionx, z, definitionz + rand () % 10, center);
+ center.y += 8;
+ }
+}
+
+static inline unsigned char
+lighten (unsigned char value, float power)
+{
+ int val = value;
+ float t = (float) val * log10 (power) / 2.0;
+
+ if (t > 0) {
+ val = (int) t; /* (32.0f * log (t)); */
+ if (val > 255)
+ val = 255;
+ if (val < 0)
+ val = 0;
+ return val;
+ } else {
+ return 0;
+ }
+}
+
+static void
+lightencolor (int *col, float power)
+{
+ unsigned char *color;
+
+ color = (unsigned char *) col;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+}
+
+/* retourne x>>s , en testant le signe de x */
+#define ShiftRight(_x,_s) ((_x<0) ? -(-_x>>_s) : (_x>>_s))
+
+static int
+evolutecolor (unsigned int src, unsigned int dest,
+ unsigned int mask, unsigned int incr)
+{
+
+ int color = src & (~mask);
+
+ src &= mask;
+ dest &= mask;
+
+ if ((src != mask)
+ && (src < dest))
+ src += incr;
+
+ if (src > dest)
+ src -= incr;
+ return (src & mask) | color;
+}
+
+static void
+pretty_move (PluginInfo * goomInfo, float cycle, float *dist, float *dist2,
+ float *rotangle, TentacleFXData * fx_data)
+{
+
+ float tmp;
+
+ /* many magic numbers here... I don't really like that. */
+ if (fx_data->happens)
+ fx_data->happens -= 1;
+ else if (fx_data->lock == 0) {
+ fx_data->happens =
+ goom_irand (goomInfo->gRandom,
+ 200) ? 0 : 100 + goom_irand (goomInfo->gRandom, 60);
+ fx_data->lock = fx_data->happens * 3 / 2;
+ } else
+ fx_data->lock--;
+
+ tmp = fx_data->happens ? 8.0f : 0;
+ *dist2 = fx_data->distt2 = (tmp + 15.0f * fx_data->distt2) / 16.0f;
+
+ tmp = 30 + D - 90.0f * (1.0f + sin (cycle * 19 / 20));
+ if (fx_data->happens)
+ tmp *= 0.6f;
+
+ *dist = fx_data->distt = (tmp + 3.0f * fx_data->distt) / 4.0f;
+
+ if (!fx_data->happens) {
+ tmp = G_PI * sin (cycle) / 32 + 3 * G_PI / 2;
+ } else {
+ fx_data->rotation =
+ goom_irand (goomInfo->gRandom,
+ 500) ? fx_data->rotation : goom_irand (goomInfo->gRandom, 2);
+ if (fx_data->rotation)
+ cycle *= 2.0f * G_PI;
+ else
+ cycle *= -1.0f * G_PI;
+ tmp = cycle - (G_PI * 2.0) * floor (cycle / (G_PI * 2.0));
+ }
+
+ if (fabs (tmp - fx_data->rot) > fabs (tmp - (fx_data->rot + 2.0 * G_PI))) {
+ fx_data->rot = (tmp + 15.0f * (fx_data->rot + 2 * G_PI)) / 16.0f;
+ if (fx_data->rot > 2.0 * G_PI)
+ fx_data->rot -= 2.0 * G_PI;
+ *rotangle = fx_data->rot;
+ } else if (fabs (tmp - fx_data->rot) >
+ fabs (tmp - (fx_data->rot - 2.0 * G_PI))) {
+ fx_data->rot = (tmp + 15.0f * (fx_data->rot - 2.0 * G_PI)) / 16.0f;
+ if (fx_data->rot < 0.0f)
+ fx_data->rot += 2.0 * G_PI;
+ *rotangle = fx_data->rot;
+ } else
+ *rotangle = fx_data->rot = (tmp + 15.0f * fx_data->rot) / 16.0f;
+}
+
+static void
+tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back, int W, int H,
+ short data[2][512], float rapport, int drawit, TentacleFXData * fx_data)
+{
+
+ int tmp;
+ int tmp2;
+
+ int color;
+ int colorlow;
+
+ float dist, dist2, rotangle;
+
+ if ((!drawit) && (fx_data->ligs > 0.0f))
+ fx_data->ligs = -fx_data->ligs;
+
+ fx_data->lig += fx_data->ligs;
+
+ if (fx_data->lig > 1.01f) {
+ if ((fx_data->lig > 10.0f) | (fx_data->lig < 1.1f))
+ fx_data->ligs = -fx_data->ligs;
+
+ if ((fx_data->lig < 6.3f) && (goom_irand (goomInfo->gRandom, 30) == 0))
+ fx_data->dstcol = goom_irand (goomInfo->gRandom, NB_TENTACLE_COLORS);
+
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff,
+ 0x01);
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff00,
+ 0x0100);
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff0000,
+ 0x010000);
+ fx_data->col =
+ evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol],
+ 0xff000000, 0x01000000);
+
+ color = fx_data->col;
+ colorlow = fx_data->col;
+
+ lightencolor (&color, fx_data->lig * 2.0f + 2.0f);
+ lightencolor (&colorlow, (fx_data->lig / 3.0f) + 0.67f);
+
+ rapport = 1.0f + 2.0f * (rapport - 1.0f);
+ rapport *= 1.2f;
+ if (rapport > 1.12f)
+ rapport = 1.12f;
+
+ pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
+
+ for (tmp = 0; tmp < nbgrid; tmp++) {
+ for (tmp2 = 0; tmp2 < definitionx; tmp2++) {
+ float val =
+ (float) (ShiftRight (data[0][goom_irand (goomInfo->gRandom, 511)],
+ 10)) * rapport;
+
+ fx_data->vals[tmp2] = val;
+ }
+
+ grid3d_update (fx_data->grille[tmp], rotangle, fx_data->vals, dist2);
+ }
+ fx_data->cycle += 0.01f;
+ for (tmp = 0; tmp < nbgrid; tmp++)
+ grid3d_draw (goomInfo, fx_data->grille[tmp], color, colorlow, dist, buf,
+ back, W, H);
+ } else {
+ fx_data->lig = 1.05f;
+ if (fx_data->ligs < 0.0f)
+ fx_data->ligs = -fx_data->ligs;
+ pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
+ fx_data->cycle += 0.1f;
+ if (fx_data->cycle > 1000)
+ fx_data->cycle = 0;
+ }
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/tentacle3d.h b/subprojects/gst-plugins-good/gst/goom/tentacle3d.h
new file mode 100644
index 0000000000..9f3ba92342
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/tentacle3d.h
@@ -0,0 +1,26 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _TENTACLE3D_H
+#define _TENTACLE3D_H
+
+#include "goom_visual_fx.h"
+
+void tentacle_fx_create(VisualFX *fx);
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/v3d.c b/subprojects/gst-plugins-good/gst/goom/v3d.c
new file mode 100644
index 0000000000..7df4f1388b
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/v3d.c
@@ -0,0 +1,38 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "v3d.h"
+
+void
+v3d_to_v2d (v3d * v3, int nbvertex, int width, int height, float distance,
+ v2d * v2)
+{
+ int i;
+
+ for (i = 0; i < nbvertex; ++i) {
+ if (v3[i].z > 2) {
+ int Xp, Yp;
+
+ F2I ((distance * v3[i].x / v3[i].z), Xp);
+ F2I ((distance * v3[i].y / v3[i].z), Yp);
+ v2[i].x = Xp + (width >> 1);
+ v2[i].y = -Yp + (height >> 1);
+ } else
+ v2[i].x = v2[i].y = -666;
+ }
+}
diff --git a/subprojects/gst-plugins-good/gst/goom/v3d.h b/subprojects/gst-plugins-good/gst/goom/v3d.h
new file mode 100644
index 0000000000..fd5f939236
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/v3d.h
@@ -0,0 +1,83 @@
+/* Goom Project
+ * Copyright (C) <2003> iOS-Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _V3D_H
+#define _V3D_H
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mathtools.h"
+
+typedef struct {
+ float x,y,z;
+} v3d;
+
+typedef struct {
+ int x,y;
+} v2d;
+
+typedef struct {
+ double x,y;
+} v2g;
+
+/*
+ * projete le vertex 3D sur le plan d'affichage
+ * retourne (0,0) si le point ne doit pas etre affiche.
+ *
+ * bonne valeur pour distance : 256
+ */
+#define V3D_TO_V2D(v3,v2,width,height,distance) \
+{ \
+ int Xp, Yp; \
+ if (v3.z > 2) { \
+ F2I((distance * v3.x / v3.z),Xp) ; \
+ F2I((distance * v3.y / v3.z),Yp) ; \
+ v2.x = Xp + (width>>1); \
+ v2.y = -Yp + (height>>1); \
+ } \
+ else v2.x=v2.y=-666; \
+}
+
+void v3d_to_v2d(v3d *src, int nbvertex, int width, int height, float distance, v2d *v2_array);
+
+/*
+ * rotation selon Y du v3d vi d'angle a (cosa=cos(a), sina=sin(a))
+ * centerz = centre de rotation en z
+ */
+#define Y_ROTATE_V3D(vi,vf,sina,cosa)\
+{\
+ vf.x = vi.x * cosa - vi.z * sina;\
+ vf.z = vi.x * sina + vi.z * cosa;\
+ vf.y = vi.y;\
+}
+
+/*
+ * translation
+ */
+#define TRANSLATE_V3D(vsrc,vdest)\
+{\
+ vdest.x += vsrc.x;\
+ vdest.y += vsrc.y;\
+ vdest.z += vsrc.z;\
+}
+
+#define MUL_V3D(lf,v) {v.x*=lf;v.y*=lf;v.z*=lf;}
+
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/xmmx.c b/subprojects/gst-plugins-good/gst/goom/xmmx.c
new file mode 100644
index 0000000000..ea87cf980e
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/xmmx.c
@@ -0,0 +1,402 @@
+/* xmmx.c
+
+ eXtended MultiMedia eXtensions GCC interface library for IA32.
+
+ To use this library, simply include this header file
+ and compile with GCC. You MUST have inlining enabled
+ in order for xmmx_ok() to work; this can be done by
+ simply using -O on the GCC command line.
+
+ Compiling with -DXMMX_TRACE will cause detailed trace
+ output to be sent to stderr for each mmx operation.
+ This adds lots of code, and obviously slows execution to
+ a crawl, but can be very useful for debugging.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ 1999 by R. Fisher
+ Based on libmmx, 1997-99 by H. Dietz and R. Fisher
+
+ Notes:
+ It appears that the latest gas has the pand problem fixed, therefore
+ I'll undefine BROKEN_PAND by default.
+*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "goom_config.h"
+
+#ifdef HAVE_MMX
+
+/* a definir pour avoir exactement le meme resultat que la fonction C
+ * (un chouillat plus lent).. mais la difference est assez peu notable.
+ */
+// #define STRICT_COMPAT
+
+#define BUFFPOINTNB 16
+#define BUFFPOINTMASK 0xffff
+#define BUFFINCR 0xff
+
+#define sqrtperte 16
+/* faire : a % sqrtperte <=> a & pertemask*/
+#define PERTEMASK 0xf
+/* faire : a / sqrtperte <=> a >> PERTEDEC*/
+#define PERTEDEC 4
+
+
+/*#define MMX_TRACE*/
+#include "mmx.h"
+/*#include "xmmx.h"*/
+#include "goom_graphic.h"
+
+int
+xmmx_supported (void)
+{
+ return (mm_support () & 0x8) >> 3;
+}
+
+void
+zoom_filter_xmmx (int prevX, int prevY,
+ Pixel * expix1, Pixel * expix2,
+ int *lbruS, int *lbruD, int buffratio, int precalCoef[16][16])
+{
+ int bufsize = prevX * prevY; /* taille du buffer */
+ volatile int loop; /* variable de boucle */
+
+ mmx_t *brutS = (mmx_t *) lbruS; /* buffer de transformation source */
+ mmx_t *brutD = (mmx_t *) lbruD; /* buffer de transformation dest */
+
+ volatile mmx_t prevXY;
+ volatile mmx_t ratiox;
+
+ /* volatile mmx_t interpix; */
+
+ expix1[0].val = expix1[prevX - 1].val = expix1[prevX * prevY - 1].val =
+ expix1[prevX * prevY - prevX].val = 0;
+
+ prevXY.ud[0] = (prevX - 1) << PERTEDEC;
+ prevXY.ud[1] = (prevY - 1) << PERTEDEC;
+
+ ratiox.d[0] = buffratio;
+ ratiox.d[1] = buffratio;
+
+ asm volatile ("\n\t movq %[ratio], %%mm6" "\n\t pslld $16, %%mm6" /* mm6 = [rat16=buffratio<<16 | rat16=buffratio<<16] */
+ "\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */
+ ::[ratio] "m" (ratiox));
+
+ loop = 0;
+
+ /*
+ * NOTE : mm6 et mm7 ne sont pas modifies dans la boucle.
+ */
+ while (loop < bufsize) {
+ /* Thread #1
+ * pre : mm6 = [rat16|rat16]
+ * post : mm0 = S + ((D-S)*rat16 format [X|Y]
+ * modified = mm0,mm1,mm2
+ */
+
+ asm volatile ("#1 \n\t movq 0(%[brutS]), %%mm0" "#1 \n\t movq 0(%[brutD]), %%mm1" "#1 \n\t psubd %%mm0, %%mm1" /* mm1 = D - S */
+ "#1 \n\t movq %%mm1, %%mm2" /* mm2 = D - S */
+ "#1 \n\t pslld $16, %%mm1" "#1 \n\t pmullw %%mm6, %%mm2" "#1 \n\t pmulhuw %%mm6, %%mm1" "#1 \n\t pslld $16, %%mm0" "#1 \n\t paddd %%mm2, %%mm1" /* mm1 = (D - S) * buffratio >> 16 */
+ "#1 \n\t paddd %%mm1, %%mm0" /* mm0 = S + mm1 */
+ "#1 \n\t psrld $16, %%mm0"::[brutS] "r" (&brutS[loop]),
+ [brutD] "r" (&brutD[loop])
+ ); /* mm0 = S */
+
+ /*
+ * pre : mm0 : position vector on screen
+ * prevXY : coordinate of the lower-right point on screen
+ * post : clipped mm0
+ * modified : mm0,mm1,mm2
+ */
+ asm volatile
+ ("#1 \n\t movq %[prevXY], %%mm1" "#1 \n\t pcmpgtd %%mm0, %%mm1"
+ /* mm0 en X contient (idem pour Y) :
+ * 1111 si prevXY > px
+ * 0000 si prevXY <= px */
+#ifdef STRICT_COMPAT
+ "#1 \n\t movq %%mm1, %%mm2"
+ "#1 \n\t punpckhdq %%mm2, %%mm2"
+ "#1 \n\t punpckldq %%mm1, %%mm1" "#1 \n\t pand %%mm2, %%mm0"
+#endif
+ "#1 \n\t pand %%mm1, %%mm0" /* on met a zero la partie qui deborde */
+ ::[prevXY] "m" (prevXY));
+
+ /* Thread #2
+ * pre : mm0 : clipped position on screen
+ *
+ * post : mm3 : coefs for this position
+ * mm1 : X vector [0|X]
+ *
+ * modif : eax,esi
+ */
+ __asm__ __volatile__ ("#2 \n\t movd %%mm0,%%esi"
+ "#2 \n\t movq %%mm0,%%mm1"
+ "#2 \n\t andl $15,%%esi"
+ "#2 \n\t psrlq $32,%%mm1"
+ "#2 \n\t shll $6,%%esi"
+ "#2 \n\t movd %%mm1,%%eax"
+ "#2 \n\t addl %[precalCoef],%%esi"
+ "#2 \n\t andl $15,%%eax"
+ "#2 \n\t movd (%%esi,%%eax,4),%%mm3"::[precalCoef]
+ "g" (precalCoef):"eax", "esi");
+
+ /*
+ * extraction des coefficients... (Thread #3)
+ *
+ * pre : coef dans mm3
+ *
+ * post : coef extraits dans mm3 (c1 & c2)
+ * et mm4 (c3 & c4)
+ *
+ * modif : mm5
+ */
+
+ /* (Thread #4)
+ * pre : mm0 : Y pos [*|Y]
+ * mm1 : X pos [*|X]
+ *
+ * post : mm0 : expix1[position]
+ * mm2 : expix1[position+largeur]
+ *
+ * modif : eax, esi
+ */
+ __asm__ __volatile__ ("#2 \n\t psrld $4, %%mm0" "#2 \n\t psrld $4, %%mm1" /* PERTEDEC = $4 */
+ "#4 \n\t movd %%mm1,%%eax"
+ "#3 \n\t movq %%mm3,%%mm5"
+ "#4 \n\t mull %[prevX]"
+ "#4 \n\t movd %%mm0,%%esi"
+ "#3 \n\t punpcklbw %%mm5, %%mm3"
+ "#4 \n\t addl %%esi, %%eax"
+ "#3 \n\t movq %%mm3, %%mm4"
+ "#3 \n\t movq %%mm3, %%mm5"
+ "#4 \n\t movl %[expix1], %%esi"
+ "#3 \n\t punpcklbw %%mm5, %%mm3"
+ "#4 \n\t movq (%%esi,%%eax,4),%%mm0"
+ "#3 \n\t punpckhbw %%mm5, %%mm4"
+ "#4 \n\t addl %[prevX],%%eax"
+ "#4 \n\t movq (%%esi,%%eax,4),%%mm2"::[expix1] "g" (expix1)
+ ,[prevX] "g" (prevX)
+ :"eax", "esi", "edx");
+
+ /*
+ * pre : mm0 : expix1[position]
+ * mm2 : expix1[position+largeur]
+ * mm3 & mm4 : coefs
+ */
+
+ /* recopie des deux premiers pixels dans mm0 et mm1 */
+ movq_r2r (mm0, mm1); /* b1-v1-r1-a1-b2-v2-r2-a2 */
+
+ /* depackage du premier pixel */
+ punpcklbw_r2r (mm7, mm0); /* 00-b2-00-v2-00-r2-00-a2 */
+
+ /* extraction des coefficients... */
+
+ movq_r2r (mm3, mm5); /* c2-c2-c2-c2-c1-c1-c1-c1 */
+
+ /*^en parrallele^ *//* depackage du 2ieme pixel */
+ /*^ */ punpckhbw_r2r (mm7, mm1);
+ /* 00-b1-00-v1-00-r1-00-a1 */
+
+ punpcklbw_r2r (mm7, mm5); /* 00-c1-00-c1-00-c1-00-c1 */
+ punpckhbw_r2r (mm7, mm3); /* 00-c2-00-c2-00-c2-00-c2 */
+
+ /* multiplication des pixels par les coefficients */
+ pmullw_r2r (mm5, mm0); /* c1*b2-c1*v2-c1*r2-c1*a2 */
+ pmullw_r2r (mm3, mm1); /* c2*b1-c2*v1-c2*r1-c2*a1 */
+ paddw_r2r (mm1, mm0);
+
+ /* ...extraction des 2 derniers coefficients */
+ movq_r2r (mm4, mm5); /* c4-c4-c4-c4-c3-c3-c3-c3 */
+ punpcklbw_r2r (mm7, mm4); /* 00-c3-00-c3-00-c3-00-c3 */
+ punpckhbw_r2r (mm7, mm5); /* 00-c4-00-c4-00-c4-00-c4 */
+
+ /* recuperation des 2 derniers pixels */
+ movq_r2r (mm2, mm1);
+
+ /* depackage des pixels */
+ punpcklbw_r2r (mm7, mm1);
+ punpckhbw_r2r (mm7, mm2);
+
+ /* multiplication pas les coeffs */
+ pmullw_r2r (mm4, mm1);
+ pmullw_r2r (mm5, mm2);
+
+ /* ajout des valeurs obtenues � la valeur finale */
+ paddw_r2r (mm1, mm0);
+ paddw_r2r (mm2, mm0);
+
+ /* division par 256 = 16+16+16+16, puis repackage du pixel final */
+ psrlw_i2r (8, mm0);
+ packuswb_r2r (mm7, mm0);
+
+ movd_r2m (mm0, expix2[loop]);
+
+ ++loop;
+ }
+ /* this was femms, which is AMD 3dnow */
+ __asm__ __volatile__ ("emms\n");
+}
+
+#define DRAWMETHOD_PLUS_XMMX(_out,_backbuf,_col) \
+{ \
+ movd_m2r(_backbuf, mm0); \
+ paddusb_m2r(_col, mm0); \
+ movd_r2m(mm0, _out); \
+}
+
+#define DRAWMETHOD DRAWMETHOD_PLUS_XMMX(*p,*p,col)
+
+void
+draw_line_xmmx (Pixel * data, int x1, int y1, int x2, int y2, int col,
+ int screenx, int screeny)
+{
+ int x, y, dx, dy, yy, xx;
+ Pixel *p;
+
+ if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny)
+ || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx))
+ goto end_of_line;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (x1 >= x2) {
+ int tmp;
+
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ dx = x2 - x1;
+ dy = y2 - y1;
+ }
+
+ /* vertical line */
+ if (dx == 0) {
+ if (y1 < y2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (y = y1; y <= y2; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ } else {
+ p = &(data[(screenx * y2) + x1]);
+ for (y = y2; y <= y1; y++) {
+ DRAWMETHOD;
+ p += screenx;
+ }
+ }
+ goto end_of_line;
+ }
+ /* horizontal line */
+ if (dy == 0) {
+ if (x1 < x2) {
+ p = &(data[(screenx * y1) + x1]);
+ for (x = x1; x <= x2; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ goto end_of_line;
+ } else {
+ p = &(data[(screenx * y1) + x2]);
+ for (x = x2; x <= x1; x++) {
+ DRAWMETHOD;
+ p++;
+ }
+ goto end_of_line;
+ }
+ }
+ /* 1 */
+ /* \ */
+ /* \ */
+ /* 2 */
+ if (y2 > y1) {
+ /* steep */
+ if (dy > dx) {
+ dx = ((dx << 16) / dy);
+ x = x1 << 16;
+ for (y = y1; y <= y2; y++) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p++;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ goto end_of_line;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ }
+ }
+ /* 2 */
+ /* / */
+ /* / */
+ /* 1 */
+ else {
+ /* steep */
+ if (-dy > dx) {
+ dx = ((dx << 16) / -dy);
+ x = (x1 + 1) << 16;
+ for (y = y1; y >= y2; y--) {
+ xx = x >> 16;
+ p = &(data[(screenx * y) + xx]);
+ DRAWMETHOD;
+ if (xx < (screenx - 1)) {
+ p--;
+ /* DRAWMETHOD; */
+ }
+ x += dx;
+ }
+ goto end_of_line;
+ }
+ /* shallow */
+ else {
+ dy = ((dy << 16) / dx);
+ y = y1 << 16;
+ for (x = x1; x <= x2; x++) {
+ yy = y >> 16;
+ p = &(data[(screenx * yy) + x]);
+ DRAWMETHOD;
+ if (yy < (screeny - 1)) {
+ p += screeny;
+ /* DRAWMETHOD; */
+ }
+ y += dy;
+ }
+ goto end_of_line;
+ }
+ }
+end_of_line:
+ /* this was femms, which is AMD 3dnow */
+ __asm__ __volatile__ ("emms\n");
+}
+#else
+int
+xmmx_supported (void)
+{
+ return (0);
+}
+#endif
diff --git a/subprojects/gst-plugins-good/gst/goom/xmmx.h b/subprojects/gst-plugins-good/gst/goom/xmmx.h
new file mode 100644
index 0000000000..70ef36143e
--- /dev/null
+++ b/subprojects/gst-plugins-good/gst/goom/xmmx.h
@@ -0,0 +1,537 @@
+/* xmmx.h
+
+ eXtended MultiMedia eXtensions GCC interface library for IA32.
+
+ To use this library, simply include this header file
+ and compile with GCC. You MUST have inlining enabled
+ in order for xmmx_ok() to work; this can be done by
+ simply using -O on the GCC command line.
+
+ Compiling with -DXMMX_TRACE will cause detailed trace
+ output to be sent to stderr for each mmx operation.
+ This adds lots of code, and obviously slows execution to
+ a crawl, but can be very useful for debugging.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ 1999 by R. Fisher
+ Based on libmmx, 1997-99 by H. Dietz and R. Fisher
+
+ Notes:
+ It appears that the latest gas has the pand problem fixed, therefore
+ I'll undefine BROKEN_PAND by default.
+*/
+
+#ifndef _XMMX_H
+#define _XMMX_H
+
+
+/* Warning: at this writing, the version of GAS packaged
+ with most Linux distributions does not handle the
+ parallel AND operation mnemonic correctly. If the
+ symbol BROKEN_PAND is defined, a slower alternative
+ coding will be used. If execution of mmxtest results
+ in an illegal instruction fault, define this symbol.
+*/
+#undef BROKEN_PAND
+
+
+/* The type of an value that fits in an (Extended) MMX register
+ (note that long long constant values MUST be suffixed
+ by LL and unsigned long long values by ULL, lest
+ they be truncated by the compiler)
+*/
+#ifndef _MMX_H
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} __attribute__ ((aligned (8))) mmx_t; /* On an 8-byte (64-bit) boundary */
+#endif
+
+
+
+/* Function to test if multimedia instructions are supported...
+*/
+static int
+mm_support(void)
+{
+ /* Returns 1 if MMX instructions are supported,
+ 3 if Cyrix MMX and Extended MMX instructions are supported
+ 5 if AMD MMX and 3DNow! instructions are supported
+ 0 if hardware does not support any of these
+ */
+ register int rval = 0;
+
+ __asm__ __volatile__ (
+ /* See if CPUID instruction is supported ... */
+ /* ... Get copies of EFLAGS into eax and ecx */
+ "pushf\n\t"
+ "popl %%eax\n\t"
+ "movl %%eax, %%ecx\n\t"
+
+ /* ... Toggle the ID bit in one copy and store */
+ /* to the EFLAGS reg */
+ "xorl $0x200000, %%eax\n\t"
+ "push %%eax\n\t"
+ "popf\n\t"
+
+ /* ... Get the (hopefully modified) EFLAGS */
+ "pushf\n\t"
+ "popl %%eax\n\t"
+
+ /* ... Compare and test result */
+ "xorl %%eax, %%ecx\n\t"
+ "testl $0x200000, %%ecx\n\t"
+ "jz NotSupported1\n\t" /* CPUID not supported */
+
+
+ /* Get standard CPUID information, and
+ go to a specific vendor section */
+ "movl $0, %%eax\n\t"
+ "cpuid\n\t"
+
+ /* Check for Intel */
+ "cmpl $0x756e6547, %%ebx\n\t"
+ "jne TryAMD\n\t"
+ "cmpl $0x49656e69, %%edx\n\t"
+ "jne TryAMD\n\t"
+ "cmpl $0x6c65746e, %%ecx\n"
+ "jne TryAMD\n\t"
+ "jmp Intel\n\t"
+
+ /* Check for AMD */
+ "\nTryAMD:\n\t"
+ "cmpl $0x68747541, %%ebx\n\t"
+ "jne TryCyrix\n\t"
+ "cmpl $0x69746e65, %%edx\n\t"
+ "jne TryCyrix\n\t"
+ "cmpl $0x444d4163, %%ecx\n"
+ "jne TryCyrix\n\t"
+ "jmp AMD\n\t"
+
+ /* Check for Cyrix */
+ "\nTryCyrix:\n\t"
+ "cmpl $0x69727943, %%ebx\n\t"
+ "jne NotSupported2\n\t"
+ "cmpl $0x736e4978, %%edx\n\t"
+ "jne NotSupported3\n\t"
+ "cmpl $0x64616574, %%ecx\n\t"
+ "jne NotSupported4\n\t"
+ /* Drop through to Cyrix... */
+
+
+ /* Cyrix Section */
+ /* See if extended CPUID level 80000001 is supported */
+ /* The value of CPUID/80000001 for the 6x86MX is undefined
+ according to the Cyrix CPU Detection Guide (Preliminary
+ Rev. 1.01 table 1), so we'll check the value of eax for
+ CPUID/0 to see if standard CPUID level 2 is supported.
+ According to the table, the only CPU which supports level
+ 2 is also the only one which supports extended CPUID levels.
+ */
+ "cmpl $0x2, %%eax\n\t"
+ "jne MMXtest\n\t" /* Use standard CPUID instead */
+
+ /* Extended CPUID supported (in theory), so get extended
+ features */
+ "movl $0x80000001, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%eax\n\t" /* Test for MMX */
+ "jz NotSupported5\n\t" /* MMX not supported */
+ "testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */
+ "jnz EMMXSupported\n\t"
+ "movl $1, %0:\n\n\t" /* MMX Supported */
+ "jmp Return\n\n"
+ "EMMXSupported:\n\t"
+ "movl $3, %0:\n\n\t" /* EMMX and MMX Supported */
+ "jmp Return\n\t"
+
+
+ /* AMD Section */
+ "AMD:\n\t"
+
+ /* See if extended CPUID is supported */
+ "movl $0x80000000, %%eax\n\t"
+ "cpuid\n\t"
+ "cmpl $0x80000000, %%eax\n\t"
+ "jl MMXtest\n\t" /* Use standard CPUID instead */
+
+ /* Extended CPUID supported, so get extended features */
+ "movl $0x80000001, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%edx\n\t" /* Test for MMX */
+ "jz NotSupported6\n\t" /* MMX not supported */
+ "testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */
+ "jnz ThreeDNowSupported\n\t"
+ "movl $1, %0:\n\n\t" /* MMX Supported */
+ "jmp Return\n\n"
+ "ThreeDNowSupported:\n\t"
+ "movl $5, %0:\n\n\t" /* 3DNow! and MMX Supported */
+ "jmp Return\n\t"
+
+
+ /* Intel Section */
+ "Intel:\n\t"
+
+ /* Check for MMX */
+ "MMXtest:\n\t"
+ "movl $1, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%edx\n\t" /* Test for MMX */
+ "jz NotSupported7\n\t" /* MMX Not supported */
+ "movl $1, %0:\n\n\t" /* MMX Supported */
+ "jmp Return\n\t"
+
+ /* Nothing supported */
+ "\nNotSupported1:\n\t"
+ "#movl $101, %0:\n\n\t"
+ "\nNotSupported2:\n\t"
+ "#movl $102, %0:\n\n\t"
+ "\nNotSupported3:\n\t"
+ "#movl $103, %0:\n\n\t"
+ "\nNotSupported4:\n\t"
+ "#movl $104, %0:\n\n\t"
+ "\nNotSupported5:\n\t"
+ "#movl $105, %0:\n\n\t"
+ "\nNotSupported6:\n\t"
+ "#movl $106, %0:\n\n\t"
+ "\nNotSupported7:\n\t"
+ "#movl $107, %0:\n\n\t"
+ "movl $0, %0:\n\n\t"
+
+ "Return:\n\t"
+ : "=a" (rval)
+ : /* no input */
+ : "eax", "ebx", "ecx", "edx"
+ );
+
+ /* Return */
+ return(rval);
+}
+
+/* Function to test if mmx instructions are supported...
+*/
+#ifndef _XMMX_H
+inline extern int
+mmx_ok(void)
+{
+ /* Returns 1 if MMX instructions are supported, 0 otherwise */
+ return ( mm_support() & 0x1 );
+}
+#endif
+
+/* Function to test if xmmx instructions are supported...
+*/
+inline extern int
+xmmx_ok(void)
+{
+ /* Returns 1 if Extended MMX instructions are supported, 0 otherwise */
+ return ( (mm_support() & 0x2) >> 1 );
+}
+
+
+/* Helper functions for the instruction macros that follow...
+ (note that memory-to-register, m2r, instructions are nearly
+ as efficient as register-to-register, r2r, instructions;
+ however, memory-to-memory instructions are really simulated
+ as a convenience, and are only 1/3 as efficient)
+*/
+#ifdef XMMX_TRACE
+
+/* Include the stuff for printing a trace to stderr...
+*/
+
+#include <stdio.h>
+
+#define mmx_i2r(op, imm, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace.uq = (imm); \
+ fprintf(stderr, #op "_i2r(" #imm "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_m2r(op, mem, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mem); \
+ fprintf(stderr, #op "_m2r(" #mem "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #reg "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_r2m(op, reg, mem) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #op "_r2m(" #reg "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ mmx_trace = (mem); \
+ fprintf(stderr, #mem "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ ); \
+ mmx_trace = (mem); \
+ fprintf(stderr, #mem "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_r2r(op, regs, regd) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #regs ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #op "_r2r(" #regs "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #regd "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=X" (mmx_trace) \
+ : /* nothing */ ); \
+ fprintf(stderr, #regd "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_m2m(op, mems, memd) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mems); \
+ fprintf(stderr, #op "_m2m(" #mems "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ mmx_trace = (memd); \
+ fprintf(stderr, #memd "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (memd) \
+ : "X" (mems)); \
+ mmx_trace = (memd); \
+ fprintf(stderr, #memd "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#else
+
+/* These macros are a lot simpler without the tracing...
+*/
+
+#define mmx_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define mmx_m2ir(op, mem, rs) \
+ __asm__ __volatile__ (#op " %0, %%" #rs \
+ : /* nothing */ \
+ : "X" (mem) )
+
+#define mmx_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define mmx_r2ir(op, rs1, rs2) \
+ __asm__ __volatile__ (#op " %%" #rs1 ", %%" #rs2 \
+ : /* nothing */ \
+ : /* nothing */ )
+
+#define mmx_m2m(op, mems, memd) \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (memd) \
+ : "X" (mems))
+
+#endif
+
+
+
+/* 1x64 MOVe Quadword
+ (this is both a load and a store...
+ in fact, it is the only way to store)
+*/
+#define movq_m2r(var, reg) mmx_m2r(movq, var, reg)
+#define movq_r2m(reg, var) mmx_r2m(movq, reg, var)
+#define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd)
+#define movq(vars, vard) \
+ __asm__ __volatile__ ("movq %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=X" (vard) \
+ : "X" (vars))
+
+
+/* 1x32 MOVe Doubleword
+ (like movq, this is both load and store...
+ but is most useful for moving things between
+ mmx registers and ordinary registers)
+*/
+#define movd_m2r(var, reg) mmx_m2r(movd, var, reg)
+#define movd_r2m(reg, var) mmx_r2m(movd, reg, var)
+#define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd)
+#define movd(vars, vard) \
+ __asm__ __volatile__ ("movd %1, %%mm0\n\t" \
+ "movd %%mm0, %0" \
+ : "=X" (vard) \
+ : "X" (vars))
+
+
+
+/* 4x16 Parallel MAGnitude
+*/
+#define pmagw_m2r(var, reg) mmx_m2r(pmagw, var, reg)
+#define pmagw_r2r(regs, regd) mmx_r2r(pmagw, regs, regd)
+#define pmagw(vars, vard) mmx_m2m(pmagw, vars, vard)
+
+
+/* 4x16 Parallel ADDs using Saturation arithmetic
+ and Implied destination
+*/
+#define paddsiw_m2ir(var, rs) mmx_m2ir(paddsiw, var, rs)
+#define paddsiw_r2ir(rs1, rs2) mmx_r2ir(paddsiw, rs1, rs2)
+#define paddsiw(vars, vard) mmx_m2m(paddsiw, vars, vard)
+
+
+/* 4x16 Parallel SUBs using Saturation arithmetic
+ and Implied destination
+*/
+#define psubsiw_m2ir(var, rs) mmx_m2ir(psubsiw, var, rs)
+#define psubsiw_r2ir(rs1, rs2) mmx_r2ir(psubsiw, rs1, rs2)
+#define psubsiw(vars, vard) mmx_m2m(psubsiw, vars, vard)
+
+
+/* 4x16 Parallel MULs giving High 4x16 portions of results
+ Rounded with 1/2 bit 15.
+*/
+#define pmulhrw_m2r(var, reg) mmx_m2r(pmulhrw, var, reg)
+#define pmulhrw_r2r(regs, regd) mmx_r2r(pmulhrw, regs, regd)
+#define pmulhrw(vars, vard) mmx_m2m(pmulhrw, vars, vard)
+
+
+/* 4x16 Parallel MULs giving High 4x16 portions of results
+ Rounded with 1/2 bit 15, storing to Implied register
+*/
+#define pmulhriw_m2ir(var, rs) mmx_m2ir(pmulhriw, var, rs)
+#define pmulhriw_r2ir(rs1, rs2) mmx_r2ir(pmulhriw, rs1, rs2)
+#define pmulhriw(vars, vard) mmx_m2m(pmulhriw, vars, vard)
+
+
+/* 4x16 Parallel Muls (and ACcumulate) giving High 4x16 portions
+ of results Rounded with 1/2 bit 15, accumulating with Implied register
+*/
+#define pmachriw_m2ir(var, rs) mmx_m2ir(pmachriw, var, rs)
+#define pmachriw_r2ir(rs1, rs2) mmx_r2ir(pmachriw, rs1, rs2)
+#define pmachriw(vars, vard) mmx_m2m(pmachriw, vars, vard)
+
+
+/* 8x8u Parallel AVErage
+*/
+#define paveb_m2r(var, reg) mmx_m2r(paveb, var, reg)
+#define paveb_r2r(regs, regd) mmx_r2r(paveb, regs, regd)
+#define paveb(vars, vard) mmx_m2m(paveb, vars, vard)
+
+
+/* 8x8u Parallel DISTance and accumulate with
+ unsigned saturation to Implied register
+*/
+#define pdistib_m2ir(var, rs) mmx_m2ir(pdistib, var, rs)
+#define pdistib(vars, vard) mmx_m2m(pdistib, vars, vard)
+
+
+/* 8x8 Parallel conditional MoVe
+ if implied register field is Zero
+*/
+#define pmvzb_m2ir(var, rs) mmx_m2ir(pmvzb, var, rs)
+
+
+/* 8x8 Parallel conditional MoVe
+ if implied register field is Not Zero
+*/
+#define pmvnzb_m2ir(var, rs) mmx_m2ir(pmvnzb, var, rs)
+
+
+/* 8x8 Parallel conditional MoVe
+ if implied register field is Less than Zero
+*/
+#define pmvlzb_m2ir(var, rs) mmx_m2ir(pmvlzb, var, rs)
+
+
+/* 8x8 Parallel conditional MoVe
+ if implied register field is Greater than or Equal to Zero
+*/
+#define pmvgezb_m2ir(var, rs) mmx_m2ir(pmvgezb, var, rs)
+
+
+/* Fast Empty MMx State
+ (used to clean-up when going from mmx to float use
+ of the registers that are shared by both; note that
+ there is no float-to-xmmx operation needed, because
+ only the float tag word info is corruptible)
+*/
+#ifdef XMMX_TRACE
+
+#define femms() \
+ { \
+ fprintf(stderr, "femms()\n"); \
+ __asm__ __volatile__ ("femms"); \
+ }
+
+#else
+
+#define femms() __asm__ __volatile__ ("femms")
+
+#endif
+
+#endif
+