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 + -
显示快捷键?