summaryrefslogtreecommitdiffstats
path: root/gst/goom/filters.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2002-02-01 19:28:30 +0000
committerWim Taymans <wim.taymans@gmail.com>2002-02-01 19:28:30 +0000
commit4d3b1472e78ac7c12460b26914c9a294a3de573a (patch)
tree4d9b1f0a6698385b086e37381b75b2d93bf85e39 /gst/goom/filters.c
parente5faa112b67c7681f653949413799180c7382451 (diff)
Added a goom plugin (goom.sourceforge.net) to test: ./gst-launch filesrc location=/opt/data/south.mp3 ! mad ! tee sil...
Original commit message from CVS: Added a goom plugin (goom.sourceforge.net) to test: ./gst-launch filesrc location=/opt/data/south.mp3 ! mad ! tee silent=true src%d! goom ! colorspace ! xvideosink tee0.src%d! osssink
Diffstat (limited to 'gst/goom/filters.c')
-rw-r--r--gst/goom/filters.c528
1 files changed, 528 insertions, 0 deletions
diff --git a/gst/goom/filters.c b/gst/goom/filters.c
new file mode 100644
index 00000000..bd267957
--- /dev/null
+++ b/gst/goom/filters.c
@@ -0,0 +1,528 @@
+/* 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(), gérant les 3 couleurs
+ * -optimisation de sinFilter (utilisant une table de sin)
+ * -asm
+ * -optimisation de la procedure de génération du buffer de transformation
+ * la vitesse est maintenant comprise dans [0..128] au lieu de [0..100]
+*/
+
+//#define _DEBUG_PIXEL;
+
+#include "filters.h"
+#include "graphic.h"
+#include "goom_tools.h"
+#include <stdlib.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifdef MMX
+#define USE_ASM
+#endif
+#ifdef POWERPC
+#define USE_ASM
+#endif
+
+#ifdef USE_ASM
+#define EFFECT_DISTORS 4
+#else
+#define EFFECT_DISTORS 10
+#endif
+
+
+extern volatile guint32 resolx;
+extern volatile guint32 resoly;
+
+#ifdef USE_ASM
+
+#ifdef MMX
+int mmx_zoom () ;
+guint32 mmx_zoom_size;
+#endif /* MMX */
+
+#ifdef POWERPC
+extern unsigned int useAltivec;
+extern void ppc_zoom(void);
+extern void ppc_zoom_altivec(void);
+unsigned int ppcsize4;
+#endif /* PowerPC */
+
+unsigned int *coeffs = 0, *freecoeffs = 0;
+guint32 *expix1 = 0; // pointeur exporte vers p1
+guint32 *expix2 = 0; // pointeur exporte vers p2
+guint32 zoom_width;
+
+#endif /* ASM */
+
+
+static int sintable [0xffff] ;
+static int vitesse = 127;
+static char theMode = AMULETTE_MODE ;
+static int vPlaneEffect = 0;
+static int hPlaneEffect = 0;
+static char noisify = 2;
+static int middleX , middleY ;
+static unsigned char sqrtperte = 16 ;
+
+static int * firedec = 0 ;
+
+
+// retourne x>>s , en testant le signe de x
+inline int ShiftRight (int x, const unsigned char s)
+{
+ if (x<0)
+ return -(-x >> s) ;
+ else
+ return x >> s ;
+}
+
+/*
+ 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 (int x, int y, int *px, int *py)
+{
+ if (theMode == WATER_MODE)
+ {
+ static int wave = 0 ;
+ static int wavesp = 0 ;
+ int yy ;
+
+ yy = y + RAND () % 4 - RAND () % 4 + wave / 10 ;
+ if (yy < 0) yy = 0 ;
+ if (yy >= resoly) yy = resoly - 1 ;
+
+ *px = (x<<4) + firedec [yy] + (wave / 10) ;
+ *py = (y<<4) + 132 - ((vitesse < 132) ? vitesse : 131) ;
+
+ wavesp += RAND () % 3 - RAND () % 3 ;
+ if (wave < -10) wavesp += 2 ;
+ if (wave > 10) wavesp -= 2 ;
+ wave += (wavesp / 10) + RAND () % 3 - RAND () % 3 ;
+ if (wavesp > 100) wavesp = (wavesp * 9) / 10 ;
+ }
+ else
+ {
+ int dist ;
+ register int vx,vy ;
+ int fvitesse = vitesse << 4 ;
+
+ if (noisify)
+ {
+ x += RAND() % noisify - RAND() % noisify ;
+ y += RAND() % noisify - RAND() % noisify ;
+ }
+
+ if (hPlaneEffect) vx = ((x - middleX) << 9) + hPlaneEffect * (y - middleY);
+ else vx = (x - middleX) << 9 ;
+
+ if (vPlaneEffect) vy = ((y - middleY) << 9) + vPlaneEffect * (x - middleX);
+ else vy = (y - middleY) << 9 ;
+
+ switch (theMode)
+ {
+ case WAVE_MODE:
+ dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
+ fvitesse *= 1024 + ShiftRight (
+ sintable [(unsigned short)(0xffff*dist*EFFECT_DISTORS)],6);
+ fvitesse /= 1024 ;
+ break ;
+ case CRYSTAL_BALL_MODE:
+ dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
+ fvitesse += (dist * EFFECT_DISTORS >> 10);
+ break;
+ case AMULETTE_MODE:
+ dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
+ fvitesse -= (dist * EFFECT_DISTORS >> 4);
+ break;
+ case SCRUNCH_MODE:
+ dist = ShiftRight(vx,9) * ShiftRight(vx,9) + ShiftRight(vy,9) * ShiftRight(vy,9);
+ fvitesse -= (dist * EFFECT_DISTORS >> 9);
+ break;
+ }
+ if (vx<0) *px = (middleX << 4) - (-(vx * fvitesse) >> 16) ;
+ else *px = (middleX << 4) + ((vx * fvitesse) >> 16) ;
+ if (vy<0) *py = (middleY << 4) - (-(vy * fvitesse) >> 16) ;
+ else *py = (middleY << 4) + ((vy * fvitesse) >> 16) ;
+ }
+}
+
+//#define _DEBUG
+
+inline void setPixelRGB(Uint *buffer, Uint x, Uint y, Color c)
+{
+// buffer[ y*WIDTH + x ] = (c.r<<16)|(c.v<<8)|c.b
+#ifdef _DEBUG_PIXEL
+ if ( x+y*resolx >= resolx * resoly)
+ {
+ fprintf (stderr,"setPixel ERROR : hors du tableau... %i, %i\n", x,y) ;
+ //exit (1) ;
+ }
+#endif
+
+#ifdef USE_DGA
+ buffer[ y*resolx + x ] = (c.b<<16)|(c.v<<8)|c.r ;
+#else
+ buffer[ y*resolx + x ] = (c.r<<16)|(c.v<<8)|c.b ;
+#endif
+}
+
+
+inline void setPixelRGB_ (Uint *buffer, Uint x, Color c)
+{
+#ifdef _DEBUG
+ if ( x >= resolx*resoly )
+ {
+ printf ("setPixel ERROR : hors du tableau... %i, %i\n", x,y) ;
+ exit (1) ;
+ }
+#endif
+
+#ifdef USE_DGA
+ buffer[ x ] = (c.b<<16)|(c.v<<8)|c.r ;
+#else
+ buffer[ x ] = (c.r<<16)|(c.v<<8)|c.b ;
+#endif
+}
+
+
+
+inline void getPixelRGB (Uint *buffer, Uint x, Uint y, Color *c)
+{
+ register unsigned char *tmp8;
+
+ #ifdef _DEBUG
+ if (x + y * resolx >= resolx*resoly)
+ {
+ printf ("getPixel ERROR : hors du tableau... %i, %i\n", x,y) ;
+ exit (1) ;
+ }
+ #endif
+
+#ifdef __BIG_ENDIAN__
+ c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + (x + y*resolx)));
+ c->r = *(unsigned char *)(++tmp8);
+ c->v = *(unsigned char *)(++tmp8);
+ c->b = *(unsigned char *)(++tmp8);
+
+#else
+ /* ATTENTION AU PETIT INDIEN */
+ c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + (x + y*resolx)));
+ c->v = *(unsigned char *)(++tmp8);
+ c->r = *(unsigned char *)(++tmp8);
+// *c = (Color) buffer[x+y*WIDTH] ;
+#endif
+}
+
+
+inline void getPixelRGB_ (Uint *buffer, Uint x, Color *c)
+{
+ register unsigned char *tmp8;
+
+ #ifdef _DEBUG
+ if ( x >= resolx*resoly )
+ {
+ printf ("getPixel ERROR : hors du tableau... %i\n", x) ;
+ exit (1) ;
+ }
+ #endif
+
+#ifdef __BIG_ENDIAN__
+ c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + x));
+ c->r = *(unsigned char *)(++tmp8);
+ c->v = *(unsigned char *)(++tmp8);
+ c->b = *(unsigned char *)(++tmp8);
+
+#else
+ /* ATTENTION AU PETIT INDIEN */
+ c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + x));
+ c->v = *(unsigned char *)(++tmp8);
+ c->r = *(unsigned char *)(++tmp8);
+// *c = (Color) buffer[x+y*WIDTH] ;
+#endif
+}
+
+
+/*===============================================================*/
+void zoomFilterFastRGB (Uint *pix1,
+ Uint *pix2,
+ ZoomFilterData *zf,
+ Uint resx, Uint resy)
+{
+ static guint32 prevX = 0, prevY = 0;
+
+ static char reverse = 0 ; //vitesse inversé..(zoom out)
+ // static int perte = 100; // 100 = normal
+ static unsigned char pertedec = 8 ;
+ static char firstTime = 1;
+
+ Uint x, y;
+
+// static unsigned int prevX = 0, prevY = 0;
+
+#ifdef USE_ASM
+ expix1 = pix1 ;
+ expix2 = pix2 ;
+#else
+ Color couleur;
+ Color col1,col2,col3,col4;
+ Uint position ;
+
+ static unsigned int *pos10 = 0;
+ static unsigned int *c1 = 0,
+ *c2 = 0,
+ *c3 = 0,
+ *c4 = 0;
+#endif
+
+ if ((prevX != resx) || (prevY != resy))
+ {
+ prevX = resx;
+ prevY = resy;
+#ifndef USE_ASM
+ if (c1) free (c1) ;
+ if (c2) free (c2) ;
+ if (c3) free (c3) ;
+ if (c4) free (c4) ;
+ if (pos10) free (pos10) ;
+ c1=c2=c3=c4=pos10=0;
+#else
+ if (coeffs) free (freecoeffs) ;
+ coeffs = 0;
+#endif
+ middleX = resx / 2 ;
+ middleY = resy - 1;
+ firstTime = 1 ;
+ if (firedec) free (firedec);
+ firedec=0;
+ }
+
+ if (zf)
+ {
+ reverse = zf->reverse ;
+ vitesse = zf->vitesse ;
+ if (reverse)
+ vitesse = 256 - vitesse ;
+#ifndef USE_ASM
+ sqrtperte = zf->sqrtperte ;
+#endif
+ pertedec = zf->pertedec ;
+ middleX = zf->middleX ;
+ middleY = zf->middleY ;
+ theMode = zf->mode ;
+ hPlaneEffect = zf->hPlaneEffect;
+ vPlaneEffect = zf->vPlaneEffect;
+ noisify = zf->noisify;
+ }
+
+ if (firstTime || zf)
+ {
+
+ // generation d'une table de sinus
+ if (firstTime)
+ {
+ unsigned short us ;
+
+ firstTime = 0;
+#ifdef USE_ASM
+ freecoeffs = (unsigned int *)
+ malloc (resx*resy*2*sizeof(unsigned int)+128);
+ coeffs = (guint32 *)((1+((unsigned int)(freecoeffs))/128)*128);
+
+#else
+ pos10 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
+ c1 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
+ c2 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
+ c3 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
+ c4 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
+#endif
+ for (us=0; us<0xffff; us++)
+ {
+ sintable [us] = (int)(1024.0f * sin (us*2*3.31415f/0xffff)) ;
+ }
+
+ {
+ int loopv ;
+ firedec = (int *) malloc (prevY * sizeof(int)) ;
+ for (loopv = prevY ; loopv != 0 ;)
+ {
+ static int decc = 0 ;
+ static int spdc = 0 ;
+ static int accel = 0 ;
+ loopv -- ;
+ firedec [loopv] = decc ;
+ decc += spdc / 10 ;
+ spdc = spdc + RAND () % 3 - RAND () % 3 ;
+
+ if (decc > 4)
+ spdc -= 1 ;
+ if (decc < -4)
+ spdc += 1 ;
+
+ if (spdc > 30)
+ spdc = spdc - RAND () % 3 + accel / 10 ;
+ if (spdc < -30)
+ spdc = spdc + RAND () % 3 + accel / 10 ;
+
+ if (decc > 8 && spdc > 1 )
+ spdc -= RAND () % 3 - 2 ;
+
+ if (decc < -8 && spdc < -1 )
+ spdc += RAND () % 3 + 2 ;
+
+ if (decc > 8 || decc < -8)
+ decc = decc * 8 / 9 ;
+
+ accel += RAND () % 2 - RAND () % 2 ;
+ if (accel > 20)
+ accel -= 2 ;
+ if (accel < -20)
+ accel += 2 ;
+ }
+ }
+ }
+
+
+ // generation du buffer
+ for (y = 0 ; y < prevY ; y++)
+ for (x = 0; x < prevX ; x++)
+ {
+ int px,py;
+ unsigned char coefv,coefh;
+
+ // calculer px et py en fonction de
+ // x,y,middleX,middleY et theMode
+ calculatePXandPY (x,y,&px, &py) ;
+ if ((px == x << 4) && (py == y << 4))
+ py += 8 ;
+
+ if ( (py<0) || (px<0) ||
+ (py>=(prevY-1)*sqrtperte) ||
+ (px>=(prevX-1)*sqrtperte))
+ {
+#ifdef USE_ASM
+ coeffs[(y*prevX+x)*2]=0 ;
+ coeffs[(y*prevX+x)*2+1]=0;
+#else
+ pos10[y*prevX+x]=0 ;
+ c1[y*prevX+x] = 0 ;
+ c2[y*prevX+x] = 0 ;
+ c3[y*prevX+x] = 0 ;
+ c4[y*prevX+x] = 0 ;
+#endif
+ }
+ else
+ {
+ int npx10 ;
+ int npy10 ;
+ int pos = (y*prevX+x)*2;
+
+ npx10 = (px/sqrtperte) ;
+ npy10 = (py/sqrtperte) ;
+
+/* if (npx10 >= prevX) fprintf(stderr,"error npx:%d",npx10);
+ if (npy10 >= prevY) fprintf(stderr,"error npy:%d",npy10);
+*/
+ coefh = px % sqrtperte ;
+ coefv = py % sqrtperte ;
+#ifdef USE_ASM
+ coeffs[pos] = (npx10 + prevX * npy10) * 4;
+
+ if (!(coefh || coefv))
+ coeffs[pos+1] = (sqrtperte*sqrtperte-1) ;
+ else
+ coeffs[pos+1] = (
+ (sqrtperte-coefh) *
+ (sqrtperte-coefv) );
+
+ coeffs[pos+1] |= (coefh * (sqrtperte-coefv)) << 8 ;
+ coeffs[pos+1] |= ((sqrtperte-coefh) * coefv) << 16 ;
+ coeffs[pos+1] |= (coefh * coefv)<<24 ;
+#else
+ pos10[y*prevX+x]= npx10 + prevX * npy10 ;
+
+ if (!(coefh || coefv))
+ c1[y*prevX+x] = sqrtperte*sqrtperte-1 ;
+ else
+ c1[y*prevX+x] = (sqrtperte-coefh) * (sqrtperte-coefv);
+
+ c2[y*prevX+x] = coefh * (sqrtperte-coefv) ;
+ c3[y*prevX+x] = (sqrtperte-coefh) * coefv ;
+ c4[y*prevX+x] = coefh * coefv ;
+#endif
+ }
+ }
+ }
+
+#ifdef USE_ASM
+
+ #ifdef MMX
+ zoom_width = prevX ;
+ mmx_zoom_size = prevX * prevY ;
+ mmx_zoom () ;
+ #endif
+
+ #ifdef POWERPC
+ zoom_width = prevX;
+ if (useAltivec)
+ {
+ ppcsize4 = ((unsigned int)(prevX*prevY))/4;
+ ppc_zoom_altivec();
+ }
+ else
+ {
+ ppcsize4 = ((unsigned int)(prevX*prevY));
+ ppc_zoom();
+ }
+ #endif
+#else
+ for (position=0; position<prevX*prevY; position++)
+ {
+ getPixelRGB_(pix1,pos10[position],&col1);
+ getPixelRGB_(pix1,pos10[position]+1,&col2);
+ getPixelRGB_(pix1,pos10[position]+prevX,&col3);
+ getPixelRGB_(pix1,pos10[position]+prevX+1,&col4);
+
+ couleur.r = col1.r * c1[position]
+ + col2.r * c2[position]
+ + col3.r * c3[position]
+ + col4.r * c4[position];
+ couleur.r >>= pertedec ;
+
+ couleur.v = col1.v * c1[position]
+ + col2.v * c2[position]
+ + col3.v * c3[position]
+ + col4.v * c4[position];
+ couleur.v >>= pertedec ;
+
+ couleur.b = col1.b * c1[position]
+ + col2.b * c2[position]
+ + col3.b * c3[position]
+ + col4.b * c4[position];
+ couleur.b >>= pertedec ;
+
+ setPixelRGB_(pix2,position,couleur);
+ }
+#endif
+}
+
+
+void pointFilter(Uint *pix1, Color c,
+ float t1, float t2, float t3, float t4,
+ Uint cycle)
+{
+ Uint x = (Uint)((int)middleX + (int)(t1*cos((float)cycle/t3)));
+ Uint y = (Uint)((int)middleY + (int)(t2*sin((float)cycle/t4)));
+ if ((x>1) && (y>1) && (x<resolx-2) && (y<resoly-2))
+ {
+ setPixelRGB(pix1, x+1, y, c);
+ setPixelRGB(pix1, x, y+1, c);
+ setPixelRGB(pix1, x+1, y+1, WHITE);
+ setPixelRGB(pix1, x+2, y+1, c);
+ setPixelRGB(pix1, x+1, y+2, c);
+ }
+}