app: Clean up the hardness feature. Lets convolve PixelRegions.

This commit is contained in:
Alexia Death 2010-01-01 18:16:29 +02:00
parent 9774988f30
commit 2c4c9ad333
3 changed files with 19 additions and 151 deletions

View File

@ -29,6 +29,7 @@
#include "gimpbrush-transform.h"
#include "base/temp-buf.h"
#include "base/pixel-region.h"
#include "paint-funcs/paint-funcs.h"
@ -335,7 +336,8 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
if (hardness < 1.0)
{
TempBuf *blur_src;
PixelRegion srcPR;
PixelRegion destPR;
gint kernel_size = gimp_brush_transform_blur_kernel_size ( result->height,
result->width,
hardness);
@ -346,9 +348,12 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
blur_src = temp_buf_copy (result, NULL);
convolve_tempbuf (blur_src, result, blur_kernel, kernel_size,
gimp_brush_transform_array_sum(blur_kernel, kernel_len),
GIMP_NORMAL_CONVOL, FALSE);
pixel_region_init_temp_buf (&srcPR, blur_src, blur_src->x, blur_src->y, blur_src->width, blur_src->height);
pixel_region_init_temp_buf (&destPR, result, result->x, result->y, result->width, result->height);
convolve_region (&srcPR, &destPR, blur_kernel, kernel_size,
gimp_brush_transform_array_sum(blur_kernel, kernel_len),
GIMP_NORMAL_CONVOL, FALSE);
}
@ -428,8 +433,6 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
gint opposite_x, distance_from_true_x;
gint opposite_y, distance_from_true_y;
source = brush->pixmap;
/*
* tl, tr etc are used because it is easier to visualize top left,
* top right etc corners of the forward transformed source image
@ -460,6 +463,7 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
*/
const guint fraction_bitmask = pow(2, fraction_bits)- 1 ;
source = brush->pixmap;
if (aspect_ratio < 1.0)
gimp_brush_transform_matrix (source,
@ -625,19 +629,24 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
if (hardness < 1.0)
{
TempBuf *blur_src;
PixelRegion srcPR;
PixelRegion destPR;
gint kernel_size = gimp_brush_transform_blur_kernel_size ( result->height,
result->width,
hardness);
gint kernel_len = kernel_size * kernel_size;
gint kernel_len = kernel_size * kernel_size;
gfloat blur_kernel [kernel_len];
gimp_brush_transform_fill_blur_kernel ( blur_kernel, kernel_len);
blur_src = temp_buf_copy (result, NULL);
convolve_tempbuf (blur_src, result, blur_kernel, kernel_size,
gimp_brush_transform_array_sum(blur_kernel, kernel_len),
GIMP_NORMAL_CONVOL, FALSE);
pixel_region_init_temp_buf (&srcPR, blur_src, blur_src->x, blur_src->y, blur_src->width, blur_src->height);
pixel_region_init_temp_buf (&destPR, result, result->x, result->y, result->width, result->height);
convolve_region (&srcPR, &destPR, blur_kernel, kernel_size,
gimp_brush_transform_array_sum(blur_kernel, kernel_len),
GIMP_NORMAL_CONVOL, FALSE);
}

View File

@ -2333,139 +2333,6 @@ convolve_region (PixelRegion *srcR,
}
}
void
convolve_tempbuf (TempBuf *srcR,
TempBuf *destR,
const gfloat *matrix,
gint size,
gdouble divisor,
GimpConvolutionType mode,
gboolean alpha_weighting)
{
/* Convolve the src image using the convolution matrix, writing to dest */
/* Convolve is not tile-enabled--use accordingly */
const guchar *src = temp_buf_get_data(srcR);
guchar *dest = temp_buf_get_data(destR);
const gint bytes = srcR->bytes;
const gint a_byte = bytes - 1;
const gint rowstride = bytes * srcR->width;
const gint dest_rowstride = bytes * destR->width;
const gint margin = size / 2;
const gint x1 = srcR->x;
const gint y1 = srcR->y;
const gint x2 = srcR->x + srcR->width - 1;
const gint y2 = srcR->y + srcR->height - 1;
gint x, y;
gint offset;
/* If the mode is NEGATIVE_CONVOL, the offset should be 128 */
if (mode == GIMP_NEGATIVE_CONVOL)
{
offset = 128;
mode = GIMP_NORMAL_CONVOL;
}
else
{
offset = 0;
}
for (y = 0; y < destR->height; y++)
{
guchar *d = dest;
if (alpha_weighting && FALSE)
{
for (x = 0; x < destR->width; x++)
{
const gfloat *m = matrix;
gdouble total[4] = { 0.0, 0.0, 0.0, 0.0 };
gdouble weighted_divisor = 0.0;
gint i, j, b;
for (j = y - margin; j <= y + margin; j++)
{
for (i = x - margin; i <= x + margin; i++, m++)
{
gint xx = CLAMP (i, x1, x2);
gint yy = CLAMP (j, y1, y2);
const guchar *s = src + yy * rowstride + xx * bytes;
const guchar a = s[a_byte];
if (a)
{
gdouble mult_alpha = *m * a;
weighted_divisor += mult_alpha;
for (b = 0; b < a_byte; b++)
total[b] += mult_alpha * s[b];
total[a_byte] += mult_alpha;
}
}
}
if (weighted_divisor == 0.0)
weighted_divisor = divisor;
for (b = 0; b < a_byte; b++)
total[b] /= weighted_divisor;
total[a_byte] /= divisor;
for (b = 0; b < bytes; b++)
{
total[b] += offset;
if (mode != GIMP_NORMAL_CONVOL && total[b] < 0.0)
total[b] = - total[b];
if (total[b] < 0.0)
*d++ = 0;
else
*d++ = (total[b] > 255.0) ? 255 : (guchar) ROUND (total[b]);
}
}
}
else
{
for (x = 0; x < destR->width; x++)
{
const gfloat *m = matrix;
gdouble total[4] = { 0.0, 0.0, 0.0, 0.0 };
gint i, j, b;
for (j = y - margin; j <= y + margin; j++)
{
for (i = x - margin; i <= x + margin; i++, m++)
{
gint xx = CLAMP (i, x1, x2);
gint yy = CLAMP (j, y1, y2);
const guchar *s = src + yy * rowstride + xx * bytes;
for (b = 0; b < bytes; b++)
total[b] += *m * s[b];
}
}
for (b = 0; b < bytes; b++)
{
total[b] = total[b] / divisor + offset;
if (mode != GIMP_NORMAL_CONVOL && total[b] < 0.0)
total[b] = - total[b];
if (total[b] < 0.0)
*d++ = 0.0;
else
*d++ = (total[b] > 255.0) ? 255 : (guchar) ROUND (total[b]);
}
}
}
dest += dest_rowstride;
}
}
/* Convert from separated alpha to premultiplied alpha. Only works on
non-tiled regions! */

View File

@ -391,7 +391,6 @@ void extract_from_region (PixelRegion *src,
GimpImageBaseType type,
gboolean cut);
void convolve_region (PixelRegion *srcR,
PixelRegion *destR,
const gfloat *matrix,
@ -400,13 +399,6 @@ void convolve_region (PixelRegion *srcR,
GimpConvolutionType mode,
gboolean alpha_weighting);
void convolve_tempbuf (TempBuf *srcR,
TempBuf *destR,
const gfloat *matrix,
gint size,
gdouble divisor,
GimpConvolutionType mode,
gboolean alpha_weighting);
void multiply_alpha_region (PixelRegion *srcR);