1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3  *
4  * kernelgen -- Copyright (C) 2000 Sven Neumann <sven@gimp.org>
5  *
6  *    Simple hack to create brush subsampling kernels.  If you want to
7  *    play with it, change some of the #defines at the top and copy
8  *    the output to app/paint/gimpbrushcore-kernels.h.
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
22  */
23 
24 #include <math.h>
25 #include <stdio.h>
26 #include <string.h>
27 
28 
29 #define STEPS          64
30 #define KERNEL_WIDTH    3     /*  changing these makes no sense  */
31 #define KERNEL_HEIGHT   3     /*  changing these makes no sense  */
32 #define KERNEL_SUM    256
33 #define SUBSAMPLE       4
34 #define THRESHOLD       0.25  /*  try to change this one         */
35 
36 #define SQR(x) ((x) * (x))
37 
38 static void
create_kernel(double x,double y)39 create_kernel (double x,
40                double y)
41 {
42   double value[KERNEL_WIDTH][KERNEL_HEIGHT];
43   double dist_x;
44   double dist_y;
45   double sum;
46   double w;
47   int i, j;
48 
49   memset (value, 0, KERNEL_WIDTH * KERNEL_HEIGHT * sizeof (double));
50   sum = 0.0;
51 
52   x += 1.0;
53   y += 1.0;
54 
55   for (j = 0; j < STEPS * KERNEL_HEIGHT; j++)
56     {
57       dist_y = y - (((double)j + 0.5) / (double)STEPS);
58 
59       for (i = 0; i < STEPS * KERNEL_WIDTH; i++)
60         {
61           dist_x = x - (((double) i + 0.5) / (double) STEPS);
62 
63           /*  I've tried to use a gauss function here instead of a
64               threshold, but the result was not that impressive.    */
65           w = (SQR (dist_x) + SQR (dist_y)) < THRESHOLD ? 1.0 : 0.0;
66 
67           value[i / STEPS][j / STEPS] += w;
68           sum += w;
69         }
70     }
71 
72   for (j = 0; j < KERNEL_HEIGHT; j++)
73     {
74       for (i = 0; i < KERNEL_WIDTH; i++)
75         {
76           w = (double) KERNEL_SUM * value[i][j] / sum;
77           printf (" %3d,", (int) (w + 0.5));
78         }
79     }
80 }
81 
82 int
main(int argc,char ** argv)83 main (int    argc,
84       char **argv)
85 {
86   int    i, j;
87   double x, y;
88 
89   printf ("/* gimpbrushcore-kernels.h\n"
90           " *\n"
91           " *   This file was generated using kernelgen as found in the tools dir.\n");
92   printf (" *   (threshold = %g)\n", THRESHOLD);
93   printf (" */\n\n");
94   printf ("#ifndef __GIMP_BRUSH_CORE_KERNELS_H__\n");
95   printf ("#define __GIMP_BRUSH_CORE_KERNELS_H__\n\n");
96   printf ("#define KERNEL_WIDTH     %d\n", KERNEL_WIDTH);
97   printf ("#define KERNEL_HEIGHT    %d\n", KERNEL_HEIGHT);
98   printf ("#define KERNEL_SUBSAMPLE %d\n", SUBSAMPLE);
99   printf ("#define KERNEL_SUM       %d\n", KERNEL_SUM);
100   printf ("\n\n");
101   printf ("/*  Brush pixel subsampling kernels  */\n");
102   printf ("static const int subsample[%d][%d][%d] =\n{\n",
103           SUBSAMPLE + 1, SUBSAMPLE + 1, KERNEL_WIDTH * KERNEL_HEIGHT);
104 
105   for (j = 0; j <= SUBSAMPLE; j++)
106     {
107       y = (double) j / (double) SUBSAMPLE;
108 
109       printf ("  {\n");
110 
111       for (i = 0; i <= SUBSAMPLE; i++)
112         {
113           x = (double) i / (double) SUBSAMPLE;
114 
115           printf ("    {");
116           create_kernel (x, y);
117           printf (" }%s", i < SUBSAMPLE ? ",\n" : "\n");
118         }
119 
120       printf ("  }%s", j < SUBSAMPLE ? ",\n" : "\n");
121     }
122 
123   printf ("};\n\n");
124 
125   printf ("#endif /* __GIMP_BRUSH_CORE_KERNELS_H__ */\n");
126 
127   return 0;
128 }
129