summaryrefslogtreecommitdiff
path: root/src/xpm/create.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xpm/create.c')
-rw-r--r--src/xpm/create.c963
1 files changed, 963 insertions, 0 deletions
diff --git a/src/xpm/create.c b/src/xpm/create.c
new file mode 100644
index 0000000..238a2bb
--- /dev/null
+++ b/src/xpm/create.c
@@ -0,0 +1,963 @@
+/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */
+/*****************************************************************************\
+* create.c: *
+* *
+* XPM library *
+* Create an X image and possibly its related shape mask *
+* from the given xpmInternAttrib. *
+* *
+* Developed by Arnaud Le Hors *
+\*****************************************************************************/
+
+#include "xpmP.h"
+#ifdef VMS
+#include "sys$library:ctype.h"
+#else
+#include <ctype.h>
+#endif
+
+LFUNC(xpmVisualType, int, (Visual *visual));
+
+LFUNC(SetColor, int, (Display * display, Colormap colormap, char *colorname,
+ unsigned int color_index, Pixel * image_pixel,
+ Pixel * mask_pixel, unsigned int * mask_pixel_index,
+ Pixel ** pixels, unsigned int * npixels,
+ XpmAttributes *attributes));
+
+LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes,
+ char ***ct, unsigned int ncolors, Pixel *ip,
+ Pixel *mp, unsigned int *mask_pixel, Pixel **pixels,
+ unsigned int *npixels));
+
+LFUNC(CreateXImage, int, (Display * display, Visual * visual,
+ unsigned int depth, unsigned int width,
+ unsigned int height, XImage ** image_return));
+
+LFUNC(SetImagePixels, void, (XImage * image, unsigned int width,
+ unsigned int height, unsigned int *pixelindex,
+ Pixel * pixels));
+
+LFUNC(SetImagePixels32, void, (XImage * image, unsigned int width,
+ unsigned int height, unsigned int *pixelindex,
+ Pixel * pixels));
+
+LFUNC(SetImagePixels16, void, (XImage * image, unsigned int width,
+ unsigned int height, unsigned int *pixelindex,
+ Pixel * pixels));
+
+LFUNC(SetImagePixels8, void, (XImage * image, unsigned int width,
+ unsigned int height, unsigned int *pixelindex,
+ Pixel * pixels));
+
+LFUNC(SetImagePixels1, void, (XImage * image, unsigned int width,
+ unsigned int height, unsigned int *pixelindex,
+ Pixel * pixels));
+
+#ifdef NEED_STRCASECMP
+
+LFUNC(strcasecmp, int, (char *s1, char *s2));
+
+/*
+ * in case strcasecmp is not provided by the system here is one
+ * which does the trick
+ */
+static int
+strcasecmp(s1, s2)
+ register char *s1, *s2;
+{
+ register int c1, c2;
+
+ while (*s1 && *s2) {
+ c1 = isupper(*s1) ? tolower(*s1) : *s1;
+ c2 = isupper(*s2) ? tolower(*s2) : *s2;
+ if (c1 != c2)
+ return (1);
+ s1++;
+ s2++;
+ }
+ if (*s1 || *s2)
+ return (1);
+ return (0);
+}
+
+#endif
+
+/*
+ * return the default color key related to the given visual
+ */
+static int
+xpmVisualType(visual)
+ Visual *visual;
+{
+ switch (visual->class) {
+ case StaticGray:
+ case GrayScale:
+ switch (visual->map_entries) {
+ case 2:
+ return (MONO);
+ case 4:
+ return (GRAY4);
+ default:
+ return (GRAY);
+ }
+ default:
+ return (COLOR);
+ }
+}
+
+/*
+ * set the color pixel related to the given colorname,
+ * return 0 if success, 1 otherwise.
+ */
+
+static int
+SetColor(display, colormap, colorname, color_index,
+ image_pixel, mask_pixel, mask_pixel_index,
+ pixels, npixels, attributes)
+ Display *display;
+ Colormap colormap;
+ char *colorname;
+ unsigned int color_index;
+ Pixel *image_pixel, *mask_pixel;
+ unsigned int *mask_pixel_index;
+ Pixel **pixels;
+ unsigned int *npixels;
+ XpmAttributes *attributes;
+{
+ XColor xcolor;
+
+ if (strcasecmp(colorname, TRANSPARENT_COLOR)) {
+ if (!XParseColor(display, colormap, colorname, &xcolor)) return(1);
+ else if (!XAllocColor(display, colormap, &xcolor))
+ {
+ if (attributes && (attributes->valuemask & XpmCloseness) &&
+ attributes->closeness != 0)
+ {
+ XColor *cols;
+ unsigned int ncols,i,closepix;
+ long int closediff,closeness = attributes->closeness;
+
+ if (attributes && attributes->valuemask & XpmDepth)
+ ncols = 1 << attributes->depth;
+ else
+ ncols = 1 << DefaultDepth(display, DefaultScreen(display));
+
+ cols = (XColor*)calloc(ncols,sizeof(XColor));
+ for (i = 0; i < ncols; ++i) cols[i].pixel = i;
+ XQueryColors(display,colormap,cols,ncols);
+
+ for (i = 0, closediff = 0x7FFFFFFF; i < ncols; ++i)
+ {
+#define COLOR_FACTOR 3
+#define BRIGHTNESS_FACTOR 1
+
+ long int newclosediff =
+ COLOR_FACTOR * (
+ abs((long)xcolor.red - (long)cols[i].red) +
+ abs((long)xcolor.green - (long)cols[i].green) +
+ abs((long)xcolor.blue - (long)cols[i].blue)) +
+ BRIGHTNESS_FACTOR * abs(
+ ((long)xcolor.red+(long)xcolor.green+(long)xcolor.blue) -
+ ((long)cols[i].red+(long)cols[i].green+(long)cols[i].blue));
+
+ if (newclosediff < closediff)
+ { closepix = i; closediff = newclosediff; }
+ }
+
+ if ((long)cols[closepix].red >= (long)xcolor.red - closeness &&
+ (long)cols[closepix].red <= (long)xcolor.red + closeness &&
+ (long)cols[closepix].green >= (long)xcolor.green - closeness &&
+ (long)cols[closepix].green <= (long)xcolor.green + closeness &&
+ (long)cols[closepix].blue >= (long)xcolor.blue - closeness &&
+ (long)cols[closepix].blue <= (long)xcolor.blue + closeness)
+ {
+ xcolor = cols[closepix]; free(cols);
+ if (!XAllocColor(display, colormap, &xcolor)) return (1);
+ }
+ else { free(cols); return (1); }
+ }
+ else return (1);
+ }
+ *image_pixel = xcolor.pixel;
+ *mask_pixel = 1;
+ (*pixels)[*npixels] = xcolor.pixel;
+ (*npixels)++;
+ } else {
+ *image_pixel = 0;
+ *mask_pixel = 0;
+ *mask_pixel_index = color_index;/* store the color table index */
+ }
+ return (0);
+}
+
+static int
+CreateColors(display, attributes, ct, ncolors,
+ ip, mp, mask_pixel, pixels, npixels)
+ Display *display;
+ XpmAttributes *attributes;
+ char ***ct;
+ unsigned int ncolors;
+ Pixel *ip;
+ Pixel *mp;
+ unsigned int *mask_pixel; /* mask pixel index */
+ Pixel **pixels; /* allocated pixels */
+ unsigned int *npixels; /* number of allocated pixels */
+{
+ /* variables stored in the XpmAttributes structure */
+ Visual *visual;
+ Colormap colormap;
+ XpmColorSymbol *colorsymbols;
+ unsigned int numsymbols;
+
+ char *colorname;
+ unsigned int a, b, l;
+ Boolean pixel_defined;
+ unsigned int key;
+ XpmColorSymbol *cs;
+ char **cts;
+ int ErrorStatus = XpmSuccess;
+ char *s;
+ int cts_index;
+
+ /*
+ * retrieve information from the XpmAttributes
+ */
+ if (attributes && attributes->valuemask & XpmColorSymbols) {
+ colorsymbols = attributes->colorsymbols;
+ numsymbols = attributes->numsymbols;
+ } else
+ numsymbols = 0;
+
+ if (attributes && attributes->valuemask & XpmVisual)
+ visual = attributes->visual;
+ else
+ visual = DefaultVisual(display, DefaultScreen(display));
+
+ if (attributes && attributes->valuemask & XpmColormap)
+ colormap = attributes->colormap;
+ else
+ colormap = DefaultColormap(display, DefaultScreen(display));
+
+ key = xpmVisualType(visual);
+ switch(key)
+ {
+ case MONO: cts_index = 2; break;
+ case GRAY4: cts_index = 3; break;
+ case GRAY: cts_index = 4; break;
+ case COLOR: cts_index = 5; break;
+ }
+
+ for (a = 0; a < ncolors; a++, ct++, ip++, mp++) {
+ colorname = NULL;
+ pixel_defined = False;
+ cts = *ct;
+
+ /*
+ * look for a defined symbol
+ */
+ if (numsymbols && cts[1]) {
+ s = cts[1];
+ for (l = 0, cs = colorsymbols; l < numsymbols; l++, cs++)
+ if ((!cs->name && cs->value && cts[cts_index] &&
+ !strcasecmp(cs->value,cts[cts_index])) ||
+ cs->name && !strcmp(cs->name, s))
+ break;
+ if (l != numsymbols) {
+ if (cs->name && cs->value)
+ colorname = cs->value;
+ else
+ pixel_defined = True;
+ }
+ }
+ if (!pixel_defined) { /* pixel not given as symbol value */
+ if (colorname) { /* colorname given as symbol value */
+ if (!SetColor(display, colormap, colorname, a, ip, mp,
+ mask_pixel, pixels, npixels, attributes))
+ pixel_defined = True;
+ else
+ ErrorStatus = XpmColorError;
+ }
+ b = key;
+ while (!pixel_defined && b > 1) {
+ if (cts[b]) {
+ if (!SetColor(display, colormap, cts[b], a, ip, mp,
+ mask_pixel, pixels, npixels, attributes)) {
+ pixel_defined = True;
+ break;
+ } else
+ ErrorStatus = XpmColorError;
+ }
+ b--;
+ }
+ b = key + 1;
+ while (!pixel_defined && b < NKEYS + 1) {
+ if (cts[b]) {
+ if (!SetColor(display, colormap, cts[b], a, ip, mp,
+ mask_pixel, pixels, npixels, attributes)) {
+ pixel_defined = True;
+ break;
+ } else
+ ErrorStatus = XpmColorError;
+ }
+ b++;
+ }
+ if (!pixel_defined)
+ return (XpmColorFailed);
+ } else {
+ *ip = colorsymbols[l].pixel;
+ *mp = 1;
+ }
+ }
+ return (ErrorStatus);
+}
+
+/* function call in case of error, frees only locally allocated variables */
+#undef RETURN
+#ifdef Debug
+/*
+ * XDestroyImage free the image data but mnemosyne don't know about it
+ * so I free them by hand to avoid mnemalyse report it as lost data.
+ */
+#define RETURN(status) \
+ { if (image) { \
+ free(image->data); \
+ XDestroyImage(image); } \
+ if (shapeimage) { \
+ free(shapeimage->data); \
+ XDestroyImage(shapeimage); } \
+ if (image_pixels) free(image_pixels); \
+ if (mask_pixels) free(mask_pixels); \
+ if (npixels) XFreeColors(display, colormap, pixels, npixels, 0); \
+ if (pixels) free(pixels); \
+ return (status); }
+
+#else
+
+#define RETURN(status) \
+ { if (image) XDestroyImage(image); \
+ if (shapeimage) XDestroyImage(shapeimage); \
+ if (image_pixels) free(image_pixels); \
+ if (mask_pixels) free(mask_pixels); \
+ if (npixels) XFreeColors(display, colormap, pixels, npixels, 0); \
+ if (pixels) free(pixels); \
+ return (status); }
+
+#endif
+
+xpmCreateImage(display, attrib, image_return, shapeimage_return, attributes)
+ Display *display;
+ xpmInternAttrib *attrib;
+ XImage **image_return;
+ XImage **shapeimage_return;
+ XpmAttributes *attributes;
+{
+ /* variables stored in the XpmAttributes structure */
+ Visual *visual;
+ Colormap colormap;
+ unsigned int depth;
+
+ /* variables to return */
+ XImage *image = NULL;
+ XImage *shapeimage = NULL;
+ unsigned int mask_pixel;
+ int ErrorStatus;
+
+ /* calculation variables */
+ Pixel *image_pixels = NULL;
+ Pixel *mask_pixels = NULL;
+ Pixel *pixels = NULL; /* allocated pixels */
+ unsigned int npixels = 0; /* number of allocated pixels */
+
+ /*
+ * retrieve information from the XpmAttributes
+ */
+ if (attributes && attributes->valuemask & XpmVisual)
+ visual = attributes->visual;
+ else
+ visual = DefaultVisual(display, DefaultScreen(display));
+
+ if (attributes && attributes->valuemask & XpmColormap)
+ colormap = attributes->colormap;
+ else
+ colormap = DefaultColormap(display, DefaultScreen(display));
+
+ if (attributes && attributes->valuemask & XpmDepth)
+ depth = attributes->depth;
+ else
+ depth = DefaultDepth(display, DefaultScreen(display));
+
+ ErrorStatus = XpmSuccess;
+
+ /*
+ * malloc pixels index tables
+ */
+
+ image_pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors);
+ if (!image_pixels)
+ return(XpmNoMemory);
+
+ mask_pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors);
+ if (!mask_pixels)
+ RETURN(ErrorStatus);
+
+ mask_pixel = UNDEF_PIXEL;
+
+ /* maximum of allocated pixels will be the number of colors */
+ pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors);
+ if (!pixels)
+ RETURN(ErrorStatus);
+
+ /*
+ * get pixel colors, store them in index tables
+ */
+
+ ErrorStatus = CreateColors(display, attributes, attrib->colorTable,
+ attrib->ncolors, image_pixels, mask_pixels,
+ &mask_pixel, &pixels, &npixels);
+ if (ErrorStatus != XpmSuccess && (ErrorStatus < 0 || attributes &&
+ (attributes->valuemask & XpmExactColors) && attributes->exactColors))
+ RETURN(ErrorStatus);
+
+ /*
+ * create the image
+ */
+ if (image_return) {
+ ErrorStatus = CreateXImage(display, visual, depth,
+ attrib->width, attrib->height, &image);
+ if (ErrorStatus != XpmSuccess)
+ RETURN(ErrorStatus);
+
+ /*
+ * set the image data
+ *
+ * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use
+ * optimized functions, otherwise use slower but sure general one.
+ *
+ */
+
+ if (image->depth == 1)
+ SetImagePixels1(image, attrib->width, attrib->height,
+ attrib->pixelindex, image_pixels);
+ else if (image->bits_per_pixel == 8)
+ SetImagePixels8(image, attrib->width, attrib->height,
+ attrib->pixelindex, image_pixels);
+ else if (image->bits_per_pixel == 16)
+ SetImagePixels16(image, attrib->width, attrib->height,
+ attrib->pixelindex, image_pixels);
+ else if (image->bits_per_pixel == 32)
+ SetImagePixels32(image, attrib->width, attrib->height,
+ attrib->pixelindex, image_pixels);
+ else
+ SetImagePixels(image, attrib->width, attrib->height,
+ attrib->pixelindex, image_pixels);
+ }
+
+ /*
+ * create the shape mask image
+ */
+ if (mask_pixel != UNDEF_PIXEL && shapeimage_return) {
+ ErrorStatus = CreateXImage(display, visual, 1, attrib->width,
+ attrib->height, &shapeimage);
+ if (ErrorStatus != XpmSuccess)
+ RETURN(ErrorStatus);
+
+ SetImagePixels1(shapeimage, attrib->width, attrib->height,
+ attrib->pixelindex, mask_pixels);
+ }
+ free(mask_pixels);
+ free(pixels);
+
+ /*
+ * if requested store used pixels in the XpmAttributes structure
+ */
+ if (attributes &&
+ (attributes->valuemask & XpmReturnInfos
+ || attributes->valuemask & XpmReturnPixels)) {
+ if (mask_pixel != UNDEF_PIXEL) {
+ Pixel *pixels, *p1, *p2;
+ unsigned int a;
+
+ attributes->npixels = attrib->ncolors - 1;
+ pixels = (Pixel *) malloc(sizeof(Pixel) * attributes->npixels);
+ if (pixels) {
+ p1 = image_pixels;
+ p2 = pixels;
+ for (a = 0; a < attrib->ncolors; a++, p1++)
+ if (a != mask_pixel)
+ *p2++ = *p1;
+ attributes->pixels = pixels;
+ } else {
+ /* if error just say we can't return requested data */
+ attributes->valuemask &= ~XpmReturnPixels;
+ attributes->valuemask &= ~XpmReturnInfos;
+ attributes->pixels = NULL;
+ attributes->npixels = 0;
+ }
+ free(image_pixels);
+ } else {
+ attributes->pixels = image_pixels;
+ attributes->npixels = attrib->ncolors;
+ }
+ attributes->mask_pixel = mask_pixel;
+ } else
+ free(image_pixels);
+
+
+ /*
+ * return created images
+ */
+ if (image_return)
+ *image_return = image;
+
+ if (shapeimage_return)
+ *shapeimage_return = shapeimage;
+
+ return (ErrorStatus);
+}
+
+
+/*
+ * Create an XImage
+ */
+static int
+CreateXImage(display, visual, depth, width, height, image_return)
+ Display *display;
+ Visual *visual;
+ unsigned int depth;
+ unsigned int width;
+ unsigned int height;
+ XImage **image_return;
+{
+ int bitmap_pad;
+
+ /* first get bitmap_pad */
+ if (depth > 16)
+ bitmap_pad = 32;
+ else if (depth > 8)
+ bitmap_pad = 16;
+ else
+ bitmap_pad = 8;
+
+ /* then create the XImage with data = NULL and bytes_per_line = 0 */
+
+ *image_return = XCreateImage(display, visual, depth, ZPixmap, 0, 0,
+ width, height, bitmap_pad, 0);
+ if (!*image_return)
+ return (XpmNoMemory);
+
+ /* now that bytes_per_line must have been set properly alloc data */
+
+ (*image_return)->data =
+ (char *) malloc((*image_return)->bytes_per_line * height);
+
+ if (!(*image_return)->data) {
+ XDestroyImage(*image_return);
+ *image_return = NULL;
+ return (XpmNoMemory);
+ }
+ return (XpmSuccess);
+}
+
+
+/*
+ * The functions below are written from X11R5 MIT's code (XImUtil.c)
+ *
+ * The idea is to have faster functions than the standard XPutPixel function
+ * to build the image data. Indeed we can speed up things by suppressing tests
+ * performed for each pixel. We do the same tests but at the image level.
+ * We also assume that we use only ZPixmap images with null offsets.
+ */
+
+LFUNC(_putbits, void, (register char *src, int dstoffset,
+ register int numbits, register char *dst));
+
+LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register int nb));
+
+static unsigned char Const _reverse_byte[0x100] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+static int
+_XReverse_Bytes(bpt, nb)
+ register unsigned char *bpt;
+ register int nb;
+{
+ do {
+ *bpt = _reverse_byte[*bpt];
+ bpt++;
+ } while (--nb > 0);
+ return 0;
+}
+
+
+void
+xpm_xynormalizeimagebits(bp, img)
+ register unsigned char *bp;
+ register XImage *img;
+{
+ register unsigned char c;
+
+ if (img->byte_order != img->bitmap_bit_order) {
+ switch (img->bitmap_unit) {
+
+ case 16:
+ c = *bp;
+ *bp = *(bp + 1);
+ *(bp + 1) = c;
+ break;
+
+ case 32:
+ c = *(bp + 3);
+ *(bp + 3) = *bp;
+ *bp = c;
+ c = *(bp + 2);
+ *(bp + 2) = *(bp + 1);
+ *(bp + 1) = c;
+ break;
+ }
+ }
+ if (img->bitmap_bit_order == MSBFirst)
+ _XReverse_Bytes(bp, img->bitmap_unit >> 3);
+}
+
+void
+xpm_znormalizeimagebits(bp, img)
+ register unsigned char *bp;
+ register XImage *img;
+{
+ register unsigned char c;
+
+ switch (img->bits_per_pixel) {
+
+ case 4:
+ *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
+ break;
+
+ case 16:
+ c = *bp;
+ *bp = *(bp + 1);
+ *(bp + 1) = c;
+ break;
+
+ case 24:
+ c = *(bp + 2);
+ *(bp + 2) = *bp;
+ *bp = c;
+ break;
+
+ case 32:
+ c = *(bp + 3);
+ *(bp + 3) = *bp;
+ *bp = c;
+ c = *(bp + 2);
+ *(bp + 2) = *(bp + 1);
+ *(bp + 1) = c;
+ break;
+ }
+}
+
+static unsigned char Const _lomask[0x09] = {
+ 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+static unsigned char Const _himask[0x09] = {
+ 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
+
+static void
+_putbits(src, dstoffset, numbits, dst)
+ register char *src; /* address of source bit string */
+ int dstoffset; /* bit offset into destination;
+ * range is 0-31 */
+ register int numbits; /* number of bits to copy to
+ * destination */
+ register char *dst; /* address of destination bit string */
+{
+ register unsigned char chlo, chhi;
+ int hibits;
+
+ dst = dst + (dstoffset >> 3);
+ dstoffset = dstoffset & 7;
+ hibits = 8 - dstoffset;
+ chlo = *dst & _lomask[dstoffset];
+ for (;;) {
+ chhi = (*src << dstoffset) & _himask[dstoffset];
+ if (numbits <= hibits) {
+ chhi = chhi & _lomask[dstoffset + numbits];
+ *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
+ break;
+ }
+ *dst = chhi | chlo;
+ dst++;
+ numbits = numbits - hibits;
+ chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
+ src++;
+ if (numbits <= dstoffset) {
+ chlo = chlo & _lomask[numbits];
+ *dst = (*dst & _himask[numbits]) | chlo;
+ break;
+ }
+ numbits = numbits - dstoffset;
+ }
+}
+
+/*
+ * Default method to write pixels into a Z image data structure.
+ * The algorithm used is:
+ *
+ * copy the destination bitmap_unit or Zpixel to temp
+ * normalize temp if needed
+ * copy the pixel bits into the temp
+ * renormalize temp if needed
+ * copy the temp back into the destination image data
+ */
+
+static void
+SetImagePixels(image, width, height, pixelindex, pixels)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ unsigned int *pixelindex;
+ Pixel *pixels;
+{
+ register char *src;
+ register char *dst;
+ register unsigned int *iptr;
+ register int x, y, i;
+ register char *data;
+ Pixel pixel, px;
+ int nbytes, depth, ibu, ibpp;
+
+ data = image->data;
+ iptr = pixelindex;
+ depth = image->depth;
+ if (image->depth == 1) {
+ ibu = image->bitmap_unit;
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++) {
+ pixel = pixels[*iptr];
+ for (i = 0, px = pixel;
+ i < sizeof(unsigned long); i++, px >>= 8)
+ ((unsigned char *) &pixel)[i] = px;
+ src = &data[XYINDEX(x, y, image)];
+ dst = (char *) &px;
+ px = 0;
+ nbytes = ibu >> 3;
+ for (i = nbytes; --i >= 0;)
+ *dst++ = *src++;
+ XYNORMALIZE(&px, image);
+ _putbits((char *) &pixel, (x % ibu), 1, (char *) &px);
+ XYNORMALIZE(&px, image);
+ src = (char *) &px;
+ dst = &data[XYINDEX(x, y, image)];
+ for (i = nbytes; --i >= 0;)
+ *dst++ = *src++;
+ }
+ } else {
+ ibpp = image->bits_per_pixel;
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++) {
+ pixel = pixels[*iptr];
+ if (depth == 4)
+ pixel &= 0xf;
+ for (i = 0, px = pixel;
+ i < sizeof(unsigned long); i++, px >>= 8)
+ ((unsigned char *) &pixel)[i] = px;
+ src = &data[ZINDEX(x, y, image)];
+ dst = (char *) &px;
+ px = 0;
+ nbytes = (ibpp + 7) >> 3;
+ for (i = nbytes; --i >= 0;)
+ *dst++ = *src++;
+ ZNORMALIZE(&px, image);
+ _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
+ ZNORMALIZE(&px, image);
+ src = (char *) &px;
+ dst = &data[ZINDEX(x, y, image)];
+ for (i = nbytes; --i >= 0;)
+ *dst++ = *src++;
+ }
+ }
+}
+
+/*
+ * write pixels into a 32-bits Z image data structure
+ */
+
+#ifndef WORD64
+static unsigned long byteorderpixel = MSBFirst << 24;
+
+#endif
+
+static void
+SetImagePixels32(image, width, height, pixelindex, pixels)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ unsigned int *pixelindex;
+ Pixel *pixels;
+{
+ register unsigned char *addr;
+ register unsigned char *data;
+ register unsigned int *iptr;
+ register int x, y;
+ Pixel pixel;
+
+ data = (unsigned char *) image->data;
+ iptr = pixelindex;
+#ifndef WORD64
+ if (*((char *) &byteorderpixel) == image->byte_order) {
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++) {
+ addr = &data[ZINDEX32(x, y, image)];
+ *((unsigned long *)addr) = pixels[*iptr];
+ }
+ } else
+#endif
+ if (image->byte_order == MSBFirst)
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++) {
+ addr = &data[ZINDEX32(x, y, image)];
+ pixel = pixels[*iptr];
+ addr[0] = pixel >> 24;
+ addr[1] = pixel >> 16;
+ addr[2] = pixel >> 8;
+ addr[3] = pixel;
+ }
+ else
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++) {
+ addr = &data[ZINDEX32(x, y, image)];
+ pixel = pixels[*iptr];
+ addr[0] = pixel;
+ addr[1] = pixel >> 8;
+ addr[2] = pixel >> 16;
+ addr[3] = pixel >> 24;
+ }
+}
+
+/*
+ * write pixels into a 16-bits Z image data structure
+ */
+
+static void
+SetImagePixels16(image, width, height, pixelindex, pixels)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ unsigned int *pixelindex;
+ Pixel *pixels;
+{
+ register unsigned char *addr;
+ register unsigned char *data;
+ register unsigned int *iptr;
+ register int x, y;
+
+ data = (unsigned char *) image->data;
+ iptr = pixelindex;
+ if (image->byte_order == MSBFirst)
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++) {
+ addr = &data[ZINDEX16(x, y, image)];
+ addr[0] = pixels[*iptr] >> 8;
+ addr[1] = pixels[*iptr];
+ }
+ else
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++) {
+ addr = &data[ZINDEX16(x, y, image)];
+ addr[0] = pixels[*iptr];
+ addr[1] = pixels[*iptr] >> 8;
+ }
+}
+
+/*
+ * write pixels into a 8-bits Z image data structure
+ */
+
+static void
+SetImagePixels8(image, width, height, pixelindex, pixels)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ unsigned int *pixelindex;
+ Pixel *pixels;
+{
+ register char *data;
+ register unsigned int *iptr;
+ register int x, y;
+
+ data = image->data;
+ iptr = pixelindex;
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++)
+ data[ZINDEX8(x, y, image)] = pixels[*iptr];
+}
+
+/*
+ * write pixels into a 1-bit depth image data structure and **offset null**
+ */
+
+static void
+SetImagePixels1(image, width, height, pixelindex, pixels)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ unsigned int *pixelindex;
+ Pixel *pixels;
+{
+ register unsigned int *iptr;
+ register int x, y;
+ register char *data;
+
+ if (image->byte_order != image->bitmap_bit_order)
+ SetImagePixels(image, width, height, pixelindex, pixels);
+ else {
+ data = image->data;
+ iptr = pixelindex;
+ if (image->bitmap_bit_order == MSBFirst)
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++) {
+ if (pixels[*iptr] & 1)
+ data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7);
+ else
+ data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7));
+ }
+ else
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++) {
+ if (pixels[*iptr] & 1)
+ data[ZINDEX1(x, y, image)] |= 1 << (x & 7);
+ else
+ data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7));
+ }
+ }
+}