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