Exemplo n.º 1
0
void process(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid,
             const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
{
  const int ch = piece->colors;
  const int ch_width = ch * roi_in->width;
  const struct dt_interpolation *interpolation = dt_interpolation_new(DT_INTERPOLATION_USERPREF);
  const dt_iop_scalepixels_data_t * const d = piece->data;

#ifdef _OPENMP
#pragma omp parallel for schedule(static) default(none) shared(interpolation)
#endif
  // (slow) point-by-point transformation.
  // TODO: optimize with scanlines and linear steps between?
  for(int j = 0; j < roi_out->height; j++)
  {
    float *out = ((float *)ovoid) + (size_t)4 * j * roi_out->width;
    for(int i = 0; i < roi_out->width; i++, out += 4)
    {
      float x = i*d->x_scale;
      float y = j*d->y_scale;

      dt_interpolation_compute_pixel4c(interpolation, (float *)ivoid, out, x, y, roi_in->width,
                                       roi_in->height, ch_width);
    }
  }
}
Exemplo n.º 2
0
// 2nd pass: which roi would this operation need as input to fill the given output region?
void modify_roi_in(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out,
                   dt_iop_roi_t *roi_in)
{
  *roi_in = *roi_out;

  const float scale = roi_in->scale / piece->iscale;

  float aabb[4] = { roi_out->x, roi_out->y, roi_out->x + roi_out->width, roi_out->y + roi_out->height };

  float aabb_in[4] = { INFINITY, INFINITY, -INFINITY, -INFINITY };

  for(int c = 0; c < 4; c++)
  {
    float p[2], o[2];

    // get corner points of roi_out
    get_corner(aabb, c, p);

    backtransform(piece, scale, p, o);

    // transform to roi_in space, get aabb.
    adjust_aabb(o, aabb_in);
  }

  const struct dt_interpolation *interpolation = dt_interpolation_new(DT_INTERPOLATION_USERPREF);
  const float IW = interpolation->width * scale;

  // adjust roi_in to minimally needed region
  roi_in->x = aabb_in[0] - IW;
  roi_in->y = aabb_in[1] - IW;
  roi_in->width = aabb_in[2] - roi_in->x + IW;
  roi_in->height = aabb_in[3] - roi_in->y + IW;
}
Exemplo n.º 3
0
// 2nd pass: which roi would this operation need as input to fill the given output region?
void modify_roi_in(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out,
                   dt_iop_roi_t *roi_in)
{
  *roi_in = *roi_out;

  const float scale = roi_in->scale / piece->iscale;

  float aabb[4] = { roi_out->x, roi_out->y, roi_out->x + roi_out->width, roi_out->y + roi_out->height };

  float aabb_in[4] = { INFINITY, INFINITY, -INFINITY, -INFINITY };

  for(int c = 0; c < 4; c++)
  {
    float p[2], o[2];

    // get corner points of roi_out
    get_corner(aabb, c, p);

    backtransform(piece, scale, p, o);

    // transform to roi_in space, get aabb.
    adjust_aabb(o, aabb_in);
  }

  const struct dt_interpolation *interpolation = dt_interpolation_new(DT_INTERPOLATION_USERPREF);
  const float IW = (float)interpolation->width * scale;

  const float orig_w = roi_in->scale * piece->buf_in.width, orig_h = roi_in->scale * piece->buf_in.height;

  // adjust roi_in to minimally needed region
  roi_in->x = fmaxf(0.0f, aabb_in[0] - IW);
  roi_in->y = fmaxf(0.0f, aabb_in[1] - IW);
  roi_in->width = fminf(orig_w - roi_in->x, aabb_in[2] - roi_in->x + IW);
  roi_in->height = fminf(orig_h - roi_in->y, aabb_in[3] - roi_in->y + IW);

  // sanity check.
  roi_in->x = CLAMP(roi_in->x, 0, (int)floorf(orig_w));
  roi_in->y = CLAMP(roi_in->y, 0, (int)floorf(orig_h));
  roi_in->width = CLAMP(roi_in->width, 1, (int)ceilf(orig_w) - roi_in->x);
  roi_in->height = CLAMP(roi_in->height, 1, (int)ceilf(orig_h) - roi_in->y);
}
Exemplo n.º 4
0
// 1st pass: how large would the output be, given this input roi?
// this is always called with the full buffer before processing.
void modify_roi_out(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, dt_iop_roi_t *roi_out,
                    const dt_iop_roi_t *const roi_in)
{
  dt_iop_rotatepixels_data_t *d = (dt_iop_rotatepixels_data_t *)piece->data;

  *roi_out = *roi_in;

  /*
   * Think of input image as:
   * 1. Square, containing:
   * 3. 4x Right triangles (two pairs), located in the Edges of square
   * 2. Rectangle (rotated 45 degrees), located in between triangles.
   *
   * Therefore, output image dimensions, that are sizes of inner Rectangle
   * can be found using Pythagorean theorem.
   *
   * Not precise pseudographics: (width == height + 1)
   *         height
   *     _  -------
   *     |  |1 /\2|
   * ty  |  | y  \|
   *     _  |/   /| width
   *        |\x / |
   *        |2\/ 1|
   *        -------
   */

  const float scale = roi_in->scale / piece->iscale, T = (float)d->ry * scale;

  const float y = sqrtf(2.0f * T * T),
              x = sqrtf(2.0f * ((float)roi_in->width - T) * ((float)roi_in->width - T));

  const struct dt_interpolation *interpolation = dt_interpolation_new(DT_INTERPOLATION_USERPREF);
  const float IW = (float)interpolation->width * scale;

  roi_out->width = y - IW;
  roi_out->height = x - IW;

  roi_out->width = MAX(0, roi_out->width & ~1);
  roi_out->height = MAX(0, roi_out->height & ~1);
}
Exemplo n.º 5
0
// 3rd (final) pass: you get this input region (may be different from what was requested above),
// do your best to fill the output region!
void process(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid,
             const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
{
  const int ch = piece->colors;
  const int ch_width = ch * roi_in->width;

  const float scale = roi_in->scale / piece->iscale;

  assert(ch == 4);

  const struct dt_interpolation *interpolation = dt_interpolation_new(DT_INTERPOLATION_USERPREF);

#ifdef _OPENMP
#pragma omp parallel for schedule(static) default(none) shared(piece, interpolation)
#endif
  // (slow) point-by-point transformation.
  // TODO: optimize with scanlines and linear steps between?
  for(int j = 0; j < roi_out->height; j++)
  {
    float *out = ((float *)ovoid) + (size_t)ch * j * roi_out->width;
    for(int i = 0; i < roi_out->width; i++, out += ch)
    {
      float pi[2], po[2];

      pi[0] = roi_out->x + i;
      pi[1] = roi_out->y + j;

      backtransform(piece, scale, pi, po);

      po[0] -= roi_in->x;
      po[1] -= roi_in->y;

      dt_interpolation_compute_pixel4c(interpolation, (float *)ivoid, out, po[0], po[1], roi_in->width,
                                       roi_in->height, ch_width);
    }
  }
}