~ubuntu-branches/ubuntu/quantal/openmotif/quantal

« back to all changes in this revision

Viewing changes to lib/Xm/Xpmcreate.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bauer
  • Date: 2010-06-23 12:12:31 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100623121231-u89gxdp51sg9wjj2
Tags: 2.3.0-1
* New Maintainer (Closes: #379258) 
* Acknowledge NMU changes
* New upstream release (Closes: #494375)
* Get rid of security patches as they are already part of new upstream
  release (00-xpmvuln.openmotif.patch, 342092-CVE-2005-3964.patch)
* Bump Standards to 3.8.4
* Added {misc:Depends} to make the package lintian cleaner
* Fix weak-library-dev-dependency by adding ${binary:Version}) for the
  -dev Package of openmotif
* Let package depend on autotools-dev to use newer autotools-helper-files
* Work around an autoconf-bug (Gentoo-Bug #1475)
* Added Client-side anti-aliased fonts support via XFT
* Added UTF-8 and UTF8_STRING atom support
* Ability to show text and pixmaps in Label, LabelGadget and all
  derived widgets
* Support of PNG/JPEG image formats in the same way as XPM is supported
* Increase FILE_OFFSET_BITS to 64 to show files >2GB in file-selector
  Idea taken from Magne Oestlyngen (Closes: #288537)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XConsortium: Xpmcreate.c /main/8 1996/09/20 08:15:02 pascale $ */
 
2
/*
 
3
 * Copyright (C) 1989-95 GROUPE BULL
 
4
 *
 
5
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
6
 * of this software and associated documentation files (the "Software"), to
 
7
 * deal in the Software without restriction, including without limitation the
 
8
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 
9
 * sell copies of the Software, and to permit persons to whom the Software is
 
10
 * furnished to do so, subject to the following conditions:
 
11
 *
 
12
 * The above copyright notice and this permission notice shall be included in
 
13
 * all copies or substantial portions of the Software.
 
14
 *
 
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
18
 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
19
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
20
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
21
 *
 
22
 * Except as contained in this notice, the name of GROUPE BULL shall not be
 
23
 * used in advertising or otherwise to promote the sale, use or other dealings
 
24
 * in this Software without prior written authorization from GROUPE BULL.
 
25
 */
 
26
 
 
27
/*****************************************************************************\
 
28
* create.c:                                                                   *
 
29
*                                                                             *
 
30
*  XPM library                                                                *
 
31
*  Create an X image and possibly its related shape mask                      *
 
32
*  from the given XpmImage.                                                   *
 
33
*                                                                             *
 
34
*  Developed by Arnaud Le Hors                                                *
 
35
\*****************************************************************************/
 
36
 
 
37
/*
 
38
 * The code related to FOR_MSW has been added by
 
39
 * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
 
40
 */
 
41
 
 
42
#ifdef HAVE_CONFIG_H
 
43
#include <config.h>
 
44
#endif
 
45
 
 
46
 
 
47
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
 
48
 
 
49
#include "XpmI.h"
 
50
#include <ctype.h>
 
51
 
 
52
LFUNC(xpmVisualType, int, (Visual *visual));
 
53
 
 
54
LFUNC(AllocColor, int, (Display *display, Colormap colormap,
 
55
                        char *colorname, XColor *xcolor, void *closure));
 
56
LFUNC(FreeColors, int, (Display *display, Colormap colormap,
 
57
                        Pixel *pixels, int n, void *closure));
 
58
 
 
59
#ifndef FOR_MSW
 
60
LFUNC(SetCloseColor, int, (Display *display, Colormap colormap,
 
61
                           Visual *visual, XColor *col,
 
62
                           Pixel *image_pixel, Pixel *mask_pixel,
 
63
                           Pixel *alloc_pixels, unsigned int *nalloc_pixels,
 
64
                           XpmAttributes *attributes, XColor *cols, int ncols,
 
65
                           XpmAllocColorFunc allocColor, void *closure));
 
66
#else
 
67
/* let the window system take care of close colors */
 
68
#endif
 
69
 
 
70
LFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual,
 
71
                      char *colorname, unsigned int color_index,
 
72
                      Pixel *image_pixel, Pixel *mask_pixel,
 
73
                      unsigned int *mask_pixel_index,
 
74
                      Pixel *alloc_pixels, unsigned int *nalloc_pixels,
 
75
                      Pixel *used_pixels, unsigned int *nused_pixels,
 
76
                      XpmAttributes *attributes, XColor *cols, int ncols,
 
77
                      XpmAllocColorFunc allocColor, void *closure));
 
78
 
 
79
LFUNC(CreateXImage, int, (Display *display, Visual *visual,
 
80
                          unsigned int depth, int format, unsigned int width,
 
81
                          unsigned int height, XImage **image_return));
 
82
 
 
83
LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes,
 
84
                          XpmColor *colors, unsigned int ncolors,
 
85
                          Pixel *image_pixels, Pixel *mask_pixels,
 
86
                          unsigned int *mask_pixel_index,
 
87
                          Pixel *alloc_pixels, unsigned int *nalloc_pixels,
 
88
                          Pixel *used_pixels, unsigned int *nused_pixels));
 
89
 
 
90
#ifndef FOR_MSW
 
91
LFUNC(ParseAndPutPixels, int, (xpmData *data, unsigned int width,
 
92
                               unsigned int height, unsigned int ncolors,
 
93
                               unsigned int cpp, XpmColor *colorTable,
 
94
                               xpmHashTable *hashtable,
 
95
                               XImage *image, Pixel *image_pixels,
 
96
                               XImage *mask, Pixel *mask_pixels));
 
97
#else  /* FOR_MSW */
 
98
LFUNC(ParseAndPutPixels, int, (Display *dc, xpmData *data, unsigned int width,
 
99
                               unsigned int height, unsigned int ncolors,
 
100
                               unsigned int cpp, XpmColor *colorTable,
 
101
                               xpmHashTable *hashtable,
 
102
                               XImage *image, Pixel *image_pixels,
 
103
                               XImage *mask, Pixel *mask_pixels));
 
104
#endif
 
105
 
 
106
#ifndef FOR_MSW
 
107
/* XImage pixel routines */
 
108
LFUNC(PutImagePixels, void, (XImage *image, unsigned int width,
 
109
                             unsigned int height, unsigned int *pixelindex,
 
110
                             Pixel *pixels));
 
111
 
 
112
LFUNC(PutImagePixels32, void, (XImage *image, unsigned int width,
 
113
                               unsigned int height, unsigned int *pixelindex,
 
114
                               Pixel *pixels));
 
115
 
 
116
LFUNC(PutImagePixels16, void, (XImage *image, unsigned int width,
 
117
                               unsigned int height, unsigned int *pixelindex,
 
118
                               Pixel *pixels));
 
119
 
 
120
LFUNC(PutImagePixels8, void, (XImage *image, unsigned int width,
 
121
                              unsigned int height, unsigned int *pixelindex,
 
122
                              Pixel *pixels));
 
123
 
 
124
LFUNC(PutImagePixels1, void, (XImage *image, unsigned int width,
 
125
                              unsigned int height, unsigned int *pixelindex,
 
126
                              Pixel *pixels));
 
127
 
 
128
LFUNC(PutPixel1, int, (XImage *ximage, int x, int y, unsigned long pixel));
 
129
LFUNC(PutPixel, int, (XImage *ximage, int x, int y, unsigned long pixel));
 
130
LFUNC(PutPixel32, int, (XImage *ximage, int x, int y, unsigned long pixel));
 
