+/* precompute shadow corners and sides to save time for large windows */
+static void
+presum_gaussian (conv *map)
+{
+ int center = map->size/2;
+ int opacity, x, y;
+
+ Gsize = map->size;
+
+ if (shadowCorner)
+ free ((void *)shadowCorner);
+ if (shadowTop)
+ free ((void *)shadowTop);
+
+ shadowCorner = (unsigned char *)(malloc ((Gsize + 1) * (Gsize + 1) * 26));
+ shadowTop = (unsigned char *)(malloc ((Gsize + 1) * 26));
+
+ for (x = 0; x <= Gsize; x++)
+ {
+ shadowTop[25 * (Gsize + 1) + x] = sum_gaussian (map, 1, x - center, center, Gsize * 2, Gsize * 2);
+ for(opacity = 0; opacity < 25; opacity++)
+ shadowTop[opacity * (Gsize + 1) + x] = shadowTop[25 * (Gsize + 1) + x] * opacity / 25;
+ for(y = 0; y <= x; y++)
+ {
+ shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x]
+ = sum_gaussian (map, 1, x - center, y - center, Gsize * 2, Gsize * 2);
+ shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + x * (Gsize + 1) + y]
+ = shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x];
+ for(opacity = 0; opacity < 25; opacity++)
+ shadowCorner[opacity * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x]
+ = shadowCorner[opacity * (Gsize + 1) * (Gsize + 1) + x * (Gsize + 1) + y]
+ = shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x] * opacity / 25;
+ }
+ }
+}
+