diff options
author | Bastien Nocera <hadess@hadess.net> | 2008-02-23 01:51:37 +0000 |
---|---|---|
committer | Bastien Nocera <hadess@hadess.net> | 2008-02-23 01:51:37 +0000 |
commit | a7bc7485b1a4d7e1b1a12ff593ca4ccb1d59e466 (patch) | |
tree | ffba99ad38c7616d089c5e728c75a6bd5f736c6c /gst/goom/filters.c | |
parent | 7f0745bb7f26c69766bb0c64458c6543588cc4dc (diff) |
configure.ac: Add checks for Flex/Yacc/Bison and other furry animals, for the new goom 2k4 based plugin
Original commit message from CVS:
2008-02-23 Bastien Nocera <hadess@hadess.net>
* configure.ac: Add checks for Flex/Yacc/Bison and other
furry animals, for the new goom 2k4 based plugin
* gst/goom/*: Update to use goom 2k4, uses liboil to detect
CPU optimisations (not working yet), move the old plugin to...
* gst/goom2k1/*: ... here, in case somebody is sick enough
Fixes #515073
Diffstat (limited to 'gst/goom/filters.c')
-rw-r--r-- | gst/goom/filters.c | 1284 |
1 files changed, 757 insertions, 527 deletions
diff --git a/gst/goom/filters.c b/gst/goom/filters.c index b898e89c..07e989e7 100644 --- a/gst/goom/filters.c +++ b/gst/goom/filters.c @@ -1,606 +1,836 @@ +// --- 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(), 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] +* 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 +/* #define _DEBUG_PIXEL */ -#include "filters.h" -#include "graphic.h" -#include "goom_tools.h" -#include "goom_core.h" +#include <string.h> #include <stdlib.h> #include <math.h> #include <stdio.h> +#include <inttypes.h> -#ifdef MMX -#define USE_ASM -#endif -#ifdef POWERPC -#define USE_ASM -#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" -#ifdef USE_ASM -#define EFFECT_DISTORS 4 -#else -#define EFFECT_DISTORS 10 -#endif +/* 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; +} -#ifdef USE_ASM +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; +} -#ifdef MMX -int mmx_zoom (); -guint32 mmx_zoom_size; -#endif /* MMX */ +static inline void +getPixelRGB (PluginInfo * goomInfo, Pixel * buffer, Uint x, Uint y, Color * c) +{ + Pixel i = *(buffer + (x + y * goomInfo->screen.width)); -#ifdef POWERPC -extern unsigned int useAltivec; -extern void ppc_zoom (void); -extern void ppc_zoom_altivec (void); -unsigned int ppcsize4; -#endif /* PowerPC */ + c->b = i.channels.b; + c->v = i.channels.g; + c->r = i.channels.r; +} +static inline void +getPixelRGB_ (Pixel * buffer, Uint x, Color * c) +{ + Pixel i = *(buffer + x); -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 */ + c->b = i.channels.b; + c->v = i.channels.g; + c->r = i.channels.r; +} +/* END TODO */ -static int firstTime = 1; -static int sintable[0xffff]; -ZoomFilterData * -zoomFilterNew () -{ - ZoomFilterData *zf = malloc (sizeof (ZoomFilterData)); - - zf->vitesse = 128; - zf->pertedec = 8; - zf->sqrtperte = 16; - zf->middleX = 1; - zf->middleY = 1; - zf->reverse = 0; - zf->mode = WAVE_MODE; - zf->hPlaneEffect = 0; - zf->vPlaneEffect = 0; - zf->noisify = 0; - zf->buffsize = 0; - zf->res_x = 0; - zf->res_y = 0; - - zf->buffer = NULL; - zf->firedec = NULL; - - zf->wave = 0; - zf->wavesp = 0; - - return zf; -} +/* 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 */ -/* retourne x>>s , en testant le signe de x */ -static inline int -ShiftRight (int x, const unsigned char s) +#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]) { - if (x < 0) - return -(-x >> s); - else - return x >> s; + c_zoom (src, dest, sizeX, sizeY, brutS, brutD, buffratio, precalCoef); } -/* - 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) -*/ -void -calculatePXandPY (GoomData * gd, int x, int y, int *px, int *py) +static void generatePrecalCoef (int precalCoef[BUFFPOINTNB][BUFFPOINTNB]); + + +typedef struct _ZOOM_FILTER_FX_WRAPPER_DATA { - ZoomFilterData *zf = gd->zfd; + + 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; - guint32 resoly = zf->res_y; - int vPlaneEffect = zf->vPlaneEffect; - int hPlaneEffect = zf->hPlaneEffect; - int vitesse = zf->vitesse; - char theMode = zf->mode; - - if (theMode == WATER_MODE) { - int wavesp = zf->wavesp; - int wave = zf->wave; - int yy = y + RAND (gd) % 4 + wave / 10; - - yy -= RAND (gd) % 4; - if (yy < 0) - yy = 0; - if (yy >= resoly) - yy = resoly - 1; - - *px = (x << 4) + zf->firedec[yy] + (wave / 10); - *py = (y << 4) + 132 - ((vitesse < 132) ? vitesse : 131); - - wavesp += RAND (gd) % 3; - wavesp -= RAND (gd) % 3; - if (wave < -10) - wavesp += 2; - if (wave > 10) - wavesp -= 2; - wave += (wavesp / 10) + RAND (gd) % 3; - wave -= RAND (gd) % 3; - if (wavesp > 100) - wavesp = (wavesp * 9) / 10; - - zf->wavesp = wavesp; - zf->wave = wave; - } else { - int dist; - register int vx, vy; - int fvitesse = vitesse << 4; - - middleX = zf->middleX; - middleY = zf->middleY; - - if (zf->noisify) { - x += RAND (gd) % zf->noisify; - x -= RAND (gd) % zf->noisify; - y += RAND (gd) % zf->noisify; - y -= RAND (gd) % zf->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); - } -} + int mustInitBuffers; + int interlace_start; -/*#define _DEBUG */ + /** modif by jeko : fixedpoint : buffration = (16:16) (donc 0<=buffration<=2^16) */ + int buffratio; + int *firedec; -static inline void -setPixelRGB (Uint * buffer, Uint x, Uint y, Color c, - guint32 resolx, guint32 resoly) -{ -/* 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 + /** modif d'optim by Jeko : precalcul des 4 coefs resultant des 2 pos */ + int precalCoef[BUFFPOINTNB][BUFFPOINTNB]; -#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 -} + /** calculatePXandPY statics */ + int wave; + int wavesp; +} ZoomFilterFXWrapperData; -static inline void -setPixelRGB_ (Uint * buffer, Uint x, Color c, guint32 resolx, guint32 resoly) + + + +static inline v2g +zoomVector (ZoomFilterFXWrapperData * data, float X, float Y) { -#ifdef _DEBUG - if (x >= resolx * resoly) { - printf ("setPixel ERROR : hors du tableau... %i >= %i*%i (%i)\n", x, resolx, - resoly, resolx * resoly); - exit (1); + v2g vecteur; + 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; } -#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 -} + 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); -static inline void -getPixelRGB (Uint * buffer, Uint x, Uint y, Color * c, - guint32 resolx, guint32 resoly) -{ - register unsigned char *tmp8; + /* Rotate */ + //vx = (X+Y)*0.1; + //vy = (Y-X)*0.1; + + + // Effects adds-on -#ifdef _DEBUG - if (x + y * resolx >= resolx * resoly) { - printf ("getPixel ERROR : hors du tableau... %i, %i\n", x, y); - exit (1); + /* Noise */ + if (data->noisify) { + vx += (((float) random ()) / ((float) RAND_MAX) - 0.5f) / 50.0f; + vy += (((float) random ()) / ((float) RAND_MAX) - 0.5f) / 50.0f; } -#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 + + /* 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; + + return vecteur; } -static inline void -getPixelRGB_ (Uint * buffer, Uint x, Color * c, guint32 resolx, guint32 resoly) +/* + * 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) { - register unsigned char *tmp8; + // Position of the pixel to compute in pixmap coordinates + Uint x, y; -#ifdef _DEBUG - if (x >= resolx * resoly) { - printf ("getPixel ERROR : hors du tableau... %i\n", x); - exit (1); + // Where (verticaly) to stop generating the buffer stripe + int maxEnd = (data->interlace_start + INTERLACE_INCR); + + // 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 (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; } -#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 */ - tmp8 = (unsigned char *) (buffer + x); - c->b = *(unsigned char *) (tmp8++); - c->v = *(unsigned char *) (tmp8++); - c->r = *(unsigned char *) (tmp8); -/* *c = (Color) buffer[x+y*WIDTH] ; */ -#endif + 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 -zoomFilterSetResolution (GoomData * gd, ZoomFilterData * zf) +c_zoom (Pixel * expix1, Pixel * expix2, unsigned int prevX, unsigned int prevY, + signed int *brutS, signed int *brutD, int buffratio, int precalCoef[16][16]) { - unsigned short us; + int myPos, myPos2; + Color couleur; - if (zf->buffsize >= gd->buffsize) { - zf->res_x = gd->resolx; - zf->res_y = gd->resoly; - zf->middleX = gd->resolx / 2; - zf->middleY = gd->resoly - 1; + unsigned int ax = (prevX - 1) << PERTEDEC, ay = (prevY - 1) << PERTEDEC; - return; - } -#ifndef USE_ASM - if (zf->buffer) - free (zf->buffer); - zf->buffer = 0; -#else - if (coeffs) - free (freecoeffs); - coeffs = 0; -#endif - zf->middleX = gd->resolx / 2; - zf->middleY = gd->resoly - 1; - zf->res_x = gd->resolx; - zf->res_y = gd->resoly; - - if (zf->firedec) - free (zf->firedec); - zf->firedec = 0; - - zf->buffsize = gd->resolx * gd->resoly * sizeof (unsigned int); - -#ifdef USE_ASM - freecoeffs = (unsigned int *) - malloc (resx * resy * 2 * sizeof (unsigned int) + 128); - coeffs = (guint32 *) ((1 + ((unsigned int) (freecoeffs)) / 128) * 128); - -#else - zf->buffer = calloc (sizeof (guint32), zf->buffsize * 5); - zf->pos10 = zf->buffer; - zf->c[0] = zf->pos10 + zf->buffsize; - zf->c[1] = zf->c[0] + zf->buffsize; - zf->c[2] = zf->c[1] + zf->buffsize; - zf->c[3] = zf->c[2] + zf->buffsize; -#endif - zf->firedec = (int *) malloc (zf->res_y * sizeof (int)); - - if (firstTime) { - firstTime = 0; - - /* generation d'une table de sinus */ - for (us = 0; us < 0xffff; us++) { - sintable[us] = (int) (1024.0f * sin (us * 2 * 3.31415f / 0xffff)); - } - } + int bufsize = prevX * prevY * 2; + int bufwidth = prevX; - { - int loopv; - - for (loopv = zf->res_y; loopv != 0;) { - int decc = 0; - int spdc = 0; - int accel = 0; - - loopv--; - zf->firedec[loopv] = decc; - decc += spdc / 10; - spdc += RAND (gd) % 3; - spdc -= RAND (gd) % 3; - - if (decc > 4) - spdc -= 1; - if (decc < -4) - spdc += 1; - - if (spdc > 30) - spdc = spdc - RAND (gd) % 3 + accel / 10; - if (spdc < -30) - spdc = spdc + RAND (gd) % 3 + accel / 10; - - if (decc > 8 && spdc > 1) - spdc -= RAND (gd) % 3 - 2; - - if (decc < -8 && spdc < -1) - spdc += RAND (gd) % 3 + 2; - - if (decc > 8 || decc < -8) - decc = decc * 8 / 9; - - accel += RAND (gd) % 2; - accel -= RAND (gd) % 2; - if (accel > 20) - accel -= 2; - if (accel < -20) - accel += 2; + 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); } } -void -zoomFilterDestroy (ZoomFilterData * zf) +/** generate the water fx horizontal direction buffer */ +static void +generateTheWaterFXHorizontalDirectionBuffer (PluginInfo * goomInfo, + ZoomFilterFXWrapperData * data) { - if (zf) { - if (zf->firedec) - free (zf->firedec); - if (zf->buffer) - free (zf->buffer); - free (zf); + + 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 (GoomData * goomdata, ZoomFilterData * zf, int zfd_update) +zoomFilterFastRGB (PluginInfo * goomInfo, Pixel * pix1, Pixel * pix2, + ZoomFilterData * zf, Uint resx, Uint resy, int switchIncr, float switchMult) { - guint32 prevX = goomdata->resolx; - guint32 prevY = goomdata->resoly; + Uint x, y; - guint32 *pix1 = goomdata->p1; - guint32 *pix2 = goomdata->p2; - unsigned int *pos10; - unsigned int **c; + ZoomFilterFXWrapperData *data = + (ZoomFilterFXWrapperData *) goomInfo->zoomFilter_fx.fx_data; - Uint x, y; + if (!BVAL (data->enabled_bp)) + return; -/* static unsigned int prevX = 0, prevY = 0; */ + /** 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; + } -#ifdef USE_ASM - expix1 = pix1; - expix2 = pix2; -#else - Color couleur; - Color col1, col2, col3, col4; - Uint position; -#endif + if (data->interlace_start != -2) + zf = NULL; - if ((goomdata->resolx != zf->res_x) || (goomdata->resoly != zf->res_y)) { - zoomFilterSetResolution (goomdata, zf); + /** 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; } - pos10 = zf->pos10; - c = zf->c; - - if (zfd_update) { - guchar sqrtperte = zf->sqrtperte; - gint start_y = 0; - - if (zf->reverse) - zf->vitesse = 256 - zf->vitesse; - - /* generation du buffer */ - for (y = 0; y < zf->res_y; y++) { - gint y_16 = y << 4; - gint max_px = (prevX - 1) * sqrtperte; - gint max_py = (prevY - 1) * sqrtperte; - - for (x = 0; x < zf->res_x; x++) { - gint px, py; - guchar coefv, coefh; - - /* calculer px et py en fonction de */ - /* x,y,middleX,middleY et theMode */ - calculatePXandPY (goomdata, x, y, &px, &py); - - if ((px == x << 4) && (py == y_16)) - py += 8; - - if ((py < 0) || (px < 0) || (py >= max_py) || (px >= max_px)) { -#ifdef USE_ASM - coeffs[(y * prevX + x) * 2] = 0; - coeffs[(y * prevX + x) * 2 + 1] = 0; -#else - pos10[start_y + x] = 0; - c[0][start_y + x] = 0; - c[1][start_y + x] = 0; - c[2][start_y + x] = 0; - c[3][start_y + x] = 0; -#endif - } else { - int npx10; - int npy10; - int pos; - - 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 - pos = (y * prevX + x) * 2; - 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 - pos = start_y + x; - pos10[pos] = npx10 + prevX * npy10; - - if (!(coefh || coefv)) - c[0][pos] = sqrtperte * sqrtperte - 1; - else - c[0][pos] = (sqrtperte - coefh) * (sqrtperte - coefv); - - c[1][pos] = coefh * (sqrtperte - coefv); - c[2][pos] = (sqrtperte - coefh) * coefv; - c[3][pos] = coefh * coefv; -#endif - } - } - /* Advance start of line index */ - start_y += prevX; + + 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; } -#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 (); + + 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); } -#endif -#else - for (position = 0; position < prevX * prevY; position++) { - getPixelRGB_ (pix1, pos10[position], &col1, goomdata->resolx, - goomdata->resoly); - getPixelRGB_ (pix1, pos10[position] + 1, &col2, goomdata->resolx, - goomdata->resoly); - getPixelRGB_ (pix1, pos10[position] + prevX, &col3, goomdata->resolx, - goomdata->resoly); - getPixelRGB_ (pix1, pos10[position] + prevX + 1, &col4, goomdata->resolx, - goomdata->resoly); - - couleur.r = col1.r * c[0][position] - + col2.r * c[1][position] - + col3.r * c[2][position] - + col4.r * c[3][position]; - couleur.r >>= zf->pertedec; - - couleur.v = col1.v * c[0][position] - + col2.v * c[1][position] - + col3.v * c[2][position] - + col4.v * c[3][position]; - couleur.v >>= zf->pertedec; - - couleur.b = col1.b * c[0][position] - + col2.b * c[1][position] - + col3.b * c[2][position] - + col4.b * c[3][position]; - couleur.b >>= zf->pertedec; - - setPixelRGB_ (pix2, position, couleur, goomdata->resolx, goomdata->resoly); + + 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 { + int 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; + } } -#endif } +/* 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; + + data->enabled_bp = secure_b_param ("Enabled", 1); + + data->params = plugin_parameters ("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) +{ + free (_this->fx_data); +} + +static void +zoomFilterVisualFXWrapper_apply (struct _VISUAL_FX *_this, Pixel * src, + Pixel * dest, PluginInfo * info) +{ +} + +VisualFX +zoomFilterVisualFXWrapper_create (void) +{ + VisualFX fx; + + fx.init = zoomFilterVisualFXWrapper_init; + fx.free = zoomFilterVisualFXWrapper_free; + fx.apply = zoomFilterVisualFXWrapper_apply; + return fx; +} + + +/* TODO : MOVE THIS AWAY */ void -pointFilter (GoomData * goomdata, Color c, - float t1, float t2, float t3, float t4, Uint cycle) +pointFilter (PluginInfo * goomInfo, Pixel * pix1, Color c, float t1, float t2, + float t3, float t4, Uint cycle) { - Uint *pix1 = goomdata->p1; - ZoomFilterData *zf = goomdata->zfd; - Uint x = (Uint) (zf->middleX + (int) (t1 * cos ((float) cycle / t3))); - Uint y = (Uint) (zf->middleY + (int) (t2 * sin ((float) cycle / t4))); - - if ((x > 1) && (y > 1) && (x < goomdata->resolx - 2) - && (y < goomdata->resoly - 2)) { - setPixelRGB (pix1, x + 1, y, c, goomdata->resolx, goomdata->resoly); - setPixelRGB (pix1, x, y + 1, c, goomdata->resolx, goomdata->resoly); - setPixelRGB (pix1, x + 1, y + 1, WHITE, goomdata->resolx, goomdata->resoly); - setPixelRGB (pix1, x + 2, y + 1, c, goomdata->resolx, goomdata->resoly); - setPixelRGB (pix1, x + 1, y + 2, c, goomdata->resolx, goomdata->resoly); + 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); } } |