131
LFUNC(PutPixel32MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
 
132
LFUNC(PutPixel32LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
 
133
LFUNC(PutPixel16MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
 
134
LFUNC(PutPixel16LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
 
135
LFUNC(PutPixel8, int, (XImage *ximage, int x, int y, unsigned long pixel));
 
136
LFUNC(PutPixel1MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
 
137
LFUNC(PutPixel1LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
 
138
 
 
139
#else  /* ndef FOR_MSW */
 
140
/* FOR_MSW pixel routine */
 
141
LFUNC(MSWPutImagePixels, void, (Display *dc, XImage *image,
 
142
                                unsigned int width, unsigned int height,
 
143
                                unsigned int *pixelindex, Pixel *pixels));
 
144
#endif /* ndef FOR_MSW */
 
145
 
 
146
#ifdef NEED_STRCASECMP
 
147
FUNC(xpmstrcasecmp, int, (char *s1, char *s2));
 
148
 
 
149
/*
 
150
 * in case strcasecmp is not provided by the system here is one
 
151
 * which does the trick
 
152
 */
 
153
int
 
154
xpmstrcasecmp(s1, s2)
 
155
    register char *s1, *s2;
 
156
{
 
157
    register int c1, c2;
 
158
 
 
159
    while (*s1 && *s2) {
 
160
        c1 = tolower(*s1);
 
161
        c2 = tolower(*s2);
 
162
        if (c1 != c2)
 
163
            return (c1 - c2);
 
164
        s1++;
 
165
        s2++;
 
166
    }
 
167
    return (int) (*s1 - *s2);
 
168
}
 
169
 
 
170
#endif
 
171
 
 
172
/*
 
173
 * return the default color key related to the given visual
 
174
 */
 
175
static int
 
176
xpmVisualType(visual)
 
177
    Visual *visual;
 
178
{
 
179
#ifndef FOR_MSW
 
180
    switch (visual->class) {
 
181
    case StaticGray:
 
182
    case GrayScale:
 
183
        switch (visual->map_entries) {
 
184
        case 2:
 
185
            return (XPM_MONO);
 
186
        case 4:
 
187
            return (XPM_GRAY4);
 
188
        default:
 
189
            return (XPM_GRAY);
 
190
        }
 
191
    default:
 
192
        return (XPM_COLOR);
 
193
    }
 
194
#else
 
195
    /* there should be a similar switch for MSW */
 
196
    return (XPM_COLOR);
 
197
#endif
 
198
}
 
199
 
 
200
 
 
201
typedef struct {
 
202
    int cols_index;
 
203
    long closeness;
 
204
}      CloseColor;
 
205
 
 
206
static int
 
207
closeness_cmp(a, b)
 
208
    Const void *a, *b;
 
209
{
 
210
    CloseColor *x = (CloseColor *) a, *y = (CloseColor *) b;
 
211
 
 
212
    /* cast to int as qsort requires */
 
213
    return (int) (x->closeness - y->closeness);
 
214
}
 
215
 
 
216
 
 
217
/* default AllocColor function:
 
218
 *   call XParseColor if colorname is given, return negative value if failure
 
219
 *   call XAllocColor and return 0 if failure, positive otherwise
 
220
 */
 
221
static int
 
222
AllocColor(display, colormap, colorname, xcolor, closure)
 
223
    Display *display;
 
224
    Colormap colormap;
 
225
    char *colorname;
 
226
    XColor *xcolor;
 
227
    void *closure;              /* not used */
 
228
{
 
229
    int status;
 
230
    if (colorname)
 
231
        if (!XParseColor(display, colormap, colorname, xcolor))
 
232
            return -1;
 
233
    status = XAllocColor(display, colormap, xcolor);
 
234
    return status != 0 ? 1 : 0;
 
235
}
 
236
 
 
237
 
 
238
#ifndef FOR_MSW
 
239
/*
 
240
 * set a close color in case the exact one can't be set
 
241
 * return 0 if success, 1 otherwise.
 
242
 */
 
243
 
 
244
static int
 
245
SetCloseColor(display, colormap, visual, col, image_pixel, mask_pixel,
 
246
              alloc_pixels, nalloc_pixels, attributes, cols, ncols,
 
247
              allocColor, closure)
 
248
    Display *display;
 
249
    Colormap colormap;
 
250
    Visual *visual;
 
251
    XColor *col;
 
252
    Pixel *image_pixel, *mask_pixel;
 
253
    Pixel *alloc_pixels;
 
254
    unsigned int *nalloc_pixels;
 
255
    XpmAttributes *attributes;
 
256
    XColor *cols;
 
257
    int ncols;
 
258
    XpmAllocColorFunc allocColor;
 
259
    void *closure;
 
260
{
 
261
 
 
262
    /*
 
263
     * Allocation failed, so try close colors. To get here the visual must
 
264
     * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor?
 
265
     * What about sharing systems like QDSS?). Beware: we have to treat
 
266
     * DirectColor differently.
 
267
     */
 
268
 
 
269
 
 
270
    long int red_closeness, green_closeness, blue_closeness;
 
271
    int n;
 
272
    Bool alloc_color;
 
273
 
 
274
    if (attributes && (attributes->valuemask & XpmCloseness))
 
275
        red_closeness = green_closeness = blue_closeness =
 
276
            attributes->closeness;
 
277
    else {
 
278
        red_closeness = attributes->red_closeness;
 
279
        green_closeness = attributes->green_closeness;
 
280
        blue_closeness = attributes->blue_closeness;
 
281
    }
 
282
    if (attributes && (attributes->valuemask & XpmAllocCloseColors))
 
283
        alloc_color = attributes->alloc_close_colors;
 
284
    else
 
285
        alloc_color = True;
 
286
 
 
287
    /*
 
288
     * We sort the colormap by closeness and try to allocate the color
 
289
     * closest to the target. If the allocation of this close color fails,
 
290
     * which almost never happens, then one of two scenarios is possible.
 
291
     * Either the colormap must have changed (since the last close color
 
292
     * allocation or possibly while we were sorting the colormap), or the
 
293
     * color is allocated as Read/Write by some other client. (Note: X
 
294
     * _should_ allow clients to check if a particular color is Read/Write,
 
295
     * but it doesn't! :-( ). We cannot determine which of these scenarios
 
296
     * occurred, so we try the next closest color, and so on, until no more
 
297
     * colors are within closeness of the target. If we knew that the
 
298
     * colormap had changed, we could skip this sequence.
 
299
     * 
 
300
     * If _none_ of the colors within closeness of the target can be allocated,
 
301
     * then we can finally be pretty sure that the colormap has actually
 
302
     * changed. In this case we try to allocate the original color (again),
 
303
     * then try the closecolor stuff (again)...
 
304
     * 
 
305
     * In theory it would be possible for an infinite loop to occur if another
 
306
     * process kept changing the colormap every time we sorted it, so we set
 
307
     * a maximum on the number of iterations. After this many tries, we use
 
308
     * XGrabServer() to ensure that the colormap remains unchanged.
 
309
     * 
 
310
     * This approach gives particularly bad worst case performance - as many as
 
311
     * <MaximumIterations> colormap reads and sorts may be needed, and as
 
312
     * many as <MaximumIterations> * <ColormapSize> attempted allocations
 
313
     * may fail. On an 8-bit system, this means as many as 3 colormap reads,
 
314
     * 3 sorts and 768 failed allocations per execution of this code!
 
315
     * Luckily, my experiments show that in general use in a typical 8-bit
 
316
     * color environment only about 1 in every 10000 allocations fails to
 
317
     * succeed in the fastest possible time. So virtually every time what
 
318
     * actually happens is a single sort followed by a successful allocate.
 
319
     * The very first allocation also costs a colormap read, but no further
 
320
     * reads are usually necessary.
 
321
     */
 
322
 
 
323
#define ITERATIONS 2                    /* more than one is almost never
 
324
                                         * necessary */
 
325
 
 
326
    for (n = 0; n <= ITERATIONS; ++n) {
 
327
        CloseColor *closenesses =
 
328
            (CloseColor *) XpmCalloc(ncols, sizeof(CloseColor));
 
329
        int i, c;
 
330
 
 
331
        for (i = 0; i < ncols; ++i) {   /* build & sort closenesses table */
 
332
#define COLOR_FACTOR       3
 
333
#define BRIGHTNESS_FACTOR  1
 
334
 
 
335
            closenesses[i].cols_index = i;
 
336
            closenesses[i].closeness =
 
337
                COLOR_FACTOR * (abs((long) col->red - (long) cols[i].red)
 
338
                                + abs((long) col->green - (long) cols[i].green)
 
339
                                + abs((long) col->blue - (long) cols[i].blue))
 
340
                + BRIGHTNESS_FACTOR * abs(((long) col->red +
 
341
                                           (long) col->green +
 
342
                                           (long) col->blue)
 
343
                                           - ((long) cols[i].red +
 
344
                                              (long) cols[i].green +
 
345
                                              (long) cols[i].blue));
 
346
        }
 
347
        qsort(closenesses, ncols, sizeof(CloseColor), closeness_cmp);
 
348
 
 
349
        i = 0;
 
350
        c = closenesses[i].cols_index;
 
351
        while ((long) cols[c].red >= (long) col->red - red_closeness &&
 
352
               (long) cols[c].red <= (long) col->red + red_closeness &&
 
353
               (long) cols[c].green >= (long) col->green - green_closeness &&
 
354
               (long) cols[c].green <= (long) col->green + green_closeness &&
 
355
               (long) cols[c].blue >= (long) col->blue - blue_closeness &&
 
356
               (long) cols[c].blue <= (long) col->blue + blue_closeness) {
 
357
            if (alloc_color) {
 
358
                if ((*allocColor)(display, colormap, NULL, &cols[c], closure)){
 
359
                    if (n == ITERATIONS)
 
360
                        XUngrabServer(display);
 
361
                    XpmFree(closenesses);
 
362
                    *image_pixel = cols[c].pixel;
 
363
                    *mask_pixel = 1;
 
364
                    alloc_pixels[(*nalloc_pixels)++] = cols[c].pixel;
 
365
                    return (0);
 
366
                } else {
 
367
                    ++i;
 
368
                    if (i == ncols)
 
369
                        break;
 
370
                    c = closenesses[i].cols_index;
 
371
                }
 
372
            } else {
 
373
                if (n == ITERATIONS)
 
374
                    XUngrabServer(display);
 
375
                XpmFree(closenesses);
 
376
                *image_pixel = cols[c].pixel;
 
377
                *mask_pixel = 1;
 
378
                return (0);
 
379
            }
 
380
        }
 
381
 
 
382
        /* Couldn't allocate _any_ of the close colors! */
 
383
 
 
384
        if (n == ITERATIONS)
 
385
            XUngrabServer(display);
 
386
        XpmFree(closenesses);
 
387
 
 
388
        if (i == 0 || i == ncols)       /* no color close enough or cannot */
 
389
            return (1);                 /* alloc any color (full of r/w's) */
 
390
 
 
391
        if ((*allocColor)(display, colormap, NULL, col, closure)) {
 
392
            *image_pixel = col->pixel;
 
393
            *mask_pixel = 1;
 
394
            alloc_pixels[(*nalloc_pixels)++] = col->pixel;
 
395
            return (0);
 
396
        } else {                        /* colormap has probably changed, so
 
397
                                         * re-read... */
 
398
            if (n == ITERATIONS - 1)
 
399
                XGrabServer(display);
 
400
 
 
401
#if 0
 
402
            if (visual->class == DirectColor) {
 
403
                /* TODO */
 
404
            } else
 
405
#endif
 
406
                XQueryColors(display, colormap, cols, ncols);
 
407
        }
 
408
    }
 
409
    return (1);
 
410
}
 
411
 
 
412
#define USE_CLOSECOLOR attributes && \
 
413
(((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \
 
414
 || ((attributes->valuemask & XpmRGBCloseness) && \
 
415
     (attributes->red_closeness != 0 \
 
416
      || attributes->green_closeness != 0 \
 
417
      || attributes->blue_closeness != 0)))
 
418
 
 
419
#else
 
420
    /* FOR_MSW part */
 
421
    /* nothing to do here, the window system does it */
 
422
#endif
 
423
 
 
424
/*
 
425
 * set the color pixel related to the given colorname,
 
426
 * return 0 if success, 1 otherwise.
 
427
 */
 
428
 
 
429
static int
 
430
SetColor(display, colormap, visual, colorname, color_index,
 
431
         image_pixel, mask_pixel, mask_pixel_index,
 
432
         alloc_pixels, nalloc_pixels, used_pixels, nused_pixels,
 
433
         attributes, cols, ncols, allocColor, closure)
 
434
    Display *display;
 
435
    Colormap colormap;
 
436
    Visual *visual;
 
437
    char *colorname;
 
438
    unsigned int color_index;
 
439
    Pixel *image_pixel, *mask_pixel;
 
440
    unsigned int *mask_pixel_index;
 
441
    Pixel *alloc_pixels;
 
442
    unsigned int *nalloc_pixels;
 
443
    Pixel *used_pixels;
 
444
    unsigned int *nused_pixels;
 
445
    XpmAttributes *attributes;
 
446
    XColor *cols;
 
447
    int ncols;
 
448
    XpmAllocColorFunc allocColor;
 
449
    void *closure;
 
450
{
 
451
    XColor xcolor;
 
452
    int status;
 
453
 
 
454
    if (xpmstrcasecmp(colorname, TRANSPARENT_COLOR)) {
 
455
        status = (*allocColor)(display, colormap, colorname, &xcolor, closure);
 
456
        if (status < 0)         /* parse color failed */
 
457
            return (1);
 
458
 
 
459
        if (status == 0) {
 
460
#ifndef FOR_MSW
 
461
            if (USE_CLOSECOLOR)
 
462
                return (SetCloseColor(display, colormap, visual, &xcolor,
 
463
                                      image_pixel, mask_pixel,
 
464
                                      alloc_pixels, nalloc_pixels,
 
465
                                      attributes, cols, ncols,
 
466
                                      allocColor, closure));
 
467
            else
 
468
#endif /* ndef FOR_MSW */
 
469
                return (1);
 
470
        } else
 
471
            alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel;
 
472
        *image_pixel = xcolor.pixel;
 
473
        *mask_pixel = 1;
 
474
        used_pixels[(*nused_pixels)++] = xcolor.pixel;
 
475
    } else {
 
476
        *image_pixel = 0;
 
477
        *mask_pixel = 0;
 
478
        /* store the color table index */
 
479
        *mask_pixel_index = color_index;
 
480
    }
 
481
    return (0);
 
482
}
 
483
 
 
484
 
 
485
static int
 
486
CreateColors(display, attributes, colors, ncolors, image_pixels, mask_pixels,
 
487
             mask_pixel_index, alloc_pixels, nalloc_pixels,
 
488
             used_pixels, nused_pixels)
 
489
    Display *display;
 
490
    XpmAttributes *attributes;
 
491
    XpmColor *colors;
 
492
    unsigned int ncolors;
 
493
    Pixel *image_pixels;
 
494
    Pixel *mask_pixels;
 
495
    unsigned int *mask_pixel_index;
 
496
    Pixel *alloc_pixels;
 
497
    unsigned int *nalloc_pixels;
 
498
    Pixel *used_pixels;
 
499
    unsigned int *nused_pixels;
 
500
{
 
501
    /* variables stored in the XpmAttributes structure */
 
502
    Visual *visual;
 
503
    Colormap colormap;
 
504
    XpmColorSymbol *colorsymbols = NULL;
 
505
    unsigned int numsymbols;
 
506
    XpmAllocColorFunc allocColor;
 
507
    void *closure;
 
508
 
 
509
    char *colorname;
 
510
    unsigned int color, key;
 
511
    Bool pixel_defined;
 
512
    XpmColorSymbol *symbol = NULL;
 
513
    char **defaults;
 
514
    int ErrorStatus = XpmSuccess;
 
515
    char *s;
 
516
    int default_index;
 
517
 
 
518
    XColor *cols = NULL;
 
519
    unsigned int ncols = 0;
 
520
 
 
521
    /*
 
522
     * retrieve information from the XpmAttributes
 
523
     */
 
524
    if (attributes && attributes->valuemask & XpmColorSymbols) {
 
525
        colorsymbols = attributes->colorsymbols;
 
526
        numsymbols = attributes->numsymbols;
 
527
    } else
 
528
        numsymbols = 0;
 
529
 
 
530
    if (attributes && attributes->valuemask & XpmVisual)
 
531
        visual = attributes->visual;
 
532
    else
 
533
        visual = XDefaultVisual(display, XDefaultScreen(display));
 
534
 
 
535
    if (attributes && (attributes->valuemask & XpmColormap))
 
536
        colormap = attributes->colormap;
 
537
    else
 
538
        colormap = XDefaultColormap(display, XDefaultScreen(display));
 
539
 
 
540
    if (attributes && (attributes->valuemask & XpmColorKey))
 
541
        key = attributes->color_key;
 
542
    else
 
543
        key = xpmVisualType(visual);
 
544
 
 
545
    if (attributes && (attributes->valuemask & XpmAllocColor))
 
546
        allocColor = attributes->alloc_color;
 
547
    else
 
548
        allocColor = AllocColor;
 
549
    if (attributes && (attributes->valuemask & XpmColorClosure))
 
550
        closure = attributes->color_closure;
 
551
    else
 
552
        closure = NULL;
 
553
 
 
554
#ifndef FOR_MSW
 
555
    if (USE_CLOSECOLOR) {
 
556
        /* originally from SetCloseColor */
 
557
#if 0
 
558
        if (visual->class == DirectColor) {
 
559
 
 
560
            /*
 
561
             * TODO: Implement close colors for DirectColor visuals. This is
 
562
             * difficult situation. Chances are that we will never get here,
 
563
             * because any machine that supports DirectColor will probably
 
564
             * also support TrueColor (and probably PseudoColor). Also,
 
565
             * DirectColor colormaps can be very large, so looking for close
 
566
             * colors may be too slow.
 
567
             */
 
568
        } else {
 
569
#endif
 
570
            unsigned int i;
 
571
 
 
572
            ncols = visual->map_entries;
 
573
            cols = (XColor *) XpmCalloc(ncols, sizeof(XColor));
 
574
            for (i = 0; i < ncols; ++i)
 
575
                cols[i].pixel = i;
 
576
            XQueryColors(display, colormap, cols, ncols);
 
577
#if 0
 
578
        }
 
579
#endif
 
580
    }
 
581
#endif /* ndef FOR_MSW */
 
582
 
 
583
    switch (key) {
 
584
    case XPM_MONO:
 
585
        default_index = 2;
 
586
        break;
 
587
    case XPM_GRAY4:
 
588
        default_index = 3;
 
589
        break;
 
590
    case XPM_GRAY:
 
591
        default_index = 4;
 
592
        break;
 
593
    case XPM_COLOR:
 
594
    default:
 
595
        default_index = 5;
 
596
        break;
 
597
    }
 
598
 
 
599
    for (color = 0; color < ncolors; color++, colors++,
 
600
                                         image_pixels++, mask_pixels++) {
 
601
        colorname = NULL;
 
602
        pixel_defined = False;
 
603
        defaults = (char **) colors;
 
604
 
 
605
        /*
 
606
         * look for a defined symbol
 
607
         */
 
608
        if (numsymbols) {
 
609
 
 
610
            unsigned int n;
 
611
 
 
612
            s = defaults[1];
 
613
            for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) {
 
614
                if (symbol->name && s && !strcmp(symbol->name, s))
 
615
                    /* override name */
 
616
                    break;
 
617
                if (!symbol->name && symbol->value) {   /* override value */
 
618
                    int def_index = default_index;
 
619
 
 
620
                    while (defaults[def_index] == NULL) /* find defined
 
621
                                                         * colorname */
 
622
                        --def_index;
 
623
                    if (def_index < 2) {/* nothing towards mono, so try
 
624
                                         * towards color */
 
625
                        def_index = default_index + 1;
 
626
                        while (def_index <= 5 && defaults[def_index] == NULL)
 
627
                            ++def_index;
 
628
                    }
 
629
                    if (def_index >= 2 && defaults[def_index] != NULL &&
 
630
                        !xpmstrcasecmp(symbol->value, defaults[def_index]))
 
631
                        break;
 
632
                }
 
633
            }
 
634
            if (n != numsymbols) {
 
635
                if (symbol->name && symbol->value)
 
636
                    colorname = symbol->value;
 
637
                else
 
638
                    pixel_defined = True;
 
639
            }
 
640
        }
 
641
        if (!pixel_defined) {           /* pixel not given as symbol value */
 
642
 
 
643
            unsigned int k;
 
644
 
 
645
            if (colorname) {            /* colorname given as symbol value */
 
646
                if (!SetColor(display, colormap, visual, colorname, color,
 
647
                              image_pixels, mask_pixels, mask_pixel_index,
 
648
                              alloc_pixels, nalloc_pixels, used_pixels,
 
649
                              nused_pixels, attributes, cols, ncols,
 
650
                              allocColor, closure))
 
651
                    pixel_defined = True;
 
652
                else
 
653
                    ErrorStatus = XpmColorError;
 
654
            }
 
655
            k = key;
 
656
            while (!pixel_defined && k > 1) {
 
657
                if (defaults[k]) {
 
658
                    if (!SetColor(display, colormap, visual, defaults[k],
 
659
                                  color, image_pixels, mask_pixels,
 
660
                                  mask_pixel_index, alloc_pixels,
 
661
                                  nalloc_pixels, used_pixels, nused_pixels,
 
662
                                  attributes, cols, ncols,
 
663
                                  allocColor, closure)) {
 
664
                        pixel_defined = True;
 
665
                        break;
 
666
                    } else
 
667
                        ErrorStatus = XpmColorError;
 
668
                }
 
669
                k--;
 
670
            }
 
671
            k = key + 1;
 
672
            while (!pixel_defined && k < NKEYS + 1) {
 
673
                if (defaults[k]) {
 
674
                    if (!SetColor(display, colormap, visual, defaults[k],
 
675
                                  color, image_pixels, mask_pixels,
 
676
                                  mask_pixel_index, alloc_pixels,
 
677
                                  nalloc_pixels, used_pixels, nused_pixels,
 
678
                                  attributes, cols, ncols,
 
679
                                  allocColor, closure)) {
 
680
                        pixel_defined = True;
 
681
                        break;
 
682
                    } else
 
683
                        ErrorStatus = XpmColorError;
 
684
                }
 
685
                k++;
 
686
            }
 
687
            if (!pixel_defined) {
 
688
                if (cols)
 
689
                    XpmFree(cols);
 
690
                return (XpmColorFailed);
 
691
            }
 
692
        } else {
 
693
            /* simply use the given pixel */
 
694
            *image_pixels = symbol->pixel;
 
695
            /* the following makes the mask to be built even if none
 
696
               is given a particular pixel */
 
697
            if (symbol->value
 
698
                && !xpmstrcasecmp(symbol->value, TRANSPARENT_COLOR)) {
 
699
                *mask_pixels = 0;
 
700
                *mask_pixel_index = color;
 
701
            } else
 
702
                *mask_pixels = 1;
 
703
            used_pixels[(*nused_pixels)++] = *image_pixels;
 
704
        }
 
705
    }
 
706
    if (cols)
 
707
        XpmFree(cols);
 
708
    return (ErrorStatus);
 
709
}
 
710
 
 
711
 
 
712
/* default FreeColors function, simply call XFreeColors */
 
713
static int
 
714
FreeColors(display, colormap, pixels, n, closure)
 
715
    Display *display;
 
716
    Colormap colormap;
 
717
    Pixel *pixels;
 
718
    int n;
 
719
    void *closure;              /* not used */
 
720
{
 
721
    return XFreeColors(display, colormap, pixels, n, 0);
 
722
}
 
723
 
 
724
 
 
725
/* function call in case of error, frees only locally allocated variables */
 
726
#undef RETURN
 
727
#define RETURN(status) \
 
728
do { \
 
729
    if (ximage) XDestroyImage(ximage); \
 
730
    if (shapeimage) XDestroyImage(shapeimage); \
 
731
    if (image_pixels) XpmFree(image_pixels); \
 
732
    if (mask_pixels) XpmFree(mask_pixels); \
 
733
    if (nalloc_pixels) \
 
734
        (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); \
 
735
    if (alloc_pixels) XpmFree(alloc_pixels); \
 
736
    if (used_pixels) XpmFree(used_pixels); \
 
737
    return (status); \
 
738
} while(0)
 
739
 
 
740
int
 
741
XpmCreateImageFromXpmImage(display, image,
 
742
                           image_return, shapeimage_return, attributes)
 
743
    Display *display;
 
744
    XpmImage *image;
 
745
    XImage **image_return;
 
746
    XImage **shapeimage_return;
 
747
    XpmAttributes *attributes;
 
748
{
 
749
    /* variables stored in the XpmAttributes structure */
 
750
    Visual *visual;
 
751
    Colormap colormap;
 
752
    unsigned int depth;
 
753
    int bitmap_format;
 
754
    XpmFreeColorsFunc freeColors;
 
755
    void *closure;
 
756
 
 
757
    /* variables to return */
 
758
    XImage *ximage = NULL;
 
759
    XImage *shapeimage = NULL;
 
760
    unsigned int mask_pixel_index = XpmUndefPixel;
 
761
    int ErrorStatus;
 
762
 
 
763
    /* calculation variables */
 
764
    Pixel *image_pixels = NULL;
 
765
    Pixel *mask_pixels = NULL;
 
766
    Pixel *alloc_pixels = NULL;
 
767
    Pixel *used_pixels = NULL;
 
768
    unsigned int nalloc_pixels = 0;
 
769
    unsigned int nused_pixels = 0;
 
770
 
 
771
    /* initialize return values */
 
772
    if (image_return)
 
773
        *image_return = NULL;
 
774
    if (shapeimage_return)
 
775
        *shapeimage_return = NULL;
 
776
 
 
777
    /* retrieve information from the XpmAttributes */
 
778
    if (attributes && (attributes->valuemask & XpmVisual))
 
779
        visual = attributes->visual;
 
780
    else
 
781
        visual = XDefaultVisual(display, XDefaultScreen(display));
 
782
 
 
783
    if (attributes && (attributes->valuemask & XpmColormap))
 
784
        colormap = attributes->colormap;
 
785
    else
 
786
        colormap = XDefaultColormap(display, XDefaultScreen(display));
 
787
 
 
788
    if (attributes && (attributes->valuemask & XpmDepth))
 
789
        depth = attributes->depth;
 
790
    else
 
791
        depth = XDefaultDepth(display, XDefaultScreen(display));
 
792
 
 
793
    if (attributes && (attributes->valuemask & XpmBitmapFormat))
 
794
        bitmap_format = attributes->bitmap_format;
 
795
    else
 
796
        bitmap_format = ZPixmap;
 
797
 
 
798
    if (attributes && (attributes->valuemask & XpmFreeColors))
 
799
        freeColors = attributes->free_colors;
 
800
    else
 
801
        freeColors = FreeColors;
 
802
    if (attributes && (attributes->valuemask & XpmColorClosure))
 
803
        closure = attributes->color_closure;
 
804
    else
 
805
        closure = NULL;
 
806
 
 
807
    ErrorStatus = XpmSuccess;
 
808
 
 
809
    if (image->ncolors >= UINT_MAX / sizeof(Pixel)) 
 
810
        return (XpmNoMemory);
 
811
 
 
812
    /* malloc pixels index tables */
 
813
    image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
 
814
    if (!image_pixels)
 
815
        return (XpmNoMemory);
 
816
 
 
817
    mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
 
818
    if (!mask_pixels)
 
819
        RETURN(XpmNoMemory);
 
820
 
 
821
    /* maximum of allocated pixels will be the number of colors */
 
822
    alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
 
823
    if (!alloc_pixels)
 
824
        RETURN(XpmNoMemory);
 
825
 
 
826
    /* maximum of allocated pixels will be the number of colors */
 
827
    used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
 
828
    if (!used_pixels)
 
829
        RETURN(XpmNoMemory);
 
830
 
 
831
    /* get pixel colors, store them in index tables */
 
832
    ErrorStatus = CreateColors(display, attributes, image->colorTable,
 
833
                               image->ncolors, image_pixels, mask_pixels,
 
834
                               &mask_pixel_index, alloc_pixels, &nalloc_pixels,
 
835
                               used_pixels, &nused_pixels);
 
836
 
 
837
    if (ErrorStatus != XpmSuccess
 
838
        && (ErrorStatus < 0 || (attributes
 
839
                                && (attributes->valuemask & XpmExactColors)
 
840
                                && attributes->exactColors)))
 
841
        RETURN(ErrorStatus);
 
842
 
 
843
    /* create the ximage */
 
844
    if (image_return) {
 
845
        ErrorStatus = CreateXImage(display, visual, depth,
 
846
                                   (depth == 1 ? bitmap_format : ZPixmap),
 
847
                                   image->width, image->height, &ximage);
 
848
        if (ErrorStatus != XpmSuccess)
 
849
            RETURN(ErrorStatus);
 
850
 
 
851
#ifndef FOR_MSW
 
852
 
 
853
        /*
 
854
         * set the ximage data using optimized functions for ZPixmap
 
855
         */
 
856
 
 
857
        if (ximage->bits_per_pixel == 8)
 
858
            PutImagePixels8(ximage, image->width, image->height,
 
859
                            image->data, image_pixels);
 
860
        else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
 
861
                 (ximage->byte_order == ximage->bitmap_bit_order))
 
862
            PutImagePixels1(ximage, image->width, image->height,
 
863
                            image->data, image_pixels);
 
864
        else if (ximage->bits_per_pixel == 16)
 
865
            PutImagePixels16(ximage, image->width, image->height,
 
866
                             image->data, image_pixels);
 
867
        else if (ximage->bits_per_pixel == 32)
 
868
            PutImagePixels32(ximage, image->width, image->height,
 
869
                             image->data, image_pixels);
 
870
        else
 
871
            PutImagePixels(ximage, image->width, image->height,
 
872
                           image->data, image_pixels);
 
873
#else  /* FOR_MSW */
 
874
        MSWPutImagePixels(display, ximage, image->width, image->height,
 
875
                          image->data, image_pixels);
 
876
#endif
 
877
    }
 
878
    /* create the shape mask image */
 
879
    if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
 
880
        ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
 
881
                                   image->width, image->height, &shapeimage);
 
882
        if (ErrorStatus != XpmSuccess)
 
883
            RETURN(ErrorStatus);
 
884
 
 
885
#ifndef FOR_MSW
 
886
        PutImagePixels1(shapeimage, image->width, image->height,
 
887
                        image->data, mask_pixels);
 
888
#else
 
889
        MSWPutImagePixels(display, shapeimage, image->width, image->height,
 
890
                          image->data, mask_pixels);
 
891
#endif
 
892
 
 
893
    }
 
894
    XpmFree(image_pixels);
 
895
    XpmFree(mask_pixels);
 
896
 
 
897
    /* if requested return used pixels in the XpmAttributes structure */
 
898
    if (attributes && (attributes->valuemask & XpmReturnPixels ||
 
899
/* 3.2 backward compatibility code */
 
900
        attributes->valuemask & XpmReturnInfos)) {
 
901
/* end 3.2 bc */
 
902
        attributes->pixels = used_pixels;
 
903
        attributes->npixels = nused_pixels;
 
904
        attributes->mask_pixel = mask_pixel_index;
 
905
    } else
 
906
        XpmFree(used_pixels);
 
907
 
 
908
    /* if requested return alloc'ed pixels in the XpmAttributes structure */
 
909
    if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) {
 
910
        attributes->alloc_pixels = alloc_pixels;
 
911
        attributes->nalloc_pixels = nalloc_pixels;
 
912
    } else
 
913
        XpmFree(alloc_pixels);
 
914
 
 
915
    /* return created images */
 
916
    if (image_return)
 
917
        *image_return = ximage;
 
918
    if (shapeimage_return)
 
919
        *shapeimage_return = shapeimage;
 
920
 
 
921
    return (ErrorStatus);
 
922
}
 
923
 
 
924
 
 
925
/*
 
926
 * Create an XImage with its data
 
927
 */
 
928
static int
 
929
CreateXImage(display, visual, depth, format, width, height, image_return)
 
930
    Display *display;
 
931
    Visual *visual;
 
932
    unsigned int depth;
 
933
    int format;
 
934
    unsigned int width;
 
935
    unsigned int height;
 
936
    XImage **image_return;
 
937
{
 
938
    int bitmap_pad;
 
939
 
 
940
    /* first get bitmap_pad */
 
941
    if (depth > 16)
 
942
        bitmap_pad = 32;
 
943
    else if (depth > 8)
 
944
        bitmap_pad = 16;
 
945
    else
 
946
        bitmap_pad = 8;
 
947
 
 
948
    /* then create the XImage with data = NULL and bytes_per_line = 0 */
 
949
    *image_return = XCreateImage(display, visual, depth, format, 0, 0,
 
950
                                 width, height, bitmap_pad, 0);
 
951
    if (!*image_return)
 
952
        return (XpmNoMemory);
 
953
 
 
954
#ifndef FOR_MSW
 
955
    if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX / height) {
 
956
        XDestroyImage(*image_return);
 
957
        return (XpmNoMemory);
 
958
    }
 
959
    if((*image_return)->bytes_per_line == 0 ||  height == 0)
 
960
        return XpmNoMemory;
 
961
    /* now that bytes_per_line must have been set properly alloc data */
 
962
    (*image_return)->data =
 
963
        (char *) XpmMalloc((*image_return)->bytes_per_line * height);
 
964
 
 
965
    if (!(*image_return)->data) {
 
966
        XDestroyImage(*image_return);
 
967
        *image_return = NULL;
 
968
        return (XpmNoMemory);
 
969
    }
 
970
#else
 
971
    /* under FOR_MSW XCreateImage has done it all */
 
972
#endif
 
973
    return (XpmSuccess);
 
974
}
 
975
 
 
976
#ifndef FOR_MSW
 
977
/*
 
978
 * The functions below are written from X11R5 MIT's code (XImUtil.c)
 
979
 *
 
980
 * The idea is to have faster functions than the standard XPutPixel function
 
981
 * to build the image data. Indeed we can speed up things by suppressing tests
 
982
 * performed for each pixel. We do the same tests but at the image level.
 
983
 * We also assume that we use only ZPixmap images with null offsets.
 
984
 */
 
985
 
 
986
LFUNC(_putbits, void, (register char *src, int dstoffset,
 
987
                       register int numbits, register char *dst));
 
988
 
 
989
LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb));
 
