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 "gimpbrush-transform.h"
|
||||||
|
|
||||||
#include "base/temp-buf.h"
|
#include "base/temp-buf.h"
|
||||||
|
#include "base/pixel-region.h"
|
||||||
|
|
||||||
#include "paint-funcs/paint-funcs.h"
|
#include "paint-funcs/paint-funcs.h"
|
||||||
|
|
||||||
|
@ -335,7 +336,8 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
|
||||||
if (hardness < 1.0)
|
if (hardness < 1.0)
|
||||||
{
|
{
|
||||||
TempBuf *blur_src;
|
TempBuf *blur_src;
|
||||||
|
PixelRegion srcPR;
|
||||||
|
PixelRegion destPR;
|
||||||
gint kernel_size = gimp_brush_transform_blur_kernel_size ( result->height,
|
gint kernel_size = gimp_brush_transform_blur_kernel_size ( result->height,
|
||||||
result->width,
|
result->width,
|
||||||
hardness);
|
hardness);
|
||||||
|
@ -346,9 +348,12 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
|
||||||
|
|
||||||
blur_src = temp_buf_copy (result, NULL);
|
blur_src = temp_buf_copy (result, NULL);
|
||||||
|
|
||||||
convolve_tempbuf (blur_src, result, blur_kernel, kernel_size,
|
pixel_region_init_temp_buf (&srcPR, blur_src, blur_src->x, blur_src->y, blur_src->width, blur_src->height);
|
||||||
gimp_brush_transform_array_sum(blur_kernel, kernel_len),
|
pixel_region_init_temp_buf (&destPR, result, result->x, result->y, result->width, result->height);
|
||||||
GIMP_NORMAL_CONVOL, FALSE);
|
|
||||||
|
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_x, distance_from_true_x;
|
||||||
gint opposite_y, distance_from_true_y;
|
gint opposite_y, distance_from_true_y;
|
||||||
|
|
||||||
source = brush->pixmap;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tl, tr etc are used because it is easier to visualize top left,
|
* tl, tr etc are used because it is easier to visualize top left,
|
||||||
* top right etc corners of the forward transformed source image
|
* 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 ;
|
const guint fraction_bitmask = pow(2, fraction_bits)- 1 ;
|
||||||
|
|
||||||
|
source = brush->pixmap;
|
||||||
|
|
||||||
if (aspect_ratio < 1.0)
|
if (aspect_ratio < 1.0)
|
||||||
gimp_brush_transform_matrix (source,
|
gimp_brush_transform_matrix (source,
|
||||||
|
@ -625,19 +629,24 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
|
||||||
if (hardness < 1.0)
|
if (hardness < 1.0)
|
||||||
{
|
{
|
||||||
TempBuf *blur_src;
|
TempBuf *blur_src;
|
||||||
|
PixelRegion srcPR;
|
||||||
|
PixelRegion destPR;
|
||||||
gint kernel_size = gimp_brush_transform_blur_kernel_size ( result->height,
|
gint kernel_size = gimp_brush_transform_blur_kernel_size ( result->height,
|
||||||
result->width,
|
result->width,
|
||||||
hardness);
|
hardness);
|
||||||
gint kernel_len = kernel_size * kernel_size;
|
gint kernel_len = kernel_size * kernel_size;
|
||||||
gfloat blur_kernel [kernel_len];
|
gfloat blur_kernel [kernel_len];
|
||||||
|
|
||||||
gimp_brush_transform_fill_blur_kernel ( blur_kernel, kernel_len);
|
gimp_brush_transform_fill_blur_kernel ( blur_kernel, kernel_len);
|
||||||
|
|
||||||
blur_src = temp_buf_copy (result, NULL);
|
blur_src = temp_buf_copy (result, NULL);
|
||||||
|
|
||||||
convolve_tempbuf (blur_src, result, blur_kernel, kernel_size,
|
pixel_region_init_temp_buf (&srcPR, blur_src, blur_src->x, blur_src->y, blur_src->width, blur_src->height);
|
||||||
gimp_brush_transform_array_sum(blur_kernel, kernel_len),
|
pixel_region_init_temp_buf (&destPR, result, result->x, result->y, result->width, result->height);
|
||||||
GIMP_NORMAL_CONVOL, FALSE);
|
|
||||||
|
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
|
/* Convert from separated alpha to premultiplied alpha. Only works on
|
||||||
non-tiled regions! */
|
non-tiled regions! */
|
||||||
|
|
|
@ -391,7 +391,6 @@ void extract_from_region (PixelRegion *src,
|
||||||
GimpImageBaseType type,
|
GimpImageBaseType type,
|
||||||
gboolean cut);
|
gboolean cut);
|
||||||
|
|
||||||
|
|
||||||
void convolve_region (PixelRegion *srcR,
|
void convolve_region (PixelRegion *srcR,
|
||||||
PixelRegion *destR,
|
PixelRegion *destR,
|
||||||
const gfloat *matrix,
|
const gfloat *matrix,
|
||||||
|
@ -400,13 +399,6 @@ void convolve_region (PixelRegion *srcR,
|
||||||
GimpConvolutionType mode,
|
GimpConvolutionType mode,
|
||||||
gboolean alpha_weighting);
|
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);
|
void multiply_alpha_region (PixelRegion *srcR);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue