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

« back to all changes in this revision

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