filters.c
来自「linux下的MPEG1」· C语言 代码 · 共 768 行 · 第 1/2 页
C
768 行
// 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 c_zoom (Pixel *expix1, Pixel *expix2, unsigned int prevX, unsigned int prevY, signed int *brutS, signed int *brutD, int buffratio, int precalCoef[16][16]){ int myPos, myPos2; Color couleur; unsigned int ax = (prevX - 1) << PERTEDEC, ay = (prevY - 1) << PERTEDEC; int bufsize = prevX * prevY * 2; int bufwidth = prevX; 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); }}/** generate the water fx horizontal direction buffer */static void generateTheWaterFXHorizontalDirectionBuffer(PluginInfo *goomInfo, ZoomFilterFXWrapperData *data) { 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 (PluginInfo *goomInfo, Pixel * pix1, Pixel * pix2, ZoomFilterData * zf, Uint resx, Uint resy, int switchIncr, float switchMult){ Uint x, y; ZoomFilterFXWrapperData *data = (ZoomFilterFXWrapperData*)goomInfo->zoomFilter_fx.fx_data; if (!BVAL(data->enabled_bp)) return; /** 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; } if (data->interlace_start != -2) zf = NULL; /** 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; } 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; } 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); } 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; } }}/* 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 = rand() % 10; 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 = {0}; fx.init = zoomFilterVisualFXWrapper_init; fx.free = zoomFilterVisualFXWrapper_free; fx.apply = zoomFilterVisualFXWrapper_apply; return fx;}/* TODO : MOVE THIS AWAY */void pointFilter (PluginInfo *goomInfo, Pixel * pix1, Color c, float t1, float t2, float t3, float t4, Uint cycle){ 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); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?