990
 
 
991
static unsigned char Const _reverse_byte[0x100] = {
 
992
    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
 
993
    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
 
994
    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
 
995
    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
 
996
    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
 
997
    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
 
998
    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
 
999
    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
 
1000
    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
 
1001
    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
 
1002
    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
 
1003
    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
 
1004
    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
 
1005
    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
 
1006
    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
 
1007
    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
 
1008
    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
 
1009
    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
 
1010
    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
 
1011
    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
 
1012
    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
 
1013
    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
 
1014
    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
 
1015
    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
 
1016
    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
 
1017
    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
 
1018
    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
 
1019
    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
 
1020
    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
 
1021
    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
 
1022
    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
 
1023
    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
 
1024
};
 
1025
 
 
1026
static int
 
1027
_XReverse_Bytes(bpt, nb)
 
1028
    register unsigned char *bpt;
 
1029
    register unsigned int nb;
 
1030
{
 
1031
    do {
 
1032
        *bpt = _reverse_byte[*bpt];
 
1033
        bpt++;
 
1034
    } while (--nb > 0); /* is nb user-controled? */
 
1035
    return 0;
 
1036
}
 
1037
 
 
1038
 
 
1039
void
 
1040
xpm_xynormalizeimagebits(bp, img)
 
1041
    register unsigned char *bp;
 
