Back to index

plt-scheme  4.2.1
scan.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1989-95 GROUPE BULL
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to
00006  * deal in the Software without restriction, including without limitation the
00007  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00008  * sell copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00017  * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00018  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00019  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00020  *
00021  * Except as contained in this notice, the name of GROUPE BULL shall not be
00022  * used in advertising or otherwise to promote the sale, use or other dealings
00023  * in this Software without prior written authorization from GROUPE BULL.
00024  */
00025 
00026 /*****************************************************************************\
00027 * scan.c:                                                                     *
00028 *                                                                             *
00029 *  XPM library                                                                *
00030 *  Scanning utility for XPM file format                                       *
00031 *                                                                             *
00032 *  Developed by Arnaud Le Hors                                                *
00033 \*****************************************************************************/
00034 
00035 /*
00036  * The code related to FOR_MSW has been added by
00037  * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
00038  */
00039 
00040 #include "xpmP.h"
00041 
00042 #define MAXPRINTABLE 92                   /* number of printable ascii chars
00043                                     * minus \ and " for string compat
00044                                     * and ? to avoid ANSI trigraphs. */
00045 
00046 static char *printable =
00047 " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\
00048 ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
00049 
00050 /*
00051  * printable begin with a space, so in most case, due to my algorithm, when
00052  * the number of different colors is less than MAXPRINTABLE, it will give a
00053  * char follow by "nothing" (a space) in the readable xpm file
00054  */
00055 
00056 
00057 typedef struct {
00058     Pixel *pixels;
00059     unsigned int *pixelindex;
00060     unsigned int size;
00061     unsigned int ncolors;
00062     unsigned int mask_pixel;              /* whether there is or not */
00063 }      PixelsMap;
00064 
00065 LFUNC(storePixel, int, (Pixel pixel, PixelsMap *pmap,
00066                      unsigned int *index_return));
00067 
00068 LFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap *pmap,
00069                          unsigned int *index_return));
00070 
00071 #ifndef FOR_MSW
00072 LFUNC(GetImagePixels, int, (XImage *image, unsigned int width,
00073                          unsigned int height, PixelsMap *pmap));
00074 
00075 LFUNC(GetImagePixels32, int, (XImage *image, unsigned int width,
00076                            unsigned int height, PixelsMap *pmap));
00077 
00078 LFUNC(GetImagePixels16, int, (XImage *image, unsigned int width,
00079                            unsigned int height, PixelsMap *pmap));
00080 
00081 LFUNC(GetImagePixels8, int, (XImage *image, unsigned int width,
00082                           unsigned int height, PixelsMap *pmap));
00083 
00084 LFUNC(GetImagePixels1, int, (XImage *image, unsigned int width,
00085                           unsigned int height, PixelsMap *pmap,
00086                           int (*storeFunc) ()));
00087 #else  /* ndef FOR_MSW */
00088 LFUNC(MSWGetImagePixels, int, (Display *d, XImage *image, unsigned int width,
00089                             unsigned int height, PixelsMap *pmap));
00090 #endif
00091 LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp,
00092                               XpmAttributes *attributes));
00093 
00094 LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, int ncolors,
00095                           Pixel *pixels, unsigned int mask,
00096                           unsigned int cpp, XpmAttributes *attributes));
00097 
00098 /*
00099  * This function stores the given pixel in the given arrays which are grown
00100  * if not large enough.
00101  */
00102 static int
00103 storePixel(pixel, pmap, index_return)
00104     Pixel pixel;
00105     PixelsMap *pmap;
00106     unsigned int *index_return;
00107 {
00108     unsigned int i;
00109     Pixel *p;
00110     unsigned int ncolors;
00111 
00112     if (*index_return) {           /* this is a transparent pixel! */
00113        *index_return = 0;
00114        return 0;
00115     }
00116     ncolors = pmap->ncolors;
00117     p = pmap->pixels + pmap->mask_pixel;
00118     for (i = pmap->mask_pixel; i < ncolors; i++, p++)
00119        if (*p == pixel)
00120            break;
00121     if (i == ncolors) {
00122        if (ncolors >= pmap->size) {
00123            pmap->size *= 2;
00124            p = (Pixel *) XpmRealloc(pmap->pixels, sizeof(Pixel) * pmap->size);
00125            if (!p)
00126               return (1);
00127            pmap->pixels = p;
00128 
00129        }
00130        (pmap->pixels)[ncolors] = pixel;
00131        pmap->ncolors++;
00132     }
00133     *index_return = i;
00134     return 0;
00135 }
00136 
00137 static int
00138 storeMaskPixel(pixel, pmap, index_return)
00139     Pixel pixel;
00140     PixelsMap *pmap;
00141     unsigned int *index_return;
00142 {
00143     if (!pixel) {
00144        if (!pmap->ncolors) {
00145            pmap->ncolors = 1;
00146            (pmap->pixels)[0] = 0;
00147            pmap->mask_pixel = 1;
00148        }
00149        *index_return = 1;
00150     } else
00151        *index_return = 0;
00152     return 0;
00153 }
00154 
00155 /* function call in case of error, frees only locally allocated variables */
00156 #undef RETURN
00157 #define RETURN(status) \
00158 { \
00159     if (pmap.pixelindex) XpmFree(pmap.pixelindex); \
00160     if (pmap.pixels) XpmFree(pmap.pixels); \
00161     if (colorTable) xpmFreeColorTable(colorTable, pmap.ncolors); \
00162     return(status); \
00163 }
00164 
00165 /*
00166  * This function scans the given image and stores the found informations in
00167  * the given XpmImage structure.
00168  */
00169 int
00170 XpmCreateXpmImageFromImage(display, image, shapeimage,
00171                         xpmimage, attributes)
00172     Display *display;
00173     XImage *image;
00174     XImage *shapeimage;
00175     XpmImage *xpmimage;
00176     XpmAttributes *attributes;
00177 {
00178     /* variables stored in the XpmAttributes structure */
00179     unsigned int cpp;
00180 
00181     /* variables to return */
00182     PixelsMap pmap;
00183     XpmColor *colorTable = NULL;
00184     int ErrorStatus;
00185 
00186     /* calculation variables */
00187     unsigned int width = 0;
00188     unsigned int height = 0;
00189     unsigned int cppm;                    /* minimum chars per pixel */
00190     unsigned int c;
00191 
00192     /* initialize pmap */
00193     pmap.pixels = NULL;
00194     pmap.pixelindex = NULL;
00195     pmap.size = 256;               /* should be enough most of the time */
00196     pmap.ncolors = 0;
00197     pmap.mask_pixel = 0;
00198 
00199     /*
00200      * get geometry
00201      */
00202     if (image) {
00203        width = image->width;
00204        height = image->height;
00205     } else if (shapeimage) {
00206        width = shapeimage->width;
00207        height = shapeimage->height;
00208     }
00209 
00210     /*
00211      * retrieve information from the XpmAttributes
00212      */
00213     if (attributes && (attributes->valuemask & XpmCharsPerPixel
00214 /* 3.2 backward compatibility code */
00215                      || attributes->valuemask & XpmInfos))
00216 /* end 3.2 bc */
00217        cpp = attributes->cpp;
00218     else
00219        cpp = 0;
00220 
00221     pmap.pixelindex =
00222        (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int));
00223     if (!pmap.pixelindex)
00224        RETURN(XpmNoMemory);
00225 
00226     pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size);
00227     if (!pmap.pixels)
00228        RETURN(XpmNoMemory);
00229 
00230     /*
00231      * scan shape mask if any
00232      */
00233     if (shapeimage) {
00234 #ifndef FOR_MSW
00235        ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap,
00236                                   storeMaskPixel);
00237 #else
00238        ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height,
00239                                    &pmap, storeMaskPixel);
00240 #endif
00241        if (ErrorStatus != XpmSuccess)
00242            RETURN(ErrorStatus);
00243     }
00244 
00245     /*
00246      * scan the image data
00247      * 
00248      * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized
00249      * functions, otherwise use slower but sure general one.
00250      * 
00251      */
00252 
00253     if (image) {
00254 #ifndef FOR_MSW
00255        if (((image->bits_per_pixel | image->depth) == 1)  &&
00256            (image->byte_order == image->bitmap_bit_order))
00257            ErrorStatus = GetImagePixels1(image, width, height, &pmap,
00258                                      storePixel);
00259        else if (image->format == ZPixmap) {
00260            if (image->bits_per_pixel == 8)
00261               ErrorStatus = GetImagePixels8(image, width, height, &pmap);
00262            else if (image->bits_per_pixel == 16)
00263               ErrorStatus = GetImagePixels16(image, width, height, &pmap);
00264            else if (image->bits_per_pixel == 32)
00265               ErrorStatus = GetImagePixels32(image, width, height, &pmap);
00266        } else
00267            ErrorStatus = GetImagePixels(image, width, height, &pmap);
00268 #else                              /* FOR_MSW */
00269        ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap);
00270 #endif
00271        if (ErrorStatus != XpmSuccess)
00272            RETURN(ErrorStatus);
00273     }
00274 
00275     /*
00276      * get rgb values and a string of char, and possibly a name for each
00277      * color
00278      */
00279 
00280     colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
00281     if (!colorTable)
00282        RETURN(XpmNoMemory);
00283 
00284     /* compute the minimal cpp */
00285     for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++)
00286        c *= MAXPRINTABLE;
00287     if (cpp < cppm)
00288        cpp = cppm;
00289 
00290     if (pmap.mask_pixel) {
00291        ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes);
00292        if (ErrorStatus != XpmSuccess)
00293            RETURN(ErrorStatus);
00294     }
00295 
00296     ErrorStatus = ScanOtherColors(display, colorTable, pmap.ncolors,
00297                               pmap.pixels, pmap.mask_pixel, cpp,
00298                               attributes);
00299     if (ErrorStatus != XpmSuccess)
00300        RETURN(ErrorStatus);
00301 
00302     /*
00303      * store found informations in the XpmImage structure
00304      */
00305     xpmimage->width = width;
00306     xpmimage->height = height;
00307     xpmimage->cpp = cpp;
00308     xpmimage->ncolors = pmap.ncolors;
00309     xpmimage->colorTable = colorTable;
00310     xpmimage->data = pmap.pixelindex;
00311 
00312     XpmFree(pmap.pixels);
00313     return (XpmSuccess);
00314 }
00315 
00316 static int
00317 ScanTransparentColor(color, cpp, attributes)
00318     XpmColor *color;
00319     unsigned int cpp;
00320     XpmAttributes *attributes;
00321 {
00322     char *s;
00323     unsigned int b;
00324 
00325     /* first get a character string */
00326     if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
00327        return (XpmNoMemory);
00328     *s++ = printable[0];
00329     for (b = 1; b < cpp; b++, s++)
00330        *s = printable[0];
00331     *s = '\0';
00332 
00333     /* then retreive related info from the attributes if any */
00334     if (attributes && (attributes->valuemask & XpmColorTable
00335 /* 3.2 backward compatibility code */
00336                      || attributes->valuemask & XpmInfos)
00337 /* end 3.2 bc */
00338        && attributes->mask_pixel != XpmUndefPixel) {
00339 
00340        unsigned int key;
00341        char **defaults = (char **) color;
00342        char **mask_defaults;
00343 
00344 /* 3.2 backward compatibility code */
00345        if (attributes->valuemask & XpmColorTable)
00346 /* end 3.2 bc */
00347            mask_defaults = (char **) (
00348               attributes->colorTable + attributes->mask_pixel);
00349 /* 3.2 backward compatibility code */
00350        else
00351            mask_defaults = (char **)
00352               ((XpmColor **) attributes->colorTable)[attributes->mask_pixel];
00353 /* end 3.2 bc */
00354        for (key = 1; key <= NKEYS; key++) {
00355            if (s = mask_defaults[key]) {
00356               defaults[key] = (char *) strdup(s);
00357               if (!defaults[key])
00358                   return (XpmNoMemory);
00359            }
00360        }
00361     } else {
00362        color->c_color = (char *) strdup(TRANSPARENT_COLOR);
00363        if (!color->c_color)
00364            return (XpmNoMemory);
00365     }
00366     return (XpmSuccess);
00367 }
00368 
00369 static int
00370 ScanOtherColors(display, colors, ncolors, pixels, mask, cpp, attributes)
00371     Display *display;
00372     XpmColor *colors;
00373     int ncolors;
00374     Pixel *pixels;
00375     unsigned int mask;
00376     unsigned int cpp;
00377     XpmAttributes *attributes;
00378 {
00379     /* variables stored in the XpmAttributes structure */
00380     Colormap colormap;
00381     char *rgb_fname;
00382 
00383 #ifndef FOR_MSW
00384     xpmRgbName rgbn[MAX_RGBNAMES];
00385 #else
00386     xpmRgbName *rgbn = NULL; 
00387 #endif    
00388     int rgbn_max = 0;
00389     unsigned int i, j, c, i2;
00390     XpmColor *color;
00391     XColor *xcolors = NULL, *xcolor;
00392     char *colorname, *s;
00393     XpmColor *colorTable, **oldColorTable = NULL;
00394     unsigned int ancolors = 0;
00395     Pixel *apixels;
00396     unsigned int mask_pixel;
00397     Bool found;
00398 
00399     /* retrieve information from the XpmAttributes */
00400     if (attributes && (attributes->valuemask & XpmColormap))
00401         colormap = attributes->colormap;
00402     else
00403         colormap = XDefaultColormap(display, XDefaultScreen(display));
00404     if (attributes && (attributes->valuemask & XpmRgbFilename))
00405        rgb_fname = attributes->rgb_fname;
00406     else
00407        rgb_fname = NULL;
00408 
00409     /* start from the right element */
00410     if (mask) {
00411        colors++;
00412        ncolors--;
00413        pixels++;
00414     }
00415 
00416     /* first get character strings and rgb values */
00417     xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
00418     if (!xcolors)
00419        return (XpmNoMemory);
00420 
00421     for (i = 0, i2 = mask, color = colors, xcolor = xcolors;
00422         i < ncolors; i++, i2++, color++, xcolor++, pixels++) {
00423 
00424        if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) {
00425            XpmFree(xcolors);
00426            return (XpmNoMemory);
00427        }
00428        {
00429          int i3 = i2;
00430          c = i3 % MAXPRINTABLE;
00431          *s++ = printable[c];
00432          for (j = 1; j < cpp; j++, s++) {
00433            i3 = (i3 - c) / MAXPRINTABLE;
00434            c = i3 % MAXPRINTABLE;
00435            *s = printable[c];
00436          }
00437        }
00438        *s = '\0';
00439 
00440        xcolor->pixel = *pixels;
00441     }
00442     XQueryColors(display, colormap, xcolors, ncolors);
00443 
00444 #ifndef FOR_MSW
00445     /* read the rgb file if any was specified */
00446     if (rgb_fname)
00447        rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn);
00448 #else
00449     /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */
00450     rgbn_max = xpmReadRgbNames(NULL, NULL);
00451 #endif
00452 
00453     if (attributes && attributes->valuemask & XpmColorTable) {
00454        colorTable = attributes->colorTable;
00455        ancolors = attributes->ncolors;
00456        apixels = attributes->pixels;
00457        mask_pixel = attributes->mask_pixel;
00458     }
00459 /* 3.2 backward compatibility code */
00460     else if (attributes && attributes->valuemask & XpmInfos) {
00461        oldColorTable = (XpmColor **) attributes->colorTable;
00462        ancolors = attributes->ncolors;
00463        apixels = attributes->pixels;
00464        mask_pixel = attributes->mask_pixel;
00465     }
00466 /* end 3.2 bc */
00467 
00468     for (i = 0, color = colors, xcolor = xcolors; i < ncolors;
00469                                             i++, color++, xcolor++) {
00470 
00471        /* look for related info from the attributes if any */
00472        found = False;
00473        if (ancolors) {
00474            unsigned int offset = 0;
00475 
00476            for (j = 0; j < ancolors; j++) {
00477               if (j == mask_pixel) {
00478                   offset = 1;
00479                   continue;
00480               }
00481               if (apixels[j - offset] == xcolor->pixel)
00482                   break;
00483            }
00484            if (j != ancolors) {
00485               unsigned int key;
00486               char **defaults = (char **) color;
00487               char **adefaults;
00488 
00489 /* 3.2 backward compatibility code */
00490               if (oldColorTable)
00491                   adefaults = (char **) oldColorTable[j];
00492               else
00493 /* end 3.2 bc */
00494                   adefaults = (char **) (colorTable + j);
00495 
00496               found = True;
00497               for (key = 1; key <= NKEYS; key++) {
00498                   if (s = adefaults[key])
00499                      defaults[key] = (char *) strdup(s);
00500               }
00501            }
00502        }
00503        if (!found) {
00504            /* if nothing found look for a color name */
00505            colorname = NULL;
00506            if (rgbn_max)
00507               colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red,
00508                                      xcolor->green, xcolor->blue);
00509            if (colorname)
00510               color->c_color = (char *) strdup(colorname);
00511            else {
00512               /* at last store the rgb value */
00513               char buf[BUFSIZ];
00514 #ifndef FOR_MSW
00515               sprintf(buf, "#%04X%04X%04X",
00516                      xcolor->red, xcolor->green, xcolor->blue);
00517 #else   
00518               sprintf(buf, "#%02x%02x%02x",
00519                      xcolor->red, xcolor->green, xcolor->blue);
00520 #endif               
00521               color->c_color = (char *) strdup(buf);
00522            }
00523            if (!color->c_color) {
00524               XpmFree(xcolors);
00525               xpmFreeRgbNames(rgbn, rgbn_max);
00526               return (XpmNoMemory);
00527            }
00528        }
00529     }
00530 
00531     XpmFree(xcolors);
00532     xpmFreeRgbNames(rgbn, rgbn_max);
00533     return (XpmSuccess);
00534 }
00535 
00536 #ifndef FOR_MSW
00537 /*
00538  * The functions below are written from X11R5 MIT's code (XImUtil.c)
00539  *
00540  * The idea is to have faster functions than the standard XGetPixel function
00541  * to scan the image data. Indeed we can speed up things by suppressing tests
00542  * performed for each pixel. We do exactly the same tests but at the image
00543  * level. Assuming that we use only ZPixmap images.
00544  */
00545 
00546 static unsigned long Const low_bits_table[] = {
00547     0x00000000, 0x00000001, 0x00000003, 0x00000007,
00548     0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
00549     0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
00550     0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
00551     0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
00552     0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
00553     0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
00554     0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
00555     0xffffffff
00556 };
00557 
00558 /*
00559  * Default method to scan pixels of a Z image data structure.
00560  * The algorithm used is:
00561  *
00562  *     copy the source bitmap_unit or Zpixel into temp
00563  *     normalize temp if needed
00564  *     extract the pixel bits into return value
00565  *
00566  */
00567 
00568 static int
00569 GetImagePixels(image, width, height, pmap)
00570     XImage *image;
00571     unsigned int width;
00572     unsigned int height;
00573     PixelsMap *pmap;
00574 {
00575     char *src;
00576     char *dst;
00577     unsigned int *iptr;
00578     char *data;
00579     int x, y, i;
00580     int bits, depth, ibu, ibpp, offset;
00581     unsigned long lbt;
00582     Pixel pixel, px;
00583 
00584     data = image->data;
00585     iptr = pmap->pixelindex;
00586     depth = image->depth;
00587     lbt = low_bits_table[depth];
00588     ibpp = image->bits_per_pixel;
00589     offset = image->xoffset;
00590 
00591     if ((image->bits_per_pixel | image->depth) == 1) {
00592        ibu = image->bitmap_unit;
00593        for (y = 0; y < height; y++)
00594            for (x = 0; x < width; x++, iptr++) {
00595               src = &data[XYINDEX(x, y, image)];
00596               dst = (char *) &pixel;
00597               pixel = 0;
00598               for (i = ibu >> 3; --i >= 0;)
00599                   *dst++ = *src++;
00600               XYNORMALIZE(&pixel, image);
00601               bits = (x + offset) % ibu;
00602               pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1;
00603               if (ibpp != depth)
00604                   pixel &= lbt;
00605               if (storePixel(pixel, pmap, iptr))
00606                   return (XpmNoMemory);
00607            }
00608     } else if (image->format == XYPixmap) {
00609        int nbytes, bpl, j;
00610        long plane = 0;
00611        ibu = image->bitmap_unit;
00612        nbytes = ibu >> 3;
00613        bpl = image->bytes_per_line;
00614        for (y = 0; y < height; y++)
00615            for (x = 0; x < width; x++, iptr++) {
00616               pixel = 0;
00617               plane = 0;
00618               for (i = depth; --i >= 0;) {
00619                   src = &data[XYINDEX(x, y, image) + plane];
00620                   dst = (char *) &px;
00621                   px = 0;
00622                   for (j = nbytes; --j >= 0;)
00623                      *dst++ = *src++;
00624                   XYNORMALIZE(&px, image);
00625                   bits = (x + offset) % ibu;
00626                   pixel = (pixel << 1) |
00627                          (((((char *) &px)[bits >> 3]) >> (bits & 7)) & 1);
00628                   plane = plane + (bpl * height);
00629               }
00630               if (ibpp != depth)
00631                   pixel &= lbt;
00632               if (storePixel(pixel, pmap, iptr))
00633                   return (XpmNoMemory);
00634            }
00635     } else if (image->format == ZPixmap) {
00636        for (y = 0; y < height; y++)
00637            for (x = 0; x < width; x++, iptr++) {
00638               src = &data[ZINDEX(x, y, image)];
00639               dst = (char *) &px;
00640               px = 0;
00641               for (i = (ibpp + 7) >> 3; --i >= 0;)
00642                   *dst++ = *src++;
00643               ZNORMALIZE(&px, image);
00644               pixel = 0;
00645               for (i = sizeof(unsigned long); --i >= 0;)
00646                   pixel = (pixel << 8) | ((unsigned char *) &px)[i];
00647               if (ibpp == 4) {
00648                   if (x & 1)
00649                      pixel >>= 4;
00650                   else
00651                      pixel &= 0xf;
00652               }
00653               if (ibpp != depth)
00654                   pixel &= lbt;
00655               if (storePixel(pixel, pmap, iptr))
00656                   return (XpmNoMemory);
00657            }
00658     } else
00659        return (XpmColorError); /* actually a bad image */
00660     return (XpmSuccess);
00661 }
00662 
00663 /*
00664  * scan pixels of a 32-bits Z image data structure
00665  */
00666 
00667 #if !defined(WORD64) && !defined(LONG64)
00668 static unsigned long byteorderpixel = MSBFirst << 24;
00669 #endif
00670 
00671 static int
00672 GetImagePixels32(image, width, height, pmap)
00673     XImage *image;
00674     unsigned int width;
00675     unsigned int height;
00676     PixelsMap *pmap;
00677 {
00678     unsigned char *addr;
00679     unsigned char *data;
00680     unsigned int *iptr;
00681     int x, y;
00682     unsigned long lbt;
00683     Pixel pixel;
00684     int depth;
00685 
00686     data = (unsigned char *) image->data;
00687     iptr = pmap->pixelindex;
00688     depth = image->depth;
00689     lbt = low_bits_table[depth];
00690 #if !defined(WORD64) && !defined(LONG64)
00691     if (*((char *) &byteorderpixel) == image->byte_order) {
00692        for (y = 0; y < height; y++)
00693            for (x = 0; x < width; x++, iptr++) {
00694               addr = &data[ZINDEX32(x, y, image)];
00695               pixel = *((unsigned long *) addr);
00696               if (depth != 32)
00697                   pixel &= lbt;
00698               if (storePixel(pixel, pmap, iptr))
00699                   return (XpmNoMemory);
00700            }
00701     } else
00702 #endif
00703     if (image->byte_order == MSBFirst)
00704        for (y = 0; y < height; y++)
00705            for (x = 0; x < width; x++, iptr++) {
00706               addr = &data[ZINDEX32(x, y, image)];
00707               pixel = ((unsigned long) addr[0] << 24 |
00708                       (unsigned long) addr[1] << 16 |
00709                       (unsigned long) addr[2] << 8 |
00710                       (unsigned long) addr[3]);
00711               if (depth != 32)
00712                   pixel &= lbt;
00713               if (storePixel(pixel, pmap, iptr))
00714                   return (XpmNoMemory);
00715            }
00716     else
00717        for (y = 0; y < height; y++)
00718            for (x = 0; x < width; x++, iptr++) {
00719               addr = &data[ZINDEX32(x, y, image)];
00720               pixel = (addr[0] |
00721                       (unsigned long) addr[1] << 8 |
00722                       (unsigned long) addr[2] << 16 |
00723                       (unsigned long) addr[3] << 24);
00724               if (depth != 32)
00725                   pixel &= lbt;
00726               if (storePixel(pixel, pmap, iptr))
00727                   return (XpmNoMemory);
00728            }
00729     return (XpmSuccess);
00730 }
00731 
00732 /*
00733  * scan pixels of a 16-bits Z image data structure
00734  */
00735 
00736 static int
00737 GetImagePixels16(image, width, height, pmap)
00738     XImage *image;
00739     unsigned int width;
00740     unsigned int height;
00741     PixelsMap *pmap;
00742 {
00743     unsigned char *addr;
00744     unsigned char *data;
00745     unsigned int *iptr;
00746     int x, y;
00747     unsigned long lbt;
00748     Pixel pixel;
00749     int depth;
00750 
00751     data = (unsigned char *) image->data;
00752     iptr = pmap->pixelindex;
00753     depth = image->depth;
00754     lbt = low_bits_table[depth];
00755     if (image->byte_order == MSBFirst)
00756        for (y = 0; y < height; y++)
00757            for (x = 0; x < width; x++, iptr++) {
00758               addr = &data[ZINDEX16(x, y, image)];
00759               pixel = addr[0] << 8 | addr[1];
00760               if (depth != 16)
00761                   pixel &= lbt;
00762               if (storePixel(pixel, pmap, iptr))
00763                   return (XpmNoMemory);
00764            }
00765     else
00766        for (y = 0; y < height; y++)
00767            for (x = 0; x < width; x++, iptr++) {
00768               addr = &data[ZINDEX16(x, y, image)];
00769               pixel = addr[0] | addr[1] << 8;
00770               if (depth != 16)
00771                   pixel &= lbt;
00772               if (storePixel(pixel, pmap, iptr))
00773                   return (XpmNoMemory);
00774            }
00775     return (XpmSuccess);
00776 }
00777 
00778 /*
00779  * scan pixels of a 8-bits Z image data structure
00780  */
00781 
00782 static int
00783 GetImagePixels8(image, width, height, pmap)
00784     XImage *image;
00785     unsigned int width;
00786     unsigned int height;
00787     PixelsMap *pmap;
00788 {
00789     unsigned int *iptr;
00790     unsigned char *data;
00791     int x, y;
00792     unsigned long lbt;
00793     Pixel pixel;
00794     int depth;
00795 
00796     data = (unsigned char *) image->data;
00797     iptr = pmap->pixelindex;
00798     depth = image->depth;
00799     lbt = low_bits_table[depth];
00800     for (y = 0; y < height; y++)
00801        for (x = 0; x < width; x++, iptr++) {
00802            pixel = data[ZINDEX8(x, y, image)];
00803            if (depth != 8)
00804               pixel &= lbt;
00805            if (storePixel(pixel, pmap, iptr))
00806               return (XpmNoMemory);
00807        }
00808     return (XpmSuccess);
00809 }
00810 
00811 /*
00812  * scan pixels of a 1-bit depth Z image data structure
00813  */
00814 
00815 static int
00816 GetImagePixels1(image, width, height, pmap, storeFunc)
00817     XImage *image;
00818     unsigned int width;
00819     unsigned int height;
00820     PixelsMap *pmap;
00821     int (*storeFunc) ();
00822 
00823 {
00824     unsigned int *iptr;
00825     int x, y;
00826     char *data;
00827     Pixel pixel;
00828     int xoff, yoff, offset, bpl;
00829 
00830     data = image->data;
00831     iptr = pmap->pixelindex;
00832     offset = image->xoffset;
00833     bpl = image->bytes_per_line;
00834 
00835     if (image->bitmap_bit_order == MSBFirst)
00836        for (y = 0; y < height; y++)
00837            for (x = 0; x < width; x++, iptr++) {
00838               xoff = x + offset;
00839               yoff = y * bpl + (xoff >> 3);
00840               xoff &= 7;
00841               pixel = (data[yoff] & (0x80 >> xoff)) ? 1 : 0;
00842               if ((*storeFunc) (pixel, pmap, iptr))
00843                   return (XpmNoMemory);
00844            }
00845     else
00846        for (y = 0; y < height; y++)
00847            for (x = 0; x < width; x++, iptr++) {
00848               xoff = x + offset;
00849               yoff = y * bpl + (xoff >> 3);
00850               xoff &= 7;
00851               pixel = (data[yoff] & (1 << xoff)) ? 1 : 0;
00852               if ((*storeFunc) (pixel, pmap, iptr))
00853                   return (XpmNoMemory);
00854            }
00855     return (XpmSuccess);
00856 }
00857 
00858 #else  /* ndef FOR_MSW */
00859 static int
00860 MSWGetImagePixels(display, image, width, height, pmap)
00861     Display *display;
00862     XImage *image;
00863     unsigned int width;
00864     unsigned int height;
00865     PixelsMap *pmap;
00866 {
00867     unsigned int *iptr;
00868     unsigned int x, y;
00869     Pixel pixel;
00870 
00871     iptr = pmap->pixelindex;
00872 
00873     for (y = 0; y < height; y++) {
00874        for (x = 0; x < width; x++, iptr++) {
00875            /* bitmap must be selected !!! ??? */
00876            pixel = GetPixel(*display, x, y);
00877            if (storePixel(pixel, pmap, iptr))
00878               return (XpmNoMemory);
00879        }
00880     }
00881     return (XpmSuccess);
00882 }
00883 
00884 #endif
00885 
00886 #ifndef FOR_MSW
00887 int
00888 XpmCreateXpmImageFromPixmap(display, pixmap, shapemask,
00889                          xpmimage, attributes)
00890     Display *display;
00891     Pixmap pixmap;
00892     Pixmap shapemask;
00893     XpmImage *xpmimage;
00894     XpmAttributes *attributes;
00895 {
00896     XImage *ximage = NULL;
00897     XImage *shapeimage = NULL;
00898     unsigned int width = 0;
00899     unsigned int height = 0;
00900     int ErrorStatus;
00901 
00902     /* get geometry */
00903     if (attributes && attributes->valuemask & XpmSize) {
00904        width = attributes->width;
00905        height = attributes->height;
00906     }
00907     /* get the ximages */
00908     if (pixmap)
00909        xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
00910     if (shapemask)
00911        xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
00912                              &width, &height);
00913 
00914     /* create the related XpmImage */
00915     ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage,
00916                                         xpmimage, attributes);
00917 
00918     /* destroy the ximages */
00919     if (ximage)
00920        XDestroyImage(ximage);
00921     if (shapeimage)
00922        XDestroyImage(shapeimage);
00923 
00924     return (ErrorStatus);
00925 }
00926 
00927 #endif /* ndef FOR_MSW */