X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fxpm-ximage.c;h=615e0cd1672b4ce36d792a520df4a9e34542ca94;hb=8eb2873d7054e705c4e83f22d18c40946a9e2529;hp=6ac712f0851f7fcdda1a72233b96a39c4e0e8404;hpb=3210e7e80ee2b5a7d2049a5aaff9f17b9c93dcc9;p=xscreensaver diff --git a/hacks/glx/xpm-ximage.c b/hacks/glx/xpm-ximage.c index 6ac712f0..615e0cd1 100644 --- a/hacks/glx/xpm-ximage.c +++ b/hacks/glx/xpm-ximage.c @@ -1,5 +1,5 @@ /* xpm-ximage.c --- converts XPM data to an XImage for use with OpenGL. - * xscreensaver, Copyright (c) 1998 Jamie Zawinski + * xscreensaver, Copyright (c) 1998, 2001 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -8,21 +8,27 @@ * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. + * + * Alpha channel support by Eric Lassauge . */ #ifdef HAVE_CONFIG_H # include "config.h" #endif -#ifdef HAVE_XPM /* whole file */ - #include #include #include + +extern char *progname; + +#ifdef HAVE_XPM /* whole file */ + #include #include -extern char *progname; +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) static Bool bigendian (void) @@ -35,7 +41,7 @@ bigendian (void) /* Returns an XImage structure containing the bits of the given XPM image. This XImage will be 32 bits per pixel, 8 each per R, G, and B, with the - extra byte set to 0xFF. + extra byte set to either 0xFF or 0x00 (based on the XPM file's mask.) The Display and Visual arguments are used only for creating the XImage; no bits are pushed to the server. @@ -53,16 +59,19 @@ xpm_to_ximage (Display *dpy, Visual *visual, Colormap cmap, char **xpm_data) out the RGB values of the pixels ourselves; and construct an XImage by hand. Regardless of the depth of the visual we're using, this XImage will have 32 bits per pixel, 8 each per R, G, and B. We put - 0xFF in the fourth slot, as GL will interpret that as "alpha". + 0xFF or 0x00 in the fourth (alpha) slot, depending on the file's mask. */ XImage *ximage = 0; XpmImage xpm_image; XpmInfo xpm_info; int result; + int transparent_color_index = -1; int x, y, i; int bpl, wpl; - XColor colors[255]; + XColor colors[256]; + memset (&xpm_image, 0, sizeof(xpm_image)); + memset (&xpm_info, 0, sizeof(xpm_info)); result = XpmCreateXpmImageFromData (xpm_data, &xpm_image, &xpm_info); if (result != XpmSuccess) { @@ -71,6 +80,13 @@ xpm_to_ximage (Display *dpy, Visual *visual, Colormap cmap, char **xpm_data) exit (1); } + if (xpm_image.ncolors > countof(colors)) + { + fprintf (stderr, "%s: too many colors (%d) in XPM.\n", + progname, xpm_image.ncolors); + exit (1); + } + ximage = XCreateImage (dpy, visual, 32, ZPixmap, 0, 0, xpm_image.width, xpm_image.height, 32, 0); @@ -81,12 +97,26 @@ xpm_to_ximage (Display *dpy, Visual *visual, Colormap cmap, char **xpm_data) /* Parse the colors in the XPM into RGB values. */ for (i = 0; i < xpm_image.ncolors; i++) - if (!XParseColor(dpy, cmap, xpm_image.colorTable[i].c_color, &colors[i])) - { - fprintf(stderr, "%s: unparsable color: %s\n", progname, - xpm_image.colorTable[i].c_color); - exit(1); - } + { + const char *c = xpm_image.colorTable[i].c_color; + if (!c) + { + fprintf(stderr, "%s: bogus color table? ($d)\n", progname, i); + exit (1); + } + else if (!strncasecmp (c, "None", 4)) + { + transparent_color_index = i; + colors[transparent_color_index].red = 0xFF; + colors[transparent_color_index].green = 0xFF; + colors[transparent_color_index].blue = 0xFF; + } + else if (!XParseColor (dpy, cmap, c, &colors[i])) + { + fprintf(stderr, "%s: unparsable color: %s\n", progname, c); + exit (1); + } + } /* Translate the XpmImage to an RGB XImage. */ { @@ -112,11 +142,11 @@ xpm_to_ximage (Display *dpy, Visual *visual, Colormap cmap, char **xpm_data) for (x = 0; x < xpm_image.width; x++) { XColor *c = &colors[iline[x]]; - /* pack it as RGBA */ - oline[x] = (((c->red >> 8) << rpos) | - ((c->green >> 8) << gpos) | - ((c->blue >> 8) << bpos) | - (0xFF << apos)); + int alpha = ((iline[x] == transparent_color_index) ? 0x00 : 0xFF); + oline[x] = (((c->red >> 8) << rpos) | + ((c->green >> 8) << gpos) | + ((c->blue >> 8) << bpos) | + (alpha << apos)); } } } @@ -133,7 +163,7 @@ xpm_to_ximage (Display *dpy, Visual *visual, Colormap cmap, char **xpm_data) #else /* !HAVE_XPM */ -static XImage * +XImage * xpm_to_ximage (char **xpm_data) { fprintf(stderr, "%s: not compiled with XPM support.\n", progname);