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
[email protected]
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer