Example #1
0
void process (struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, void *ivoid, void *ovoid, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out)
{
  dt_iop_lowpass_data_t *data = (dt_iop_lowpass_data_t *)piece->data;
  float *in  = (float *)ivoid;
  float *out = (float *)ovoid;


  const int width = roi_in->width;
  const int height = roi_in->height;
  const int ch = piece->colors;

  const int   use_bilateral = data->radius < 0 ? 1 : 0;
  const float radius = fmax(0.1f, fabs(data->radius));
  const float sigma = radius * roi_in->scale / piece ->iscale;
  const int order = data->order;

  const float Labmax[] = { 100.0f, 128.0f, 128.0f, 1.0f };
  const float Labmin[] = { 0.0f, -128.0f, -128.0f, 0.0f };


  if(!use_bilateral)
  {
    dt_gaussian_t *g = dt_gaussian_init(width, height, ch, Labmax, Labmin, sigma, order);
    if(!g) return;
    dt_gaussian_blur_4c(g, in, out);
    dt_gaussian_free(g);
  }
  else
  {
    const float sigma_r = 100.0f;// d->sigma_r; // does not depend on scale
    const float sigma_s = sigma;
    const float detail = -1.0f; // we want the bilateral base layer

    dt_bilateral_t *b = dt_bilateral_init(width, height, sigma_s, sigma_r);
    if(!b) return;
    dt_bilateral_splat(b, in);
    dt_bilateral_blur(b);
    dt_bilateral_slice(b, in, out, detail);
    dt_bilateral_free(b);
  }

  // some aliased pointers for compilers that don't yet understand operators on __m128
  const float *const Labminf = (float *)&Labmin;
  const float *const Labmaxf = (float *)&Labmax;
#ifdef _OPENMP
  #pragma omp parallel for default(none) shared(in,out,data,roi_out) schedule(static)
#endif
  for(int k=0; k<roi_out->width*roi_out->height; k++)
  {
    out[k*ch+0] = (out[k*ch+0] < 100.0f) ? data->table[CLAMP((int)(out[k*ch+0]/100.0f*0x10000ul), 0, 0xffff)] :
                  dt_iop_eval_exp(data->unbounded_coeffs, out[k*ch+0]/100.0f);
    out[k*ch+1] = CLAMPF(out[k*ch+1]*data->saturation, Labminf[1], Labmaxf[1]);
    out[k*ch+2] = CLAMPF(out[k*ch+2]*data->saturation, Labminf[2], Labmaxf[2]);
    out[k*ch+3] = in[k*ch+3];
  }
}
Example #2
0
/******************************************************************************
 * fogging
 */
