+static GdkPixbuf *
+load_pixbuf (const char *file)
+{
+ GdkPixbuf *pb;
+#ifdef HAVE_GTK2
+ GError *err = NULL;
+
+ pb = gdk_pixbuf_new_from_file (file, &err);
+#else /* !HAVE_GTK2 */
+ pb = gdk_pixbuf_new_from_file (file);
+#endif /* HAVE_GTK2 */
+
+ if (!pb)
+ {
+#ifdef HAVE_GTK2
+ fprintf (stderr, "%s: %s\n", progname, err->message);
+ g_error_free (err);
+#else /* !HAVE_GTK2 */
+ fprintf (stderr, "%s: unable to load %s\n", progname, file);
+#endif /* !HAVE_GTK2 */
+ exit (1);
+ }
+
+ return pb;
+}
+
+
+static void
+bevel_image (GdkPixbuf **pbP, int bevel_pct,
+ int x, int y, int w, int h)
+{
+ GdkPixbuf *pb = *pbP;
+
+ int bevel_size = (w > h ? h : w) * (bevel_pct / 100.0);
+
+ if (bevel_size < 10) /* too small to bother */
+ return;
+
+ /* Ensure the pixbuf has an alpha channel. */
+ if (! gdk_pixbuf_get_has_alpha (pb))
+ {
+ GdkPixbuf *pb2 = gdk_pixbuf_add_alpha (pb, FALSE, 0, 0, 0);
+ gdk_pixbuf_unref (pb);
+ pb = pb2;
+ }
+
+ {
+ guchar *data = gdk_pixbuf_get_pixels (pb);
+ guchar *line;
+ int rs = gdk_pixbuf_get_rowstride (pb);
+ int ch = gdk_pixbuf_get_n_channels (pb);
+ int xx, yy;
+ double *ramp = (double *) malloc (sizeof(*ramp) * (bevel_size + 1));
+
+ if (!ramp)
+ {
+ fprintf (stderr, "%s: out of memory (%d)\n", progname, bevel_size);
+ exit (1);
+ }
+
+ for (xx = 0; xx <= bevel_size; xx++)
+ {
+
+# if 0 /* linear */
+ ramp[xx] = xx / (double) bevel_size;
+
+# else /* sinusoidal */
+ double p = (xx / (double) bevel_size);
+ double s = sin (p * M_PI / 2);
+ ramp[xx] = s;
+# endif
+ }
+
+ line = data + (rs * y);
+ for (yy = 0; yy < h; yy++)
+ {
+ guchar *p = line + (x * ch);
+ for (xx = 0; xx < w; xx++)
+ {
+ double rx, ry, r;
+
+ if (xx < bevel_size) rx = ramp[xx];
+ else if (xx >= w - bevel_size) rx = ramp[w - xx - 1];
+ else rx = 1;
+
+ if (yy < bevel_size) ry = ramp[yy];
+ else if (yy >= h - bevel_size) ry = ramp[h - yy - 1];
+ else ry = 1;
+
+ r = rx * ry;
+ if (r != 1)
+ p[ch-1] *= r;
+
+ /* p[0]=p[1]=p[2]=0; / * #### */
+
+ p += ch;
+ }
+ line += rs;
+ }
+
+#if 0 /* show the ramp */
+ for (xx = 0; xx < bevel_size * 2; xx++)
+ {
+ int ii = (256 * (xx >= bevel_size ? 1 : ramp[xx]));
+ int yy;
+ for (yy = 0; yy < ii; yy++)
+ {
+ data [((y + (256-yy)) * rs) + ((x + xx) * ch) + 0] = 0;
+ data [((y + (256-yy)) * rs) + ((x + xx) * ch) + 1] = 0;
+ data [((y + (256-yy)) * rs) + ((x + xx) * ch) + 2] = 0;
+ data [((y + (256-yy)) * rs) + ((x + xx) * ch) + 3] = 255;
+ }
+ }
+#endif
+
+ free (ramp);
+
+ if (verbose_p)
+ fprintf (stderr, "%s: added %d%% bevel (%d px)\n", progname,
+ bevel_pct, bevel_size);
+ }
+
+ *pbP = pb;
+}
+