Re: Sample implementation of a new GEGL op

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I've added comments in my code. If still there is anything to do, please let me know.

--
Sourav De
2nd Year Student
Department of Computer Science and Engineering
IIT KHARAGPUR

/****************************************************************************
 * Blur:
 *
 * Blur applies a (2n+1)x(2n+1) blurring convolution kernel to the specified image.
 *
 * Where n is the blur radius specified by the user.
 *
 * This works only with RGB and grayscale images.
 *
 ****************************************************************************/

#include "config.h"
#include <glib/gi18n-lib.h>

#ifdef GEGL_CHANT_PROPERTIES

gegl_chant_int    (radius, _("Radius"), 0, 50, 3,
   _("Blur Radius"))

#else

#define GEGL_CHANT_TYPE_AREA_FILTER
#define GEGL_CHANT_C_FILE  "blur.c"

#include <gegl-chant.h>
#include <math.h>
#include <stdio.h>


static void blur(GeglBuffer *src,const GeglRectangle *src_rect,GeglBuffer *dst,const GeglRectangle *dst_rect,gint radius);

static inline void  prepare(GeglOperation *operation)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *area = GEGL_OPERATION_AREA_FILTER (operation);
  area->left = area->right = area->top = area->bottom=o->radius;
  gegl_operation_set_format (operation, "input", babl_format ("RaGaBaA float"));
  gegl_operation_set_format (operation, "output", babl_format ("RaGaBaA float"));
}

static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle rect;
  GeglOperationAreaFilter *op_area;
  op_area = GEGL_OPERATION_AREA_FILTER (operation);
  rect.x = result->x - op_area->left;
  rect.width = result->width + op_area->left + op_area->right;
  rect.y = result->y - op_area->top;
  rect.height = result->height + op_area->top + op_area->bottom;
  blur(input, &rect, output, result,o->radius);
  return TRUE;
}

/*********************************
 *
 *  blur()
 *
 *  Actually mess with the image.
 *
 ********************************/

static void blur (GeglBuffer *src,const GeglRectangle *src_rect,GeglBuffer *dst,const GeglRectangle *dst_rect,gint radius)
{
  gint x,y;
  gint i,j;
  gint a,b;
  gfloat *src_buf,*dst_buf;
  gint offset;

  src_buf = g_new0 (gfloat, src_rect->width * src_rect->height * 4);
  dst_buf = g_new0 (gfloat, dst_rect->width * dst_rect->height * 4);

  gegl_buffer_get (src, 1.0, src_rect, babl_format ("RaGaBaA float"), src_buf, GEGL_AUTO_ROWSTRIDE);

  gint src_width=src_rect->width;

  offset=0;
  for(y=0; y<dst_rect->height; y++)
    {
      for (x=0; x<dst_rect->width; x++)
	{
	  /* creates an array of length 4
	     first 3 elements are for Red, Green & Blue channel
	     last element is for no alpha channel */
	  gfloat gradient[4] = {0.0f, 0.0f, 0.0f, 0.0f};
	  gint c;
	  i=x+radius;
	  j=y+radius;
	  gfloat *src_pix = src_buf + (i + j * src_width) * 4;

	  /*The parameter radius determines the size of the area of source pixels, 
	    that is averaged for each blurred destination pixel. */

	  for (c=0;c<4;c++)
	    {
	      for (a = -radius; a <= radius; ++a)
		{
		  for (b = -radius; b <= radius; ++b)
		    gradient[c]+= src_pix[c+a*src_width*4+4*b];
		}
	      gradient[c]/=pow((radius * 2 + 1),2);
	    }
	  
	  /* transfers calculated average pixel values to the destination buffer */
	  for (c=0; c<4;c++)
	    dst_buf[offset*4+c] = gradient[c];

	  offset++;
	}
    }

  gegl_buffer_set (dst, dst_rect, babl_format ("RaGaBaA float"), dst_buf,GEGL_AUTO_ROWSTRIDE);

  g_free (src_buf);
  g_free (dst_buf);
}

static void gegl_chant_class_init (GeglChantClass *klass)
{
  GeglOperationClass *operation_class;
  GeglOperationFilterClass *filter_class;

  operation_class = GEGL_OPERATION_CLASS (klass);
  filter_class = GEGL_OPERATION_FILTER_CLASS (klass);

  filter_class->process = process;
  operation_class->prepare = prepare;

  operation_class->categories = "blur";
  operation_class->name = "gegl:blur";
  operation_class->description = _("Performs an averaging of pixels.");
}

#endif
_______________________________________________
Gimp-developer mailing list
Gimp-developer@xxxxxxxxxxxxxxxxxxxxxx
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer

[Index of Archives]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [GIMP for Windows]     [KDE]     [GEGL]     [Gimp's Home]     [Gimp on GUI]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux