コード例 #1
0
ファイル: circle.c プロジェクト: a3novy/darktable
static int dt_circle_get_area(dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form,
                              int *width, int *height, int *posx, int *posy)
{
  // we get the circle values
  dt_masks_point_circle_t *circle = (dt_masks_point_circle_t *)(g_list_first(form->points)->data);
  float wd = piece->pipe->iwidth, ht = piece->pipe->iheight;

  float r = (circle->radius + circle->border) * MIN(wd, ht);
  int l = (int)(2.0 * M_PI * r);
  // buffer allocations
  float *points = calloc(2 * (l + 1), sizeof(float));

  // now we set the points
  points[0] = circle->center[0] * wd;
  points[1] = circle->center[1] * ht;
  for(int i = 1; i < l + 1; i++)
  {
    float alpha = (i - 1) * 2.0 * M_PI / (float)l;
    points[i * 2] = points[0] + r * cosf(alpha);
    points[i * 2 + 1] = points[1] + r * sinf(alpha);
  }

  // and we transform them with all distorted modules
  if(!dt_dev_distort_transform_plus(module->dev, piece->pipe, 0, module->priority, points, l + 1))
  {
    free(points);
    return 0;
  }

  // now we search min and max
  float xmin, xmax, ymin, ymax;
  xmin = ymin = FLT_MAX;
  xmax = ymax = FLT_MIN;
  for(int i = 1; i < l + 1; i++)
  {
    xmin = fminf(points[i * 2], xmin);
    xmax = fmaxf(points[i * 2], xmax);
    ymin = fminf(points[i * 2 + 1], ymin);
    ymax = fmaxf(points[i * 2 + 1], ymax);
  }
  free(points);

  // and we set values
  *posx = xmin;
  *posy = ymin;
  *width = (xmax - xmin);
  *height = (ymax - ymin);
  return 1;
}
コード例 #2
0
ファイル: gradient.c プロジェクト: CarVac/darktable
static int dt_gradient_get_area(dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form,
                                int *width, int *height, int *posx, int *posy)
{
  float wd = piece->pipe->iwidth, ht = piece->pipe->iheight;

  float points[8];

  // now we set the points
  points[0] = 0;
  points[1] = 0;
  points[2] = wd;
  points[3] = 0;
  points[4] = wd;
  points[5] = ht;
  points[6] = 0;
  points[7] = ht;

  // and we transform them with all distorted modules
  if(!dt_dev_distort_transform_plus(module->dev, piece->pipe, 0, module->priority, points, 4)) return 0;

  // now we search min and max
  float xmin, xmax, ymin, ymax;
  xmin = ymin = FLT_MAX;
  xmax = ymax = FLT_MIN;
  for(int i = 0; i < 4; i++)
  {
    xmin = fminf(points[i * 2], xmin);
    xmax = fmaxf(points[i * 2], xmax);
    ymin = fminf(points[i * 2 + 1], ymin);
    ymax = fmaxf(points[i * 2 + 1], ymax);
  }

  // and we set values
  *posx = xmin;
  *posy = ymin;
  *width = (xmax - xmin);
  *height = (ymax - ymin);
  return 1;
}
コード例 #3
0
ファイル: develop.c プロジェクト: ealasu/darktable
int dt_dev_distort_transform(dt_develop_t *dev, float *points, int points_count)
{
  return dt_dev_distort_transform_plus(dev,dev->preview_pipe,0,99999,points,points_count);
}
コード例 #4
0
ファイル: graduatednd.c プロジェクト: dtorop/darktable
static int set_points_from_grad(struct dt_iop_module_t *self, float *xa, float *ya, float *xb, float *yb,
                                float rotation, float offset)
{
  // we get the extremities of the line
  const float v = (-rotation / 180) * M_PI;
  const float sinv = sin(v);
  float pts[4];

  dt_dev_pixelpipe_iop_t *piece = dt_dev_distort_get_iop_pipe(self->dev, self->dev->preview_pipe, self);
  if(!piece) return 0;
  float wp = piece->buf_out.width, hp = piece->buf_out.height;

  // if sinv=0 then this is just the offset
  if(sinv == 0)
  {
    if(v == 0)
    {
      pts[0] = wp * 0.1;
      pts[2] = wp * 0.9;
      pts[1] = pts[3] = hp * offset / 100.0;
    }
    else
    {
      pts[2] = wp * 0.1;
      pts[0] = wp * 0.9;
      pts[1] = pts[3] = hp * (1.0 - offset / 100.0);
    }
  }
  else
  {
    // otherwise we determine the extremities
    const float cosv = cos(v);
    float xx1 = (sinv - cosv + 1.0 - offset / 50.0) * wp * 0.5 / sinv;
    float xx2 = (sinv + cosv + 1.0 - offset / 50.0) * wp * 0.5 / sinv;
    float yy1 = 0;
    float yy2 = hp;
    float a = hp / (xx2 - xx1);
    float b = -xx1 * a;
    // now ensure that the line isn't outside image borders
    if(xx2 > wp)
    {
      yy2 = a * wp + b;
      xx2 = wp;
    }
    if(xx2 < 0)
    {
      yy2 = b;
      xx2 = 0;
    }
    if(xx1 > wp)
    {
      yy1 = a * wp + b;
      xx1 = wp;
    }
    if(xx1 < 0)
    {
      yy1 = b;
      xx1 = 0;
    }

    // we want extremities not to be on image border
    xx2 -= (xx2 - xx1) * 0.1;
    xx1 += (xx2 - xx1) * 0.1;
    yy2 -= (yy2 - yy1) * 0.1;
    yy1 += (yy2 - yy1) * 0.1;

    // now we have to decide which point is where, depending of the angle
    /*xx1 /= wd;
    xx2 /= wd;
    yy1 /= ht;
    yy2 /= ht;*/
    if(v < M_PI * 0.5 && v > -M_PI * 0.5)
    {
      // we want xa < xb
      if(xx1 < xx2)
      {
        pts[0] = xx1;
        pts[1] = yy1;
        pts[2] = xx2;
        pts[3] = yy2;
      }
      else
      {
        pts[2] = xx1;
        pts[3] = yy1;
        pts[0] = xx2;
        pts[1] = yy2;
      }
    }
    else
    {
      // we want xb < xa
      if(xx2 < xx1)
      {
        pts[0] = xx1;
        pts[1] = yy1;
        pts[2] = xx2;
        pts[3] = yy2;
      }
      else
      {
        pts[2] = xx1;
        pts[3] = yy1;
        pts[0] = xx2;
        pts[1] = yy2;
      }
    }
  }
  // now we want that points to take care of distort modules

  if(!dt_dev_distort_transform_plus(self->dev, self->dev->preview_pipe, self->priority + 1, 999999, pts, 2))
    return 0;
  *xa = pts[0] / self->dev->preview_pipe->backbuf_width;
  *ya = pts[1] / self->dev->preview_pipe->backbuf_height;
  *xb = pts[2] / self->dev->preview_pipe->backbuf_width;
  *yb = pts[3] / self->dev->preview_pipe->backbuf_height;
  return 1;
}
コード例 #5
0
ファイル: ellipse.c プロジェクト: CarVac/darktable
static int dt_ellipse_get_area(dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form,
                               int *width, int *height, int *posx, int *posy)
{
  // we get the ellipse values
  dt_masks_point_ellipse_t *ellipse = (dt_masks_point_ellipse_t *)(g_list_first(form->points)->data);

  const float wd = piece->pipe->iwidth, ht = piece->pipe->iheight;

  const float total[2] = { (ellipse->flags & DT_MASKS_ELLIPSE_PROPORTIONAL ? ellipse->radius[0] * (1.0f + ellipse->border) : ellipse->radius[0] + ellipse->border) * MIN(wd, ht),
                           (ellipse->flags & DT_MASKS_ELLIPSE_PROPORTIONAL ? ellipse->radius[1] * (1.0f + ellipse->border) : ellipse->radius[1] + ellipse->border) * MIN(wd, ht) };
  const float v1 = ((ellipse->rotation) / 180.0f) * M_PI;
  const float v2 = ((ellipse->rotation - 90.0f) / 180.0f) * M_PI;
  float a, b, v;

  if(total[0] >= total[1])
  {
    a = total[0];
    b = total[1];
    v = v1;
  }
  else
  {
    a = total[1];
    b = total[0];
    v = v2;
  }

  const float sinv = sinf(v);
  const float cosv = cosf(v);

  // how many points do we need ?
  const float lambda = (a - b) / (a + b);
  const int l = (int)(M_PI * (a + b)
                      * (1.0f + (3.0f * lambda * lambda) / (10.0f + sqrtf(4.0f - 3.0f * lambda * lambda))));

  // buffer allocations
  float *points = calloc(2 * (l + 5), sizeof(float));

  // now we set the points
  const float x = points[0] = ellipse->center[0] * wd;
  const float y = points[1] = ellipse->center[1] * ht;

  points[2] = x + a * cos(v);
  points[3] = y + a * sin(v);
  points[4] = x - a * cos(v);
  points[5] = y - a * sin(v);

  points[6] = x + b * cos(v - M_PI / 2.0f);
  points[7] = y + b * sin(v - M_PI / 2.0f);
  points[8] = x - b * cos(v - M_PI / 2.0f);
  points[9] = y - b * sin(v - M_PI / 2.0f);

  for(int i = 5; i < l + 5; i++)
  {
    float alpha = (i - 5) * 2.0 * M_PI / (float)l;
    points[i * 2] = x + a * cosf(alpha) * cosv - b * sinf(alpha) * sinv;
    points[i * 2 + 1] = y + a * cosf(alpha) * sinv + b * sinf(alpha) * cosv;
  }

  // and we transform them with all distorted modules
  if(!dt_dev_distort_transform_plus(module->dev, piece->pipe, 0, module->priority, points, l + 5))
  {
    free(points);
    return 0;
  }

  // now we search min and max
  float xmin, xmax, ymin, ymax;
  xmin = ymin = FLT_MAX;
  xmax = ymax = FLT_MIN;
  for(int i = 5; i < l + 5; i++)
  {
    xmin = fminf(points[i * 2], xmin);
    xmax = fmaxf(points[i * 2], xmax);
    ymin = fminf(points[i * 2 + 1], ymin);
    ymax = fmaxf(points[i * 2 + 1], ymax);
  }
  free(points);

  // and we set values
  *posx = xmin;
  *posy = ymin;
  *width = (xmax - xmin);
  *height = (ymax - ymin);
  return 1;
}