1 /* filter.c version 0.7
2 * contient les filtres applicable a un buffer
3 * creation : 01/10/2000
4 * -ajout de sinFilter()
5 * -ajout de zoomFilter()
6 * -copie de zoomFilter() en zoomFilterRGB(), gérant les 3 couleurs
7 * -optimisation de sinFilter (utilisant une table de sin)
9 * -optimisation de la procedure de génération du buffer de transformation
10 * la vitesse est maintenant comprise dans [0..128] au lieu de [0..100]
13 /*#define _DEBUG_PIXEL; */
21 #include "goom_tools.h"
34 #define EFFECT_DISTORS 4
36 #define EFFECT_DISTORS 10
40 extern volatile guint32 resolx;
41 extern volatile guint32 resoly;
47 guint32 mmx_zoom_size;
51 extern unsigned int useAltivec;
52 extern void ppc_zoom (void);
53 extern void ppc_zoom_altivec (void);
54 unsigned int ppcsize4;
57 unsigned int *coeffs = 0, *freecoeffs = 0;
58 guint32 *expix1 = 0; /* pointeur exporte vers p1 */
59 guint32 *expix2 = 0; /* pointeur exporte vers p2 */
65 static int sintable[0xffff];
66 static int vitesse = 127;
67 static char theMode = AMULETTE_MODE;
68 static int vPlaneEffect = 0;
69 static int hPlaneEffect = 0;
70 static char noisify = 2;
71 static int middleX, middleY;
72 static unsigned char sqrtperte = 16;
74 static int *firedec = 0;
77 /* retourne x>>s , en testant le signe de x */
79 ShiftRight (int x, const unsigned char s)
88 calculer px et py en fonction de x,y,middleX,middleY et theMode
89 px et py indique la nouvelle position (en sqrtperte ieme de pixel)
93 calculatePXandPY (int x, int y, int *px, int *py)
95 if (theMode == WATER_MODE) {
97 static int wavesp = 0;
100 yy = y + RAND () % 4 + wave / 10;
107 *px = (x << 4) + firedec[yy] + (wave / 10);
108 *py = (y << 4) + 132 - ((vitesse < 132) ? vitesse : 131);
110 wavesp += RAND () % 3;
111 wavesp -= RAND () % 3;
116 wave += (wavesp / 10) + RAND () % 3;
119 wavesp = (wavesp * 9) / 10;
123 int fvitesse = vitesse << 4;
126 x += RAND () % noisify;
127 x -= RAND () % noisify;
128 y += RAND () % noisify;
129 y -= RAND () % noisify;
133 vx = ((x - middleX) << 9) + hPlaneEffect * (y - middleY);
135 vx = (x - middleX) << 9;
138 vy = ((y - middleY) << 9) + vPlaneEffect * (x - middleX);
140 vy = (y - middleY) << 9;
145 ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
146 9) * ShiftRight (vy, 9);
149 ShiftRight (sintable[(unsigned short) (0xffff * dist *
150 EFFECT_DISTORS)], 6);
153 case CRYSTAL_BALL_MODE:
155 ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
156 9) * ShiftRight (vy, 9);
157 fvitesse += (dist * EFFECT_DISTORS >> 10);
161 ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
162 9) * ShiftRight (vy, 9);
163 fvitesse -= (dist * EFFECT_DISTORS >> 4);
167 ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
168 9) * ShiftRight (vy, 9);
169 fvitesse -= (dist * EFFECT_DISTORS >> 9);
173 *px = (middleX << 4) - (-(vx * fvitesse) >> 16);
175 *px = (middleX << 4) + ((vx * fvitesse) >> 16);
177 *py = (middleY << 4) - (-(vy * fvitesse) >> 16);
179 *py = (middleY << 4) + ((vy * fvitesse) >> 16);
186 setPixelRGB (Uint * buffer, Uint x, Uint y, Color c)
188 /* buffer[ y*WIDTH + x ] = (c.r<<16)|(c.v<<8)|c.b */
190 if (x + y * resolx >= resolx * resoly) {
191 fprintf (stderr, "setPixel ERROR : hors du tableau... %i, %i\n", x, y);
197 buffer[y * resolx + x] = (c.b << 16) | (c.v << 8) | c.r;
199 buffer[y * resolx + x] = (c.r << 16) | (c.v << 8) | c.b;
205 setPixelRGB_ (Uint * buffer, Uint x, Color c)
208 if (x >= resolx * resoly) {
209 printf ("setPixel ERROR : hors du tableau... %i, %i\n", x, y);
215 buffer[x] = (c.b << 16) | (c.v << 8) | c.r;
217 buffer[x] = (c.r << 16) | (c.v << 8) | c.b;
224 getPixelRGB (Uint * buffer, Uint x, Uint y, Color * c)
226 register unsigned char *tmp8;
229 if (x + y * resolx >= resolx * resoly) {
230 printf ("getPixel ERROR : hors du tableau... %i, %i\n", x, y);
235 #ifdef __BIG_ENDIAN__
236 c->b = *(unsigned char *) (tmp8 =
237 (unsigned char *) (buffer + (x + y * resolx)));
238 c->r = *(unsigned char *) (++tmp8);
239 c->v = *(unsigned char *) (++tmp8);
240 c->b = *(unsigned char *) (++tmp8);
243 /* ATTENTION AU PETIT INDIEN */
244 c->b = *(unsigned char *) (tmp8 =
245 (unsigned char *) (buffer + (x + y * resolx)));
246 c->v = *(unsigned char *) (++tmp8);
247 c->r = *(unsigned char *) (++tmp8);
248 /* *c = (Color) buffer[x+y*WIDTH] ; */
254 getPixelRGB_ (Uint * buffer, Uint x, Color * c)
256 register unsigned char *tmp8;
259 if (x >= resolx * resoly) {
260 printf ("getPixel ERROR : hors du tableau... %i\n", x);
265 #ifdef __BIG_ENDIAN__
266 c->b = *(unsigned char *) (tmp8 = (unsigned char *) (buffer + x));
267 c->r = *(unsigned char *) (++tmp8);
268 c->v = *(unsigned char *) (++tmp8);
269 c->b = *(unsigned char *) (++tmp8);
272 /* ATTENTION AU PETIT INDIEN */
273 c->b = *(unsigned char *) (tmp8 = (unsigned char *) (buffer + x));
274 c->v = *(unsigned char *) (++tmp8);
275 c->r = *(unsigned char *) (++tmp8);
276 /* *c = (Color) buffer[x+y*WIDTH] ; */
281 /*===============================================================*/
283 zoomFilterFastRGB (Uint * pix1,
284 Uint * pix2, ZoomFilterData * zf, Uint resx, Uint resy)
286 static guint32 prevX = 0, prevY = 0;
288 static char reverse = 0; /*vitesse inversé..(zoom out) */
290 /* static int perte = 100; // 100 = normal */
291 static unsigned char pertedec = 8;
292 static char firstTime = 1;
296 /* static unsigned int prevX = 0, prevY = 0; */
303 Color col1, col2, col3, col4;
306 static unsigned int *pos10 = 0;
307 static unsigned int *c1 = 0, *c2 = 0, *c3 = 0, *c4 = 0;
310 if ((prevX != resx) || (prevY != resy)) {
324 c1 = c2 = c3 = c4 = pos10 = 0;
339 reverse = zf->reverse;
340 vitesse = zf->vitesse;
342 vitesse = 256 - vitesse;
344 sqrtperte = zf->sqrtperte;
346 pertedec = zf->pertedec;
347 middleX = zf->middleX;
348 middleY = zf->middleY;
350 hPlaneEffect = zf->hPlaneEffect;
351 vPlaneEffect = zf->vPlaneEffect;
352 noisify = zf->noisify;
355 if (firstTime || zf) {
357 /* generation d'une table de sinus */
363 freecoeffs = (unsigned int *)
364 malloc (resx * resy * 2 * sizeof (unsigned int) + 128);
365 coeffs = (guint32 *) ((1 + ((unsigned int) (freecoeffs)) / 128) * 128);
368 pos10 = (unsigned int *) malloc (resx * resy * sizeof (unsigned int));
369 c1 = (unsigned int *) malloc (resx * resy * sizeof (unsigned int));
370 c2 = (unsigned int *) malloc (resx * resy * sizeof (unsigned int));
371 c3 = (unsigned int *) malloc (resx * resy * sizeof (unsigned int));
372 c4 = (unsigned int *) malloc (resx * resy * sizeof (unsigned int));
374 for (us = 0; us < 0xffff; us++) {
375 sintable[us] = (int) (1024.0f * sin (us * 2 * 3.31415f / 0xffff));
380 firedec = (int *) malloc (prevY * sizeof (int));
381 for (loopv = prevY; loopv != 0;) {
384 static int accel = 0;
387 firedec[loopv] = decc;
398 spdc = spdc - RAND () % 3 + accel / 10;
400 spdc = spdc + RAND () % 3 + accel / 10;
402 if (decc > 8 && spdc > 1)
403 spdc -= RAND () % 3 - 2;
405 if (decc < -8 && spdc < -1)
406 spdc += RAND () % 3 + 2;
408 if (decc > 8 || decc < -8)
411 accel += RAND () % 2;
412 accel -= RAND () % 2;
422 /* generation du buffer */
423 for (y = 0; y < prevY; y++)
424 for (x = 0; x < prevX; x++) {
426 unsigned char coefv, coefh;
428 /* calculer px et py en fonction de */
429 /* x,y,middleX,middleY et theMode */
430 calculatePXandPY (x, y, &px, &py);
431 if ((px == x << 4) && (py == y << 4))
434 if ((py < 0) || (px < 0) ||
435 (py >= (prevY - 1) * sqrtperte) ||
436 (px >= (prevX - 1) * sqrtperte)) {
438 coeffs[(y * prevX + x) * 2] = 0;
439 coeffs[(y * prevX + x) * 2 + 1] = 0;
441 pos10[y * prevX + x] = 0;
442 c1[y * prevX + x] = 0;
443 c2[y * prevX + x] = 0;
444 c3[y * prevX + x] = 0;
445 c4[y * prevX + x] = 0;
452 npx10 = (px / sqrtperte);
453 npy10 = (py / sqrtperte);
455 /* if (npx10 >= prevX) fprintf(stderr,"error npx:%d",npx10);
456 if (npy10 >= prevY) fprintf(stderr,"error npy:%d",npy10);
458 coefh = px % sqrtperte;
459 coefv = py % sqrtperte;
461 pos = (y * prevX + x) * 2;
462 coeffs[pos] = (npx10 + prevX * npy10) * 4;
464 if (!(coefh || coefv))
465 coeffs[pos + 1] = (sqrtperte * sqrtperte - 1);
467 coeffs[pos + 1] = ((sqrtperte - coefh) * (sqrtperte - coefv));
469 coeffs[pos + 1] |= (coefh * (sqrtperte - coefv)) << 8;
470 coeffs[pos + 1] |= ((sqrtperte - coefh) * coefv) << 16;
471 coeffs[pos + 1] |= (coefh * coefv) << 24;
474 pos10[pos] = npx10 + prevX * npy10;
476 if (!(coefh || coefv))
477 c1[pos] = sqrtperte * sqrtperte - 1;
479 c1[pos] = (sqrtperte - coefh) * (sqrtperte - coefv);
481 c2[pos] = coefh * (sqrtperte - coefv);
482 c3[pos] = (sqrtperte - coefh) * coefv;
483 c4[pos] = coefh * coefv;
492 mmx_zoom_size = prevX * prevY;
499 ppcsize4 = ((unsigned int) (prevX * prevY)) / 4;
502 ppcsize4 = ((unsigned int) (prevX * prevY));
507 for (position = 0; position < prevX * prevY; position++) {
508 getPixelRGB_ (pix1, pos10[position], &col1);
509 getPixelRGB_ (pix1, pos10[position] + 1, &col2);
510 getPixelRGB_ (pix1, pos10[position] + prevX, &col3);
511 getPixelRGB_ (pix1, pos10[position] + prevX + 1, &col4);
513 couleur.r = col1.r * c1[position]
514 + col2.r * c2[position]
515 + col3.r * c3[position]
516 + col4.r * c4[position];
517 couleur.r >>= pertedec;
519 couleur.v = col1.v * c1[position]
520 + col2.v * c2[position]
521 + col3.v * c3[position]
522 + col4.v * c4[position];
523 couleur.v >>= pertedec;
525 couleur.b = col1.b * c1[position]
526 + col2.b * c2[position]
527 + col3.b * c3[position]
528 + col4.b * c4[position];
529 couleur.b >>= pertedec;
531 setPixelRGB_ (pix2, position, couleur);
538 pointFilter (Uint * pix1, Color c,
539 float t1, float t2, float t3, float t4, Uint cycle)
541 Uint x = (Uint) ((int) middleX + (int) (t1 * cos ((float) cycle / t3)));
542 Uint y = (Uint) ((int) middleY + (int) (t2 * sin ((float) cycle / t4)));
544 if ((x > 1) && (y > 1) && (x < resolx - 2) && (y < resoly - 2)) {
545 setPixelRGB (pix1, x + 1, y, c);
546 setPixelRGB (pix1, x, y + 1, c);
547 setPixelRGB (pix1, x + 1, y + 1, WHITE);
548 setPixelRGB (pix1, x + 2, y + 1, c);
549 setPixelRGB (pix1, x + 1, y + 2, c);