static void
tnl_fogging (void)
{
    int i, n;
    GLfloat d;

    if (!ctx_fog.fogging) {
	return;
    }

    if (ctx_fog.source == GL_FOG_COORDINATE) {
	GLfloat4 *fogcoord = tnl_vb.attr[TNL_FOGCOORD].data;
	const GLuint fogcoord_stride = tnl_vb.attr[TNL_FOGCOORD].stride;
	n = fogcoord_stride ? tnl_vb.len : 1;
	switch (ctx_fog.mode) {
	    case GL_LINEAR:
		if (ctx_fog.start == ctx_fog.end) {
		    d = 1.0F;
		} else {
		    d = 1.0F / (ctx_fog.end - ctx_fog.start);
		}
		for (i = 0; i < n; i++) {
		    const GLfloat z = FABS(fogcoord[0][0]);
		    GLfloat f = (ctx_fog.end - z) * d;
		    tnl_vb.fogcoord[i][0] = CLAMPF(f);
		    fogcoord += fogcoord_stride;
		}
		break;
	    case GL_EXP:
		d = ctx_fog.density;
		for (i = 0; i < n; i++) {
		    const GLfloat z = FABS(fogcoord[0][0]);
		    tnl_vb.fogcoord[i][0] = CLAMPF(EXP(- d * z));
		    fogcoord += fogcoord_stride;
		}
		break;
	    case GL_EXP2:
		d = ctx_fog.density * ctx_fog.density;
		for (i = 0; i < n; i++) {
		    const GLfloat z = FABS(fogcoord[0][0]);
		    tnl_vb.fogcoord[i][0] = CLAMPF(EXP(- d * z * z));
		    fogcoord += fogcoord_stride;
		}
		break;
	}
	tnl_vb.attr[TNL_FOGCOORD].data = tnl_vb.fogcoord;
    } else {
	/* XXX not implemented */
    }
}
Example #3
0
void glLightModelfv (GLenum pname, const GLfloat *params)
{
	switch (pname) {
	case GL_LIGHT_MODEL_AMBIENT:
		sendCommandi(CMD_AMBIENT_COLOR, COLOR3(params));
		sendCommandi(CMD_AMBIENT_ALPHA, (int) (255.0 * CLAMPF(params[3])));
		break;
	case GL_LIGHT_MODEL_COLOR_CONTROL:
		sendCommandi(CMD_LIGHTMODEL,
			     (params[0] == GL_SEPARATE_SPECULAR_COLOR) ? 1 : 0);
		break;
	default:
		GLERROR(GL_INVALID_ENUM);
		return;
	}
}
Example #4
0
void
dt_gaussian_blur(
    dt_gaussian_t *g,
    float    *in,
    float    *out)
{

  const int width = g->width;
  const int height = g->height;
  const int ch = g->channels;

  float a0, a1, a2, a3, b1, b2, coefp, coefn;

  compute_gauss_params(g->sigma, g->order, &a0, &a1, &a2, &a3, &b1, &b2, &coefp, &coefn);

  float *temp = g->buf;

  float *Labmax = g->max;
  float *Labmin = g->min;

  // vertical blur column by column
#ifdef _OPENMP
  #pragma omp parallel for default(none) shared(in,out,temp,Labmin,Labmax,a0,a1,a2,a3,b1,b2,coefp,coefn) schedule(static)
#endif
  for(int i=0; i<width; i++)
  {
    float xp[ch];
    float yb[ch];
    float yp[ch];
    float xc[ch];
    float yc[ch];
    float xn[ch];
    float xa[ch];
    float yn[ch];
    float ya[ch];

    // forward filter
    for(int k=0; k<ch; k++)
    {
      xp[k] = CLAMPF(in[i*ch+k], Labmin[k], Labmax[k]);
      yb[k] = xp[k] * coefp;
      yp[k] = yb[k];
      xc[k] = yc[k] = xn[k] = xa[k] = yn[k] = ya[k] = 0.0f;
    }
 
    for(int j=0; j<height; j++)
    {
      int offset = (i + j * width)*ch;

      for(int k=0; k<ch; k++)
      {
        xc[k] = CLAMPF(in[offset+k], Labmin[k], Labmax[k]);
        yc[k] = (a0 * xc[k]) + (a1 * xp[k]) - (b1 * yp[k]) - (b2 * yb[k]);

        temp[offset+k] = yc[k];

        xp[k] = xc[k];
        yb[k] = yp[k];
        yp[k] = yc[k];
      }
    }

    // backward filter
    for(int k=0; k<ch; k++)
    {
      xn[k] = CLAMPF(in[((height - 1) * width + i)*ch+k], Labmin[k], Labmax[k]);
      xa[k] = xn[k];
      yn[k] = xn[k] * coefn;
      ya[k] = yn[k];
    }

    for(int j=height - 1; j > -1; j--)
    {
      int offset = (i + j * width)*ch;

      for(int k=0; k<ch; k++)
      {      
        xc[k] = CLAMPF(in[offset+k], Labmin[k], Labmax[k]);

        yc[k] = (a2 * xn[k]) + (a3 * xa[k]) - (b1 * yn[k]) - (b2 * ya[k]);

        xa[k] = xn[k]; 
        xn[k] = xc[k]; 
        ya[k] = yn[k]; 
        yn[k] = yc[k];

        temp[offset+k] += yc[k];
      }
    }
  }

  // horizontal blur line by line
#ifdef _OPENMP
  #pragma omp parallel for default(none) shared(out,temp,Labmin,Labmax,a0,a1,a2,a3,b1,b2,coefp,coefn) schedule(static)
#endif
  for(int j=0; j<height; j++)
  {
    float xp[ch];
    float yb[ch];
    float yp[ch];
    float xc[ch];
    float yc[ch];
    float xn[ch];
    float xa[ch];
    float yn[ch];
    float ya[ch];

    // forward filter
    for(int k=0; k<ch; k++)
    {
      xp[k] = CLAMPF(temp[j*width*ch+k], Labmin[k], Labmax[k]);
      yb[k] = xp[k] * coefp;
      yp[k] = yb[k];
      xc[k] = yc[k] = xn[k] = xa[k] = yn[k] = ya[k] = 0.0f;
    }
 
    for(int i=0; i<width; i++)
    {
      int offset = (i + j * width)*ch;

      for(int k=0; k<ch; k++)
      {
        xc[k] = CLAMPF(temp[offset+k], Labmin[k], Labmax[k]);
        yc[k] = (a0 * xc[k]) + (a1 * xp[k]) - (b1 * yp[k]) - (b2 * yb[k]);

        out[offset+k] = yc[k];

        xp[k] = xc[k];
        yb[k] = yp[k];
        yp[k] = yc[k];
      }
    }

    // backward filter
    for(int k=0; k<ch; k++)
    {
      xn[k] = CLAMPF(temp[((j + 1)*width - 1)*ch + k], Labmin[k], Labmax[k]);
      xa[k] = xn[k];
      yn[k] = xn[k] * coefn;
      ya[k] = yn[k];
    }

    for(int i=width - 1; i > -1; i--)
    {
      int offset = (i + j * width)*ch;

      for(int k=0; k<ch; k++)
      {      
        xc[k] = CLAMPF(temp[offset+k], Labmin[k], Labmax[k]);

        yc[k] = (a2 * xn[k]) + (a3 * xa[k]) - (b1 * yn[k]) - (b2 * ya[k]);

        xa[k] = xn[k]; 
        xn[k] = xc[k]; 
        ya[k] = yn[k]; 
        yn[k] = yc[k];

        out[offset+k] += yc[k];
      }
    }
  }
}
Example #5
0
void dt_gaussian_blur(dt_gaussian_t *g, const float *const in, float *const out)
{

  const int width = g->width;
  const int height = g->height;
  const int ch = g->channels;

  float a0, a1, a2, a3, b1, b2, coefp, coefn;

  compute_gauss_params(g->sigma, g->order, &a0, &a1, &a2, &a3, &b1, &b2, &coefp, &coefn);

  float *const temp = g->buf;

  float *const Labmax = g->max;
  float *const Labmin = g->min;

  float *const buf = malloc((size_t)9 * ch * dt_get_num_threads() * sizeof(float));

// vertical blur column by column
#ifdef _OPENMP
#pragma omp parallel for default(none) shared(a0, a1, a2, a3, b1, b2, coefp, coefn) schedule(static)
#endif
  for(int i = 0; i < width; i++)
  {
    const int threadnum = dt_get_thread_num();
    float *xp = buf + (size_t)9 * ch * threadnum + 0;
    float *yb = buf + (size_t)9 * ch * threadnum + 1;
    float *yp = buf + (size_t)9 * ch * threadnum + 2;
    float *xc = buf + (size_t)9 * ch * threadnum + 3;
    float *yc = buf + (size_t)9 * ch * threadnum + 4;
    float *xn = buf + (size_t)9 * ch * threadnum + 5;
    float *xa = buf + (size_t)9 * ch * threadnum + 6;
    float *yn = buf + (size_t)9 * ch * threadnum + 7;
    float *ya = buf + (size_t)9 * ch * threadnum + 8;

    // forward filter
    for(int k = 0; k < ch; k++)
    {
      xp[k] = CLAMPF(in[(size_t)i * ch + k], Labmin[k], Labmax[k]);
      yb[k] = xp[k] * coefp;
      yp[k] = yb[k];
      xc[k] = yc[k] = xn[k] = xa[k] = yn[k] = ya[k] = 0.0f;
    }

    for(int j = 0; j < height; j++)
    {
      size_t offset = ((size_t)j * width + i) * ch;

      for(int k = 0; k < ch; k++)
      {
        xc[k] = CLAMPF(in[offset + k], Labmin[k], Labmax[k]);
        yc[k] = (a0 * xc[k]) + (a1 * xp[k]) - (b1 * yp[k]) - (b2 * yb[k]);

        temp[offset + k] = yc[k];

        xp[k] = xc[k];
        yb[k] = yp[k];
        yp[k] = yc[k];
      }
    }

    // backward filter
    for(int k = 0; k < ch; k++)
    {
      xn[k] = CLAMPF(in[((size_t)(height - 1) * width + i) * ch + k], Labmin[k], Labmax[k]);
      xa[k] = xn[k];
      yn[k] = xn[k] * coefn;
      ya[k] = yn[k];
    }

    for(int j = height - 1; j > -1; j--)
    {
      size_t offset = ((size_t)j * width + i) * ch;

      for(int k = 0; k < ch; k++)
      {
        xc[k] = CLAMPF(in[offset + k], Labmin[k], Labmax[k]);

        yc[k] = (a2 * xn[k]) + (a3 * xa[k]) - (b1 * yn[k]) - (b2 * ya[k]);

        xa[k] = xn[k];
        xn[k] = xc[k];
        ya[k] = yn[k];
        yn[k] = yc[k];

        temp[offset + k] += yc[k];
      }
    }
  }

// horizontal blur line by line
#ifdef _OPENMP
#pragma omp parallel for default(none) shared(a0, a1, a2, a3, b1, b2, coefp, coefn) schedule(static)
#endif
  for(int j = 0; j < height; j++)
  {
    const int threadnum = dt_get_thread_num();
    float *xp = buf + (size_t)9 * ch * threadnum + 0;
    float *yb = buf + (size_t)9 * ch * threadnum + 1;
    float *yp = buf + (size_t)9 * ch * threadnum + 2;
    float *xc = buf + (size_t)9 * ch * threadnum + 3;
    float *yc = buf + (size_t)9 * ch * threadnum + 4;
    float *xn = buf + (size_t)9 * ch * threadnum + 5;
    float *xa = buf + (size_t)9 * ch * threadnum + 6;
    float *yn = buf + (size_t)9 * ch * threadnum + 7;
    float *ya = buf + (size_t)9 * ch * threadnum + 8;


    // forward filter
    for(int k = 0; k < ch; k++)
    {
      xp[k] = CLAMPF(temp[(size_t)j * width * ch + k], Labmin[k], Labmax[k]);
      yb[k] = xp[k] * coefp;
      yp[k] = yb[k];
      xc[k] = yc[k] = xn[k] = xa[k] = yn[k] = ya[k] = 0.0f;
    }

    for(int i = 0; i < width; i++)
    {
      size_t offset = ((size_t)j * width + i) * ch;

      for(int k = 0; k < ch; k++)
      {
        xc[k] = CLAMPF(temp[offset + k], Labmin[k], Labmax[k]);
        yc[k] = (a0 * xc[k]) + (a1 * xp[k]) - (b1 * yp[k]) - (b2 * yb[k]);

        out[offset + k] = yc[k];

        xp[k] = xc[k];
        yb[k] = yp[k];
        yp[k] = yc[k];
      }
    }

    // backward filter
    for(int k = 0; k < ch; k++)
    {
      xn[k] = CLAMPF(temp[((size_t)(j + 1) * width - 1) * ch + k], Labmin[k], Labmax[k]);
      xa[k] = xn[k];
      yn[k] = xn[k] * coefn;
      ya[k] = yn[k];
    }

    for(int i = width - 1; i > -1; i--)
    {
      size_t offset = ((size_t)j * width + i) * ch;

      for(int k = 0; k < ch; k++)
      {
        xc[k] = CLAMPF(temp[offset + k], Labmin[k], Labmax[k]);

        yc[k] = (a2 * xn[k]) + (a3 * xa[k]) - (b1 * yn[k]) - (b2 * ya[k]);

        xa[k] = xn[k];
        xn[k] = xc[k];
        ya[k] = yn[k];
        yn[k] = yc[k];

        out[offset + k] += yc[k];
      }
    }
  }

  free(buf);
}