home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / x / x11r6-ch / xpm-3.4 / xpm-3 / xpm-3.4c / lib / scan.c < prev    next >
C/C++ Source or Header  |  1994-06-06  |  24KB  |  881 lines

  1. /*
  2.  * Copyright (C) 1989-94 GROUPE BULL
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  5.  * of this software and associated documentation files (the "Software"), to
  6.  * deal in the Software without restriction, including without limitation the
  7.  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8.  * sell copies of the Software, and to permit persons to whom the Software is
  9.  * furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17.  * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  18.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20.  *
  21.  * Except as contained in this notice, the name of GROUPE BULL shall not be
  22.  * used in advertising or otherwise to promote the sale, use or other dealings
  23.  * in this Software without prior written authorization from GROUPE BULL.
  24.  */
  25.  
  26. /*****************************************************************************\
  27. * scan.c:                                                                     *
  28. *                                                                             *
  29. *  XPM library                                                                *
  30. *  Scanning utility for XPM file format                                       *
  31. *                                                                             *
  32. *  Developed by Arnaud Le Hors                                                *
  33. \*****************************************************************************/
  34.  
  35. /*
  36.  * The code related to FOR_MSW has been added by
  37.  * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
  38.  */
  39.  
  40. #include "xpmP.h"
  41.  
  42. #define MAXPRINTABLE 92            /* number of printable ascii chars
  43.                      * minus \ and " for string compat
  44.                      * and ? to avoid ANSI trigraphs. */
  45.  
  46. static char *printable =
  47. " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\
  48. ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
  49.  
  50. /*
  51.  * printable begin with a space, so in most case, due to my algorithm, when
  52.  * the number of different colors is less than MAXPRINTABLE, it will give a
  53.  * char follow by "nothing" (a space) in the readable xpm file
  54.  */
  55.  
  56.  
  57. typedef struct {
  58.     Pixel *pixels;
  59.     unsigned int *pixelindex;
  60.     unsigned int size;
  61.     unsigned int ncolors;
  62.     unsigned int mask_pixel;        /* whether there is or not */
  63. }      PixelsMap;
  64.  
  65. LFUNC(storePixel, int, (Pixel pixel, PixelsMap *pmap,
  66.             unsigned int *index_return));
  67.  
  68. LFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap *pmap,
  69.                 unsigned int *index_return));
  70.  
  71. #ifndef FOR_MSW
  72. LFUNC(GetImagePixels, int, (XImage *image, unsigned int width,
  73.                 unsigned int height, PixelsMap *pmap));
  74.  
  75. LFUNC(GetImagePixels32, int, (XImage *image, unsigned int width,
  76.                   unsigned int height, PixelsMap *pmap));
  77.  
  78. LFUNC(GetImagePixels16, int, (XImage *image, unsigned int width,
  79.                   unsigned int height, PixelsMap *pmap));
  80.  
  81. LFUNC(GetImagePixels8, int, (XImage *image, unsigned int width,
  82.                  unsigned int height, PixelsMap *pmap));
  83.  
  84. LFUNC(GetImagePixels1, int, (XImage *image, unsigned int width,
  85.                  unsigned int height, PixelsMap *pmap,
  86.                  int (*storeFunc) ()));
  87. #else  /* ndef FOR_MSW */
  88. LFUNC(MSWGetImagePixels, int, (Display *d, XImage *image, unsigned int width,
  89.                    unsigned int height, PixelsMap *pmap));
  90. #endif
  91. LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp,
  92.                   XpmAttributes *attributes));
  93.  
  94. LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, int ncolors,
  95.                  Pixel *pixels, unsigned int mask,
  96.                  unsigned int cpp, XpmAttributes *attributes));
  97.  
  98. /*
  99.  * This function stores the given pixel in the given arrays which are grown
  100.  * if not large enough.
  101.  */
  102. static int
  103. storePixel(pixel, pmap, index_return)
  104.     Pixel pixel;
  105.     PixelsMap *pmap;
  106.     unsigned int *index_return;
  107. {
  108.     unsigned int i;
  109.     Pixel *p;
  110.     unsigned int ncolors;
  111.  
  112.     if (*index_return) {        /* this is a transparent pixel! */
  113.     *index_return = 0;
  114.     return 0;
  115.     }
  116.     ncolors = pmap->ncolors;
  117.     p = pmap->pixels + pmap->mask_pixel;
  118.     for (i = pmap->mask_pixel; i < ncolors; i++, p++)
  119.     if (*p == pixel)
  120.         break;
  121.     if (i == ncolors) {
  122.     if (ncolors >= pmap->size) {
  123.         pmap->size *= 2;
  124.         p = (Pixel *) XpmRealloc(pmap->pixels, sizeof(Pixel) * pmap->size);
  125.         if (!p)
  126.         return (1);
  127.         pmap->pixels = p;
  128.  
  129.     }
  130.     (pmap->pixels)[ncolors] = pixel;
  131.     pmap->ncolors++;
  132.     }
  133.     *index_return = i;
  134.     return 0;
  135. }
  136.  
  137. static int
  138. storeMaskPixel(pixel, pmap, index_return)
  139.     Pixel pixel;
  140.     PixelsMap *pmap;
  141.     unsigned int *index_return;
  142. {
  143.     if (!pixel) {
  144.     if (!pmap->ncolors) {
  145.         pmap->ncolors = 1;
  146.         (pmap->pixels)[0] = 0;
  147.         pmap->mask_pixel = 1;
  148.     }
  149.     *index_return = 1;
  150.     } else
  151.     *index_return = 0;
  152.     return 0;
  153. }
  154.  
  155. /* function call in case of error, frees only locally allocated variables */
  156. #undef RETURN
  157. #define RETURN(status) \
  158. { \
  159.     if (pmap.pixelindex) XpmFree(pmap.pixelindex); \
  160.     if (pmap.pixels) XpmFree(pmap.pixels); \
  161.     if (colorTable) xpmFreeColorTable(colorTable, pmap.ncolors); \
  162.     return(status); \
  163. }
  164.  
  165. /*
  166.  * This function scans the given image and stores the found informations in
  167.  * the given XpmImage structure.
  168.  */
  169. int
  170. XpmCreateXpmImageFromImage(display, image, shapeimage,
  171.                xpmimage, attributes)
  172.     Display *display;
  173.     XImage *image;
  174.     XImage *shapeimage;
  175.     XpmImage *xpmimage;
  176.     XpmAttributes *attributes;
  177. {
  178.     /* variables stored in the XpmAttributes structure */
  179.     unsigned int cpp;
  180.  
  181.     /* variables to return */
  182.     PixelsMap pmap;
  183.     XpmColor *colorTable = NULL;
  184.     int ErrorStatus;
  185.  
  186.     /* calculation variables */
  187.     unsigned int width = 0;
  188.     unsigned int height = 0;
  189.     unsigned int cppm;            /* minimum chars per pixel */
  190.     unsigned int c;
  191.     unsigned int offset;
  192.  
  193.     /* initialize pmap */
  194.     pmap.pixels = NULL;
  195.     pmap.pixelindex = NULL;
  196.     pmap.size = 256;            /* should be enough most of the time */
  197.     pmap.ncolors = 0;
  198.     pmap.mask_pixel = 0;
  199.  
  200.     /*
  201.      * get geometry
  202.      */
  203.     if (image) {
  204.     width = image->width;
  205.     height = image->height;
  206.     } else if (shapeimage) {
  207.     width = shapeimage->width;
  208.     height = shapeimage->height;
  209.     }
  210.  
  211.     /*
  212.      * retrieve information from the XpmAttributes
  213.      */
  214.     if (attributes && (attributes->valuemask & XpmCharsPerPixel
  215. /* 3.2 backward compatibility code */
  216.                || attributes->valuemask & XpmInfos))
  217. /* end 3.2 bc */
  218.     cpp = attributes->cpp;
  219.     else
  220.     cpp = 0;
  221.  
  222.     pmap.pixelindex =
  223.     (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int));
  224.     if (!pmap.pixelindex)
  225.     RETURN(XpmNoMemory);
  226.  
  227.     pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size);
  228.     if (!pmap.pixels)
  229.     RETURN(XpmNoMemory);
  230.  
  231.     /*
  232.      * scan shape mask if any
  233.      */
  234.     if (shapeimage) {
  235. #ifndef FOR_MSW
  236.     ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap,
  237.                       storeMaskPixel);
  238. #else
  239.     ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height,
  240.                     &pmap, storeMaskPixel);
  241. #endif
  242.     if (ErrorStatus != XpmSuccess)
  243.         RETURN(ErrorStatus);
  244.     }
  245.  
  246.     /*
  247.      * scan the image data
  248.      * 
  249.      * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized
  250.      * functions, otherwise use slower but sure general one.
  251.      * 
  252.      */
  253.  
  254.     if (image) {
  255. #ifndef FOR_MSW
  256.     if (image->depth == 1)
  257.         ErrorStatus = GetImagePixels1(image, width, height, &pmap,
  258.                       storePixel);
  259.     else if (image->bits_per_pixel == 8)
  260.         ErrorStatus = GetImagePixels8(image, width, height, &pmap);
  261.     else if (image->bits_per_pixel == 16)
  262.         ErrorStatus = GetImagePixels16(image, width, height, &pmap);
  263.     else if (image->bits_per_pixel == 32)
  264.         ErrorStatus = GetImagePixels32(image, width, height, &pmap);
  265.     else
  266.         ErrorStatus = GetImagePixels(image, width, height, &pmap);
  267. #else                    /* FOR_MSW */
  268.     ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap);
  269. #endif
  270.     if (ErrorStatus != XpmSuccess)
  271.         RETURN(ErrorStatus);
  272.     }
  273.  
  274.     /*
  275.      * get rgb values and a string of char, and possibly a name for each
  276.      * color
  277.      */
  278.  
  279.     colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
  280.     if (!colorTable)
  281.     RETURN(XpmNoMemory);
  282.  
  283.     /* compute the minimal cpp */
  284.     for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++)
  285.     c *= MAXPRINTABLE;
  286.     if (cpp < cppm)
  287.     cpp = cppm;
  288.  
  289.     if (pmap.mask_pixel) {
  290.     ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes);
  291.     if (ErrorStatus != XpmSuccess)
  292.         RETURN(ErrorStatus);
  293.     offset = 1;
  294.     } else
  295.     offset = 0;
  296.  
  297.     ErrorStatus = ScanOtherColors(display, colorTable + offset,
  298.                   pmap.ncolors - offset, pmap.pixels + offset,
  299.                   pmap.mask_pixel, cpp, attributes);
  300.     if (ErrorStatus != XpmSuccess)
  301.     RETURN(ErrorStatus);
  302.  
  303.     /*
  304.      * store found informations in the XpmImage structure
  305.      */
  306.     xpmimage->width = width;
  307.     xpmimage->height = height;
  308.     xpmimage->cpp = cpp;
  309.     xpmimage->ncolors = pmap.ncolors;
  310.     xpmimage->colorTable = colorTable;
  311.     xpmimage->data = pmap.pixelindex;
  312.  
  313.     XpmFree(pmap.pixels);
  314.     return (XpmSuccess);
  315. }
  316.  
  317. static int
  318. ScanTransparentColor(color, cpp, attributes)
  319.     XpmColor *color;
  320.     unsigned int cpp;
  321.     XpmAttributes *attributes;
  322. {
  323.     char *s;
  324.     unsigned int a, b, c;
  325.  
  326.     /* first get a character string */
  327.     a = 0;
  328.     if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
  329.     return (XpmNoMemory);
  330.     *s++ = printable[c = a % MAXPRINTABLE];
  331.     for (b = 1; b < cpp; b++, s++)
  332.     *s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE];
  333.     *s = '\0';
  334.  
  335.     /* then retreive related info from the attributes if any */
  336.     if (attributes && attributes->mask_pixel != XpmUndefPixel && (
  337. /* 3.2 backward compatibility code */
  338.     attributes->valuemask & XpmInfos ||
  339. /* end 3.2 bc */
  340.     attributes->valuemask & XpmColorTable)) {
  341.  
  342.     unsigned int key;
  343.     char **defaults = (char **) color;
  344.     char **mask_defaults;
  345.  
  346. /* 3.2 backward compatibility code */
  347.     if (attributes->valuemask & XpmInfos)
  348.         mask_defaults = (char **)
  349.         ((XpmColor **) attributes->colorTable)[attributes->mask_pixel];
  350.     else
  351. /* end 3.2 bc */
  352.         mask_defaults = (char **) (
  353.         attributes->colorTable + attributes->mask_pixel);
  354.     for (key = 1; key <= NKEYS; key++) {
  355.         if (s = mask_defaults[key]) {
  356.         defaults[key] = (char *) strdup(s);
  357.         if (!defaults[key])
  358.             return (XpmNoMemory);
  359.         }
  360.     }
  361.     } else {
  362.     color->c_color = (char *) strdup(TRANSPARENT_COLOR);
  363.     if (!color->c_color)
  364.         return (XpmNoMemory);
  365.     }
  366.     return (XpmSuccess);
  367. }
  368.  
  369. static int
  370. ScanOtherColors(display, colors, ncolors, pixels, mask, cpp, attributes)
  371.     Display *display;
  372.     XpmColor *colors;
  373.     int ncolors;
  374.     Pixel *pixels;
  375.     unsigned int cpp;
  376.     unsigned int mask;
  377.     XpmAttributes *attributes;
  378. {
  379.     /* variables stored in the XpmAttributes structure */
  380.     Colormap colormap;
  381.     char *rgb_fname;
  382.  
  383. #ifndef FOR_MSW
  384.     xpmRgbName rgbn[MAX_RGBNAMES];
  385. #else
  386.     xpmRgbName *rgbn = NULL; 
  387. #endif    
  388.     int rgbn_max = 0;
  389.     unsigned int i, j, c, i2;
  390.     XpmColor *color;
  391.     XColor *xcolors = NULL, *xcolor;
  392.     char *colorname, *s;
  393.     XpmColor *colorTable, **oldColorTable = NULL;
  394.     unsigned int ancolors = 0;
  395.     Pixel *apixels;
  396.     unsigned int mask_pixel;
  397.     Bool found;
  398.  
  399.     /* retrieve information from the XpmAttributes */
  400.     if (attributes && (attributes->valuemask & XpmColormap))
  401.     colormap = attributes->colormap;
  402.     else
  403.     colormap = XDefaultColormap(display, XDefaultScreen(display));
  404.     if (attributes && (attributes->valuemask & XpmRgbFilename))
  405.     rgb_fname = attributes->rgb_fname;
  406.     else
  407.     rgb_fname = NULL;
  408.  
  409.     /* first get character strings and rgb values */
  410.     xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
  411.     if (!xcolors)
  412.     return (XpmNoMemory);
  413.  
  414.     for (i = 0, i2 = (mask ? i + 1 : i), color = colors, xcolor = xcolors;
  415.      i < ncolors; i++, i2++, color++, xcolor++, pixels++) {
  416.  
  417.     if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) {
  418.         XpmFree(xcolors);
  419.         return (XpmNoMemory);
  420.     }
  421.     *s++ = printable[c = i2 % MAXPRINTABLE];
  422.     for (j = 1; j < cpp; j++, s++)
  423.         *s = printable[c = ((i2 - c) / MAXPRINTABLE) % MAXPRINTABLE];
  424.     *s = '\0';
  425.  
  426.     xcolor->pixel = *pixels;
  427.     }
  428.     XQueryColors(display, colormap, xcolors, ncolors);
  429.  
  430. #ifndef FOR_MSW
  431.     /* read the rgb file if any was specified */
  432.     if (rgb_fname)
  433.     rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn);
  434. #else
  435.     /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */
  436.     rgbn_max = xpmReadRgbNames(NULL, NULL);
  437. #endif
  438.  
  439.     if (attributes && attributes->valuemask & XpmColorTable) {
  440.     colorTable = attributes->colorTable;
  441.     ancolors = attributes->ncolors;
  442.     apixels = attributes->pixels;
  443.     mask_pixel = attributes->mask_pixel;
  444.     }
  445. /* 3.2 backward compatibility code */
  446.     else if (attributes && attributes->valuemask & XpmInfos) {
  447.     oldColorTable = (XpmColor **) attributes->colorTable;
  448.     ancolors = attributes->ncolors;
  449.     apixels = attributes->pixels;
  450.     mask_pixel = attributes->mask_pixel;
  451.     }
  452. /* end 3.2 bc */
  453.  
  454.     for (i = 0, color = colors, xcolor = xcolors; i < ncolors;
  455.                           i++, color++, xcolor++) {
  456.  
  457.     /* look for related info from the attributes if any */
  458.     found = False;
  459.     if (ancolors) {
  460.         unsigned int offset = 0;
  461.  
  462.         for (j = 0; j < ancolors; j++) {
  463.         if (j == mask_pixel) {
  464.             offset = 1;
  465.             continue;
  466.         }
  467.         if (apixels[j - offset] == xcolor->pixel)
  468.             break;
  469.         }
  470.         if (j != ancolors) {
  471.         unsigned int key;
  472.         char **defaults = (char **) color;
  473.         char **adefaults;
  474.  
  475. /* 3.2 backward compatibility code */
  476.         if (oldColorTable)
  477.             adefaults = (char **) oldColorTable[j];
  478.         else
  479. /* end 3.2 bc */
  480.             adefaults = (char **) (colorTable + j);
  481.  
  482.         found = True;
  483.         for (key = 1; key <= NKEYS; key++) {
  484.             if (s = adefaults[key])
  485.             defaults[key] = (char *) strdup(s);
  486.         }
  487.         }
  488.     }
  489.     if (!found) {
  490.         /* if nothing found look for a color name */
  491.         colorname = NULL;
  492.         if (rgbn_max)
  493.         colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red,
  494.                       xcolor->green, xcolor->blue);
  495.         if (colorname)
  496.         color->c_color = (char *) strdup(colorname);
  497.         else {
  498.         /* at last store the rgb value */
  499.         char buf[BUFSIZ];
  500. #ifndef FOR_MSW
  501.         sprintf(buf, "#%04X%04X%04X",
  502.             xcolor->red, xcolor->green, xcolor->blue);
  503. #else   
  504.         sprintf(buf, "#%02x%02x%02x",
  505.             xcolor->red, xcolor->green, xcolor->blue);
  506. #endif            
  507.         color->c_color = (char *) strdup(buf);
  508.         }
  509.         if (!color->c_color) {
  510.         XpmFree(xcolors);
  511.         xpmFreeRgbNames(rgbn, rgbn_max);
  512.         return (XpmNoMemory);
  513.         }
  514.     }
  515.     }
  516.  
  517.     XpmFree(xcolors);
  518.     xpmFreeRgbNames(rgbn, rgbn_max);
  519.     return (XpmSuccess);
  520. }
  521.  
  522. #ifndef FOR_MSW
  523. /*
  524.  * The functions below are written from X11R5 MIT's code (XImUtil.c)
  525.  *
  526.  * The idea is to have faster functions than the standard XGetPixel function
  527.  * to scan the image data. Indeed we can speed up things by suppressing tests
  528.  * performed for each pixel. We do exactly the same tests but at the image
  529.  * level. Assuming that we use only ZPixmap images.
  530.  */
  531.  
  532. static unsigned long Const low_bits_table[] = {
  533.     0x00000000, 0x00000001, 0x00000003, 0x00000007,
  534.     0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
  535.     0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
  536.     0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
  537.     0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
  538.     0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
  539.     0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
  540.     0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
  541.     0xffffffff
  542. };
  543.  
  544. /*
  545.  * Default method to scan pixels of a Z image data structure.
  546.  * The algorithm used is:
  547.  *
  548.  *    copy the source bitmap_unit or Zpixel into temp
  549.  *    normalize temp if needed
  550.  *    extract the pixel bits into return value
  551.  *
  552.  */
  553.  
  554. static int
  555. GetImagePixels(image, width, height, pmap)
  556.     XImage *image;
  557.     unsigned int width;
  558.     unsigned int height;
  559.     PixelsMap *pmap;
  560. {
  561.     char *src;
  562.     char *dst;
  563.     unsigned int *iptr;
  564.     char *data;
  565.     int x, y, i;
  566.     int bits, depth, ibu, ibpp;
  567.     unsigned long lbt;
  568.     Pixel pixel, px;
  569.  
  570.     data = image->data;
  571.     iptr = pmap->pixelindex;
  572.     depth = image->depth;
  573.     lbt = low_bits_table[depth];
  574.     ibpp = image->bits_per_pixel;
  575.     if (image->depth == 1) {
  576.     ibu = image->bitmap_unit;
  577.     for (y = 0; y < height; y++)
  578.         for (x = 0; x < width; x++, iptr++) {
  579.         src = &data[XYINDEX(x, y, image)];
  580.         dst = (char *) &pixel;
  581.         pixel = 0;
  582.         for (i = ibu >> 3; --i >= 0;)
  583.             *dst++ = *src++;
  584.         XYNORMALIZE(&pixel, image);
  585.         bits = x % ibu;
  586.         pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1;
  587.         if (ibpp != depth)
  588.             pixel &= lbt;
  589.         if (storePixel(pixel, pmap, iptr))
  590.             return (XpmNoMemory);
  591.         }
  592.     } else {
  593.     for (y = 0; y < height; y++)
  594.         for (x = 0; x < width; x++, iptr++) {
  595.         src = &data[ZINDEX(x, y, image)];
  596.         dst = (char *) &px;
  597.         px = 0;
  598.         for (i = (ibpp + 7) >> 3; --i >= 0;)
  599.             *dst++ = *src++;
  600.         ZNORMALIZE(&px, image);
  601.         pixel = 0;
  602.         for (i = sizeof(unsigned long); --i >= 0;)
  603.             pixel = (pixel << 8) | ((unsigned char *) &px)[i];
  604.         if (ibpp == 4) {
  605.             if (x & 1)
  606.             pixel >>= 4;
  607.             else
  608.             pixel &= 0xf;
  609.         }
  610.         if (ibpp != depth)
  611.             pixel &= lbt;
  612.         if (storePixel(pixel, pmap, iptr))
  613.             return (XpmNoMemory);
  614.         }
  615.     }
  616.     return (XpmSuccess);
  617. }
  618.  
  619. /*
  620.  * scan pixels of a 32-bits Z image data structure
  621.  */
  622.  
  623. #ifndef WORD64
  624. static unsigned long byteorderpixel = MSBFirst << 24;
  625.  
  626. #endif
  627.  
  628. static int
  629. GetImagePixels32(image, width, height, pmap)
  630.     XImage *image;
  631.     unsigned int width;
  632.     unsigned int height;
  633.     PixelsMap *pmap;
  634. {
  635.     unsigned char *addr;
  636.     unsigned char *data;
  637.     unsigned int *iptr;
  638.     int x, y;
  639.     unsigned long lbt;
  640.     Pixel pixel;
  641.     int depth;
  642.  
  643.     data = (unsigned char *) image->data;
  644.     iptr = pmap->pixelindex;
  645.     depth = image->depth;
  646.     lbt = low_bits_table[depth];
  647. #ifndef WORD64
  648.     if (*((char *) &byteorderpixel) == image->byte_order) {
  649.     for (y = 0; y < height; y++)
  650.         for (x = 0; x < width; x++, iptr++) {
  651.         addr = &data[ZINDEX32(x, y, image)];
  652.         pixel = *((unsigned long *) addr);
  653.         if (depth != 32)
  654.             pixel &= lbt;
  655.         if (storePixel(pixel, pmap, iptr))
  656.             return (XpmNoMemory);
  657.         }
  658.     } else
  659. #endif
  660.     if (image->byte_order == MSBFirst)
  661.     for (y = 0; y < height; y++)
  662.         for (x = 0; x < width; x++, iptr++) {
  663.         addr = &data[ZINDEX32(x, y, image)];
  664.         pixel = ((unsigned long) addr[0] << 24 |
  665.              (unsigned long) addr[1] << 16 |
  666.              (unsigned long) addr[2] << 8 |
  667.              addr[4]);
  668.         if (depth != 32)
  669.             pixel &= lbt;
  670.         if (storePixel(pixel, pmap, iptr))
  671.             return (XpmNoMemory);
  672.         }
  673.     else
  674.     for (y = 0; y < height; y++)
  675.         for (x = 0; x < width; x++, iptr++) {
  676.         addr = &data[ZINDEX32(x, y, image)];
  677.         pixel = (addr[0] |
  678.              (unsigned long) addr[1] << 8 |
  679.              (unsigned long) addr[2] << 16 |
  680.              (unsigned long) addr[3] << 24);
  681.         if (depth != 32)
  682.             pixel &= lbt;
  683.         if (storePixel(pixel, pmap, iptr))
  684.             return (XpmNoMemory);
  685.         }
  686.     return (XpmSuccess);
  687. }
  688.  
  689. /*
  690.  * scan pixels of a 16-bits Z image data structure
  691.  */
  692.  
  693. static int
  694. GetImagePixels16(image, width, height, pmap)
  695.     XImage *image;
  696.     unsigned int width;
  697.     unsigned int height;
  698.     PixelsMap *pmap;
  699. {
  700.     unsigned char *addr;
  701.     unsigned char *data;
  702.     unsigned int *iptr;
  703.     int x, y;
  704.     unsigned long lbt;
  705.     Pixel pixel;
  706.     int depth;
  707.  
  708.     data = (unsigned char *) image->data;
  709.     iptr = pmap->pixelindex;
  710.     depth = image->depth;
  711.     lbt = low_bits_table[depth];
  712.     if (image->byte_order == MSBFirst)
  713.     for (y = 0; y < height; y++)
  714.         for (x = 0; x < width; x++, iptr++) {
  715.         addr = &data[ZINDEX16(x, y, image)];
  716.         pixel = addr[0] << 8 | addr[1];
  717.         if (depth != 16)
  718.             pixel &= lbt;
  719.         if (storePixel(pixel, pmap, iptr))
  720.             return (XpmNoMemory);
  721.         }
  722.     else
  723.     for (y = 0; y < height; y++)
  724.         for (x = 0; x < width; x++, iptr++) {
  725.         addr = &data[ZINDEX16(x, y, image)];
  726.         pixel = addr[0] | addr[1] << 8;
  727.         if (depth != 16)
  728.             pixel &= lbt;
  729.         if (storePixel(pixel, pmap, iptr))
  730.             return (XpmNoMemory);
  731.         }
  732.     return (XpmSuccess);
  733. }
  734.  
  735. /*
  736.  * scan pixels of a 8-bits Z image data structure
  737.  */
  738.  
  739. static int
  740. GetImagePixels8(image, width, height, pmap)
  741.     XImage *image;
  742.     unsigned int width;
  743.     unsigned int height;
  744.     PixelsMap *pmap;
  745. {
  746.     unsigned int *iptr;
  747.     unsigned char *data;
  748.     int x, y;
  749.     unsigned long lbt;
  750.     Pixel pixel;
  751.     int depth;
  752.  
  753.     data = (unsigned char *) image->data;
  754.     iptr = pmap->pixelindex;
  755.     depth = image->depth;
  756.     lbt = low_bits_table[depth];
  757.     for (y = 0; y < height; y++)
  758.     for (x = 0; x < width; x++, iptr++) {
  759.         pixel = data[ZINDEX8(x, y, image)];
  760.         if (depth != 8)
  761.         pixel &= lbt;
  762.         if (storePixel(pixel, pmap, iptr))
  763.         return (XpmNoMemory);
  764.     }
  765.     return (XpmSuccess);
  766. }
  767.  
  768. /*
  769.  * scan pixels of a 1-bit depth Z image data structure
  770.  */
  771.  
  772. static int
  773. GetImagePixels1(image, width, height, pmap, storeFunc)
  774.     XImage *image;
  775.     unsigned int width;
  776.     unsigned int height;
  777.     PixelsMap *pmap;
  778.     int (*storeFunc) ();
  779.  
  780. {
  781.     unsigned int *iptr;
  782.     int x, y;
  783.     char *data;
  784.     Pixel pixel;
  785.  
  786.     if (image->byte_order != image->bitmap_bit_order)
  787.     return (GetImagePixels(image, width, height, pmap));
  788.     else {
  789.     data = image->data;
  790.     iptr = pmap->pixelindex;
  791.     if (image->bitmap_bit_order == MSBFirst)
  792.         for (y = 0; y < height; y++)
  793.         for (x = 0; x < width; x++, iptr++) {
  794.             pixel = (data[ZINDEX1(x, y, image)] & (0x80 >> (x & 7)))
  795.             ? 1 : 0;
  796.             if ((*storeFunc) (pixel, pmap, iptr))
  797.             return (XpmNoMemory);
  798.         }
  799.     else
  800.         for (y = 0; y < height; y++)
  801.         for (x = 0; x < width; x++, iptr++) {
  802.             pixel = (data[ZINDEX1(x, y, image)] & (1 << (x & 7)))
  803.             ? 1 : 0;
  804.             if ((*storeFunc) (pixel, pmap, iptr))
  805.             return (XpmNoMemory);
  806.         }
  807.     }
  808.     return (XpmSuccess);
  809. }
  810.  
  811. #else  /* ndef FOR_MSW */
  812. static int
  813. MSWGetImagePixels(display, image, width, height, pmap)
  814.     Display *display;
  815.     XImage *image;
  816.     unsigned int width;
  817.     unsigned int height;
  818.     PixelsMap *pmap;
  819. {
  820.     unsigned int *iptr;
  821.     unsigned int x, y;
  822.     Pixel pixel;
  823.  
  824.     iptr = pmap->pixelindex;
  825.  
  826.     for (y = 0; y < height; y++) {
  827.     for (x = 0; x < width; x++, iptr++) {
  828.         /* bitmap must be selected !!! ??? */
  829.         pixel = GetPixel(*display, x, y);
  830.         if (storePixel(pixel, pmap, iptr))
  831.         return (XpmNoMemory);
  832.     }
  833.     }
  834.     return (XpmSuccess);
  835. }
  836.  
  837. #endif
  838.  
  839. #ifndef FOR_MSW
  840. int
  841. XpmCreateXpmImageFromPixmap(display, pixmap, shapemask,
  842.                 xpmimage, attributes)
  843.     Display *display;
  844.     Pixmap pixmap;
  845.     Pixmap shapemask;
  846.     XpmImage *xpmimage;
  847.     XpmAttributes *attributes;
  848. {
  849.     XImage *ximage = NULL;
  850.     XImage *shapeimage = NULL;
  851.     unsigned int width = 0;
  852.     unsigned int height = 0;
  853.     int ErrorStatus;
  854.  
  855.     /* get geometry */
  856.     if (attributes && attributes->valuemask & XpmSize) {
  857.     width = attributes->width;
  858.     height = attributes->height;
  859.     }
  860.     /* get the ximages */
  861.     if (pixmap)
  862.     xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
  863.     if (shapemask)
  864.     xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
  865.                  &width, &height);
  866.  
  867.     /* create the related XpmImage */
  868.     ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage,
  869.                          xpmimage, attributes);
  870.  
  871.     /* destroy the ximages */
  872.     if (ximage)
  873.     XDestroyImage(ximage);
  874.     if (shapeimage)
  875.     XDestroyImage(shapeimage);
  876.  
  877.     return (ErrorStatus);
  878. }
  879.  
  880. #endif /* ndef FOR_MSW */
  881.