void *FastGaussianBlurOperation::initializeTileData(rcti *rect) { lockMutex(); if (!this->m_iirgaus) { MemoryBuffer *newBuf = (MemoryBuffer *)this->m_inputProgram->initializeTileData(rect); MemoryBuffer *copy = newBuf->duplicate(); updateSize(); int c; this->m_sx = this->m_data.sizex * this->m_size / 2.0f; this->m_sy = this->m_data.sizey * this->m_size / 2.0f; if ((this->m_sx == this->m_sy) && (this->m_sx > 0.0f)) { for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c) IIR_gauss(copy, this->m_sx, c, 3); } else { if (this->m_sx > 0.0f) { for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c) IIR_gauss(copy, this->m_sx, c, 1); } if (this->m_sy > 0.0f) { for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c) IIR_gauss(copy, this->m_sy, c, 2); } } this->m_iirgaus = copy; } unlockMutex(); return this->m_iirgaus; }
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); }
void *FastGaussianBlurOperation::initializeTileData(rcti *rect) { #if 0 lockMutex(); if (!this->m_iirgaus) { MemoryBuffer *newBuf = (MemoryBuffer *)this->m_inputProgram->initializeTileData(rect); MemoryBuffer *copy = newBuf->duplicate(); updateSize(); int c; this->m_sx = this->m_data->sizex * this->m_size / 2.0f; this->m_sy = this->m_data->sizey * this->m_size / 2.0f; if ((this->m_sx == this->m_sy) && (this->m_sx > 0.f)) { for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) IIR_gauss(copy, this->m_sx, c, 3); } else { if (this->m_sx > 0.0f) { for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) IIR_gauss(copy, this->m_sx, c, 1); } if (this->m_sy > 0.0f) { for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) IIR_gauss(copy, this->m_sy, c, 2); } } this->m_iirgaus = copy; } unlockMutex(); return this->m_iirgaus; #else lockMutex(); if (this->m_iirgaus) { // if this->m_iirgaus is set, we don't do tile rendering, so // we can return the already calculated cache unlockMutex(); return this->m_iirgaus; } updateSize(); rcti dai; bool use_tiles = getDAI(rect, &dai); if (use_tiles) { unlockMutex(); } MemoryBuffer *buffer = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL); rcti *buf_rect = buffer->getRect(); dai.xmin = max(dai.xmin, buf_rect->xmin); dai.xmax = min(dai.xmax, buf_rect->xmax); dai.ymin = max(dai.ymin, buf_rect->ymin); dai.ymax = min(dai.ymax, buf_rect->ymax); MemoryBuffer *tile = new MemoryBuffer(NULL, &dai); tile->copyContentFrom(buffer); int c; float sx = this->m_data->sizex * this->m_size / 2.0f; float sy = this->m_data->sizey * this->m_size / 2.0f; if ((sx == sy) && (sx > 0.f)) { for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) IIR_gauss(tile, sx, c, 3); } else { if (sx > 0.0f) { for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) IIR_gauss(tile, sx, c, 1); } if (sy > 0.0f) { for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) IIR_gauss(tile, sy, c, 2); } } if (!use_tiles) { this->m_iirgaus = tile; unlockMutex(); } return tile; #endif }
static void lensDistort(CompBuf* dst, CompBuf* src, float kr, float kg, float kb, int jit, int proj, int fit) { int x, y, z; const float cx = 0.5f*(float)dst->x, cy = 0.5f*(float)dst->y; if (proj) { // shift CompBuf* tsrc = dupalloc_compbuf(src); for (z=0; z<tsrc->type; ++z) IIR_gauss(tsrc, (kr+0.5f)*(kr+0.5f), z, 1); kr *= 20.f; for (y=0; y<dst->y; y++) { fRGB* colp = (fRGB*)&dst->rect[y*dst->x*dst->type]; const float v = (y + 0.5f)/(float)dst->y; for (x=0; x<dst->x; x++) { const float u = (x + 0.5f)/(float)dst->x; qd_getPixelLerpChan(tsrc, (u*dst->x + kr) - 0.5f, v*dst->y - 0.5f, 0, colp[x]); if (tsrc->type == CB_VAL) colp[x][1] = tsrc->rect[x + y*tsrc->x]; else colp[x][1] = tsrc->rect[(x + y*tsrc->x)*tsrc->type + 1]; qd_getPixelLerpChan(tsrc, (u*dst->x - kr) - 0.5f, v*dst->y - 0.5f, 2, colp[x]+2); } } free_compbuf(tsrc); } else { // Spherical // Scale factor to make bottom/top & right/left sides fit in window after deform // so in the case of pincushion (kn < 0), corners will be outside window. // Now also optionally scales image such that black areas are not visible when distort factor is positive // (makes distorted corners match window corners, but really only valid if mk<=0.5) const float mk = MAX3(kr, kg, kb); const float sc = (fit && (mk > 0.f)) ? (1.f/(1.f + 2.f*mk)) : (1.f/(1.f + mk)); const float drg = 4.f*(kg - kr), dgb = 4.f*(kb - kg); kr *= 4.f, kg *= 4.f, kb *= 4.f; for (y=0; y<dst->y; y++) { fRGB* colp = (fRGB*)&dst->rect[y*dst->x*dst->type]; const float v = sc*((y + 0.5f) - cy)/cy; for (x=0; x<dst->x; x++) { int dr = 0, dg = 0, db = 0; float d, t, ln[6] = {0, 0, 0, 0, 0, 0}; fRGB c1, tc = {0, 0, 0, 0}; const float u = sc*((x + 0.5f) - cx)/cx; int sta = 0, mid = 0, end = 0; if ((t = 1.f - kr*(u*u + v*v)) >= 0.f) { d = 1.f/(1.f + sqrtf(t)); ln[0] = (u*d + 0.5f)*dst->x - 0.5f, ln[1] = (v*d + 0.5f)*dst->y - 0.5f; sta = 1; } if ((t = 1.f - kg*(u*u + v*v)) >= 0.f) { d = 1.f/(1.f + sqrtf(t)); ln[2] = (u*d + 0.5f)*dst->x - 0.5f, ln[3] = (v*d + 0.5f)*dst->y - 0.5f; mid = 1; } if ((t = 1.f - kb*(u*u + v*v)) >= 0.f) { d = 1.f/(1.f + sqrtf(t)); ln[4] = (u*d + 0.5f)*dst->x - 0.5f, ln[5] = (v*d + 0.5f)*dst->y - 0.5f; end = 1; } if (sta && mid && end) { // RG const int dx = ln[2] - ln[0], dy = ln[3] - ln[1]; const float dsf = sqrtf(dx*dx + dy*dy) + 1.f; const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf); const float sd = 1.f/(float)ds; for (z=0; z<ds; ++z) { const float tz = ((float)z + (jit ? BLI_frand() : 0.5f))*sd; t = 1.f - (kr + tz*drg)*(u*u + v*v); d = 1.f / (1.f + sqrtf(t)); qd_getPixelLerp(src, (u*d + 0.5f)*dst->x - 0.5f, (v*d + 0.5f)*dst->y - 0.5f, c1); if (src->type == CB_VAL) c1[1] = c1[2] = c1[0]; tc[0] += (1.f-tz)*c1[0], tc[1] += tz*c1[1]; dr++, dg++; } // GB { const int dx = ln[4] - ln[2], dy = ln[5] - ln[3]; const float dsf = sqrtf(dx*dx + dy*dy) + 1.f; const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf); const float sd = 1.f/(float)ds; for (z=0; z<ds; ++z) { const float tz = ((float)z + (jit ? BLI_frand() : 0.5f))*sd; t = 1.f - (kg + tz*dgb)*(u*u + v*v); d = 1.f / (1.f + sqrtf(t)); qd_getPixelLerp(src, (u*d + 0.5f)*dst->x - 0.5f, (v*d + 0.5f)*dst->y - 0.5f, c1); if (src->type == CB_VAL) c1[1] = c1[2] = c1[0]; tc[1] += (1.f-tz)*c1[1], tc[2] += tz*c1[2]; dg++, db++; } } } if (dr) colp[x][0] = 2.f*tc[0] / (float)dr; if (dg) colp[x][1] = 2.f*tc[1] / (float)dg; if (db) colp[x][2] = 2.f*tc[2] / (float)db; } } } }