filters.c
来自「linux下的MPEG1」· C语言 代码 · 共 768 行 · 第 1/2 页
C
768 行
// --- 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 */#include <string.h>#include <stdlib.h>#include <math.h>#include <stdio.h>#include <inttypes.h>#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 (PluginInfo *goomInfo, Pixel *buffer, Uint x, Uint y, Color * c){ Pixel i = *(buffer + (x + y * goomInfo->screen.width)); 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); 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 v2g zoomVector(ZoomFilterFXWrapperData *data, float X, float Y){ 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; } 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; return vecteur;}/* * 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 = (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; } 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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?