fixed rounding so that all brush kernels are created with a constant sum

2004-12-31  Sven Neumann  <sven@gimp.org>

	* tools/kernelgen.c: fixed rounding so that all brush kernels are
	created with a constant sum of 256.

	* app/paint/gimpbrushcore-kernels.h: regenerated.

	* app/paint/gimpbrushcore.c (gimp_brush_core_subsample_mask): use
	the constant defined un app/paint/gimpbrushcore-kernels.h. Should
	give a tiny speedup.
This commit is contained in:
Sven Neumann 2004-12-31 16:20:51 +00:00 committed by Sven Neumann
parent b650df0c8e
commit 515482fc20
4 changed files with 53 additions and 50 deletions

View File

@ -1,7 +1,18 @@
2004-12-31 Sven Neumann <sven@gimp.org>
* tools/kernelgen.c: fixed rounding so that all brush kernels are
created with a constant sum of 256.
* app/paint/gimpbrushcore-kernels.h: regenerated.
* app/paint/gimpbrushcore.c (gimp_brush_core_subsample_mask): use
the constant defined un app/paint/gimpbrushcore-kernels.h. Should
give a tiny speedup.
2004-12-31 Bill Skaggs <weskaggs@primate.ucdavis.edu> 2004-12-31 Bill Skaggs <weskaggs@primate.ucdavis.edu>
* app/paint/gimpbrushcore.c: invert dependence of brush size on pressure, * app/paint/gimpbrushcore.c: invert dependence of brush size on
using formula from Dave Ahlswede in bug #149576. pressure, using formula from Dave Ahlswede in bug #149576.
2004-12-31 Michael Natterer <mitch@gimp.org> 2004-12-31 Michael Natterer <mitch@gimp.org>

View File

@ -10,6 +10,7 @@
#define KERNEL_WIDTH 3 #define KERNEL_WIDTH 3
#define KERNEL_HEIGHT 3 #define KERNEL_HEIGHT 3
#define KERNEL_SUBSAMPLE 4 #define KERNEL_SUBSAMPLE 4
#define KERNEL_SUM 256
/* Brush pixel subsampling kernels */ /* Brush pixel subsampling kernels */
@ -17,37 +18,37 @@ static const int subsample[5][5][9] =
{ {
{ {
{ 64, 64, 0, 64, 64, 0, 0, 0, 0, }, { 64, 64, 0, 64, 64, 0, 0, 0, 0, },
{ 25, 102, 0, 25, 102, 0, 0, 0, 0, }, { 25, 103, 0, 25, 103, 0, 0, 0, 0, },
{ 0, 128, 0, 0, 128, 0, 0, 0, 0, }, { 0, 128, 0, 0, 128, 0, 0, 0, 0, },
{ 0, 102, 25, 0, 102, 25, 0, 0, 0, }, { 0, 103, 25, 0, 103, 25, 0, 0, 0, },
{ 0, 64, 64, 0, 64, 64, 0, 0, 0, } { 0, 64, 64, 0, 64, 64, 0, 0, 0, }
}, },
{ {
{ 25, 25, 0, 102, 102, 0, 0, 0, 0, }, { 25, 25, 0, 103, 103, 0, 0, 0, 0, },
{ 6, 43, 0, 43, 162, 0, 0, 0, 0, }, { 6, 44, 0, 44, 162, 0, 0, 0, 0, },
{ 0, 50, 0, 0, 205, 0, 0, 0, 0, }, { 0, 50, 0, 0, 206, 0, 0, 0, 0, },
{ 0, 43, 6, 0, 162, 43, 0, 0, 0, }, { 0, 44, 6, 0, 162, 44, 0, 0, 0, },
{ 0, 25, 25, 0, 102, 102, 0, 0, 0, } { 0, 25, 25, 0, 103, 103, 0, 0, 0, }
}, },
{ {
{ 0, 0, 0, 128, 128, 0, 0, 0, 0, }, { 0, 0, 0, 128, 128, 0, 0, 0, 0, },
{ 0, 0, 0, 50, 205, 0, 0, 0, 0, }, { 0, 0, 0, 50, 206, 0, 0, 0, 0, },
{ 0, 0, 0, 0, 256, 0, 0, 0, 0, }, { 0, 0, 0, 0, 256, 0, 0, 0, 0, },
{ 0, 0, 0, 0, 205, 50, 0, 0, 0, }, { 0, 0, 0, 0, 206, 50, 0, 0, 0, },
{ 0, 0, 0, 0, 128, 128, 0, 0, 0, } { 0, 0, 0, 0, 128, 128, 0, 0, 0, }
}, },
{ {
{ 0, 0, 0, 102, 102, 0, 25, 25, 0, }, { 0, 0, 0, 103, 103, 0, 25, 25, 0, },
{ 0, 0, 0, 43, 162, 0, 6, 43, 0, }, { 0, 0, 0, 44, 162, 0, 6, 44, 0, },
{ 0, 0, 0, 0, 205, 0, 0, 50, 0, }, { 0, 0, 0, 0, 206, 0, 0, 50, 0, },
{ 0, 0, 0, 0, 162, 43, 0, 43, 6, }, { 0, 0, 0, 0, 162, 44, 0, 44, 6, },
{ 0, 0, 0, 0, 102, 102, 0, 25, 25, } { 0, 0, 0, 0, 103, 103, 0, 25, 25, }
}, },
{ {
{ 0, 0, 0, 64, 64, 0, 64, 64, 0, }, { 0, 0, 0, 64, 64, 0, 64, 64, 0, },
{ 0, 0, 0, 25, 102, 0, 25, 102, 0, }, { 0, 0, 0, 25, 103, 0, 25, 103, 0, },
{ 0, 0, 0, 0, 128, 0, 0, 128, 0, }, { 0, 0, 0, 0, 128, 0, 0, 128, 0, },
{ 0, 0, 0, 0, 102, 25, 0, 102, 25, }, { 0, 0, 0, 0, 103, 25, 0, 103, 25, },
{ 0, 0, 0, 0, 64, 64, 0, 64, 64, } { 0, 0, 0, 0, 64, 64, 0, 64, 64, }
} }
}; };

