~ubuntu-branches/ubuntu/lucid/libxpm/lucid

« back to all changes in this revision

Viewing changes to src/scan.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Stone
  • Date: 2005-07-23 01:33:31 UTC
  • Revision ID: james.westby@ubuntu.com-20050723013331-3azqgwnbdc7sjosd
Tags: upstream-3.5.2
ImportĀ upstreamĀ versionĀ 3.5.2

Show diffs side-by-side

added added

removed removed

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