diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2002-02-01 19:28:30 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2002-02-01 19:28:30 +0000 |
commit | 4d3b1472e78ac7c12460b26914c9a294a3de573a (patch) | |
tree | 4d9b1f0a6698385b086e37381b75b2d93bf85e39 /gst/goom/filters.c | |
parent | e5faa112b67c7681f653949413799180c7382451 (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.c | 528 |
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); + } +} |