1042
    register XImage *img;
 
1043
{
 
1044
    register unsigned char c;
 
1045
 
 
1046
    if (img->byte_order != img->bitmap_bit_order) {
 
1047
        switch (img->bitmap_unit) {
 
1048
 
 
1049
        case 16:
 
1050
            c = *bp;
 
1051
            *bp = *(bp + 1);
 
1052
            *(bp + 1) = c;
 
1053
            break;
 
1054
 
 
1055
        case 32:
 
1056
            c = *(bp + 3);
 
1057
            *(bp + 3) = *bp;
 
1058
            *bp = c;
 
1059
            c = *(bp + 2);
 
1060
            *(bp + 2) = *(bp + 1);
 
1061
            *(bp + 1) = c;
 
1062
            break;
 
1063
        }
 
1064
    }
 
1065
    if (img->bitmap_bit_order == MSBFirst)
 
1066
        _XReverse_Bytes(bp, img->bitmap_unit >> 3);
 
1067
}
 
1068
 
 
1069
void
 
1070
xpm_znormalizeimagebits(bp, img)
 
1071
    register unsigned char *bp;
 
1072
    register XImage *img;
 
1073
{
 
1074
    register unsigned char c;
 
1075
 
 
1076
    switch (img->bits_per_pixel) {
 
1077
 
 
1078
    case 2:
 
1079
        _XReverse_Bytes(bp, 1);
 
1080
        break;
 
1081
 
 
1082
    case 4:
 
1083
        *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
 
1084
        break;
 
1085
 
 
1086
    case 16:
 
1087
        c = *bp;
 
1088
        *bp = *(bp + 1);
 
1089
        *(bp + 1) = c;
 
1090
        break;
 
1091
 
 
1092
    case 24:
 
1093
        c = *(bp + 2);
 
1094
        *(bp + 2) = *bp;
 
1095
        *bp = c;
 
1096
        break;
 
1097
 
 
1098
    case 32:
 
1099
        c = *(bp + 3);
 
1100
        *(bp + 3) = *bp;
 
1101
        *bp = c;
 
1102
        c = *(bp + 2);
 
1103
        *(bp + 2) = *(bp + 1);
 
1104
        *(bp + 1) = c;
 
1105
        break;
 
1106
    }
 
1107
}
 
