mirror of https://github.com/GNOME/gimp.git
app: Clean up the hardness feature. Lets convolve PixelRegions.
This commit is contained in:
parent
9774988f30
commit
2c4c9ad333
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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! */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue