コード例 #1
0
ファイル: linear-gradient.c プロジェクト: dankamongmen/gegl
static gboolean
process (GeglOperation       *operation,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  gfloat     *out_pixel = out_buf;
  gfloat      color1[4];
  gfloat      color2[4];
  gint        x, y;
  gfloat      dx, dy;

  gfloat length = dist (o->x1, o->y1, o->x2, o->y2);

  gegl_color_get_pixel (o->color1, babl_format ("RGBA float"), color1);
  gegl_color_get_pixel (o->color2, babl_format ("RGBA float"), color2);


  x= roi->x;
  y= roi->y;

  dx = (o->x2-o->x1)/length;
  dy = (o->y2-o->y1)/length;

  while (n_pixels--)
    {
      gfloat v;
      gint c;

      if (length == 0.0)
        v = 0.5;
      else
        {
          v = (dx * x + dy * y) / length;

          if (v < 0.0)
            v = 0.0;
          else if (v>1.0)
            v = 1.0;
        }

      for (c=0;c<4;c++)
        out_pixel[c]=color1[c] * v + color2[c] * (1.0-v);

      out_pixel += 4;

      /* update x and y coordinates */
      if (++x>=roi->x + roi->width)
        {
          x=roi->x;
          y++;
      }
    }

  return  TRUE;
}
コード例 #2
0
static gboolean
process (GeglOperation       *operation,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  gfloat         *out_pixel = out_buf;
  gfloat          color1[4], color2[4], length, dx, dy;

  dx = o->end_x - o->start_x;
  dy = o->end_y - o->start_y;

  length = dx * dx + dy * dy;

  if (GEGL_FLOAT_IS_ZERO (length))
    {
      memset (out_buf, 0, n_pixels * sizeof(float) * 4);
    }
  else
    {
      gfloat vec0 = dx / length;
      gfloat vec1 = dy / length;
      gint x, y;

      gegl_color_get_pixel (o->start_color, babl_format ("R'G'B'A float"), color1);
      gegl_color_get_pixel (o->end_color, babl_format ("R'G'B'A float"), color2);

      for (y = roi->y; y < roi->y + roi->height; ++y)
        {
          for (x = roi->x; x < roi->x + roi->width; ++x)
            {
              gint c;
              gfloat v = vec0 * (x - o->start_x) + vec1 * (y - o->start_y);

              if (v > 1.0f - GEGL_FLOAT_EPSILON)
                v = 1.0f;
              if (v < 0.0f + GEGL_FLOAT_EPSILON)
                v = 0.0f;

              for (c = 0; c < 4; c++)
                out_pixel[c] = color1[c] * v + color2[c] * (1.0f - v);

              out_pixel += 4;
            }
        }
    }

  return  TRUE;
}
コード例 #3
0
ファイル: checkerboard.c プロジェクト: Distrotech/gegl
static gboolean
checkerboard_cl_process (GeglOperation       *operation,
                         cl_mem               out_tex,
                         size_t               global_worksize,
                         const GeglRectangle *roi,
                         gint                 level)
{
  GeglProperties *o         = GEGL_PROPERTIES (operation);
  const Babl   *out_format  = gegl_operation_get_format (operation, "output");
  const size_t  gbl_size[2] = {roi->width, roi->height};
  const size_t  gbl_offs[2] = {roi->x, roi->y};
  cl_int        cl_err      = 0;
  float         color1[4];
  float         color2[4];

  if (!cl_data)
  {
    const char *kernel_name[] = {"kernel_checkerboard", NULL};
    cl_data = gegl_cl_compile_and_build (checkerboard_cl_source, kernel_name);

    if (!cl_data)
      return TRUE;
  }

  gegl_color_get_pixel (o->color1, out_format, color1);
  gegl_color_get_pixel (o->color2, out_format, color2);

  cl_err = gegl_cl_set_kernel_args (cl_data->kernel[0],
                                    sizeof(cl_mem), &out_tex,
                                    sizeof(color1), &color1,
                                    sizeof(color2), &color2,
                                    sizeof(cl_int), &o->x,
                                    sizeof(cl_int), &o->y,
                                    sizeof(cl_int), &o->x_offset,
                                    sizeof(cl_int), &o->y_offset,
                                    NULL);
  CL_CHECK;

  cl_err = gegl_clEnqueueNDRangeKernel (gegl_cl_get_command_queue (),
                                        cl_data->kernel[0], 2,
                                        gbl_offs, gbl_size, NULL,
                                        0, NULL, NULL);
  CL_CHECK;

  return FALSE;
error:
  return TRUE;
}
コード例 #4
0
ファイル: color-to-alpha.c プロジェクト: Distrotech/gegl
static gboolean
process (GeglOperation       *operation,
         void                *in_buf,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties *o      = GEGL_PROPERTIES (operation);
  const Babl *format = babl_format ("R'G'B'A float");
  gfloat      color[4];
  gint        x;

  gfloat *in_buff = in_buf;
  gfloat *out_buff = out_buf;

  gegl_color_get_pixel (o->color, format, color);

  for (x = 0; x < n_pixels; x++)
    {
      color_to_alpha (color, in_buff, out_buff);
      in_buff  += 4;
      out_buff += 4;
    }

  return TRUE;
}
コード例 #5
0
ファイル: apply-lens.c プロジェクト: OpenCL/GEGL-OpenCL
static void
prepare (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  const Babl *format = babl_format ("RGBA float");

  GeglRectangle  *whole_region;
  AlParamsType   *params;

  if (! o->user_data)
    o->user_data = g_slice_new0 (AlParamsType);

  params = (AlParamsType *) o->user_data;

  whole_region = gegl_operation_source_get_bounding_box (operation, "input");

  if (whole_region)
    {
      params->a = 0.5 * whole_region->width;
      params->b = 0.5 * whole_region->height;
      params->c = MIN (params->a, params->b);
      params->asqr = params->a * params->a;
      params->bsqr = params->b * params->b;
      params->csqr = params->c * params->c;
    }

  gegl_color_get_pixel (o->background_color, format, params->bg_color);

  gegl_operation_set_format (operation, "input", format);
  gegl_operation_set_format (operation, "output", format);
}
コード例 #6
0
static gboolean
process (GeglOperation       *operation,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties *o         = GEGL_PROPERTIES (operation);
  gfloat         *out_pixel = out_buf;
  gfloat         color1[4];
  gfloat         color2[4];
  gfloat         length = dist (o->start_x, o->start_y, o->end_x, o->end_y);

  gegl_color_get_pixel (o->start_color, babl_format ("R'G'B'A float"), color1);
  gegl_color_get_pixel (o->end_color, babl_format ("R'G'B'A float"), color2);

  if (GEGL_FLOAT_IS_ZERO (length))
    {
      gegl_memset_pattern (out_buf, color2, sizeof(float) * 4, n_pixels);
    }
  else
    {
      gint x, y;
      for (y = roi->y; y < roi->y + roi->height; ++y)
        {
          for (x = roi->x; x < roi->x + roi->width; ++x)
            {
              gint c;
              gfloat v = dist (x, y, o->start_x, o->start_y) / length;

              if (v > 1.0f - GEGL_FLOAT_EPSILON)
                v = 1.0f;

              for (c = 0; c < 4; c++)
                out_pixel[c] = color1[c] * v + color2[c] * (1.0f - v);

              out_pixel += 4;
            }
        }
    }

  return  TRUE;
}
コード例 #7
0
ファイル: color-exchange.c プロジェクト: GNOME/gegl
static void
prepare (GeglOperation *operation)
{
  GeglProperties *o      = GEGL_PROPERTIES (operation);
  const Babl     *format = babl_format ("R'G'B'A float");
  const Babl     *colorformat = babl_format ("R'G'B' float");
  CeParamsType *params;
  gfloat        color_in[3];
  gfloat        color_out[3];
  gint          chan;

  if (o->user_data == NULL)
    o->user_data = g_slice_new0 (CeParamsType);

  params = (CeParamsType*) o->user_data;

  gegl_color_get_pixel (o->from_color, colorformat, &color_in);
  gegl_color_get_pixel (o->to_color, colorformat, &color_out);

  params->min[0] = CLAMP (color_in[0] - o->red_threshold,
                          0.0, 1.0) - GEGL_FLOAT_EPSILON;

  params->max[0] = CLAMP (color_in[0] + o->red_threshold,
                          0.0, 1.0) + GEGL_FLOAT_EPSILON;

  params->min[1] = CLAMP (color_in[1] - o->green_threshold,
                          0.0, 1.0) - GEGL_FLOAT_EPSILON;

  params->max[1] = CLAMP (color_in[1] + o->green_threshold,
                          0.0, 1.0) + GEGL_FLOAT_EPSILON;

  params->min[2] = CLAMP (color_in[2] - o->blue_threshold,
                          0.0, 1.0) - GEGL_FLOAT_EPSILON;

  params->max[2] = CLAMP (color_in[2] + o->blue_threshold,
                          0.0, 1.0) + GEGL_FLOAT_EPSILON;

  for (chan = 0; chan < 3; chan++)
    params->color_diff[chan] = color_out[chan] - color_in[chan];

  gegl_operation_set_format (operation, "input", format);
  gegl_operation_set_format (operation, "output", format);
}
コード例 #8
0
ファイル: color-to-alpha.c プロジェクト: Distrotech/gegl
static gboolean
cl_process (GeglOperation       *operation,
            cl_mem              in,
            cl_mem              out,
            size_t              global_worksize,
            const GeglRectangle *roi,
            gint                level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  gfloat      color[4];
  gegl_color_get_pixel (o->color, babl_format ("R'G'B'A float"), color);

  if (!cl_data)
    {
      const char *kernel_name[] = {"cl_color_to_alpha",NULL};
      cl_data = gegl_cl_compile_and_build (color_to_alpha_cl_source, kernel_name);
    }
  if (!cl_data)
    return TRUE;
  else
  {
    cl_int cl_err = 0;
    cl_float4 f_color;
    f_color.s[0] = color[0];
    f_color.s[1] = color[1];
    f_color.s[2] = color[2];
    f_color.s[3] = color[3];

    cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 0,  sizeof(cl_mem),   (void*)&in);
    CL_CHECK;
    cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 1,  sizeof(cl_mem),   (void*)&out);
    CL_CHECK;
    cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 2,  sizeof(cl_float4),(void*)&f_color);
    CL_CHECK;

    cl_err = gegl_clEnqueueNDRangeKernel(gegl_cl_get_command_queue (),
                                         cl_data->kernel[0], 1,
                                         NULL, &global_worksize, NULL,
                                         0, NULL, NULL);
    CL_CHECK;
  }

  return  FALSE;

 error:
  return TRUE;
}
コード例 #9
0
ファイル: apply-lens.c プロジェクト: don-mccomb/gegl
/**
 * Process the gegl filter
 * @param operation the given Gegl operation
 * @param input the input buffer.
 * @param output the output buffer.
 * @param result the region of interest.
 * @param level the level of detail
 * @return True, if the filter was successfull applied.
 */
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties         *o = GEGL_PROPERTIES (operation);
  const Babl  *input_format = gegl_buffer_get_format (input);
  const int bytes_per_pixel = babl_format_get_bytes_per_pixel (input_format);

  /**
   * src_buf, dst_buf:
   * Input- and output-buffers, containing the whole selection,
   * the filter should be applied on.
   *
   * src_pixel, dst_pixel:
   * pointers to the current source- and destination-pixel.
   * Using these pointers, the reading and writing can be delayed till the
   * end of the loop. Hence src_pixel can also point to background_color if
   * necessary.
   */
  guint8    *src_buf, *dst_buf, *src_pixel, *dst_pixel, background_color[bytes_per_pixel];

  /**
   * (x, y): Position of the pixel we compute at the moment.
   * (width, height): Dimensions of the lens
   * pixel_offset: For calculating the pixels position in src_buf / dst_buf.
   */
  gint         x, y,
               width, height,
               pixel_offset, projected_pixel_offset;

  /**
   * Further parameters that are needed to calculate the position of a projected
   * further pixel at (x, y).
   */
  gfloat       a, b, c,
               asqr, bsqr, csqr,
               dx, dy, dysqr,
               projected_x, projected_y,
               refraction_index;

  gboolean     keep_surroundings;

  width = result->width;
  height = result->height;

  refraction_index = o->refraction_index;
  keep_surroundings = o->keep_surroundings;
  gegl_color_get_pixel (o->background_color, input_format, background_color);

  a = 0.5 * width;
  b = 0.5 * height;
  c = MIN (a, b);
  asqr = a * a;
  bsqr = b * b;
  csqr = c * c;

  /**
   * Todo: We might want to change the buffers sizes, as the memory consumption
   * could be rather large.However, due to the lens, it might happen, that one pixel from the
   * images center gets stretched to the whole image, so we will still need
   * at least a src_buf of size (width/2) * (height/2) * 4 to be able to
   * process one quarter of the image.
   */
  src_buf = gegl_malloc (width * height * bytes_per_pixel);
  dst_buf = gegl_malloc (width * height * bytes_per_pixel);

  gegl_buffer_get (input, result, 1.0, input_format, src_buf,
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  for (y = 0; y < height; y++)
    {
      /* dy is the current pixels distance (in y-direction) of the lenses center */
      dy = -((gfloat)y - b + 0.5);

      /**
       * To determine, whether the pixel is within the elliptical region affected
       * by the lens, we furthermore need the squared distance. So we calculate it
       * once for each row.
       */
      dysqr = dy * dy;
      for (x = 0; x < width; x++)
        {
          /* Again we need to calculate the pixels distance from the lens dx. */
          dx = (gfloat)x - a + 0.5;

          /* Given x and y we can now determine the pixels offset in our buffer. */
          pixel_offset = (x + y * width) * bytes_per_pixel;

          /* As described above, we only read and write image data once. */
          dst_pixel = &dst_buf[pixel_offset];

          if (dysqr < (bsqr - (bsqr * dx * dx) / asqr))
            {
              /**
               * If (x, y) is inside the affected region, we can find its projected
               * position, calculate the projected_pixel_offset and set the src_pixel
               * to where we want to copy the pixel-data from.
               */
              find_projected_pos (asqr, bsqr, csqr, dx, dy, refraction_index,
                                  &projected_x, &projected_y);

              projected_pixel_offset = ( (gint)(-projected_y + b) * width +
                                         (gint)( projected_x + a) ) * bytes_per_pixel;

              src_pixel = &src_buf[projected_pixel_offset];
            }
          else
            {
              /**
               * Otherwise (that is for pixels outside the lens), we could either leave
               * the image data unchanged, or set it to a specified 'background_color',
               * depending on the user input.
               */
              if (keep_surroundings)
                src_pixel = &src_buf[pixel_offset];
              else
                src_pixel = background_color;
            }

          /**
           * At the end, we can copy the src_pixel (which was determined above), to
           * dst_pixel.
           */
          memcpy (dst_pixel, src_pixel, bytes_per_pixel);
        }
  }

  gegl_buffer_set (output, result, 0, gegl_buffer_get_format (output), dst_buf,
                   GEGL_AUTO_ROWSTRIDE);

  gegl_free (dst_buf);
  gegl_free (src_buf);

  return TRUE;
}
コード例 #10
0
ファイル: pixelize.c プロジェクト: Distrotech/gegl
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglRectangle            src_rect;
  GeglRectangle           *whole_region;
  GeglProperties          *o = GEGL_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area;

  op_area = GEGL_OPERATION_AREA_FILTER (operation);

  whole_region = gegl_operation_source_get_bounding_box (operation, "input");

  if (gegl_operation_use_opencl (operation))
    if (cl_process (operation, input, output, roi))
      return TRUE;

  if (o->size_x * o->size_y < SQR (ALLOC_THRESHOLD_SIZE))
    {
      gfloat  background_color[4];
      gfloat *input_buf  = g_new (gfloat,
                                  (CHUNK_SIZE + o->size_x * 2) *
                                  (CHUNK_SIZE + o->size_y * 2) * 4);
      gfloat *output_buf = g_new (gfloat, SQR (CHUNK_SIZE) * 4);
      gint    i, j;

      gegl_color_get_pixel (o->background, babl_format("RaGaBaA float"),
                            background_color);

      for (j = 0; (j-1) * CHUNK_SIZE < roi->height; j++)
        for (i = 0; (i-1) * CHUNK_SIZE < roi->width; i++)
          {
            GeglRectangle chunked_result;
            GeglRectangle chunked_sizes;

            chunked_result = *GEGL_RECTANGLE (roi->x + i * CHUNK_SIZE,
                                              roi->y + j * CHUNK_SIZE,
                                              CHUNK_SIZE, CHUNK_SIZE);

            gegl_rectangle_intersect (&chunked_result, &chunked_result, roi);

            if (chunked_result.width < 1  || chunked_result.height < 1)
              continue;

            src_rect = chunked_result;
            src_rect.x -= op_area->left;
            src_rect.y -= op_area->top;
            src_rect.width += op_area->left + op_area->right;
            src_rect.height += op_area->top + op_area->bottom;

            gegl_buffer_get (input, &src_rect, 1.0, babl_format ("RaGaBaA float"),
                             input_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);

            gegl_rectangle_copy (&chunked_sizes, &chunked_result);
            chunked_sizes.x = 0;
            chunked_sizes.y = 0;

            set_rectangle (output_buf, &chunked_sizes, &chunked_sizes,
                           chunked_result.width, background_color,
                           GEGL_PIXELIZE_NORM_INFINITY);

            pixelize (input_buf, output_buf, &chunked_result, &src_rect,
                      whole_region, o);

            gegl_buffer_set (output, &chunked_result, 0,
                             babl_format ("RaGaBaA float"),
                             output_buf, GEGL_AUTO_ROWSTRIDE);
          }

      g_free (input_buf);
      g_free (output_buf);
    }
  else
    {
      gegl_buffer_set_color (output, roi, o->background);
      pixelize_noalloc (input, output, roi, whole_region, o);
    }

  return  TRUE;
}
コード例 #11
0
ファイル: pixelize.c プロジェクト: Distrotech/gegl
static gboolean
cl_process (GeglOperation       *operation,
            GeglBuffer          *input,
            GeglBuffer          *output,
            const GeglRectangle *roi)
{
  const Babl *in_format  = babl_format ("RaGaBaA float");
  const Babl *out_format = babl_format ("RaGaBaA float");
  gint   err;
  gfloat bg_color[4];
  gint   norm;

  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglProperties *o = GEGL_PROPERTIES (operation);
  GeglRectangle *image_extent;

  GeglBufferClIterator *i = gegl_buffer_cl_iterator_new   (output,
                                                           roi,
                                                           out_format,
                                                           GEGL_CL_BUFFER_WRITE);

  gint read = gegl_buffer_cl_iterator_add_2 (i,
                                             input,
                                             roi,
                                             in_format,
                                             GEGL_CL_BUFFER_READ,
                                             op_area->left,
                                             op_area->right,
                                             op_area->top,
                                             op_area->bottom,
                                             GEGL_ABYSS_CLAMP);

  gint aux = gegl_buffer_cl_iterator_add_aux (i,
                                              roi,
                                              in_format,
                                              op_area->left,
                                              op_area->right,
                                              op_area->top,
                                              op_area->bottom);


  gegl_color_get_pixel (o->background, babl_format ("RaGaBaA float"), bg_color);

  norm = 0;
  norm = o->norm == GEGL_PIXELIZE_NORM_EUCLIDEAN ? 1 : norm;
  norm = o->norm == GEGL_PIXELIZE_NORM_INFINITY  ? 2 : norm;

  image_extent = gegl_operation_source_get_bounding_box (operation, "input");

  while (gegl_buffer_cl_iterator_next (i, &err) && !err)
    {
      err = cl_pixelize(i->tex[read],
                        i->tex[aux],
                        i->tex[0],
                        &i->roi[read],
                        &i->roi[0],
                        o->size_x,
                        o->size_y,
                        o->ratio_x,
                        o->ratio_y,
                        bg_color,
                        norm,
                        image_extent);

      if (err)
        {
          gegl_buffer_cl_iterator_stop (i);
          break;
        }
    }

  return !err;
}
コード例 #12
0
ファイル: pixelize.c プロジェクト: Distrotech/gegl
static void
set_rectangle_noalloc (GeglBuffer      *output,
                       GeglRectangle   *rect,
                       GeglRectangle   *rect_shape,
                       GeglColor       *color,
                       GeglPixelizeNorm norm)
{
  if (norm == GEGL_PIXELIZE_NORM_INFINITY)
    {
      GeglRectangle rect2;
      gegl_rectangle_intersect (&rect2, rect, rect_shape);
      gegl_buffer_set_color (output, &rect2, color);
    }
  else
    {
      GeglBufferIterator *gi;
      gint                c, x, y;
      gfloat              col[4];
      gfloat              center_x, center_y;
      gfloat              shape_area = rect_shape->width * rect_shape->height;

      center_x = rect_shape->x + rect_shape->width / 2.0f;
      center_y = rect_shape->y + rect_shape->height / 2.0f;

      gegl_color_get_pixel (color, babl_format ("RaGaBaA float"), col);

      gi = gegl_buffer_iterator_new (output, rect, 0, babl_format ("RaGaBaA float"),
                                     GEGL_ACCESS_WRITE, GEGL_ABYSS_CLAMP);

      while (gegl_buffer_iterator_next (gi))
        {
          gfloat       *data = (gfloat*) gi->data[0];
          GeglRectangle roi = gi->roi[0];

          switch (norm)
            {
            case (GEGL_PIXELIZE_NORM_EUCLIDEAN):

              for (y = 0; y < roi.height; y++)
                for (x = 0; x < roi.width; x++)
                  if (SQR ((x + roi.x - center_x) / (gfloat) rect_shape->width) +
                      SQR ((y + roi.y - center_y) / (gfloat) rect_shape->height) <= 1.0f)
                    for (c = 0; c < 4; c++)
                      data [4 * (y * roi.width + x) + c] = col[c];
              break;

            case (GEGL_PIXELIZE_NORM_MANHATTAN):

              for (y = 0; y < roi.height; y++)
                for (x = 0; x < roi.width; x++)
                  if (fabsf (x + roi.x - center_x) * rect_shape->height +
                      fabsf (y + roi.y - center_y) * rect_shape->width
                      < shape_area)
                    for (c = 0; c < 4; c++)
                      data [4 * (y * roi.width + x) + c] = col[c];
              break;

            case (GEGL_PIXELIZE_NORM_INFINITY):
              break;
            }
        }
    }
}
コード例 #13
0
ファイル: color-exchange.c プロジェクト: ChristianBusch/gegl
static gboolean
process (GeglOperation       *op,
         void                *in_buf,
         void                *out_buf,
         glong                samples,
         const GeglRectangle *roi,
         gint                 level)
{ 
  GeglChantO *o = GEGL_CHANT_PROPERTIES (op);

  guint8     * GEGL_ALIGNED in_pixel;
  guint8     * GEGL_ALIGNED out_pixel;

  guint8      colorFrom[4];
  guint8      colorTo[4];
  guint8      threshold[4];
  guint8      delta[4];

  in_pixel   = in_buf;
  out_pixel  = out_buf;

  gegl_color_get_pixel (o->start_color, babl_format ("RGBA u8"), colorFrom);
  gegl_color_get_pixel (o->end_color, babl_format ("RGBA u8"), colorTo);

  threshold[0] = o->red_threshold;
  threshold[1] = o->blue_threshold;
  threshold[2] = o->green_threshold;

  for (glong i = 0; i < samples; i++)
    {
      if (in_pixel[0] >= CLAMP (colorFrom[0] - threshold[0], 0, 255) &&
          in_pixel[0] <= CLAMP (colorFrom[0] + threshold[0], 0, 255) &&
          in_pixel[1] >= CLAMP (colorFrom[1] - threshold[1], 0, 255) &&
          in_pixel[1] <= CLAMP (colorFrom[1] + threshold[1], 0, 255) &&
          in_pixel[2] >= CLAMP (colorFrom[2] - threshold[2], 0, 255) &&
          in_pixel[2] <= CLAMP (colorFrom[2] + threshold[2], 0, 255))
        {
          delta[0] = in_pixel[0] > colorFrom[0] ?
            in_pixel[0] - colorFrom[0] : colorFrom[0] - in_pixel[0];
          delta[1] = in_pixel[1] > colorFrom[1] ?
            in_pixel[1] - colorFrom[1] : colorFrom[1] - in_pixel[1];
          delta[2] = in_pixel[2] > colorFrom[2] ?
            in_pixel[2] - colorFrom[2] : colorFrom[2] - in_pixel[2];

          out_pixel[0] = CLAMP (colorTo[0] + delta[0], 0, 255);
          out_pixel[1] = CLAMP (colorTo[1] + delta[1], 0, 255);
          out_pixel[2] = CLAMP (colorTo[2] + delta[2], 0, 255);
        }
      else
        {
          out_pixel[0] = in_pixel[0];
          out_pixel[1] = in_pixel[1];
          out_pixel[2] = in_pixel[2];
        }

      out_pixel[3] = in_pixel[3];

      in_pixel += 4;
      out_pixel += 4;
    }

  return TRUE;

}
コード例 #14
0
ファイル: checkerboard.c プロジェクト: Distrotech/gegl
static gboolean
checkerboard_process (GeglOperation       *operation,
                      void                *out_buf,
                      glong                n_pixels,
                      const GeglRectangle *roi,
                      gint                 level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  const Babl *out_format = gegl_operation_get_format (operation, "output");
  gint        pixel_size = babl_format_get_bytes_per_pixel (out_format);
  guchar     *out_pixel = out_buf;
  void       *color1 = alloca(pixel_size);
  void       *color2 = alloca(pixel_size);
  gint        y;
  const gint  x_min = roi->x - o->x_offset;
  const gint  y_min = roi->y - o->y_offset;
  const gint  x_max = roi->x + roi->width - o->x_offset;
  const gint  y_max = roi->y + roi->height - o->y_offset;

  const gint  square_width  = o->x;
  const gint  square_height = o->y;

  if (level)
    return checkerboard_process_simple (operation, out_buf, n_pixels, roi, level);

  gegl_color_get_pixel (o->color1, out_format, color1);
  gegl_color_get_pixel (o->color2, out_format, color2);

  for (y = y_min; y < y_max; y++)
    {
      gint  x = x_min;
      void *cur_color;

      /* Figure out which box we're in */
      gint tilex = TILE_INDEX (x, square_width);
      gint tiley = TILE_INDEX (y, square_height);
      if ((tilex + tiley) % 2 == 0)
        cur_color = color1;
      else
        cur_color = color2;

      while (x < x_max)
        {
          /* Figure out how long this stripe is */
          gint count;
          gint stripe_end = (TILE_INDEX (x, square_width) + 1) * square_width;
               stripe_end = stripe_end > x_max ? x_max : stripe_end;

          count = stripe_end - x;

          gegl_memset_pattern (out_pixel, cur_color, pixel_size, count);
          out_pixel += count * pixel_size;
          x = stripe_end;

          if (cur_color == color1)
            cur_color = color2;
          else
            cur_color = color1;
        }
    }

  return TRUE;
}
コード例 #15
0
ファイル: checkerboard.c プロジェクト: Distrotech/gegl
static gboolean
checkerboard_process_simple (GeglOperation       *operation,
                             void                *out_buf,
                             glong                n_pixels,
                             const GeglRectangle *roi,
                             gint                 level)
{
  gint        factor = 1 << level;
  GeglProperties *o = GEGL_PROPERTIES (operation);
  const Babl *out_format = gegl_operation_get_format (operation, "output");

  gint        pixel_size = babl_format_get_bytes_per_pixel (out_format);
  guchar     *out_pixel = out_buf;
  void       *color1 = alloca(pixel_size);
  void       *color2 = alloca(pixel_size);

  gint        x = roi->x; /* initial x                   */
  gint        y = roi->y; /*           and y coordinates */

  gegl_color_get_pixel (o->color1, out_format, color1);
  gegl_color_get_pixel (o->color2, out_format, color2);

  while (n_pixels--)
    {
      gint nx,ny;

      if ((x - o->x_offset) < 0)
        {
          nx = div (x - o->x_offset + 1, o->x / factor).quot;
        }
      else
        {
          nx = div (x - o->x_offset, o->x / factor).quot;
        }

      if ((y - o->y_offset) < 0)
        {
          ny = div (y - o->y_offset + 1, o->y / factor).quot;
        }
      else
        {
          ny = div (y - o->y_offset, o->y / factor).quot;
        }

      /* shift negative cell indices */
      nx -= (x - o->x_offset) < 0 ? 1 : 0;
      ny -= (y - o->y_offset) < 0 ? 1 : 0;

      if ( (nx+ny) % 2 == 0)
        memcpy (out_pixel, color1, pixel_size);
      else
        memcpy (out_pixel, color2, pixel_size);

      out_pixel += pixel_size;

      /* update x and y coordinates */
      x++;
      if (x>=roi->x + roi->width)
        {
          x=roi->x;
          y++;
        }
    }

  return  TRUE;
}
コード例 #16
0
gdouble *
gegl_color_get_components (GeglColor *color, GValue *value, gint *components_length)
{
  Babl *format;

  if (G_TYPE_POINTER == G_VALUE_TYPE(value))
    format = g_value_get_pointer (value);
  else
    {
      *components_length = 0;
      return NULL;
    }

  if (!color || !format)
    {
      *components_length = 0;
      return NULL;
    }
  else
    {
      gint        components = babl_format_get_n_components (format);
      gint        bpp        = babl_format_get_bytes_per_pixel (format);
      const Babl *comp_type  = babl_format_get_type (format, 0);

      gdouble *result = g_new (gdouble, components);
      *components_length = components;

      if (comp_type == babl_type ("u8"))
        {
          int i;
          guint8 *pixel_buf = alloca (bpp * components);

          gegl_color_get_pixel (color, format, pixel_buf);

          for (i = 0; i < components; ++i)
            result[i] = pixel_buf[i];
        }
      else if (comp_type == babl_type ("u16"))
        {
          int i;
          guint16 *pixel_buf = alloca (bpp * components);

          gegl_color_get_pixel (color, format, pixel_buf);

          for (i = 0; i < components; ++i)
            result[i] = pixel_buf[i];
        }
      else if (comp_type == babl_type ("u32"))
        {
          int i;
          guint32 *pixel_buf = alloca (bpp * components);

          gegl_color_get_pixel (color, format, pixel_buf);

          for (i = 0; i < components; ++i)
            result[i] = pixel_buf[i];
        }
      else if (comp_type == babl_type ("float"))
        {
          int i;
          float *pixel_buf = alloca (bpp * components);

          gegl_color_get_pixel (color, format, pixel_buf);

          for (i = 0; i < components; ++i)
            result[i] = pixel_buf[i];
        }
      else if (comp_type == babl_type ("double"))
        {
          gegl_color_get_pixel (color, format, result);
        }
      else
        {
          g_free (result);
          *components_length = 0;
        }

      return result;
    }
}
コード例 #17
0
ファイル: vignette.c プロジェクト: ChristianBusch/gegl
static gboolean
cl_process (GeglOperation       *operation,
            cl_mem               in_tex,
            cl_mem               out_tex,
            size_t               global_worksize,
            const GeglRectangle *roi,
            gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  gfloat      scale;
  gfloat      radius0, radius1;
  gint        roi_x, roi_y,x;
  gint        midx, midy;
  GeglRectangle *bounds = gegl_operation_source_get_bounding_box (operation, "input");

  gfloat length = hypot (bounds->width, bounds->height)/2;
  gfloat rdiff;
  gfloat cost, sint;
  gfloat      color[4];

  scale = bounds->width / (1.0 * bounds->height);
  scale = scale * (o->proportion) + 1.0 * (1.0-o->proportion);
  scale *= aspect_to_scale (o->squeeze);
  length = (bounds->width/2.0);

  if (scale > 1.0)
    length /= scale;

  gegl_color_get_pixel (o->color, babl_format ("RGBA float"), color);

  for (x=0; x<3; x++)   /* premultiply */
    color[x] *= color[3];

  radius0 = o->radius * (1.0-o->softness);
  radius1 = o->radius;
  rdiff = radius1-radius0;
  if (fabs (rdiff) < 0.0001)
    rdiff = 0.0001;

  midx = bounds->x + bounds->width * o->x;
  midy = bounds->y + bounds->height * o->y;

  roi_x = roi->x;
  roi_y = roi->y;

  /* constant for all pixels */
  cost = cos(-o->rotation * (G_PI*2/360.0));
  sint = sin(-o->rotation * (G_PI*2/360.0));

  if (!cl_data)
    {
      const char *kernel_name[] = {"vignette_cl",NULL};
      cl_data = gegl_cl_compile_and_build (vignette_cl_source, kernel_name);
    }
  if (!cl_data) return TRUE;

  {
  const size_t gbl_size[2] = {roi->width, roi->height};

  gint   shape = (gint) o->shape;
  gfloat gamma = o->gamma;

  cl_int cl_err = 0;
  cl_float4 f_color;
  f_color.s[0] = color[0];
  f_color.s[1] = color[1];
  f_color.s[2] = color[2];
  f_color.s[3] = color[3];

  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 0,  sizeof(cl_mem),   (void*)&in_tex);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 1,  sizeof(cl_mem),   (void*)&out_tex);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 2,  sizeof(cl_float4),(void*)&f_color);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 3,  sizeof(cl_float), (void*)&scale);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 4,  sizeof(cl_float), (void*)&cost);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 5,  sizeof(cl_float), (void*)&sint);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 6,  sizeof(cl_int),   (void*)&roi_x);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 7,  sizeof(cl_int),   (void*)&roi_y);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 8,  sizeof(cl_int),   (void*)&midx);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 9,  sizeof(cl_int),   (void*)&midy);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 10, sizeof(cl_int),   (void*)&shape);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 11, sizeof(cl_float), (void*)&gamma);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 12, sizeof(cl_float), (void*)&length);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 13, sizeof(cl_float), (void*)&radius0);
  CL_CHECK;
  cl_err = gegl_clSetKernelArg(cl_data->kernel[0], 14, sizeof(cl_float), (void*)&rdiff);
  CL_CHECK;

  cl_err = gegl_clEnqueueNDRangeKernel(gegl_cl_get_command_queue (),
                                       cl_data->kernel[0], 2,
                                       NULL, gbl_size, NULL,
                                       0, NULL, NULL);
  CL_CHECK;
  }

  return  FALSE;

