app: port gimp:shapeburst's input from u8 to float

This commit is contained in:
Michael Natterer 2014-05-01 20:32:26 +02:00
parent d0c67f84c8
commit 540d3bb6ae
2 changed files with 27 additions and 23 deletions

View File

@ -550,12 +550,10 @@ gradient_precalc_shapeburst (GimpImage *image,
babl_format ("Y float"));
/* allocate the selection mask copy
* XXX: its format should be the same of gimp:shapeburst input buffer
* porting the op to 'float' should be reflected here as well
*/
temp_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
region->width, region->height),
babl_format ("Y u8"));
babl_format ("Y float"));
mask = gimp_image_get_mask (image);
@ -581,7 +579,7 @@ gradient_precalc_shapeburst (GimpImage *image,
{
const Babl *component_format;
component_format = babl_format ("A u8");
component_format = babl_format ("A float");
/* extract the aplha into the temp mask */
gegl_buffer_set_format (temp_buffer, component_format);

View File

@ -163,7 +163,7 @@ gimp_operation_shapeburst_set_property (GObject *object,
static void
gimp_operation_shapeburst_prepare (GeglOperation *operation)
{
gegl_operation_set_format (operation, "input", babl_format ("Y u8"));
gegl_operation_set_format (operation, "input", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", babl_format ("Y float"));
}
@ -189,7 +189,7 @@ gimp_operation_shapeburst_process (GeglOperation *operation,
const GeglRectangle *roi,
gint level)
{
const Babl *input_format = babl_format ("Y u8");
const Babl *input_format = babl_format ("Y float");
const Babl *output_format = babl_format ("Y float");
gfloat max_iterations = 0.0;
gfloat *distp_cur;
@ -211,7 +211,7 @@ gimp_operation_shapeburst_process (GeglOperation *operation,
for (i = 0; i < roi->height; i++)
{
gfloat *tmp;
gint src = 0;
gfloat src = 0.0;
gint j;
/* set the current dist row to 0's */
@ -223,13 +223,23 @@ gimp_operation_shapeburst_process (GeglOperation *operation,
gfloat min_prev = MIN (distp_cur[j-1], distp_prev[j]);
gint min_left = MIN ((roi->width - j - 1), (roi->height - i - 1));
gint min = (gint) MIN (min_left, min_prev);
gint fraction = 255;
gfloat fraction = 1.0;
gint k;
/* This might need to be changed to 0
instead of k = (min) ? (min - 1) : 0 */
#define EPSILON 0.0001
for (k = (min) ? (min - 1) : 0; k <= min; k++)
/* This loop used to start at "k = (min) ? (min - 1) : 0"
* and this comment suggested it might have to be changed to
* "k = 0", but "k = 0" increases processing time significantly.
*
* When porting this to float, i noticed that starting at
* "min - 2" gets rid of a lot of 8-bit artifacts, while starting
* at "min - 3" or smaller would introduce different artifacts.
*
* Note that I didn't really understand the entire algorithm,
* I just "blindly" ported it to float :) --mitch
*/
for (k = MAX (min - 2, 0); k <= min; k++)
{
gint x = j;
gint y = i + k;
@ -237,24 +247,20 @@ gimp_operation_shapeburst_process (GeglOperation *operation,
while (y >= end)
{
guchar src_uchar;
#if 1
/* FIXME: this should be much faster, it converts
* to 32 bit rgba intermediately, bah...
*/
gegl_buffer_sample (input, x, y, NULL, &src_uchar,
gegl_buffer_sample (input, x, y, NULL, &src,
input_format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
#else
gegl_buffer_get (input, GEGL_RECTANGLE (x, y, 1, 1), 1.0,
input_format, &src_uchar,
input_format, &src,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
#endif
src = src_uchar;
if (src == 0)
if (ABS (src) < EPSILON)
{
min = k;
y = -1;
@ -269,17 +275,17 @@ gimp_operation_shapeburst_process (GeglOperation *operation,
}
}
if (src != 0)
if (src > EPSILON)
{
/* If min_left != min_prev use the previous fraction
* if it is less than the one found
*/
if (min_left != min)
{
gint prev_frac = (int) (255 * (min_prev - min));
gfloat prev_frac = min_prev - min;
if (prev_frac == 255)
prev_frac = 0;
if (ABS (prev_frac - 1.0) < EPSILON)
prev_frac = 0.0;
fraction = MIN (fraction, prev_frac);
}
@ -287,7 +293,7 @@ gimp_operation_shapeburst_process (GeglOperation *operation,
min++;
}
float_tmp = distp_cur[j] = min + fraction / 256.0;
float_tmp = distp_cur[j] = min + fraction * (1.0 - EPSILON);
if (float_tmp > max_iterations)
max_iterations = float_tmp;