static void prepare (GeglOperation *operation) { #define max(A,B) ((A) > (B) ? (A) : (B)) GeglOperationAreaFilter *area = GEGL_OPERATION_AREA_FILTER (operation); GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); gfloat fir_radius_x = fir_calc_convolve_matrix_length (o->std_dev_x) / 2; gfloat fir_radius_y = fir_calc_convolve_matrix_length (o->std_dev_y) / 2; gfloat iir_radius_x = o->std_dev_x * RADIUS_SCALE; gfloat iir_radius_y = o->std_dev_y * RADIUS_SCALE; /* XXX: these should be calculated exactly considering o->filter, but we just * make sure there is enough space */ area->left = area->right = ceil ( max (fir_radius_x, iir_radius_x)); area->top = area->bottom = ceil ( max (fir_radius_y, iir_radius_y)); gegl_operation_set_format (operation, "output", babl_format ("RaGaBaA float")); #undef max }
static gint fir_gen_convolve_matrix (gdouble sigma, gdouble **cmatrix_p) { gint matrix_length; gdouble *cmatrix; matrix_length = fir_calc_convolve_matrix_length (sigma); cmatrix = g_new (gdouble, matrix_length); if (!cmatrix) return 0; if (matrix_length == 1) { cmatrix[0] = 1; } else { gint i,x; gdouble sum = 0; for (i=0; i<matrix_length/2+1; i++) { gdouble y; x = i - (matrix_length/2); y = (1.0/(sigma*sqrt(2.0*G_PI))) * exp(-(x*x) / (2.0*sigma*sigma)); cmatrix[i] = y; sum += cmatrix[i]; } for (i=matrix_length/2 + 1; i<matrix_length; i++) { cmatrix[i] = cmatrix[matrix_length-i-1]; sum += cmatrix[i]; } for (i=0; i<matrix_length; i++) { cmatrix[i] /= sum; } } *cmatrix_p = cmatrix; return matrix_length; }
static GeglRectangle gegl_gblur_1d_enlarge_extent (GeglProperties *o, const GeglRectangle *input_extent) { gint clen = fir_calc_convolve_matrix_length (o->std_dev); GeglRectangle bounding_box = *input_extent; if (o->orientation == GEGL_ORIENTATION_HORIZONTAL) { bounding_box.x -= clen / 2; bounding_box.width += clen - 1; } else { bounding_box.y -= clen / 2; bounding_box.height += clen - 1; } return bounding_box; }
static gint fir_gen_convolve_matrix (gfloat sigma, gfloat **cmatrix) { gint clen; gfloat *cmatrix_p; clen = fir_calc_convolve_matrix_length (sigma); *cmatrix = gegl_malloc (sizeof (gfloat) * clen); cmatrix_p = *cmatrix; if (clen == 1) { cmatrix_p [0] = 1; } else { gint i; gdouble sum = 0; gint half_clen = clen / 2; for (i = 0; i < clen; i++) { cmatrix_p [i] = gaussian_func_1d (i - half_clen, sigma); sum += cmatrix_p [i]; } for (i = 0; i < clen; i++) { cmatrix_p [i] /= sum; } } return clen; }