error:
  return TRUE;
}
コード例 #18
0
ファイル: checkerboard.c プロジェクト: AjayRamanathan/gegl
static gboolean
process (GeglOperation       *operation,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  gfloat     *out_pixel = out_buf;
  gfloat      color1[4];
  gfloat      color2[4];
  gint        x = roi->x; /* initial x                   */
  gint        y = roi->y; /*           and y coordinates */

  gegl_color_get_pixel (o->color1, babl_format ("RGBA float"), color1);
  gegl_color_get_pixel (o->color2, babl_format ("RGBA float"), color2);

  while (n_pixels--)
    {
      gint nx,ny;

      if ((x - o->x_offset) < 0)
        {
          nx = div (x - o->x_offset + 1, o->x).quot;
        }
      else
        {
          nx = div (x - o->x_offset, o->x).quot;
        }

      if ((y - o->y_offset) < 0)
        {
          ny = div (y - o->y_offset + 1, o->y).quot;
        }
      else
        {
          ny = div (y - o->y_offset, o->y).quot;
        }

      /* shift negative cell indices */
      nx -= (x - o->x_offset) < 0 ? 1 : 0;
      ny -= (y - o->y_offset) < 0 ? 1 : 0;

      if ( (nx+ny) % 2 == 0)
        {
          out_pixel[0]=color1[0];
          out_pixel[1]=color1[1];
          out_pixel[2]=color1[2];
          out_pixel[3]=color1[3];
        }
      else
        {
          out_pixel[0]=color2[0];
          out_pixel[1]=color2[1];
          out_pixel[2]=color2[2];
          out_pixel[3]=color2[3];
        }

      out_pixel += 4;

      /* update x and y coordinates */
      x++;
      if (x>=roi->x + roi->width)
        {
          x=roi->x;
          y++;
        }
    }

  return  TRUE;
}
コード例 #19
0
ファイル: lens-distortion.c プロジェクト: ChristianBusch/gegl
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO    *o = GEGL_CHANT_PROPERTIES (operation);
  LensValues     lens;
  GeglRectangle  boundary;
  gint           i, j;
  gfloat        *src_buf, *dst_buf;
  gfloat         background[4];

  boundary = *gegl_operation_source_get_bounding_box (operation, "input");
  lens     =  lens_setup_calc (o, boundary);

  src_buf = g_new0 (gfloat, SQR (MAX_WH) * 4);
  dst_buf = g_new0 (gfloat, SQR (CHUNK_SIZE) * 4);

  gegl_color_get_pixel (o->background, babl_format ("RGBA float"), background);

  for (j = 0; (j-1) * CHUNK_SIZE < result->height; j++)
    for (i = 0; (i-1) * CHUNK_SIZE < result->width; i++)
      {
        GeglRectangle chunked_result;
        GeglRectangle area;
        gint          x, y;

        chunked_result = *GEGL_RECTANGLE (result->x + i * CHUNK_SIZE,
                                          result->y + j * CHUNK_SIZE,
                                          CHUNK_SIZE, CHUNK_SIZE);

        gegl_rectangle_intersect (&chunked_result, &chunked_result, result);

        if (chunked_result.width < 1  || chunked_result.height < 1)
          continue;

        area = get_required (&boundary, &chunked_result, operation);

        clamp_area (&area, lens.centre_x, lens.centre_y);

        gegl_buffer_get (input, &area, 1.0, babl_format ("RGBA float"), src_buf,
                         GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);

        for (y = chunked_result.y; y < chunked_result.y + chunked_result.height; y++)
          for (x = chunked_result.x; x < chunked_result.x + chunked_result.width; x++)
            {
              lens_distort_func (src_buf, dst_buf, &area, &chunked_result, &boundary,
                                 &lens, x, y, input, background);
            }

        gegl_buffer_set (output, &chunked_result, 0, babl_format ("RGBA float"),
                         dst_buf, GEGL_AUTO_ROWSTRIDE);
      }

  g_free (dst_buf);
  g_free (src_buf);

  return TRUE;
}
コード例 #20
0
ファイル: cubism.c プロジェクト: ChristianBusch/gegl
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO              *o         = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area   = GEGL_OPERATION_AREA_FILTER (operation);
  GeglRectangle            boundary  = get_effective_area (operation);
  GeglRectangle            extended;
  const Babl              *format    = babl_format ("RGBA float");

  GRand  *gr = g_rand_new_with_seed (o->seed);
  gfloat  color[4];
  gint    cols, rows, num_tiles, count;
  gint   *random_indices;
  gfloat *dst_buf;
  gfloat *buf;

  Polygon poly;
  gint    i;

  extended.x      = CLAMP (result->x - op_area->left, boundary.x, boundary.x +
                           boundary.width);
  extended.width  = CLAMP (result->width + op_area->left + op_area->right, 0,
                           boundary.width);
  extended.y      = CLAMP (result->y - op_area->top, boundary.y, boundary.y +
                           boundary.width);
  extended.height = CLAMP (result->height + op_area->top + op_area->bottom, 0,
                           boundary.height);

  dst_buf = g_new0 (gfloat, extended.width * extended.height * 4);

  gegl_color_get_pixel (o->bg_color, format, color);

  i   = extended.width * extended.height;
  buf = dst_buf;

  while (i--)
    {
      buf[0] = color[0];
      buf[1] = color[1];
      buf[2] = color[2];
      buf[3] = color[3];

      buf += 4;
    }

  cols = (result->width + o->tile_size - 1) / o->tile_size;
  rows = (result->height + o->tile_size - 1) / o->tile_size;

  num_tiles = (rows + 1) * (cols + 1);

  random_indices = g_new0 (gint, num_tiles);

  for (i = 0; i < num_tiles; i++)
    random_indices[i] = i;

  randomize_indices (num_tiles, random_indices, gr);

  for (count = 0; count < num_tiles; count++)
    {
      gint i, j, ix, iy;
      gdouble x, y, width, height, theta;

      i = random_indices[count] / (cols + 1);
      j = random_indices[count] % (cols + 1);

      x = j * o->tile_size + (o->tile_size / 4.0)
        - g_rand_double_range (gr, 0, (o->tile_size /2.0)) + result->x;

      y = i * o->tile_size + (o->tile_size / 4.0)
        - g_rand_double_range (gr, 0, (o->tile_size /2.0)) + result->y;

      width  = (o->tile_size +
                g_rand_double_range (gr, -o->tile_size / 8.0, o->tile_size / 8.0))
        * o->tile_saturation;

      height = (o->tile_size +
                g_rand_double_range (gr, -o->tile_size / 8.0, o->tile_size / 8.0))
        * o->tile_saturation;

      theta = g_rand_double_range (gr, 0, 2 * G_PI);

      polygon_reset (&poly);
      polygon_add_point (&poly, -width / 2.0, -height / 2.0);
      polygon_add_point (&poly,  width / 2.0,  -height / 2.0);
      polygon_add_point (&poly,  width / 2.0,   height / 2.0);
      polygon_add_point (&poly, -width / 2.0,  height / 2.0);
      polygon_rotate (&poly, theta);
      polygon_translate (&poly, x, y);

      ix = CLAMP (x, boundary.x, boundary.x + boundary.width - 1);
      iy = CLAMP (y, boundary.y, boundary.y + boundary.height - 1);

      gegl_buffer_sample (input, ix, iy, NULL, color, format,
                          GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);

      fill_poly_color (&poly, &extended, &boundary, dst_buf, color);
    }

  gegl_buffer_set (output, &extended, 0, format, dst_buf, GEGL_AUTO_ROWSTRIDE);

  g_free (dst_buf);
  g_free (random_indices);
  g_free (gr);

  return TRUE;
}
コード例 #21
0
ファイル: vignette.c プロジェクト: ChristianBusch/gegl
static gboolean
process (GeglOperation       *operation,
         void                *in_buf,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  gfloat     *in_pixel =  in_buf;
  gfloat     *out_pixel = out_buf;
  gfloat      scale;
  gfloat      radius0, radius1;
  gint        x, y;
  gint        midx, midy;
  GeglRectangle *bounds = gegl_operation_source_get_bounding_box (operation, "input");
  gfloat length = hypot (bounds->width, bounds->height)/2;
  gfloat rdiff;
  gfloat cost, sint;
  gfloat costy, sinty;

  gfloat      color[4];

  scale = bounds->width / (1.0 * bounds->height);
  scale = scale * (o->proportion) + 1.0 * (1.0-o->proportion);

  scale *= aspect_to_scale (o->squeeze);

  length = (bounds->width/2.0);

  if (scale > 1.0)
    length /= scale;

  gegl_color_get_pixel (o->color, babl_format ("RGBA float"), color);

  for (x=0; x<3; x++)   /* premultiply */
    color[x] *= color[3];

  radius0 = o->radius * (1.0-o->softness);
  radius1 = o->radius;
  rdiff = radius1-radius0;
  if (fabs (rdiff) < 0.0001)
    rdiff = 0.0001;

  midx = bounds->x + bounds->width * o->x;
  midy = bounds->y + bounds->height * o->y;

  x = roi->x;
  y = roi->y;

  /* constant for all pixels */
  cost = cos(-o->rotation * (G_PI*2/360.0));
  sint = sin(-o->rotation * (G_PI*2/360.0));

  /* constant per scanline */
  sinty = sint * (y-midy) - midx;
  costy = cost * (y-midy) + midy;

  while (n_pixels--)
    {
      gfloat strength = 0.0;
      gfloat u, v;
#if 0
      u = cost * (x-midx) - sint * (y-midy) + midx;
      v = sint * (x-midx) + cost * (y-midy) + midy;
      /* optimized out of innerscanline loop */
#endif
      u = cost * (x-midx) - sinty;
      v = sint * (x-midx) + costy;

      if (length == 0.0)
        strength = 0.0;
      else
        {
          switch (o->shape)
          {
            case GEGl_VIGNETTE_SHAPE_CIRCLE:
              strength = hypot ((u-midx) / scale, v-midy);      break;
            case GEGl_VIGNETTE_SHAPE_SQUARE:
              strength = MAX(ABS(u-midx) / scale, ABS(v-midy)); break;
            case GEGl_VIGNETTE_SHAPE_DIAMOND:
              strength = ABS(u-midx) / scale + ABS(v-midy);     break;
          }
          strength /= length;
          strength = (strength-radius0) / rdiff;
        }

      if (strength<0.0)
        strength = 0.0;
      if (strength>1.0)
        strength = 1.0;

      if (o->gamma > 0.9999 && o->gamma < 2.0001)
        strength *= strength;  /* fast path for default gamma */
      else if (o->gamma != 1.0)
        strength = powf(strength, o->gamma); /* this gamma factor is
                                              * very expensive..
                                              */

      out_pixel[0]=in_pixel[0] * (1.0-strength) + color[0] * strength;
      out_pixel[1]=in_pixel[1] * (1.0-strength) + color[1] * strength;
      out_pixel[2]=in_pixel[2] * (1.0-strength) + color[2] * strength;
      out_pixel[3]=in_pixel[3] * (1.0-strength) + color[3] * strength;

      out_pixel += 4;
      in_pixel  += 4;

      /* update x and y coordinates */
      if (++x>=roi->x + roi->width)
        {
          x=roi->x;
          y++;
          sinty = sint * (y-midy) - midx;
          costy = cost * (y-midy) + midy;
        }
    }

  return  TRUE;
}