1108
 
 
1109
static unsigned char Const _lomask[0x09] = {
 
1110
0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
 
1111
static unsigned char Const _himask[0x09] = {
 
1112
0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
 
1113
 
 
1114
static void
 
1115
_putbits(src, dstoffset, numbits, dst)
 
1116
    register char *src;                 /* address of source bit string */
 
1117
    int dstoffset;                      /* bit offset into destination;
 
1118
                                         * range is 0-31 */
 
1119
    register int numbits;               /* number of bits to copy to
 
1120
                                         * destination */
 
1121
    register char *dst;                 /* address of destination bit string */
 
1122
{
 
1123
    register unsigned char chlo, chhi;
 
1124
    int hibits;
 
1125
 
 
1126
    dst = dst + (dstoffset >> 3);
 
1127
    dstoffset = dstoffset & 7;
 
1128
    hibits = 8 - dstoffset;
 
1129
    chlo = *dst & _lomask[dstoffset];
 
1130
    for (;;) {
 
1131
        chhi = (*src << dstoffset) & _himask[dstoffset];
 
1132
        if (numbits <= hibits) {
 
1133
            chhi = chhi & _lomask[dstoffset + numbits];
 
1134
            *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
 
1135
            break;
 
1136
        }
 
1137
        *dst = chhi | chlo;
 
1138
        dst++;
 
1139
        numbits = numbits - hibits;
 
1140
        chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
 
1141
        src++;
 
1142
        if (numbits <= dstoffset) {
 
1143
            chlo = chlo & _lomask[numbits];
 
1144
            *dst = (*dst & _himask[numbits]) | chlo;
 
1145
            break;
 
1146
        }
 
1147
        numbits = numbits - dstoffset;
 
1148
    }
 
1149
}
 
1150
 
 
1151
/*
 
1152
 * Default method to write pixels into a Z image data structure.
 
1153
 * The algorithm used is:
 
1154
 *
 
1155
 *      copy the destination bitmap_unit or Zpixel to temp
 
1156
 *      normalize temp if needed
 
1157
 *      copy the pixel bits into the temp
 
1158
 *      renormalize temp if needed
 
1159
 *      copy the temp back into the destination image data
 
1160
 */
 
1161
 
 
1162
static void
 
1163
PutImagePixels(image, width, height, pixelindex, pixels)
 
1164
    XImage *image;
 
1165
    unsigned int width;
 
1166
    unsigned int height;
 
1167
    unsigned int *pixelindex;
 
1168
    Pixel *pixels;
 
1169
{
 
1170
    register char *src;
 
1171
    register char *dst;
 
1172
    register unsigned int *iptr;
 
1173
    register unsigned int x, y;
 
1174
    register char *data;
 
1175
    Pixel pixel, px;
 
1176
    int nbytes, depth, ibu, ibpp, i;
 
1177
 
 
1178
    data = image->data;
 
1179
    iptr = pixelindex;
 
1180
    depth = image->depth;
 
1181
    if (depth == 1) {
 
1182
        ibu = image->bitmap_unit;
 
1183
        for (y = 0; y < height; y++) /* how can we trust height */
 
1184
            for (x = 0; x < width; x++, iptr++) { /* how can we trust width */
 
1185
                pixel = pixels[*iptr];
 
1186
                for (i = 0, px = pixel; i < sizeof(unsigned long);
 
1187
                     i++, px >>= 8)
 
1188
                    ((unsigned char *) &pixel)[i] = px;
 
1189
                src = &data[XYINDEX(x, y, image)];
 
1190
                dst = (char *) &px;
 
1191
                px = 0;
 
1192
                nbytes = ibu >> 3;
 
1193
                for (i = nbytes; --i >= 0;)
 
1194
                    *dst++ = *src++;
 
1195
                XYNORMALIZE(&px, image);
 
1196
                _putbits((char *) &pixel, (x % ibu), 1, (char *) &px);
 
1197
                XYNORMALIZE(&px, image);
 
1198
                src = (char *) &px;
 
1199
                dst = &data[XYINDEX(x, y, image)];
 
1200
                for (i = nbytes; --i >= 0;)
 
1201
                    *dst++ = *src++;
 
1202
            }
 
1203
    } else {
 
1204
        ibpp = image->bits_per_pixel;
 
1205
        for (y = 0; y < height; y++)
 
1206
            for (x = 0; x < width; x++, iptr++) {
 
1207
                pixel = pixels[*iptr];
 
1208
                if (depth == 4)
 
1209
                    pixel &= 0xf;
 
1210
                for (i = 0, px = pixel; i < sizeof(unsigned long); i++,
 
1211
                     px >>= 8)
 
1212
                    ((unsigned char *) &pixel)[i] = px;
 
1213
                src = &data[ZINDEX(x, y, image)];
 
1214
                dst = (char *) &px;
 
1215
                px = 0;
 
1216
                nbytes = (ibpp + 7) >> 3;
 
1217
                for (i = nbytes; --i >= 0;)
 
1218
                    *dst++ = *src++;
 
1219
                ZNORMALIZE(&px, image);
 
1220
                _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
 
1221
                ZNORMALIZE(&px, image);
 
1222
                src = (char *) &px;
 
1223
                dst = &data[ZINDEX(x, y, image)];
 
1224
                for (i = nbytes; --i >= 0;)
 
1225
                    *dst++ = *src++;
 
1226
            }
 
1227
    }
 
1228
}
 
1229
 
 
1230
/*
 
1231
 * write pixels into a 32-bits Z image data structure
 
1232
 */
 
1233
 
 
1234
#if !defined(WORD64) && !defined(LONG64)
 
1235
/* this item is static but deterministic so let it slide; doesn't
 
1236
 * hurt re-entrancy of this library. Note if it is actually const then would
 
1237
 * be OK under rules of ANSI-C but probably not C++ which may not
 
1238
 * want to allocate space for it.
 
1239
 */
 
1240
static unsigned long byteorderpixel = MSBFirst << 24;
 
1241
 
 
1242
#endif
 
1243
 
 
1244
/*
 
1245
   WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original
 
1246
   3.2e code - by default you get the speeded-up version.
 
1247
*/
 
1248
 
 
1249
static void
 
1250
PutImagePixels32(image, width, height, pixelindex, pixels)
 
1251
    XImage *image;
 
1252
    unsigned int width;
 
1253
    unsigned int height;
 
1254
    unsigned int *pixelindex;
 
1255
    Pixel *pixels;
 
1256
{
 
1257
    unsigned char *data;
 
1258
    unsigned int *iptr;
 
1259
    unsigned int y;
 
1260
    Pixel pixel;
 
1261
 
 
1262
#ifdef WITHOUT_SPEEDUPS
 
1263
 
 
1264
    unsigned int x;
 
1265
    unsigned char *addr;
 
1266
 
 
1267
    data = (unsigned char *) image->data;
 
1268
    iptr = pixelindex;
 
1269
#if !defined(WORD64) && !defined(LONG64)
 
1270
    if (*((char *) &byteorderpixel) == image->byte_order) {
 
1271
        for (y = 0; y < height; y++)
 
1272
            for (x = 0; x < width; x++, iptr++) {
 
1273
                addr = &data[ZINDEX32(x, y, image)];
 
1274
                *((unsigned long *) addr) = pixels[*iptr];
 
1275
            }
 
1276
    } else
 
1277
#endif
 
1278
    if (image->byte_order == MSBFirst)
 
1279
        for (y = 0; y < height; y++)
 
1280
            for (x = 0; x < width; x++, iptr++) {
 
1281
                addr = &data[ZINDEX32(x, y, image)];
 
1282
                pixel = pixels[*iptr];
 
1283
                addr[0] = pixel >> 24;
 
1284
                addr[1] = pixel >> 16;
 
1285
                addr[2] = pixel >> 8;
 
1286
                addr[3] = pixel;
 
1287
            }
 
1288
    else
 
1289
        for (y = 0; y < height; y++)
 
1290
            for (x = 0; x < width; x++, iptr++) {
 
1291
                addr = &data[ZINDEX32(x, y, image)];
 
1292
                pixel = pixels[*iptr];
 
1293
                addr[0] = pixel;
 
1294
                addr[1] = pixel >> 8;
 
1295
                addr[2] = pixel >> 16;
 
1296
                addr[3] = pixel >> 24;
 
1297
            }
 
1298
 
 
1299
#else  /* WITHOUT_SPEEDUPS */
 
1300
 
 
1301
    unsigned int bpl = image->bytes_per_line;
 
1302
    unsigned char *data_ptr, *max_data;
 
1303
 
 
1304
    data = (unsigned char *) image->data;
 
1305
    iptr = pixelindex;
 
1306
#if !defined(WORD64) && !defined(LONG64)
 
1307
    if (*((char *) &byteorderpixel) == image->byte_order) {
 
1308
        for (y = 0; y < height; y++) {
 
1309
            data_ptr = data;
 
1310
            max_data = data_ptr + (width << 2);
 
1311
 
 
1312
            while (data_ptr < max_data) {
 
1313
                *((unsigned long *) data_ptr) = pixels[*(iptr++)];
 
1314
                data_ptr += (1 << 2);
 
1315
            }
 
1316
            data += bpl;
 
1317
        }
 
1318
    } else
 
1319
#endif
 
1320
    if (image->byte_order == MSBFirst)
 
1321
        for (y = 0; y < height; y++) {
 
1322
            data_ptr = data;
 
1323
            max_data = data_ptr + (width << 2);
 
1324
 
 
1325
            while (data_ptr < max_data) {
 
1326
                pixel = pixels[*(iptr++)];
 
1327
 
 
1328
                *data_ptr++ = pixel >> 24;
 
1329
                *data_ptr++ = pixel >> 16;
 
1330
                *data_ptr++ = pixel >> 8;
 
1331
                *data_ptr++ = pixel;
 
1332
 
 
1333
            }
 
1334
            data += bpl;
 
1335
        }
 
1336
    else
 
1337
        for (y = 0; y < height; y++) {
 
1338
            data_ptr = data;
 
1339
            max_data = data_ptr + (width << 2);
 
1340
 
 
1341
            while (data_ptr < max_data) {
 
1342
                pixel = pixels[*(iptr++)];
 
1343
 
 
1344
                *data_ptr++ = pixel;
 
1345
                *data_ptr++ = pixel >> 8;
 
1346
                *data_ptr++ = pixel >> 16;
 
1347
                *data_ptr++ = pixel >> 24;
 
1348
            }
 
1349
            data += bpl;
 
1350
        }
 
1351
 
 
1352
#endif /* WITHOUT_SPEEDUPS */
 
1353
}
 
1354
 
 
1355
/*
 
1356
 * write pixels into a 16-bits Z image data structure
 
1357
 */
 
1358
 
 
1359
static void
 
1360
PutImagePixels16(image, width, height, pixelindex, pixels)
 
1361
    XImage *image;
 
1362
    unsigned int width;
 
1363
    unsigned int height;
 
1364
    unsigned int *pixelindex;
 
1365
    Pixel *pixels;
 
1366
{
 
1367
    unsigned char *data;
 
1368
    unsigned int *iptr;
 
1369
    unsigned int y;
 
1370
 
 
1371
#ifdef WITHOUT_SPEEDUPS
 
1372
 
 
1373
    unsigned int x;
 
1374
    unsigned char *addr;
 
1375
 
 
1376
    data = (unsigned char *) image->data;
 
1377
    iptr = pixelindex;
 
1378
    if (image->byte_order == MSBFirst)
 
1379
        for (y = 0; y < height; y++)
 
1380
            for (x = 0; x < width; x++, iptr++) {
 
1381
                addr = &data[ZINDEX16(x, y, image)];
 
1382
                addr[0] = pixels[*iptr] >> 8;
 
1383
                addr[1] = pixels[*iptr];
 
1384
            }
 
1385
    else
 
1386
        for (y = 0; y < height; y++)
 
1387
            for (x = 0; x < width; x++, iptr++) {
 
1388
                addr = &data[ZINDEX16(x, y, image)];
 
1389
                addr[0] = pixels[*iptr];
 
1390
                addr[1] = pixels[*iptr] >> 8;
 
1391
            }
 
1392
 
 
1393
#else  /* WITHOUT_SPEEDUPS */
 
1394
 
 
1395
    Pixel pixel;
 
1396
 
 
1397
    unsigned int bpl = image->bytes_per_line;
 
1398
    unsigned char *data_ptr, *max_data;
 
1399
 
 
1400
    data = (unsigned char *) image->data;
 
1401
    iptr = pixelindex;
 
1402
    if (image->byte_order == MSBFirst)
 
1403
        for (y = 0; y < height; y++) {
 
1404
            data_ptr = data;
 
1405
            max_data = data_ptr + (width << 1);
 
1406
 
 
1407
            while (data_ptr < max_data) {
 
1408
                pixel = pixels[*(iptr++)];
 
1409
 
 
1410
                data_ptr[0] = pixel >> 8;
 
1411
                data_ptr[1] = pixel;
 
1412
 
 
1413
                data_ptr += (1 << 1);
 
1414
            }
 
1415
            data += bpl;
 
1416
        }
 
1417
    else
 
1418
        for (y = 0; y < height; y++) {
 
1419
            data_ptr = data;
 
1420
            max_data = data_ptr + (width << 1);
 
1421
 
 
1422
            while (data_ptr < max_data) {
 
1423
                pixel = pixels[*(iptr++)];
 
1424
 
 
1425
                data_ptr[0] = pixel;
 
1426
                data_ptr[1] = pixel >> 8;
 
1427
 
 
1428
                data_ptr += (1 << 1);
 
1429
            }
 
1430
            data += bpl;
 
1431
        }
 
1432
 
 
1433
#endif /* WITHOUT_SPEEDUPS */
 
1434
}
 
1435
 
 
1436
/*
 
1437
 * write pixels into a 8-bits Z image data structure
 
1438
 */
 
1439
 
 
1440
static void
 
1441
PutImagePixels8(image, width, height, pixelindex, pixels)
 
1442
    XImage *image;
 
1443
    unsigned int width;
 
1444
    unsigned int height;
 
1445
    unsigned int *pixelindex;
 
1446
    Pixel *pixels;
 
1447
{
 
1448
    char *data;
 
1449
    unsigned int *iptr;
 
1450
    unsigned int y;
 
1451
 
 
1452
#ifdef WITHOUT_SPEEDUPS
 
1453
 
 
1454
    unsigned int x;
 
1455
 
 
1456
    data = image->data;
 
1457
    iptr = pixelindex;
 
1458
    for (y = 0; y < height; y++)
 
1459
        for (x = 0; x < width; x++, iptr++)
 
1460
            data[ZINDEX8(x, y, image)] = pixels[*iptr];
 
1461
 
 
1462
#else  /* WITHOUT_SPEEDUPS */
 
1463
 
 
1464
    unsigned int bpl = image->bytes_per_line;
 
1465
    char *data_ptr, *max_data;
 
1466
 
 
1467
    data = image->data;
 
1468
    iptr = pixelindex;
 
1469
 
 
1470
    for (y = 0; y < height; y++) {
 
1471
        data_ptr = data;
 
1472
        max_data = data_ptr + width;
 
1473
 
 
1474
        while (data_ptr < max_data)
 
1475
            *(data_ptr++) = pixels[*(iptr++)];
 
1476
 
 
1477
        data += bpl;
 
1478
    }
 
1479
 
 
1480
#endif /* WITHOUT_SPEEDUPS */
 
1481
}
 
1482
 
 
1483
/*
 
1484
 * write pixels into a 1-bit depth image data structure and **offset null**
 
1485
 */
 
1486
 
 
1487
static void
 
1488
PutImagePixels1(image, width, height, pixelindex, pixels)
 
1489
    XImage *image;
 
1490
    unsigned int width;
 
1491
    unsigned int height;
 
1492
    unsigned int *pixelindex;
 
1493
    Pixel *pixels;
 
1494
{
 
1495
    if (image->byte_order != image->bitmap_bit_order)
 
1496
        PutImagePixels(image, width, height, pixelindex, pixels);
 
1497
    else {
 
1498
        unsigned int *iptr;
 
1499
        unsigned int y;
 
1500
        char *data;
 
1501
 
 
1502
#ifdef WITHOUT_SPEEDUPS
 
1503
 
 
1504
        unsigned int x;
 
1505
 
 
1506
        data = image->data;
 
1507
        iptr = pixelindex;
 
1508
        if (image->bitmap_bit_order == MSBFirst)
 
1509
            for (y = 0; y < height; y++)
 
1510
                for (x = 0; x < width; x++, iptr++) {
 
1511
                    if (pixels[*iptr] & 1)
 
1512
                        data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7);
 
1513
                    else
 
1514
                        data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7));
 
1515
                }
 
1516
        else
 
1517
            for (y = 0; y < height; y++)
 
1518
                for (x = 0; x < width; x++, iptr++) {
 
1519
                    if (pixels[*iptr] & 1)
 
1520
                        data[ZINDEX1(x, y, image)] |= 1 << (x & 7);
 
1521
                    else
 
1522
                        data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7));
 
