static void draw_histogram(bNode *node, CompBuf *out, int* bins) { int x,y; float color[4]; float value; int max; /* find max value */ max=0; for(x=0; x<256; x++) { if(bins[x]>max) max=bins[x]; } /*draw histogram in buffer */ for(x=0; x<out->x; x++) { for(y=0;y<out->y; y++) { /* get normalized value (0..255) */ value=((float)bins[x]/(float)max)*255.0; if(y < (int)value) { /*if the y value is below the height of the bar for this line then draw with the color */ switch (node->custom1) { case 1: { /* draw in black */ color[0]=0.0; color[1]=0.0; color[2]=0.0; color[3]=1.0; break; } case 2: { /* draw in red */ color[0]=1.0; color[1]=0.0; color[2]=0.0; color[3]=1.0; break; } case 3: { /* draw in green */ color[0]=0.0; color[1]=1.0; color[2]=0.0; color[3]=1.0; break; } case 4: { /* draw in blue */ color[0]=0.0; color[1]=0.0; color[2]=1.0; color[3]=1.0; break; } case 5: { /* draw in white */ color[0]=1.0; color[1]=1.0; color[2]=1.0; color[3]=1.0; break; } } } else{ color[0]=0.8; color[1]=0.8; color[2]=0.8; color[3]=1.0; } /* set the color */ qd_setPixel(out, x, y, color); } } }
static void fglow(NodeGlare* ndg, CompBuf* dst, CompBuf* src) { int x, y; float scale, u, v, r, w, d; fRGB fcol; CompBuf *tsrc, *ckrn; unsigned int sz = 1 << ndg->size; const float cs_r = 1.f, cs_g = 1.f, cs_b = 1.f; // temp. src image tsrc = BTP(src, ndg->threshold, 1 << ndg->quality); // make the convolution kernel ckrn = alloc_compbuf(sz, sz, CB_RGBA, 1); scale = 0.25f*sqrtf(sz*sz); for (y=0; y<sz; ++y) { v = 2.f*(y / (float)sz) - 1.f; for (x=0; x<sz; ++x) { u = 2.f*(x / (float)sz) - 1.f; r = (u*u + v*v)*scale; d = -sqrtf(sqrtf(sqrtf(r)))*9.f; fcol[0] = expf(d*cs_r), fcol[1] = expf(d*cs_g), fcol[2] = expf(d*cs_b); // linear window good enough here, visual result counts, not scientific analysis //w = (1.f-fabs(u))*(1.f-fabs(v)); // actually, Hanning window is ok, cos^2 for some reason is slower w = (0.5f + 0.5f*cos((double)u*M_PI))*(0.5f + 0.5f*cos((double)v*M_PI)); fRGB_mult(fcol, w); qd_setPixel(ckrn, x, y, fcol); } } convolve(tsrc, tsrc, ckrn); free_compbuf(ckrn); mixImages(dst, tsrc, 0.5f + 0.5f*ndg->mix); free_compbuf(tsrc); }
static void ghosts(NodeGlare* ndg, CompBuf* dst, CompBuf* src) { // colormodulation and scale factors (cm & scalef) for 16 passes max: 64 int x, y, n, p, np; fRGB c, tc, cm[64]; float sc, isc, u, v, sm, s, t, ofs, scalef[64]; CompBuf *tbuf1, *tbuf2, *gbuf; const float cmo = 1.f - ndg->colmod; const int qt = 1 << ndg->quality; const float s1 = 4.f/(float)qt, s2 = 2.f*s1; gbuf = BTP(src, ndg->threshold, qt); tbuf1 = dupalloc_compbuf(gbuf); IIR_gauss(tbuf1, s1, 0, 3); IIR_gauss(tbuf1, s1, 1, 3); IIR_gauss(tbuf1, s1, 2, 3); tbuf2 = dupalloc_compbuf(tbuf1); IIR_gauss(tbuf2, s2, 0, 3); IIR_gauss(tbuf2, s2, 1, 3); IIR_gauss(tbuf2, s2, 2, 3); if (ndg->iter & 1) ofs = 0.5f; else ofs = 0.f; for (x=0; x<(ndg->iter*4); x++) { y = x & 3; cm[x][0] = cm[x][1] = cm[x][2] = 1; if (y==1) fRGB_rgbmult(cm[x], 1.f, cmo, cmo); if (y==2) fRGB_rgbmult(cm[x], cmo, cmo, 1.f); if (y==3) fRGB_rgbmult(cm[x], cmo, 1.f, cmo); scalef[x] = 2.1f*(1.f-(x+ofs)/(float)(ndg->iter*4)); if (x & 1) scalef[x] = -0.99f/scalef[x]; } sc = 2.13; isc = -0.97; for (y=0; y<gbuf->y; y++) { v = (float)(y+0.5f) / (float)gbuf->y; for (x=0; x<gbuf->x; x++) { u = (float)(x+0.5f) / (float)gbuf->x; s = (u-0.5f)*sc + 0.5f, t = (v-0.5f)*sc + 0.5f; qd_getPixelLerp(tbuf1, s*gbuf->x, t*gbuf->y, c); sm = smoothMask(s, t); fRGB_mult(c, sm); s = (u-0.5f)*isc + 0.5f, t = (v-0.5f)*isc + 0.5f; qd_getPixelLerp(tbuf2, s*gbuf->x - 0.5f, t*gbuf->y - 0.5f, tc); sm = smoothMask(s, t); fRGB_madd(c, tc, sm); qd_setPixel(gbuf, x, y, c); } } memset(tbuf1->rect, 0, tbuf1->x*tbuf1->y*tbuf1->type*sizeof(float)); for (n=1; n<ndg->iter; n++) { for (y=0; y<gbuf->y; y++) { v = (float)(y+0.5f) / (float)gbuf->y; for (x=0; x<gbuf->x; x++) { u = (float)(x+0.5f) / (float)gbuf->x; tc[0] = tc[1] = tc[2] = 0.f; for (p=0;p<4;p++) { np = (n<<2) + p; s = (u-0.5f)*scalef[np] + 0.5f; t = (v-0.5f)*scalef[np] + 0.5f; qd_getPixelLerp(gbuf, s*gbuf->x - 0.5f, t*gbuf->y - 0.5f, c); fRGB_colormult(c, cm[np]); sm = smoothMask(s, t)*0.25f; fRGB_madd(tc, c, sm); } p = (x + y*tbuf1->x)*tbuf1->type; tbuf1->rect[p] += tc[0]; tbuf1->rect[p+1] += tc[1]; tbuf1->rect[p+2] += tc[2]; } } memcpy(gbuf->rect, tbuf1->rect, tbuf1->x*tbuf1->y*tbuf1->type*sizeof(float)); } free_compbuf(tbuf1); free_compbuf(tbuf2); mixImages(dst, gbuf, 0.5f + 0.5f*ndg->mix); free_compbuf(gbuf); }
static void star4(NodeGlare* ndg, CompBuf* dst, CompBuf* src) { int x, y, i, xm, xp, ym, yp; float c[4] = {0,0,0,0}, tc[4] = {0,0,0,0}; CompBuf *tbuf1, *tbuf2, *tsrc; const float f1 = 1.f - ndg->fade, f2 = (1.f - f1)*0.5f; //const float t3 = ndg->threshold*3.f; const float sc = (float)(1 << ndg->quality); const float isc = 1.f/sc; tsrc = BTP(src, ndg->threshold, (int)sc); tbuf1 = dupalloc_compbuf(tsrc); tbuf2 = dupalloc_compbuf(tsrc); for (i=0; i<ndg->iter; i++) { // (x || x-1, y-1) to (x || x+1, y+1) // F for (y=0; y<tbuf1->y; y++) { ym = y - i; yp = y + i; for (x=0; x<tbuf1->x; x++) { xm = x - i; xp = x + i; qd_getPixel(tbuf1, x, y, c); fRGB_mult(c, f1); qd_getPixel(tbuf1, (ndg->angle ? xm : x), ym, tc); fRGB_madd(c, tc, f2); qd_getPixel(tbuf1, (ndg->angle ? xp : x), yp, tc); fRGB_madd(c, tc, f2); qd_setPixel(tbuf1, x, y, c); } } // B for (y=tbuf1->y-1; y>=0; y--) { ym = y - i; yp = y + i; for (x=tbuf1->x-1; x>=0; x--) { xm = x - i; xp = x + i; qd_getPixel(tbuf1, x, y, c); fRGB_mult(c, f1); qd_getPixel(tbuf1, (ndg->angle ? xm : x), ym, tc); fRGB_madd(c, tc, f2); qd_getPixel(tbuf1, (ndg->angle ? xp : x), yp, tc); fRGB_madd(c, tc, f2); qd_setPixel(tbuf1, x, y, c); } } // (x-1, y || y+1) to (x+1, y || y-1) // F for (y=0; y<tbuf2->y; y++) { ym = y - i; yp = y + i; for (x=0; x<tbuf2->x; x++) { xm = x - i; xp = x + i; qd_getPixel(tbuf2, x, y, c); fRGB_mult(c, f1); qd_getPixel(tbuf2, xm, (ndg->angle ? yp : y), tc); fRGB_madd(c, tc, f2); qd_getPixel(tbuf2, xp, (ndg->angle ? ym : y), tc); fRGB_madd(c, tc, f2); qd_setPixel(tbuf2, x, y, c); } } // B for (y=tbuf2->y-1; y>=0; y--) { ym = y - i; yp = y + i; for (x=tbuf2->x-1; x>=0; x--) { xm = x - i; xp = x + i; qd_getPixel(tbuf2, x, y, c); fRGB_mult(c, f1); qd_getPixel(tbuf2, xm, (ndg->angle ? yp : y), tc); fRGB_madd(c, tc, f2); qd_getPixel(tbuf2, xp, (ndg->angle ? ym : y), tc); fRGB_madd(c, tc, f2); qd_setPixel(tbuf2, x, y, c); } } } for (y=0; y<tbuf1->y; ++y) for (x=0; x<tbuf1->x; ++x) { unsigned int p = (x + y*tbuf1->x)*tbuf1->type; tbuf1->rect[p] += tbuf2->rect[p]; tbuf1->rect[p+1] += tbuf2->rect[p+1]; tbuf1->rect[p+2] += tbuf2->rect[p+2]; } for (y=0; y<dst->y; ++y) { const float m = 0.5f + 0.5f*ndg->mix; for (x=0; x<dst->x; ++x) { unsigned int p = (x + y*dst->x)*dst->type; qd_getPixelLerp(tbuf1, x*isc, y*isc, tc); dst->rect[p] = src->rect[p] + m*(tc[0] - src->rect[p]); dst->rect[p+1] = src->rect[p+1] + m*(tc[1] - src->rect[p+1]); dst->rect[p+2] = src->rect[p+2] + m*(tc[2] - src->rect[p+2]); } } free_compbuf(tbuf1); free_compbuf(tbuf2); free_compbuf(tsrc); }
static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float *UNUSED(veccol), CompBuf *xbuf, CompBuf *ybuf, float *xscale, float *yscale) { ImBuf *ibuf; int x, y; float p_dx, p_dy; /* main displacement in pixel space */ float d_dx, d_dy; float dxt, dyt; float u, v; float xs, ys; float vec[3], vecdx[3], vecdy[3]; float col[3]; ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0); ibuf->rect_float= cbuf->rect; for(y=0; y < stackbuf->y; y++) { for(x=0; x < stackbuf->x; x++) { /* calc pixel coordinates */ qd_getPixel(vecbuf, x-vecbuf->xof, y-vecbuf->yof, vec); if (xbuf) qd_getPixel(xbuf, x-xbuf->xof, y-xbuf->yof, &xs); else xs = xscale[0]; if (ybuf) qd_getPixel(ybuf, x-ybuf->xof, y-ybuf->yof, &ys); else ys = yscale[0]; p_dx = vec[0] * xs; p_dy = vec[1] * ys; /* if no displacement, then just copy this pixel */ if (fabsf(p_dx) < DISPLACE_EPSILON && fabsf(p_dy) < DISPLACE_EPSILON) { qd_getPixel(cbuf, x-cbuf->xof, y-cbuf->yof, col); qd_setPixel(stackbuf, x, y, col); continue; } /* displaced pixel in uv coords, for image sampling */ u = (x - cbuf->xof - p_dx + 0.5f) / (float)stackbuf->x; v = (y - cbuf->yof - p_dy + 0.5f) / (float)stackbuf->y; /* calc derivatives */ qd_getPixel(vecbuf, x-vecbuf->xof+1, y-vecbuf->yof, vecdx); qd_getPixel(vecbuf, x-vecbuf->xof, y-vecbuf->yof+1, vecdy); d_dx = vecdx[0] * xs; d_dy = vecdy[0] * ys; /* clamp derivatives to minimum displacement distance in UV space */ dxt = p_dx - d_dx; dyt = p_dy - d_dy; dxt = signf(dxt)*maxf(fabsf(dxt), DISPLACE_EPSILON)/(float)stackbuf->x; dyt = signf(dyt)*maxf(fabsf(dyt), DISPLACE_EPSILON)/(float)stackbuf->y; ibuf_sample(ibuf, u, v, dxt, dyt, col); qd_setPixel(stackbuf, x, y, col); } } IMB_freeImBuf(ibuf); /* simple method for reference, linear interpolation */ /* int x, y; float dx, dy; float u, v; float vec[3]; float col[3]; for(y=0; y < stackbuf->y; y++) { for(x=0; x < stackbuf->x; x++) { qd_getPixel(vecbuf, x, y, vec); dx = vec[0] * (xscale[0]); dy = vec[1] * (yscale[0]); u = (x - dx + 0.5f) / (float)stackbuf->x; v = (y - dy + 0.5f) / (float)stackbuf->y; qd_getPixelLerp(cbuf, u*cbuf->x - 0.5f, v*cbuf->y - 0.5f, col); qd_setPixel(stackbuf, x, y, col); } } */ }