Re: GsoC - 2011 - Porting GIMP plugins to GEGL operations

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

 



Here is my last task. I attached the emboss plug-in ported to gegl. Just paste in the gegl/operations/common, compile and run it.
If there is something wrong please write it and I will immidiatelly correct it.

Thank you,
Robert Sasu
#include "config.h"
#include <glib/gi18n-lib.h>

#ifdef GEGL_CHANT_PROPERTIES

gegl_chant_double (azimuth, _("Azimuth"), 0.0, 360.0, 30.0,
   _("The value of azimuth"))
gegl_chant_double (elevation, _("Elevation"), 0.0, 180.0, 45.0,
   _("The value of elevation"))
gegl_chant_int    (depth, _("Depth"), 1, 100, 20,
   _("Pixel depth"))
gegl_chant_string (filter, _("Filter"), "emboss",
   _("Optional parameter to override automatic selection of emboss filert. "
     "Choices are emboss, blur-map" ))

#else

#define GEGL_CHANT_TYPE_AREA_FILTER

#define GEGL_CHANT_C_FILE	"emboss.c"
#define RADIUS 3


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

static void 
emboss       (GeglBuffer          *src,
              const GeglRectangle *src_rect,
              GeglBuffer          *dst,
              const GeglRectangle *dst_rect,
	      gchar		  *text,
              gint		   floats_per_pixel, /*floats per pixel*/
	      gint		   alpha,
	      gdouble		   azimuth,
	      gdouble		   elevation,
	      gint		   depth)
{
  gfloat     *src_buf;
  gfloat     *dst_buf;
  gint	      x;
  gint	      y;
  gint        offset, verify;
  gint	      bytes;

  gdouble Lx   = cos (azimuth) * cos (elevation);
  gdouble Ly   = sin (azimuth) * cos (elevation);
  gdouble Lz   = sin (elevation) ;
  gdouble Nz2  = 1 / (depth * depth);
  gdouble NzLz = (1 / depth) * Lz;

  bytes = (alpha) ? floats_per_pixel - 1 : floats_per_pixel;

  src_buf = g_new0 (gfloat, src_rect->width * src_rect->height * floats_per_pixel);
  dst_buf = g_new0 (gfloat, dst_rect->width * dst_rect->height * floats_per_pixel);
  
  gegl_buffer_get (src, 1.0, src_rect, babl_format (text),
                   src_buf, GEGL_AUTO_ROWSTRIDE);

  verify = src_rect->width*src_rect->height*floats_per_pixel;
  offset = 0;
  for (x = 0; x < dst_rect->height; x++)
    {
    for (y = 0; y < dst_rect->width; y++)
	{
	  gint	  i, j, b, count;
	  gfloat  Nx, Ny, NdotL;
          gfloat  shade;
	  gfloat  M[3][3];
          gfloat  a;

	  for (i = 0; i < 3; i++)
            for (j = 0; j < 3; j++)
               M[i][j] = 0.0;	  
          
	  for (b = 0; b < bytes; b++)
           {
           for (i = 0; i < 3; i++)
             for (j = 0; j < 3; j++)
               {
		 count = ((x+i-1)*src_rect->width + (y+j-1))*floats_per_pixel + bytes;
		/*verify each time that we are in the source image*/
                 if (alpha && count >= 0 && count < verify)
                   a = src_buf[count];
                 else
                   a = 1.0;

		/*calculate recalculate the sorrounding pixels by multiplication*/
		/*after we have that we can calculate new value of the pixel*/
		 if ((count - bytes + b) >= 0 && (count - bytes + b) < verify)
                    M[i][j] += a * src_buf[count - bytes + b];	
		}
            }
	
	   Nx = M[0][0] + M[1][0] + M[2][0] - M[0][2] - M[1][2] - M[2][2];
           Ny = M[2][0] + M[2][1] + M[2][2] - M[0][0] - M[0][1] - M[0][2];
	  

	   /*calculating the shading result (same as in gimp)*/
	   if ( Nx == 0 && Ny == 0 )
              shade = Lz;
           else if ( (NdotL = Nx * Lx + Ny * Ly + NzLz) < 0 )
              shade = 0;
           else
              shade = NdotL / sqrt(Nx*Nx + Ny*Ny + Nz2);

	   count = (x*src_rect->width + y)*floats_per_pixel;

  	   if (bytes == 1)
	 	dst_buf[offset++] = shade; /*setting the destination buffer*/
	   else
	      {
		for (b = 0; b < bytes; b++)
		   if ((count + b) >= 0 && (count + b) < verify) /*recalculating every byte of a pixel*/
              	      dst_buf[offset++] = (src_buf[count+b] * shade) ;  /*by multiplying with the shading result*/
		   else
		      dst_buf[offset++] = 1.0;

          	if (alpha && (count + bytes) >= 0 && (count + bytes) < verify) /*preserving alpha*/
            	   dst_buf[offset++] = src_buf[count + bytes];
		else
		   dst_buf[offset++] = 1.0 ; 
              }
	}
     }
  gegl_buffer_set (dst, dst_rect, babl_format (text),
                   dst_buf, GEGL_AUTO_ROWSTRIDE);
  g_free (src_buf);
  g_free (dst_buf);
}


static void prepare (GeglOperation *operation)
{
  GeglChantO              *o       = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  gchar 		  *type;
  gboolean      	   filter_blurmap;

  op_area->left=op_area->right=op_area->top=op_area->bottom=3;
  
  filter_blurmap = o->filter && !strcmp(o->filter, "blur-map");
  
  type = (filter_blurmap) ? "RGBA float" : "Y float";
  
  gegl_operation_set_format (operation, "output", babl_format (type));
}

static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result)
{
  GeglChantO              *o       = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);

  GeglRectangle rect;
  
  gboolean      filter_blurmap;
  gchar	       *type;
  /*blur-map or emboss*/
  filter_blurmap = o->filter && !strcmp(o->filter, "blur-map");
  type = (filter_blurmap) ? "RGBA float" : "Y float";

  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;

  emboss(input, &rect, output, &rect, type, (filter_blurmap) ? 4 : 1,
	 (filter_blurmap) ? 1 : 0, o->azimuth, o->elevation, o->depth);

  return TRUE;
}

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  = "distort";
  operation_class->name        = "gegl:emboss";
  operation_class->description =
        _("Performs embossing on the image.");
}

#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