1523
                }
 
1524
 
 
1525
#else  /* WITHOUT_SPEEDUPS */
 
1526
 
 
1527
        char value;
 
1528
        char *data_ptr, *max_data;
 
1529
        int bpl = image->bytes_per_line;
 
1530
        int diff, count;
 
1531
 
 
1532
        data = image->data;
 
1533
        iptr = pixelindex;
 
1534
 
 
1535
        diff = width & 7;
 
1536
        width >>= 3;
 
1537
 
 
1538
        if (image->bitmap_bit_order == MSBFirst)
 
1539
            for (y = 0; y < height; y++) {
 
1540
                data_ptr = data;
 
1541
                max_data = data_ptr + width;
 
1542
                while (data_ptr < max_data) {
 
1543
                    value = 0;
 
1544
 
 
1545
                    value = (value << 1) | (pixels[*(iptr++)] & 1);
 
1546
                    value = (value << 1) | (pixels[*(iptr++)] & 1);
 
1547
                    value = (value << 1) | (pixels[*(iptr++)] & 1);
 
1548
                    value = (value << 1) | (pixels[*(iptr++)] & 1);
 
1549
                    value = (value << 1) | (pixels[*(iptr++)] & 1);
 
1550
                    value = (value << 1) | (pixels[*(iptr++)] & 1);
 
1551
                    value = (value << 1) | (pixels[*(iptr++)] & 1);
 
1552
                    value = (value << 1) | (pixels[*(iptr++)] & 1);
 
1553
 
 
1554
                    *(data_ptr++) = value;
 
1555
                }
 
1556
                if (diff) {
 
1557
                    value = 0;
 
1558
                    for (count = 0; count < diff; count++) {
 
1559
                        if (pixels[*(iptr++)] & 1)
 
1560
                            value |= (0x80 >> count);
 
1561
                    }
 
1562
                    *(data_ptr) = value;
 
1563
                }
 
1564
                data += bpl;
 
1565
            }
 
1566
        else
 
1567
            for (y = 0; y < height; y++) {
 
1568
                data_ptr = data;
 
1569
                max_data = data_ptr + width;
 
1570
                while (data_ptr < max_data) {
 
1571
                    value = 0;
 
1572
                    iptr += 8;
 
1573
 
 
1574
                    value = (value << 1) | (pixels[*(--iptr)] & 1);
 
1575
                    value = (value << 1) | (pixels[*(--iptr)] & 1);
 
1576
                    value = (value << 1) | (pixels[*(--iptr)] & 1);
 
1577
                    value = (value << 1) | (pixels[*(--iptr)] & 1);
 
1578
                    value = (value << 1) | (pixels[*(--iptr)] & 1);
 
1579
                    value = (value << 1) | (pixels[*(--iptr)] & 1);
 
1580
                    value = (value << 1) | (pixels[*(--iptr)] & 1);
 
1581
                    value = (value << 1) | (pixels[*(--iptr)] & 1);
 
1582
 
 
1583
                    iptr += 8;
 
1584
                    *(data_ptr++) = value;
 
1585
                }
 
1586
                if (diff) {
 
1587
                    value = 0;
 
1588
                    for (count = 0; count < diff; count++) {
 
1589
                        if (pixels[*(iptr++)] & 1)
 
1590
                            value |= (1 << count);
 
1591
                    }
 
1592
                    *(data_ptr) = value;
 
1593
                }
 
1594
                data += bpl;
 
1595
            }
 
1596
 
 
1597
#endif /* WITHOUT_SPEEDUPS */
 
1598
    }
 
1599
}
 
1600
 
 
1601
int
 
1602
XpmCreatePixmapFromXpmImage(display, d, image,
 
1603
                            pixmap_return, shapemask_return, attributes)
 
1604
    Display *display;
 
1605
    Drawable d;
 
1606
    XpmImage *image;
 
1607
    Pixmap *pixmap_return;
 
1608
    Pixmap *shapemask_return;
 
1609
    XpmAttributes *attributes;
 
1610
{
 
1611
    XImage *ximage, *shapeimage;
 
1612
    int ErrorStatus;
 
1613
 
 
1614
    /* initialize return values */
 
1615
    if (pixmap_return)
 
1616
        *pixmap_return = 0;
 
1617
    if (shapemask_return)
 
1618
        *shapemask_return = 0;
 
1619
 
 
1620
    /* create the ximages */
 
1621
    ErrorStatus = XpmCreateImageFromXpmImage(display, image,
 
1622
                                             (pixmap_return ? &ximage : NULL),
 
1623
                                             (shapemask_return ?
 
1624
                                              &shapeimage : NULL),
 
1625
                                             attributes);
 
1626
    if (ErrorStatus < 0)
 
1627
        return (ErrorStatus);
 
1628
 
 
1629
    /* create the pixmaps and destroy images */
 
1630
    if (pixmap_return && ximage) {
 
1631
        xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
 
1632
        XDestroyImage(ximage);
 
1633
    }
 
1634
    if (shapemask_return && shapeimage) {
 
1635
        xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
 
1636
        XDestroyImage(shapeimage);
 
1637
    }
 
1638
    return (ErrorStatus);
 
1639
}
 
1640
 
 
1641
#else  /* FOR_MSW part follows */
 
1642
static void
 
1643
MSWPutImagePixels(dc, image, width, height, pixelindex, pixels)
 
1644
    Display *dc;
 
1645
    XImage *image;
 
1646
    unsigned int width;
 
1647
    unsigned int height;
 
1648
    unsigned int *pixelindex;
 
1649
    Pixel *pixels;
 
1650
{
 
1651
    unsigned int *data = pixelindex;
 
1652
    unsigned int x, y;
 
1653
 
 
1654
    SelectObject(*dc, image->bitmap);
 
1655
    for (y = 0; y < height; y++) {
 
1656
        for (x = 0; x < width; x++) {
 
1657
            SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */
 
1658
        }
 
1659
    }
 
1660
}
 
1661
 
 
1662
#endif /* FOR_MSW */
 
1663
 
 
1664
 
 
1665
 
 
1666
#ifndef FOR_MSW
 
1667
 
 
1668
static int
 
1669
PutPixel1(ximage, x, y, pixel)
 
1670
    register XImage *ximage;
 
1671
    int x;
 
1672
    int y;
 
1673
    unsigned long pixel;
 
1674
{
 
1675
    register char *src;
 
1676
    register char *dst;
 
1677
    register int i;
 
1678
    register char *data;
 
1679
    Pixel px;
 
1680
    int nbytes;
 
1681
 
 
1682
    if(x < 0 || y < 0)
 
1683
        return 0;
 
1684
 
 
1685
    for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8)
 
1686
        ((unsigned char *)&pixel)[i] = px;
 
1687
    src = &ximage->data[XYINDEX(x, y, ximage)];
 
1688
    dst = (char *)&px;
 
1689
    px = 0;
 
1690
    nbytes = ximage->bitmap_unit >> 3;
 
1691
    for (i = nbytes; --i >= 0; ) *dst++ = *src++;
 
1692
    XYNORMALIZE(&px, ximage);
 
1693
    i = ((x + ximage->xoffset) % ximage->bitmap_unit);
 
1694
    _putbits ((char *)&pixel, i, 1, (char *)&px);
 
1695
    XYNORMALIZE(&px, ximage);
 
1696
    src = (char *) &px;
 
1697
    dst = &ximage->data[XYINDEX(x, y, ximage)];
 
1698
    for (i = nbytes; --i >= 0; )
 
1699
        *dst++ = *src++;
 
1700
 
 
1701
    return 1;
 
1702
}
 
1703
 
 
1704
static int
 
1705
PutPixel(ximage, x, y, pixel)
 
1706
    register XImage *ximage;
 
1707
    int x;
 
1708
    int y;
 
1709
    unsigned long pixel;
 
1710
{
 
1711
    register char *src;
 
1712
    register char *dst;
 
1713
    register int i;
 
1714
    register char *data;
 
1715
    Pixel px;
 
1716
    unsigned int nbytes, ibpp;
 
1717
 
 
1718
    if(x < 0 || y < 0)
 
1719
        return 0;
 
1720
 
 
1721
    ibpp = ximage->bits_per_pixel;
 
1722
    if (ximage->depth == 4)
 
1723
        pixel &= 0xf;
 
1724
    for (i = 0, px = pixel; i < sizeof(unsigned long); i++, px >>= 8)
 
1725
        ((unsigned char *) &pixel)[i] = px;
 
1726
    src = &ximage->data[ZINDEX(x, y, ximage)];
 
1727
    dst = (char *) &px;
 
1728
    px = 0;
 
1729
    nbytes = (ibpp + 7) >> 3;
 
1730
    for (i = nbytes; --i >= 0;)
 
1731
        *dst++ = *src++;
 
1732
    ZNORMALIZE(&px, ximage);
 
1733
    _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
 
1734
    ZNORMALIZE(&px, ximage);
 
1735
    src = (char *) &px;
 
1736
    dst = &ximage->data[ZINDEX(x, y, ximage)];
 
1737
    for (i = nbytes; --i >= 0;)
 
1738
        *dst++ = *src++;
 
1739
 
 
1740
    return 1;
 
1741
}
 
1742
 
 
1743
static int
 
1744
PutPixel32(ximage, x, y, pixel)
 
1745
    register XImage *ximage;
 
1746
    int x;
 
1747
    int y;
 
1748
    unsigned long pixel;
 
1749
{
 
1750
    unsigned char *addr;
 
1751
 
 
1752
    if(x < 0 || y < 0)
 
1753
        return 0;
 
1754
 
 
1755
    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
 
1756
    *((unsigned long *)addr) = pixel;
 
1757
    return 1;
 
1758
}
 
1759
 
 
1760
static int
 
1761
PutPixel32MSB(ximage, x, y, pixel)
 
1762
    register XImage *ximage;
 
1763
    int x;
 
1764
    int y;
 
1765
    unsigned long pixel;
 
1766
{
 
1767
    unsigned char *addr;
 
1768
 
 
1769
    if(x < 0 || y < 0)
 
1770
        return 0;
 
1771
 
 
1772
    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
 
1773
    addr[0] = pixel >> 24;
 
1774
    addr[1] = pixel >> 16;
 
1775
    addr[2] = pixel >> 8;
 
1776
    addr[3] = pixel;
 
1777
    return 1;
 
1778
}
 
1779
 
 
1780
static int
 
1781
PutPixel32LSB(ximage, x, y, pixel)
 
1782
    register XImage *ximage;
 
1783
    int x;
 
1784
    int y;
 
1785
    unsigned long pixel;
 
1786
{
 
1787
    unsigned char *addr;
 
1788
 
 
1789
    if(x < 0 || y < 0)
 
1790
        return 0;
 
1791
 
 
1792
    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
 
1793
    addr[3] = pixel >> 24;
 
1794
    addr[2] = pixel >> 16;
 
1795
    addr[1] = pixel >> 8;
 
1796
    addr[0] = pixel;
 
1797
    return 1;
 
1798
}
 
1799
 
 
1800
static int
 
1801
PutPixel16MSB(ximage, x, y, pixel)
 
1802
    register XImage *ximage;
 
1803
    int x;
 
1804
    int y;
 
1805
    unsigned long pixel;
 
1806
{
 
1807
    unsigned char *addr;
 
1808
    
 
1809
    if(x < 0 || y < 0)
 
1810
        return 0;
 
1811
 
 
1812
    addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
 
1813
    addr[0] = pixel >> 8;
 
1814
    addr[1] = pixel;
 
1815
    return 1;
 
1816
}
 
1817
 
 
1818
static int
 
1819
PutPixel16LSB(ximage, x, y, pixel)
 
1820
    register XImage *ximage;
 
1821
    int x;
 
1822
    int y;
 
1823
    unsigned long pixel;
 
1824
{
 
1825
    unsigned char *addr;
 
1826
    
 
1827
    if(x < 0 || y < 0)
 
1828
        return 0;
 
1829
 
 
1830
    addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
 
1831
    addr[1] = pixel >> 8;
 
1832
    addr[0] = pixel;
 
1833
    return 1;
 
1834
}
 