View File

@ -909,13 +909,16 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
gint r, s; gint r, s;
gulong *accum[KERNEL_HEIGHT]; gulong *accum[KERNEL_HEIGHT];
gint offs; gint offs;
gint kernel_sum;
while (x < 0) x += mask->width; while (x < 0)
x += mask->width;
left = x - floor (x); left = x - floor (x);
index1 = (gint) (left * (gdouble) (KERNEL_SUBSAMPLE + 1)); index1 = (gint) (left * (gdouble) (KERNEL_SUBSAMPLE + 1));
while (y < 0) y += mask->height; while (y < 0)
y += mask->height;
left = y - floor (y); left = y - floor (y);
index2 = (gint) (left * (gdouble) (KERNEL_SUBSAMPLE + 1)); index2 = (gint) (left * (gdouble) (KERNEL_SUBSAMPLE + 1));
@ -971,15 +974,6 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
for (i = 0; i < KERNEL_HEIGHT ; i++) for (i = 0; i < KERNEL_HEIGHT ; i++)
accum[i] = g_new0 (gulong, dest->width + 1); accum[i] = g_new0 (gulong, dest->width + 1);
/* Investigate modifiying kernelgen to make the sum the same
* for all kernels. That way kernal_sum becomes a constant
*/
kernel_sum = 0;
for (i = 0; i < KERNEL_HEIGHT * KERNEL_WIDTH; i++)
{
kernel_sum += kernel[i];
}
core->kernel_brushes[index2][index1] = dest; core->kernel_brushes[index2][index1] = dest;
m = mask_buf_data (mask); m = mask_buf_data (mask);
@ -993,9 +987,7 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
offs = j + dest_offset_x; offs = j + dest_offset_x;
s = KERNEL_WIDTH; s = KERNEL_WIDTH;
while (s--) while (s--)
{ accum[r][offs++] += *m * *k++;
accum[r][offs++] += *m * *k++;
}
} }
m++; m++;
} }
@ -1003,7 +995,7 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
/* store the accum buffer into the destination mask */ /* store the accum buffer into the destination mask */
d = mask_buf_data (dest) + (i + dest_offset_y) * dest->width; d = mask_buf_data (dest) + (i + dest_offset_y) * dest->width;
for (j = 0; j < dest->width; j++) for (j = 0; j < dest->width; j++)
*d++ = (accum[0][j] + 127) / kernel_sum; *d++ = (accum[0][j] + 127) / KERNEL_SUM;
rotate_pointers (accum, KERNEL_HEIGHT); rotate_pointers (accum, KERNEL_HEIGHT);
@ -1015,7 +1007,7 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
{ {
d = mask_buf_data (dest) + (i + dest_offset_y) * dest->width; d = mask_buf_data (dest) + (i + dest_offset_y) * dest->width;
for (j = 0; j < dest->width; j++) for (j = 0; j < dest->width; j++)
*d++ = (accum[0][j] + (kernel_sum / 2)) / kernel_sum; *d++ = (accum[0][j] + (KERNEL_SUM / 2)) / KERNEL_SUM;
rotate_pointers (accum, KERNEL_HEIGHT); rotate_pointers (accum, KERNEL_HEIGHT);
i++; i++;
@ -1113,7 +1105,7 @@ gimp_brush_core_pressurize_mask (GimpBrushCore *core,
j = pressure + pressure; j = pressure + pressure;
k = 0; k = 0;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
if (k > 255) if (k > 255)
@ -1134,9 +1126,7 @@ gimp_brush_core_pressurize_mask (GimpBrushCore *core,
i = subsample_mask->width * subsample_mask->height; i = subsample_mask->width * subsample_mask->height;
while (i--) while (i--)
{ *dest++ = mapi[(*source++)];
*dest++ = mapi[(*source++)];
}
return core->pressure_brush; return core->pressure_brush;
} }
@ -1156,7 +1146,8 @@ gimp_brush_core_solidify_mask (GimpBrushCore *core,
if ((brush_mask->width % 2) == 0) if ((brush_mask->width % 2) == 0)
{ {
while (x < 0) x += brush_mask->width; while (x < 0)
x += brush_mask->width;
if ((x - floor (x)) >= 0.5) if ((x - floor (x)) >= 0.5)
dest_offset_x++; dest_offset_x++;
@ -1164,7 +1155,8 @@ gimp_brush_core_solidify_mask (GimpBrushCore *core,
if ((brush_mask->height % 2) == 0) if ((brush_mask->height % 2) == 0)
{ {
while (y < 0) y += brush_mask->height; while (y < 0)
y += brush_mask->height;
if ((y - floor (y)) >= 0.5) if ((y - floor (y)) >= 0.5)
dest_offset_y++; dest_offset_y++;
@ -1203,9 +1195,7 @@ gimp_brush_core_solidify_mask (GimpBrushCore *core,
for (i = 0; i < brush_mask->height; i++) for (i = 0; i < brush_mask->height; i++)
{ {
for (j = 0; j < brush_mask->width; j++) for (j = 0; j < brush_mask->width; j++)
{ *d++ = (*m++) ? OPAQUE_OPACITY : TRANSPARENT_OPACITY;
*d++ = (*m++) ? OPAQUE_OPACITY : TRANSPARENT_OPACITY;
}
d += 2; d += 2;
} }
@ -1478,7 +1468,6 @@ paint_line_pixmap_mask (GimpImage *dest,
for (byte_loop = 0; byte_loop < bytes - 1; byte_loop++) for (byte_loop = 0; byte_loop < bytes - 1; byte_loop++)
d[byte_loop] *= alpha; d[byte_loop] *= alpha;
/* printf("i: %i d->r: %i d->g: %i d->b: %i d->a: %i\n",i,(int)d[0], (int)d[1], (int)d[2], (int)d[3]); */
gimp_image_transform_color (dest, drawable, d, GIMP_RGB, p); gimp_image_transform_color (dest, drawable, d, GIMP_RGB, p);
d += bytes; d += bytes;
} }

View File

@ -30,6 +30,7 @@
#define STEPS 64 #define STEPS 64
#define KERNEL_WIDTH 3 /* changing these makes no sense */ #define KERNEL_WIDTH 3 /* changing these makes no sense */
#define KERNEL_HEIGHT 3 /* changing these makes no sense */ #define KERNEL_HEIGHT 3 /* changing these makes no sense */
#define KERNEL_SUM 256
#define SUBSAMPLE 4 #define SUBSAMPLE 4
#define THRESHOLD 0.25 /* try to change this one */ #define THRESHOLD 0.25 /* try to change this one */
@ -58,7 +59,7 @@ create_kernel (double x,
for (i = 0; i < STEPS * KERNEL_WIDTH; i++) for (i = 0; i < STEPS * KERNEL_WIDTH; i++)
{ {
dist_x = x - (((double)i + 0.5) / (double)STEPS); dist_x = x - (((double) i + 0.5) / (double) STEPS);
/* I've tried to use a gauss function here instead of a /* I've tried to use a gauss function here instead of a
threshold, but the result was not that impressive. */ threshold, but the result was not that impressive. */
@ -73,8 +74,8 @@ create_kernel (double x,
{ {
for (i = 0; i < KERNEL_WIDTH; i++) for (i = 0; i < KERNEL_WIDTH; i++)
{ {
w = 256.0 * (value[i][j] / sum); w = (double) KERNEL_SUM * value[i][j] / sum;
printf (" %3d,", (int)w); printf (" %3d,", (int) (w + 0.5));
} }
} }
} }
@ -96,6 +97,7 @@ main (int argc,
printf ("#define KERNEL_WIDTH %d\n", KERNEL_WIDTH); printf ("#define KERNEL_WIDTH %d\n", KERNEL_WIDTH);
printf ("#define KERNEL_HEIGHT %d\n", KERNEL_HEIGHT); printf ("#define KERNEL_HEIGHT %d\n", KERNEL_HEIGHT);
printf ("#define KERNEL_SUBSAMPLE %d\n", SUBSAMPLE); printf ("#define KERNEL_SUBSAMPLE %d\n", SUBSAMPLE);
printf ("#define KERNEL_SUM %d\n", KERNEL_SUM);
printf ("\n\n"); printf ("\n\n");
printf ("/* Brush pixel subsampling kernels */\n"); printf ("/* Brush pixel subsampling kernels */\n");
printf ("static const int subsample[%d][%d][%d] =\n{\n", printf ("static const int subsample[%d][%d][%d] =\n{\n",
@ -103,13 +105,13 @@ main (int argc,
for (j = 0; j <= SUBSAMPLE; j++) for (j = 0; j <= SUBSAMPLE; j++)
{ {
y = (double)j / (double)(SUBSAMPLE); y = (double) j / (double) SUBSAMPLE;
printf (" {\n"); printf (" {\n");
for (i = 0; i <= SUBSAMPLE; i++) for (i = 0; i <= SUBSAMPLE; i++)
{ {
x = (double)i / (double)(SUBSAMPLE); x = (double) i / (double) SUBSAMPLE;
printf (" {"); printf (" {");
create_kernel (x, y); create_kernel (x, y);