home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / xpm-3.2a / create.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-16  |  23.4 KB  |  902 lines

  1. /* Copyright 1990,91 GROUPE BULL -- See license conditions in file COPYRIGHT */
  2. /*****************************************************************************\
  3. * create.c:                                                                   *
  4. *                                                                             *
  5. *  XPM library                                                                *
  6. *  Create an X image and possibly its related shape mask                     *
  7. *  from the given xpmInternAttrib.                                            *
  8. *                                                                             *
  9. *  Developed by Arnaud Le Hors                                                *
  10. \*****************************************************************************/
  11.  
  12. #include "xpmP.h"
  13. #ifdef VMS
  14. #include "sys$library:ctype.h"
  15. #else
  16. #include <ctype.h>
  17. #endif
  18.  
  19. LFUNC(xpmVisualType, int, (Visual *visual));
  20.  
  21. LFUNC(SetColor, int, (Display * display, Colormap colormap, char *colorname,
  22.               unsigned int color_index, Pixel * image_pixel,
  23.               Pixel * mask_pixel, unsigned int * mask_pixel_index,
  24.               Pixel ** pixels, unsigned int * npixels));
  25.  
  26. LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes,
  27.               char ***ct, unsigned int ncolors, Pixel *ip,
  28.               Pixel *mp, unsigned int *mask_pixel, Pixel **pixels,
  29.               unsigned int *npixels));
  30.  
  31. LFUNC(CreateXImage, int, (Display * display, Visual * visual,
  32.               unsigned int depth, unsigned int width,
  33.               unsigned int height, XImage ** image_return));
  34.  
  35. LFUNC(SetImagePixels, int, (XImage * image, unsigned int width,
  36.                 unsigned int height, unsigned int *pixelindex,
  37.                 Pixel * pixels));
  38.  
  39. LFUNC(SetImagePixels32, int, (XImage * image, unsigned int width,
  40.                   unsigned int height, unsigned int *pixelindex,
  41.                   Pixel * pixels));
  42.  
  43. LFUNC(SetImagePixels16, int, (XImage * image, unsigned int width,
  44.                   unsigned int height, unsigned int *pixelindex,
  45.                   Pixel * pixels));
  46.  
  47. LFUNC(SetImagePixels8, int, (XImage * image, unsigned int width,
  48.                  unsigned int height, unsigned int *pixelindex,
  49.                  Pixel * pixels));
  50.  
  51. LFUNC(SetImagePixels1, int, (XImage * image, unsigned int width,
  52.                  unsigned int height, unsigned int *pixelindex,
  53.                  Pixel * pixels));
  54.  
  55. #ifdef NEED_STRCASECMP
  56.  
  57. LFUNC(strcasecmp, int, (char *s1, char *s2));
  58.  
  59. /*
  60.  * in case strcasecmp is not provided by the system here is one
  61.  * which does the trick
  62.  */
  63. static int
  64. strcasecmp(s1, s2)
  65.     register char *s1, *s2;
  66. {
  67.     register int c1, c2;
  68.  
  69.     while (*s1 && *s2) {
  70.     c1 = isupper(*s1) ? tolower(*s1) : *s1;
  71.     c2 = isupper(*s2) ? tolower(*s2) : *s2;
  72.     if (c1 != c2)
  73.         return (1);
  74.     s1++;
  75.     s2++;
  76.     }
  77.     if (*s1 || *s2)
  78.     return (1);
  79.     return (0);
  80. }
  81.  
  82. #endif
  83.  
  84. /*
  85.  * return the default color key related to the given visual 
  86.  */
  87. static int
  88. xpmVisualType(visual)
  89.     Visual *visual;
  90. {
  91.     switch (visual->class) {
  92.     case StaticGray:
  93.     case GrayScale:
  94.     switch (visual->map_entries) {
  95.     case 2:
  96.         return (MONO);
  97.     case 4:
  98.         return (GRAY4);
  99.     default:
  100.         return (GRAY);
  101.     }
  102.     default:
  103.     return (COLOR);
  104.     }
  105. }
  106.  
  107. /*
  108.  * set the color pixel related to the given colorname,
  109.  * return 0 if success, 1 otherwise.
  110.  */
  111.  
  112. static int
  113. SetColor(display, colormap, colorname, color_index,
  114.      image_pixel, mask_pixel, mask_pixel_index,
  115.      pixels, npixels)
  116.     Display *display;
  117.     Colormap colormap;
  118.     char *colorname;
  119.     unsigned int color_index;
  120.     Pixel *image_pixel, *mask_pixel;
  121.     unsigned int *mask_pixel_index;
  122.     Pixel **pixels;
  123.     unsigned int *npixels;
  124. {
  125.     XColor xcolor;
  126.  
  127.     if (strcasecmp(colorname, TRANSPARENT_COLOR)) {
  128.     if (!XParseColor(display, colormap, colorname, &xcolor)
  129.         || (!XAllocColor(display, colormap, &xcolor)))
  130.         return (1);
  131.     *image_pixel = xcolor.pixel;
  132.     *mask_pixel = 1;
  133.     (*pixels)[*npixels] = xcolor.pixel;
  134.     (*npixels)++;
  135.     } else {
  136.     *image_pixel = 0;
  137.     *mask_pixel = 0;
  138.     *mask_pixel_index = color_index;/* store the color table index */
  139.     }
  140.     return (0);
  141. }
  142.  
  143. static int
  144. CreateColors(display, attributes, ct, ncolors,
  145.          ip, mp, mask_pixel, pixels, npixels)
  146.     Display *display;
  147.     XpmAttributes *attributes;
  148.     char ***ct;
  149.     unsigned int ncolors;
  150.     Pixel *ip;
  151.     Pixel *mp;
  152.     unsigned int *mask_pixel;        /* mask pixel index */
  153.     Pixel **pixels;            /* allocated pixels */
  154.     unsigned int *npixels;        /* number of allocated pixels */
  155. {
  156.     /* variables stored in the XpmAttributes structure */
  157.     Visual *visual;
  158.     Colormap colormap;
  159.     XpmColorSymbol *colorsymbols;
  160.     unsigned int numsymbols;
  161.  
  162.     char *colorname;
  163.     unsigned int a, b, l;
  164.     Boolean pixel_defined;
  165.     unsigned int key;
  166.     XpmColorSymbol *cs;
  167.     char **cts;
  168.     unsigned int ErrorStatus = XpmSuccess;
  169.     char *s;
  170.  
  171.     /*
  172.      * retrieve information from the XpmAttributes 
  173.      */
  174.     if (attributes && attributes->valuemask & XpmColorSymbols) {
  175.     colorsymbols = attributes->colorsymbols;
  176.     numsymbols = attributes->numsymbols;
  177.     } else
  178.     numsymbols = 0;
  179.  
  180.     if (attributes && attributes->valuemask & XpmVisual)
  181.     visual = attributes->visual;
  182.     else
  183.     visual = DefaultVisual(display, DefaultScreen(display));
  184.  
  185.     if (attributes && attributes->valuemask & XpmColormap)
  186.     colormap = attributes->colormap;
  187.     else
  188.     colormap = DefaultColormap(display, DefaultScreen(display));
  189.  
  190.     key = xpmVisualType(visual);
  191.     for (a = 0; a < ncolors; a++, ct++, ip++, mp++) {
  192.     colorname = NULL;
  193.     pixel_defined = False;
  194.     cts = *ct;
  195.  
  196.     /*
  197.      * look for a defined symbol 
  198.      */
  199.     if (numsymbols && cts[1]) {
  200.         s = cts[1];
  201.         for (l = 0, cs = colorsymbols; l < numsymbols; l++, cs++)
  202.         if (!strcmp(cs->name, s))
  203.             break;
  204.         if (l != numsymbols) {
  205.         if (cs->value)
  206.             colorname = cs->value;
  207.         else
  208.             pixel_defined = True;
  209.         }
  210.     }
  211.     if (!pixel_defined) {        /* pixel not given as symbol value */
  212.         if (colorname) {        /* colorname given as symbol value */
  213.         if (!SetColor(display, colormap, colorname, a, ip, mp,
  214.                   mask_pixel, pixels, npixels))
  215.             pixel_defined = True;
  216.         else
  217.             ErrorStatus = XpmColorError;
  218.         }
  219.         b = key;
  220.         while (!pixel_defined && b > 1) {
  221.         if (cts[b]) {
  222.             if (!SetColor(display, colormap, cts[b], a, ip, mp,
  223.                   mask_pixel, pixels, npixels)) {
  224.             pixel_defined = True;
  225.             break;
  226.             } else
  227.             ErrorStatus = XpmColorError;
  228.         }
  229.         b--;
  230.         }
  231.         b = key + 1;
  232.         while (!pixel_defined && b < NKEYS + 1) {
  233.         if (cts[b]) {
  234.             if (!SetColor(display, colormap, cts[b], a, ip, mp,
  235.                   mask_pixel, pixels, npixels)) {
  236.             pixel_defined = True;
  237.             break;
  238.             } else
  239.             ErrorStatus = XpmColorError;
  240.         }
  241.         b++;
  242.         }
  243.         if (!pixel_defined)
  244.         return (XpmColorFailed);
  245.     } else {
  246.         *ip = colorsymbols[l].pixel;
  247.         *mp = 1;
  248.     }
  249.     }
  250.     return (ErrorStatus);
  251. }    
  252.  
  253. /* function call in case of error, frees only locally allocated variables */
  254. #undef RETURN
  255. #ifdef Debug
  256. /*
  257.  * XDestroyImage free the image data but mnemosyne don't know about it
  258.  * so I free them by hand to avoid mnemalyse report it as lost data.
  259.  */
  260. #define RETURN(status) \
  261.     { if (image) { \
  262.     free(image->data); \
  263.     XDestroyImage(image); } \
  264.     if (shapeimage) { \
  265.     free(shapeimage->data); \
  266.     XDestroyImage(shapeimage); } \
  267.     if (image_pixels) free(image_pixels); \
  268.     if (mask_pixels) free(mask_pixels); \
  269.     if (npixels) XFreeColors(display, colormap, pixels, npixels, 0); \
  270.     if (pixels) free(pixels); \
  271.     return (status); }
  272.  
  273. #else
  274.  
  275. #define RETURN(status) \
  276.     { if (image) XDestroyImage(image); \
  277.     if (shapeimage) XDestroyImage(shapeimage); \
  278.     if (image_pixels) free(image_pixels); \
  279.     if (mask_pixels) free(mask_pixels); \
  280.     if (npixels) XFreeColors(display, colormap, pixels, npixels, 0); \
  281.     if (pixels) free(pixels); \
  282.     return (status); }
  283.  
  284. #endif
  285.  
  286. xpmCreateImage(display, attrib, image_return, shapeimage_return, attributes)
  287.     Display *display;
  288.     xpmInternAttrib *attrib;
  289.     XImage **image_return;
  290.     XImage **shapeimage_return;
  291.     XpmAttributes *attributes;
  292. {
  293.     /* variables stored in the XpmAttributes structure */
  294.     Visual *visual;
  295.     Colormap colormap;
  296.     unsigned int depth;
  297.  
  298.     /* variables to return */
  299.     XImage *image = NULL;
  300.     XImage *shapeimage = NULL;
  301.     unsigned int mask_pixel;
  302.     unsigned int ErrorStatus;
  303.  
  304.     /* calculation variables */
  305.     Pixel *image_pixels = NULL;
  306.     Pixel *mask_pixels = NULL;
  307.     Pixel *pixels = NULL;        /* allocated pixels */
  308.     unsigned int npixels = 0;        /* number of allocated pixels */
  309.  
  310.     /*
  311.      * retrieve information from the XpmAttributes 
  312.      */
  313.     if (attributes && attributes->valuemask & XpmVisual)
  314.     visual = attributes->visual;
  315.     else
  316.     visual = DefaultVisual(display, DefaultScreen(display));
  317.  
  318.     if (attributes && attributes->valuemask & XpmColormap)
  319.     colormap = attributes->colormap;
  320.     else
  321.     colormap = DefaultColormap(display, DefaultScreen(display));
  322.  
  323.     if (attributes && attributes->valuemask & XpmDepth)
  324.     depth = attributes->depth;
  325.     else
  326.     depth = DefaultDepth(display, DefaultScreen(display));
  327.  
  328.     ErrorStatus = XpmSuccess;
  329.  
  330.     /*
  331.      * malloc pixels index tables 
  332.      */
  333.  
  334.     image_pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors);
  335.     if (!image_pixels)
  336.     return(XpmNoMemory);
  337.  
  338.     mask_pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors);
  339.     if (!mask_pixels)
  340.     RETURN(ErrorStatus);
  341.  
  342.     mask_pixel = UNDEF_PIXEL;
  343.  
  344.     /* maximum of allocated pixels will be the number of colors */
  345.     pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors);
  346.     if (!pixels)
  347.     RETURN(ErrorStatus);
  348.  
  349.     /*
  350.      * get pixel colors, store them in index tables 
  351.      */
  352.  
  353.     ErrorStatus = CreateColors(display, attributes, attrib->colorTable,
  354.                    attrib->ncolors, image_pixels, mask_pixels,
  355.                    &mask_pixel, &pixels, &npixels);
  356.     if (ErrorStatus != XpmSuccess)
  357.     RETURN(ErrorStatus);
  358.  
  359.     /*
  360.      * create the image 
  361.      */
  362.     if (image_return) {
  363.     ErrorStatus = CreateXImage(display, visual, depth,
  364.                     attrib->width, attrib->height, &image);
  365.     if (ErrorStatus != XpmSuccess)
  366.         RETURN(ErrorStatus);
  367.  
  368.     /*
  369.      * set the image data 
  370.      *
  371.      * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use
  372.      * optimized functions, otherwise use slower but sure general one. 
  373.      *
  374.      */
  375.  
  376.     if (image->depth == 1)
  377.         SetImagePixels1(image, attrib->width, attrib->height,
  378.                 attrib->pixelindex, image_pixels);
  379.     else if (image->bits_per_pixel == 8)
  380.         SetImagePixels8(image, attrib->width, attrib->height,
  381.                 attrib->pixelindex, image_pixels);
  382.     else if (image->bits_per_pixel == 16)
  383.         SetImagePixels16(image, attrib->width, attrib->height,
  384.                  attrib->pixelindex, image_pixels);
  385.     else if (image->bits_per_pixel == 32)
  386.         SetImagePixels32(image, attrib->width, attrib->height,
  387.                  attrib->pixelindex, image_pixels);
  388.     else
  389.         SetImagePixels(image, attrib->width, attrib->height,
  390.                attrib->pixelindex, image_pixels);
  391.     }
  392.  
  393.     /*
  394.      * create the shape mask image 
  395.      */
  396.     if (mask_pixel != UNDEF_PIXEL && shapeimage_return) {
  397.     ErrorStatus = CreateXImage(display, visual, 1, attrib->width,
  398.                     attrib->height, &shapeimage);
  399.     if (ErrorStatus != XpmSuccess)
  400.         RETURN(ErrorStatus);
  401.  
  402.     SetImagePixels1(shapeimage, attrib->width, attrib->height,
  403.             attrib->pixelindex, mask_pixels);
  404.     }
  405.     free(mask_pixels);
  406.     free(pixels);
  407.  
  408.     /*
  409.      * if requested store used pixels in the XpmAttributes structure 
  410.      */
  411.     if (attributes &&
  412.     (attributes->valuemask & XpmReturnInfos
  413.      || attributes->valuemask & XpmReturnPixels)) {
  414.     if (mask_pixel != UNDEF_PIXEL) {
  415.         Pixel *pixels, *p1, *p2;
  416.         unsigned int a;
  417.  
  418.         attributes->npixels = attrib->ncolors - 1;
  419.         pixels = (Pixel *) malloc(sizeof(Pixel) * attributes->npixels);
  420.         if (pixels) {
  421.         p1 = image_pixels;
  422.         p2 = pixels;
  423.         for (a = 0; a < attrib->ncolors; a++, p1++)
  424.             if (a != mask_pixel)
  425.             *p2++ = *p1;
  426.         attributes->pixels = pixels;
  427.         } else {
  428.         /* if error just say we can't return requested data */
  429.         attributes->valuemask &= ~XpmReturnPixels;
  430.         attributes->valuemask &= ~XpmReturnInfos;
  431.         attributes->pixels = NULL;
  432.         attributes->npixels = 0;
  433.         }
  434.         free(image_pixels);
  435.     } else {
  436.         attributes->pixels = image_pixels;
  437.         attributes->npixels = attrib->ncolors;
  438.     }
  439.     attributes->mask_pixel = mask_pixel;
  440.     } else
  441.     free(image_pixels);
  442.  
  443.  
  444.     /*
  445.      * return created images 
  446.      */
  447.     if (image_return)
  448.     *image_return = image;
  449.  
  450.     if (shapeimage_return)
  451.     *shapeimage_return = shapeimage;
  452.  
  453.     return (ErrorStatus);
  454. }
  455.  
  456.  
  457. /*
  458.  * Create an XImage
  459.  */
  460. static int
  461. CreateXImage(display, visual, depth, width, height, image_return)
  462.     Display *display;
  463.     Visual *visual;
  464.     unsigned int depth;
  465.     unsigned int width;
  466.     unsigned int height;
  467.     XImage **image_return;
  468. {
  469.     int bitmap_pad;
  470.  
  471.     /* first get bitmap_pad */
  472.     if (depth > 16)
  473.     bitmap_pad = 32;
  474.     else if (depth > 8)
  475.     bitmap_pad = 16;
  476.     else
  477.     bitmap_pad = 8;
  478.  
  479.     /* then create the XImage with data = NULL and bytes_per_line = 0 */
  480.  
  481.     *image_return = XCreateImage(display, visual, depth, ZPixmap, 0, 0,
  482.                  width, height, bitmap_pad, 0);
  483.     if (!*image_return)
  484.     return (XpmNoMemory);
  485.  
  486.     /* now that bytes_per_line must have been set properly alloc data */
  487.  
  488.     (*image_return)->data =
  489.     (char *) malloc((*image_return)->bytes_per_line * height);
  490.  
  491.     if (!(*image_return)->data) {
  492.     XDestroyImage(*image_return);
  493.     *image_return = NULL;
  494.     return (XpmNoMemory);
  495.     }
  496.     return (XpmSuccess);
  497. }
  498.  
  499.  
  500. /*
  501.  * The functions below are written from X11R5 MIT's code (XImUtil.c)
  502.  *
  503.  * The idea is to have faster functions than the standard XPutPixel function
  504.  * to build the image data. Indeed we can speed up things by suppressing tests
  505.  * performed for each pixel. We do the same tests but at the image level.
  506.  * We also assume that we use only ZPixmap images with null offsets.
  507.  */
  508.  
  509. LFUNC(_putbits, int, (register char *src, int dstoffset,
  510.               register int numbits, register char *dst));
  511.  
  512. LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register int nb));
  513.  
  514. static unsigned char Const _reverse_byte[0x100] = {
  515.                 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  516.                 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  517.                 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  518.                 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  519.                 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  520.                 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  521.                 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  522.                 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  523.                 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  524.                 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  525.                 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  526.                 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  527.                 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  528.                 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  529.                 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  530.                 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  531.                 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  532.                 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  533.                 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  534.                 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  535.                 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  536.                 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  537.                 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  538.                 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  539.                 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  540.                 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  541.                 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  542.                 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  543.                 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  544.                 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  545.                 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  546.                  0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
  547. };
  548.  
  549. static int
  550. _XReverse_Bytes(bpt, nb)
  551.     register unsigned char *bpt;
  552.     register int nb;
  553. {
  554.     do {
  555.     *bpt = _reverse_byte[*bpt];
  556.     bpt++;
  557.     } while (--nb > 0);
  558.     return;
  559. }
  560.  
  561.  
  562. int
  563. xpm_xynormalizeimagebits(bp, img)
  564.     register unsigned char *bp;
  565.     register XImage *img;
  566. {
  567.     register unsigned char c;
  568.  
  569.     if (img->byte_order != img->bitmap_bit_order) {
  570.     switch (img->bitmap_unit) {
  571.  
  572.     case 16:
  573.         c = *bp;
  574.         *bp = *(bp + 1);
  575.         *(bp + 1) = c;
  576.         break;
  577.  
  578.     case 32:
  579.         c = *(bp + 3);
  580.         *(bp + 3) = *bp;
  581.         *bp = c;
  582.         c = *(bp + 2);
  583.         *(bp + 2) = *(bp + 1);
  584.         *(bp + 1) = c;
  585.         break;
  586.     }
  587.     }
  588.     if (img->bitmap_bit_order == MSBFirst)
  589.     _XReverse_Bytes(bp, img->bitmap_unit >> 3);
  590. }
  591.  
  592. int
  593. xpm_znormalizeimagebits(bp, img)
  594.     register unsigned char *bp;
  595.     register XImage *img;
  596. {
  597.     register unsigned char c;
  598.  
  599.     switch (img->bits_per_pixel) {
  600.  
  601.     case 4:
  602.     *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
  603.     break;
  604.  
  605.     case 16:
  606.     c = *bp;
  607.     *bp = *(bp + 1);
  608.     *(bp + 1) = c;
  609.     break;
  610.  
  611.     case 24:
  612.     c = *(bp + 2);
  613.     *(bp + 2) = *bp;
  614.     *bp = c;
  615.     break;
  616.  
  617.     case 32:
  618.     c = *(bp + 3);
  619.     *(bp + 3) = *bp;
  620.     *bp = c;
  621.     c = *(bp + 2);
  622.     *(bp + 2) = *(bp + 1);
  623.     *(bp + 1) = c;
  624.     break;
  625.     }
  626. }
  627.  
  628. static unsigned char Const _lomask[0x09] = {
  629.              0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
  630. static unsigned char Const _himask[0x09] = {
  631.              0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
  632.  
  633. static
  634. _putbits(src, dstoffset, numbits, dst)
  635.     register char *src;            /* address of source bit string */
  636.     int dstoffset;            /* bit offset into destination;
  637.                      * range is 0-31 */
  638.     register int numbits;        /* number of bits to copy to
  639.                      * destination */
  640.     register char *dst;            /* address of destination bit string */
  641. {
  642.     register unsigned char chlo, chhi;
  643.     int hibits;
  644.  
  645.     dst = dst + (dstoffset >> 3);
  646.     dstoffset = dstoffset & 7;
  647.     hibits = 8 - dstoffset;
  648.     chlo = *dst & _lomask[dstoffset];
  649.     for (;;) {
  650.     chhi = (*src << dstoffset) & _himask[dstoffset];
  651.     if (numbits <= hibits) {
  652.         chhi = chhi & _lomask[dstoffset + numbits];
  653.         *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
  654.         break;
  655.     }
  656.     *dst = chhi | chlo;
  657.     dst++;
  658.     numbits = numbits - hibits;
  659.     chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
  660.     src++;
  661.     if (numbits <= dstoffset) {
  662.         chlo = chlo & _lomask[numbits];
  663.         *dst = (*dst & _himask[numbits]) | chlo;
  664.         break;
  665.     }
  666.     numbits = numbits - dstoffset;
  667.     }
  668. }
  669.  
  670. /*
  671.  * Default method to write pixels into a Z image data structure.
  672.  * The algorithm used is:
  673.  *
  674.  *    copy the destination bitmap_unit or Zpixel to temp
  675.  *    normalize temp if needed
  676.  *    copy the pixel bits into the temp
  677.  *    renormalize temp if needed
  678.  *    copy the temp back into the destination image data
  679.  */
  680.  
  681. static int
  682. SetImagePixels(image, width, height, pixelindex, pixels)
  683.     XImage *image;
  684.     unsigned int width;
  685.     unsigned int height;
  686.     unsigned int *pixelindex;
  687.     Pixel *pixels;
  688. {
  689.     register char *src;
  690.     register char *dst;
  691.     register unsigned int *iptr;
  692.     register int x, y, i;
  693.     register char *data;
  694.     Pixel pixel, px;
  695.     int nbytes, depth, ibu, ibpp;
  696.  
  697.     data = image->data;
  698.     iptr = pixelindex;
  699.     depth = image->depth;
  700.     if (image->depth == 1) {
  701.     ibu = image->bitmap_unit;
  702.     for (y = 0; y < height; y++)
  703.         for (x = 0; x < width; x++, iptr++) {
  704.         pixel = pixels[*iptr];
  705.         for (i = 0, px = pixel;
  706.              i < sizeof(unsigned long); i++, px >>= 8)
  707.             ((unsigned char *) &pixel)[i] = px;
  708.         src = &data[XYINDEX(x, y, image)];
  709.         dst = (char *) &px;
  710.         px = 0;
  711.         nbytes = ibu >> 3;
  712.         for (i = nbytes; --i >= 0;)
  713.             *dst++ = *src++;
  714.         XYNORMALIZE(&px, image);
  715.         _putbits((char *) &pixel, (x % ibu), 1, (char *) &px);
  716.         XYNORMALIZE(&px, image);
  717.         src = (char *) &px;
  718.         dst = &data[XYINDEX(x, y, image)];
  719.         for (i = nbytes; --i >= 0;)
  720.             *dst++ = *src++;
  721.         }
  722.     } else {
  723.     ibpp = image->bits_per_pixel;
  724.     for (y = 0; y < height; y++)
  725.         for (x = 0; x < width; x++, iptr++) {
  726.         pixel = pixels[*iptr];
  727.         if (depth == 4)
  728.             pixel &= 0xf;
  729.         for (i = 0, px = pixel;
  730.              i < sizeof(unsigned long); i++, px >>= 8)
  731.             ((unsigned char *) &pixel)[i] = px;
  732.         src = &data[ZINDEX(x, y, image)];
  733.         dst = (char *) &px;
  734.         px = 0;
  735.         nbytes = (ibpp + 7) >> 3;
  736.         for (i = nbytes; --i >= 0;)
  737.             *dst++ = *src++;
  738.         ZNORMALIZE(&px, image);
  739.         _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
  740.         ZNORMALIZE(&px, image);
  741.         src = (char *) &px;
  742.         dst = &data[ZINDEX(x, y, image)];
  743.         for (i = nbytes; --i >= 0;)
  744.             *dst++ = *src++;
  745.         }
  746.     }
  747. }
  748.  
  749. /*
  750.  * write pixels into a 32-bits Z image data structure
  751.  */
  752.  
  753. #ifndef WORD64
  754. static unsigned long byteorderpixel = MSBFirst << 24;
  755.  
  756. #endif
  757.  
  758. static int
  759. SetImagePixels32(image, width, height, pixelindex, pixels)
  760.     XImage *image;
  761.     unsigned int width;
  762.     unsigned int height;
  763.     unsigned int *pixelindex;
  764.     Pixel *pixels;
  765. {
  766.     register unsigned char *addr;
  767.     register unsigned char *data;
  768.     register unsigned int *iptr;
  769.     register int x, y;
  770.     Pixel pixel;
  771.  
  772.     data = (unsigned char *) image->data;
  773.     iptr = pixelindex;
  774. #ifndef WORD64
  775.     if (*((char *) &byteorderpixel) == image->byte_order) {
  776.     for (y = 0; y < height; y++)
  777.         for (x = 0; x < width; x++, iptr++) {
  778.         addr = &data[ZINDEX32(x, y, image)];
  779.         *((unsigned long *)addr) = pixels[*iptr];
  780.         }
  781.     } else
  782. #endif
  783.     if (image->byte_order == MSBFirst)
  784.     for (y = 0; y < height; y++)
  785.         for (x = 0; x < width; x++, iptr++) {
  786.         addr = &data[ZINDEX32(x, y, image)];
  787.         pixel = pixels[*iptr];
  788.         addr[0] = pixel >> 24;
  789.         addr[1] = pixel >> 16;
  790.         addr[2] = pixel >> 8;
  791.         addr[3] = pixel;
  792.         }
  793.     else
  794.     for (y = 0; y < height; y++)
  795.         for (x = 0; x < width; x++, iptr++) {
  796.         addr = &data[ZINDEX32(x, y, image)];
  797.         pixel = pixels[*iptr];
  798.         addr[0] = pixel;
  799.         addr[1] = pixel >> 8;
  800.         addr[2] = pixel >> 16;
  801.         addr[3] = pixel >> 24;
  802.         }
  803. }
  804.  
  805. /*
  806.  * write pixels into a 16-bits Z image data structure
  807.  */
  808.  
  809. static int
  810. SetImagePixels16(image, width, height, pixelindex, pixels)
  811.     XImage *image;
  812.     unsigned int width;
  813.     unsigned int height;
  814.     unsigned int *pixelindex;
  815.     Pixel *pixels;
  816. {
  817.     register unsigned char *addr;
  818.     register unsigned char *data;
  819.     register unsigned int *iptr;
  820.     register int x, y;
  821.  
  822.     data = (unsigned char *) image->data;
  823.     iptr = pixelindex;
  824.     if (image->byte_order == MSBFirst)
  825.     for (y = 0; y < height; y++)
  826.         for (x = 0; x < width; x++, iptr++) {
  827.         addr = &data[ZINDEX16(x, y, image)];
  828.         addr[0] = pixels[*iptr] >> 8;
  829.         addr[1] = pixels[*iptr];
  830.         }
  831.     else
  832.     for (y = 0; y < height; y++)
  833.         for (x = 0; x < width; x++, iptr++) {
  834.         addr = &data[ZINDEX16(x, y, image)];
  835.         addr[0] = pixels[*iptr];
  836.         addr[1] = pixels[*iptr] >> 8;
  837.         }
  838. }
  839.  
  840. /*
  841.  * write pixels into a 8-bits Z image data structure
  842.  */
  843.  
  844. static int
  845. SetImagePixels8(image, width, height, pixelindex, pixels)
  846.     XImage *image;
  847.     unsigned int width;
  848.     unsigned int height;
  849.     unsigned int *pixelindex;
  850.     Pixel *pixels;
  851. {
  852.     register char *data;
  853.     register unsigned int *iptr;
  854.     register int x, y;
  855.  
  856.     data = image->data;
  857.     iptr = pixelindex;
  858.     for (y = 0; y < height; y++)
  859.     for (x = 0; x < width; x++, iptr++)
  860.         data[ZINDEX8(x, y, image)] = pixels[*iptr];
  861. }
  862.  
  863. /*
  864.  * write pixels into a 1-bit depth image data structure and **offset null**
  865.  */
  866.  
  867. static int
  868. SetImagePixels1(image, width, height, pixelindex, pixels)
  869.     XImage *image;
  870.     unsigned int width;
  871.     unsigned int height;
  872.     unsigned int *pixelindex;
  873.     Pixel *pixels;
  874. {
  875.     register unsigned int *iptr;
  876.     register int x, y;
  877.     register char *data;
  878.  
  879.     if (image->byte_order != image->bitmap_bit_order)
  880.     SetImagePixels(image, width, height, pixelindex, pixels);
  881.     else {
  882.     data = image->data;
  883.     iptr = pixelindex;
  884.     if (image->bitmap_bit_order == MSBFirst)
  885.         for (y = 0; y < height; y++)
  886.         for (x = 0; x < width; x++, iptr++) {
  887.             if (pixels[*iptr] & 1)
  888.             data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7);
  889.             else
  890.             data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7));
  891.         }
  892.     else
  893.         for (y = 0; y < height; y++)
  894.         for (x = 0; x < width; x++, iptr++) {
  895.             if (pixels[*iptr] & 1)
  896.             data[ZINDEX1(x, y, image)] |= 1 << (x & 7);
  897.             else
  898.             data[ZINDEX1(x, y, image)] &= ~(1 << x & 7);
  899.         }
  900.     }
  901. }
  902.