1835
 
 
1836
static int
 
1837
PutPixel8(ximage, x, y, pixel)
 
1838
    register XImage *ximage;
 
1839
    int x;
 
1840
    int y;
 
1841
    unsigned long pixel;
 
1842
{
 
1843
    if(x < 0 || y < 0)
 
1844
        return 0;
 
1845
 
 
1846
    ximage->data[ZINDEX8(x, y, ximage)] = pixel;
 
1847
    return 1;
 
1848
}
 
1849
 
 
1850
static int
 
1851
PutPixel1MSB(ximage, x, y, pixel)
 
1852
    register XImage *ximage;
 
1853
    int x;
 
1854
    int y;
 
1855
    unsigned long pixel;
 
1856
{
 
1857
    if(x < 0 || y < 0)
 
1858
        return 0;
 
1859
 
 
1860
    if (pixel & 1)
 
1861
        ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7);
 
1862
    else
 
1863
        ximage->data[ZINDEX1(x, y, ximage)] &= ~(0x80 >> (x & 7));
 
1864
    return 1;
 
1865
}
 
1866
 
 
1867
static int
 
1868
PutPixel1LSB(ximage, x, y, pixel)
 
1869
    register XImage *ximage;
 
1870
    int x;
 
1871
    int y;
 
1872
    unsigned long pixel;
 
1873
{
 
1874
    if(x < 0 || y < 0)
 
1875
        return 0;
 
1876
 
 
1877
    if (pixel & 1)
 
1878
        ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7);
 
1879
    else
 
1880
        ximage->data[ZINDEX1(x, y, ximage)] &= ~(1 << (x & 7));
 
1881
    return 1;
 
1882
}
 
1883
 
 
1884
#endif /* FOR_MSW */
 
1885
 
 
1886
/* function call in case of error, frees only locally allocated variables */
 
1887
#undef RETURN
 
1888
#define RETURN(status) \
 
1889
{ \
 
1890
    if (USE_HASHTABLE) xpmHashTableFree(&hashtable); \
 
1891
    if (colorTable) xpmFreeColorTable(colorTable, ncolors); \
 
1892
    if (hints_cmt)  XpmFree(hints_cmt); \
 
1893
    if (colors_cmt) XpmFree(colors_cmt); \
 
1894
    if (pixels_cmt) XpmFree(pixels_cmt); \
 
1895
    if (ximage) XDestroyImage(ximage); \
 
1896
    if (shapeimage) XDestroyImage(shapeimage); \
 
1897
    if (image_pixels) XpmFree(image_pixels); \
 
1898
    if (mask_pixels) XpmFree(mask_pixels); \
 
1899
    if (nalloc_pixels) \
 
1900
        (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); \
 
1901
    if (alloc_pixels) XpmFree(alloc_pixels); \
 
1902
    if (used_pixels) XpmFree(used_pixels); \
 
1903
    return(status); \
 
1904
}
 
1905
 
 
1906
/*
 
1907
 * This function parses an Xpm file or data and directly create an XImage
 
1908
 */
 
1909
int
 
1910
xpmParseDataAndCreate(display, data, image_return, shapeimage_return,
 
1911
                      image, info, attributes)
 
1912
    Display *display;
 
1913
    xpmData *data;
 
1914
    XImage **image_return;
 
1915
    XImage **shapeimage_return;
 
1916
    XpmImage *image;
 
1917
    XpmInfo *info;
 
1918
    XpmAttributes *attributes;
 
1919
{
 
1920
    /* variables stored in the XpmAttributes structure */
 
1921
    Visual *visual;
 
1922
    Colormap colormap;
 
1923
    unsigned int depth;
 
1924
    int bitmap_format;
 
1925
    XpmFreeColorsFunc freeColors;
 
1926
    void *closure;
 
1927
 
 
1928
    /* variables to return */
 
1929
    XImage *ximage = NULL;
 
1930
    XImage *shapeimage = NULL;
 
1931
    unsigned int mask_pixel_index = XpmUndefPixel;
 
1932
 
 
1933
    /* calculation variables */
 
1934
    Pixel *image_pixels = NULL;
 
1935
    Pixel *mask_pixels = NULL;
 
1936
    Pixel *alloc_pixels = NULL;
 
1937
    Pixel *used_pixels = NULL;
 
1938
    unsigned int nalloc_pixels = 0;
 
1939
    unsigned int nused_pixels = 0;
 
1940
    unsigned int width, height, ncolors, cpp;
 
1941
    unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0;
 
1942
    XpmColor *colorTable = NULL;
 
1943
    char *hints_cmt = NULL;
 
1944
    char *colors_cmt = NULL;
 
1945
    char *pixels_cmt = NULL;
 
1946
 
 
1947
    unsigned int cmts;
 
1948
    int ErrorStatus;
 
1949
    xpmHashTable hashtable;
 
1950
 
 
1951
 
 
1952
    /* initialize return values */
 
1953
    if (image_return)
 
1954
        *image_return = NULL;
 
1955
    if (shapeimage_return)
 
1956
        *shapeimage_return = NULL;
 
1957
 
 
1958
 
 
1959
    /* retrieve information from the XpmAttributes */
 
1960
    if (attributes && (attributes->valuemask & XpmVisual))
 
1961
        visual = attributes->visual;
 
1962
    else
 
1963
        visual = XDefaultVisual(display, XDefaultScreen(display));
 
1964
 
 
1965
    if (attributes && (attributes->valuemask & XpmColormap))
 
1966
        colormap = attributes->colormap;
 
1967
    else
 
1968
        colormap = XDefaultColormap(display, XDefaultScreen(display));
 
1969
 
 
1970
    if (attributes && (attributes->valuemask & XpmDepth))
 
1971
        depth = attributes->depth;
 
1972
    else
 
1973
        depth = XDefaultDepth(display, XDefaultScreen(display));
 
1974
 
 
1975
    if (attributes && (attributes->valuemask & XpmBitmapFormat))
 
1976
        bitmap_format = attributes->bitmap_format;
 
1977
    else
 
1978
        bitmap_format = ZPixmap;
 
1979
 
 
1980
    if (attributes && (attributes->valuemask & XpmFreeColors))
 
1981
        freeColors = attributes->free_colors;
 
1982
    else
 
1983
        freeColors = FreeColors;
 
1984
    if (attributes && (attributes->valuemask & XpmColorClosure))
 
1985
        closure = attributes->color_closure;
 
1986
    else
 
1987
        closure = NULL;
 
1988
 
 
1989
    cmts = info && (info->valuemask & XpmReturnComments);
 
1990
 
 
1991
    /*
 
1992
     * parse the header
 
1993
     */
 
1994
    ErrorStatus = xpmParseHeader(data);
 
1995
    if (ErrorStatus != XpmSuccess)
 
1996
        return (ErrorStatus);
 
1997
 
 
1998
    /*
 
1999
     * read values
 
2000
     */
 
2001
    ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp,
 
2002
                                 &x_hotspot, &y_hotspot, &hotspot,
 
2003
                                 &extensions);
 
2004
    if (ErrorStatus != XpmSuccess)
 
2005
        return (ErrorStatus);
 
2006
 
 
2007
    /*
 
2008
     * store the hints comment line
 
2009
     */
 
2010
    if (cmts)
 
2011
        xpmGetCmt(data, &hints_cmt);
 
2012
 
 
2013
    /*
 
2014
     * init the hastable
 
2015
     */
 
2016
    if (USE_HASHTABLE) {
 
2017
        ErrorStatus = xpmHashTableInit(&hashtable);
 
2018
        if (ErrorStatus != XpmSuccess)
 
2019
            return (ErrorStatus);
 
2020
    }
 
2021
 
 
2022
    /*
 
2023
     * read colors
 
2024
     */
 
2025
    ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable);
 
2026
    if (ErrorStatus != XpmSuccess)
 
2027
        RETURN(ErrorStatus);
 
2028
 
 
2029
    /*
 
2030
     * store the colors comment line
 
2031
     */
 
2032
    if (cmts)
 
2033
        xpmGetCmt(data, &colors_cmt);
 
2034
 
 
2035
    /* malloc pixels index tables */
 
2036
    if (ncolors >= UINT_MAX / sizeof(Pixel)) 
 
2037
      RETURN (XpmNoMemory);
 
2038
 
 
2039
    image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
 
2040
    if (!image_pixels)
 
2041
        RETURN(XpmNoMemory);
 
2042
 
 
2043
    mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
 
2044
    if (!mask_pixels)
 
2045
        RETURN(XpmNoMemory);
 
2046
 
 
2047
    /* maximum of allocated pixels will be the number of colors */
 
2048
    alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
 
2049
    if (!alloc_pixels)
 
2050
        RETURN(XpmNoMemory);
 
2051
 
 
2052
    /* maximum of allocated pixels will be the number of colors */
 
2053
    used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
 
2054
    if (!used_pixels)
 
2055
        RETURN(XpmNoMemory);
 
2056
 
 
2057
    /* get pixel colors, store them in index tables */
 
2058
    ErrorStatus = CreateColors(display, attributes, colorTable, ncolors,
 
2059
                               image_pixels, mask_pixels, &mask_pixel_index,
 
2060
                               alloc_pixels, &nalloc_pixels, used_pixels,
 
2061
                               &nused_pixels);
 
2062
 
 
2063
    if (ErrorStatus != XpmSuccess
 
2064
        && (ErrorStatus < 0 || (attributes
 
2065
                                && (attributes->valuemask & XpmExactColors)
 
2066
                                && attributes->exactColors)))
 
2067
        RETURN(ErrorStatus);
 
2068
 
 
2069
    /* now create the ximage */
 
2070
    if (image_return) {
 
2071
        ErrorStatus = CreateXImage(display, visual, depth,
 
2072
                                   (depth == 1 ? bitmap_format : ZPixmap),
 
2073
                                   width, height, &ximage);
 
2074
        if (ErrorStatus != XpmSuccess)
 
2075
            RETURN(ErrorStatus);
 
2076
 
 
2077
#ifndef FOR_MSW
 
2078
 
 
2079
        /*
 
2080
         * set the XImage pointer function, to be used with XPutPixel,
 
2081
         * to an internal optimized function
 
2082
         */
 
2083
 
 
2084
        if (ximage->bits_per_pixel == 8)
 
2085
            ximage->f.put_pixel = PutPixel8;
 
2086
        else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
 
2087
                 (ximage->byte_order == ximage->bitmap_bit_order))
 
2088
            if (ximage->bitmap_bit_order == MSBFirst)
 
2089
                ximage->f.put_pixel = PutPixel1MSB;
 
2090
            else
 
2091
                ximage->f.put_pixel = PutPixel1LSB;
 
2092
        else if (ximage->bits_per_pixel == 16)
 
2093
            if (ximage->bitmap_bit_order == MSBFirst)
 
2094
                ximage->f.put_pixel = PutPixel16MSB;
 
2095
            else
 
2096
                ximage->f.put_pixel = PutPixel16LSB;
 
2097
        else if (ximage->bits_per_pixel == 32)
 
2098
#if !defined(WORD64) && !defined(LONG64)
 
2099
            if (*((char *)&byteorderpixel) == ximage->byte_order)
 
2100
                ximage->f.put_pixel = PutPixel32;
 
2101
            else
 
2102
#endif
 
2103
                if (ximage->bitmap_bit_order == MSBFirst)
 
2104
                    ximage->f.put_pixel = PutPixel32MSB;
 
2105
                else
 
2106
                    ximage->f.put_pixel = PutPixel32LSB;
 
2107
        else if ((ximage->bits_per_pixel | ximage->depth) == 1)
 
2108
            ximage->f.put_pixel = PutPixel1;
 
2109
        else
 
2110
            ximage->f.put_pixel = PutPixel;
 
2111
#endif
 
2112
    }
 
2113
    /* create the shape mask image */
 
2114
    if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
 
2115
        ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
 
2116
                                   width, height, &shapeimage);
 
2117
        if (ErrorStatus != XpmSuccess)
 
2118
            RETURN(ErrorStatus);
 
2119
 
 
2120
#ifndef FOR_MSW
 
2121
        if (shapeimage->bitmap_bit_order == MSBFirst)
 
2122
            shapeimage->f.put_pixel = PutPixel1MSB;
 
2123
        else
 
2124
            shapeimage->f.put_pixel = PutPixel1LSB;
 
2125
#endif
 
2126
    }
 
