diff options
Diffstat (limited to 'subprojects/gst-plugins-good/gst/goom')
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, ¶m1, ¶m2, &couleur, &mode, &litude, + 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, ¶m1, ¶m2, &couleur1, + &mode, &litude, 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, ¶m1, ¶m2, &couleur1, + &mode, &litude, 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 + |