2127
 
 
2128
    /*
 
2129
     * read pixels and put them in the XImage
 
2130
     */
 
2131
#ifndef FOR_MSW
 
2132
    ErrorStatus = ParseAndPutPixels(data, width, height, ncolors, cpp,
 
2133
#else
 
2134
    ErrorStatus = ParseAndPutPixels(display, data, width, height, ncolors, cpp,
 
2135
#endif
 
2136
                                    colorTable, &hashtable,
 
2137
                                    ximage, image_pixels,
 
2138
                                    shapeimage, mask_pixels);
 
2139
    XpmFree(image_pixels);
 
2140
    image_pixels = NULL;
 
2141
    XpmFree(mask_pixels);
 
2142
    mask_pixels = NULL;
 
2143
 
 
2144
    /*
 
2145
     * free the hastable
 
2146
     */
 
2147
    if (ErrorStatus != XpmSuccess)
 
2148
        RETURN(ErrorStatus)
 
2149
    else if (USE_HASHTABLE)
 
2150
        xpmHashTableFree(&hashtable);
 
2151
 
 
2152
    /*
 
2153
     * store the pixels comment line
 
2154
     */
 
2155
    if (cmts)
 
2156
        xpmGetCmt(data, &pixels_cmt);
 
2157
 
 
2158
    /*
 
2159
     * parse extensions
 
2160
     */
 
2161
    if (info && (info->valuemask & XpmReturnExtensions))
 
2162
    {
 
2163
        if (extensions) {
 
2164
            ErrorStatus = xpmParseExtensions(data, &info->extensions,
 
2165
                                             &info->nextensions);
 
2166
            if (ErrorStatus != XpmSuccess)
 
2167
                RETURN(ErrorStatus);
 
2168
        } else {
 
2169
            info->extensions = NULL;
 
2170
            info->nextensions = 0;
 
2171
        }
 
2172
    }
 
2173
 
 
2174
    /*
 
2175
     * store found informations in the XpmImage structure
 
2176
     */
 
2177
    image->width = width;
 
2178
    image->height = height;
 
2179
    image->cpp = cpp;
 
2180
    image->ncolors = ncolors;
 
2181
    image->colorTable = colorTable;
 
2182
    image->data = NULL;
 
2183
 
 
2184
    if (info) {
 
2185
        if (cmts) {
 
2186
            info->hints_cmt = hints_cmt;
 
2187
            info->colors_cmt = colors_cmt;
 
2188
            info->pixels_cmt = pixels_cmt;
 
2189
        }
 
2190
        if (hotspot) {
 
2191
            info->x_hotspot = x_hotspot;
 
2192
            info->y_hotspot = y_hotspot;
 
2193
            info->valuemask |= XpmHotspot;
 
2194
        }
 
2195
    }
 
2196
    /* if requested return used pixels in the XpmAttributes structure */
 
2197
    if (attributes && (attributes->valuemask & XpmReturnPixels ||
 
2198
/* 3.2 backward compatibility code */
 
2199
        attributes->valuemask & XpmReturnInfos)) {
 
2200
/* end 3.2 bc */
 
2201
        attributes->pixels = used_pixels;
 
2202
        attributes->npixels = nused_pixels;
 
2203
        attributes->mask_pixel = mask_pixel_index;
 
2204
    } else
 
2205
        XpmFree(used_pixels);
 
2206
 
 
2207
    /* if requested return alloc'ed pixels in the XpmAttributes structure */
 
2208
    if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) {
 
2209
        attributes->alloc_pixels = alloc_pixels;
 
2210
        attributes->nalloc_pixels = nalloc_pixels;
 
2211
    } else
 
2212
        XpmFree(alloc_pixels);
 
2213
 
 
2214
    /* return created images */
 
2215
    if (image_return)
 
2216
        *image_return = ximage;
 
2217
    if (shapeimage_return)
 
2218
        *shapeimage_return = shapeimage;
 
2219
 
 
2220
    return (XpmSuccess);
 
2221
}
 
2222
 
 
2223
#ifndef FOR_MSW
 
2224
static int
 
2225
ParseAndPutPixels(data, width, height, ncolors, cpp, colorTable, hashtable,
 
2226
                  image, image_pixels, shapeimage, shape_pixels)
 
2227
#else  /* FOR_MSW */
 
2228
static int
 
2229
ParseAndPutPixels(dc, data, width, height, ncolors, cpp, colorTable, hashtable,
 
2230
                  image, image_pixels, shapeimage, shape_pixels)
 
2231
    Display *dc;
 
2232
#endif
 
2233
    xpmData *data;
 
2234
    unsigned int width;
 
2235
    unsigned int height;
 
2236
    unsigned int ncolors;
 
2237
    unsigned int cpp;
 
2238
    XpmColor *colorTable;
 
2239
    xpmHashTable *hashtable;
 
2240
    XImage *image;
 
2241
    Pixel *image_pixels;
 
2242
    XImage *shapeimage;
 
2243
    Pixel *shape_pixels;
 
2244
{
 
2245
    unsigned int a, x, y;
 
2246
 
 
2247
    switch (cpp) {
 
2248
 
 
2249
    case (1):                           /* Optimize for single character
 
2250
                                         * colors */
 
2251
        {
 
2252
            unsigned short colidx[256];
 
2253
 
 
2254
            if (ncolors > 256)
 
2255
                return (XpmFileInvalid);
 
2256
 
 
2257
            bzero((char *)colidx, 256 * sizeof(short));
 
2258
            for (a = 0; a < ncolors; a++)
 
2259
                colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
 
2260
 
 
2261
            for (y = 0; y < height; y++) {
 
2262
                xpmNextString(data);
 
2263
                for (x = 0; x < width; x++) {
 
2264
                    int c = xpmGetC(data);
 
2265
 
 
2266
                    if (c > 0 && c < 256 && colidx[c] != 0) {
 
2267
#ifndef FOR_MSW
 
2268
                        XPutPixel(image, x, y, image_pixels[colidx[c] - 1]);
 
2269
                        if (shapeimage)
 
2270
                            XPutPixel(shapeimage, x, y,
 
2271
                                      shape_pixels[colidx[c] - 1]);
 
2272
#else
 
2273
                        SelectObject(*dc, image->bitmap);
 
2274
                        SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]);
 
2275
                        if (shapeimage) {
 
2276
                            SelectObject(*dc, shapeimage->bitmap);
 
2277
                            SetPixel(*dc, x, y, shape_pixels[colidx[c] - 1]);
 
2278
                        }
 
2279
#endif
 
2280
                    } else
 
2281
                        return (XpmFileInvalid);
 
2282
                }
 
2283
            }
 
2284
        }
 
2285
        break;
 
2286
 
 
2287
    case (2):                           /* Optimize for double character
 
2288
                                         * colors */
 
2289
        {
 
2290
 
 
2291
/* free all allocated pointers at all exits */
 
2292
#define FREE_CIDX {int f; for (f = 0; f < 256; f++) \
 
2293
if (cidx[f]) XpmFree(cidx[f]);}
 
2294
 
 
2295
            /* array of pointers malloced by need */
 
2296
            unsigned short *cidx[256];
 
2297
            unsigned int char1;
 
2298
 
 
2299
            bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
 
2300
            for (a = 0; a < ncolors; a++) {
 
2301
                char1 = (unsigned char) colorTable[a].string[0];
 
2302
                if (cidx[char1] == NULL) { /* get new memory */
 
2303
                    cidx[char1] = (unsigned short *)
 
2304
                        XpmCalloc(256, sizeof(unsigned short));
 
2305
                    if (cidx[char1] == NULL) { /* new block failed */
 
2306
                        FREE_CIDX;
 
2307
                        return (XpmNoMemory);
 
2308
                    }
 
2309
                }
 
2310
                cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
 
2311
            }
 
2312
 
 
2313
            for (y = 0; y < height; y++) {
 
2314
                xpmNextString(data);
 
2315
                for (x = 0; x < width; x++) {
 
2316
                    int cc1 = xpmGetC(data);
 
2317
                    if (cc1 > 0 && cc1 < 256) {
 
2318
                        int cc2 = xpmGetC(data);
 
2319
                        if (cc2 > 0 && cc2 < 256 && cidx[cc1][cc2] != 0) {
 
2320
#ifndef FOR_MSW
 
2321
                            XPutPixel(image, x, y,
 
2322
                                      image_pixels[cidx[cc1][cc2] - 1]);
 
2323
                            if (shapeimage)
 
2324
                                XPutPixel(shapeimage, x, y,
 
2325
                                          shape_pixels[cidx[cc1][cc2] - 1]);
 
2326
#else
 
2327
                        SelectObject(*dc, image->bitmap);
 
2328
                        SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]);
 
2329
                        if (shapeimage) {
 
2330
                            SelectObject(*dc, shapeimage->bitmap);
 
2331
                            SetPixel(*dc, x, y,
 
2332
                                     shape_pixels[cidx[cc1][cc2] - 1]);
 
2333
                        }
 
2334
#endif
 
2335
                        } else {
 
2336
                            FREE_CIDX;
 
2337
                            return (XpmFileInvalid);
 
2338
                        }
 
2339
                    } else {
 
2340
                        FREE_CIDX;
 
2341
                        return (XpmFileInvalid);
 
2342
                    }
 
2343
                }
 
2344
            }
 
2345
            FREE_CIDX;
 
2346
        }
 
2347
        break;
 
2348
 
 
2349
    default:                            /* Non-optimized case of long color
 
2350
                                         * names */
 
2351
        {
 
2352
            char *s;
 
2353
            char buf[BUFSIZ];
 
2354
 
 
2355
            if (cpp >= sizeof(buf))
 
2356
                return (XpmFileInvalid);
 
2357
 
 
2358
            buf[cpp] = '\0';
 
2359
            if (USE_HASHTABLE) {
 
2360
                xpmHashAtom *slot;
 
2361
 
 
2362
                for (y = 0; y < height; y++) {
 
2363
                    xpmNextString(data);
 
2364
                    for (x = 0; x < width; x++) {
 
2365
                        for (a = 0, s = buf; a < cpp; a++, s++)
 
2366
                            *s = xpmGetC(data);
 
2367
                        slot = xpmHashSlot(hashtable, buf);
 
2368
                        if (!*slot)     /* no color matches */
 
2369
                            return (XpmFileInvalid);
 
2370
#ifndef FOR_MSW
 
2371
                        XPutPixel(image, x, y,
 
2372
                                  image_pixels[HashColorIndex(slot)]);
 
2373
                        if (shapeimage)
 
2374
                            XPutPixel(shapeimage, x, y,
 
2375
                                      shape_pixels[HashColorIndex(slot)]);
 
2376
#else
 
2377
                        SelectObject(*dc, image->bitmap);
 
2378
                        SetPixel(*dc, x, y,
 
2379
                                 image_pixels[HashColorIndex(slot)]);
 
2380
                        if (shapeimage) {
 
2381
                            SelectObject(*dc, shapeimage->bitmap);
 
2382
                            SetPixel(*dc, x, y,
 
2383
                                     shape_pixels[HashColorIndex(slot)]);
 
2384
                        }
 
2385
#endif
 
2386
                    }
 
2387
                }
 
2388
            } else {
 
2389
                for (y = 0; y < height; y++) {
 
2390
                    xpmNextString(data);
 
2391
                    for (x = 0; x < width; x++) {
 
2392
                        for (a = 0, s = buf; a < cpp; a++, s++)
 
2393
                            *s = xpmGetC(data);
 
2394
                        for (a = 0; a < ncolors; a++)
 
2395
                            if (!strcmp(colorTable[a].string, buf))
 
2396
                                break;
 
2397
                        if (a == ncolors)       /* no color matches */
 
2398
                            return (XpmFileInvalid);
 
2399
#ifndef FOR_MSW
 
2400
                        XPutPixel(image, x, y, image_pixels[a]);
 
2401
                        if (shapeimage)
 
2402
                            XPutPixel(shapeimage, x, y, shape_pixels[a]);
 
2403
#else
 
2404
                        SelectObject(*dc, image->bitmap);
 
2405
                        SetPixel(*dc, x, y, image_pixels[a]);
 
2406
                        if (shapeimage) {
 
2407
                            SelectObject(*dc, shapeimage->bitmap);
 
2408
                            SetPixel(*dc, x, y, shape_pixels[a]);
 
2409
                        }
 
2410
#endif
 
2411
                    }
 
2412
                }
 
2413
            }
 
2414
        }
 
2415
        break;
 
2416
    }
 
2417
    return (XpmSuccess);
 
2418
}